diff --git a/.travis.yml b/.travis.yml index 045f3d8d1..27c725f94 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,16 +23,14 @@ matrix: - go: tip cache: - yarn: true + directories: + - ui/node_modules before_install: - nvm install 8 - nvm use 8 - # Repo for Yarn - - sudo apt-key adv --fetch-keys http://dl.yarnpkg.com/debian/pubkey.gpg - - echo "deb http://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list - - sudo apt-get update -qq - - sudo apt-get install -y -qq yarn + - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.9.4 + - export PATH="$HOME/.yarn/bin:$PATH" branches: only: diff --git a/ui/.editorconfig b/ui/.editorconfig index 219985c22..e37fb8f67 100644 --- a/ui/.editorconfig +++ b/ui/.editorconfig @@ -13,6 +13,11 @@ insert_final_newline = true indent_style = space indent_size = 2 +[*.js] +quote_type = single +max_line_length = 110 + + [*.hbs] insert_final_newline = false diff --git a/ui/.eslintignore b/ui/.eslintignore new file mode 100644 index 000000000..6437276cc --- /dev/null +++ b/ui/.eslintignore @@ -0,0 +1,18 @@ +# unconventional js +/blueprints/*/files/ +/vendor/ + +# compiled output +/dist/ +/tmp/ + +# dependencies +/bower_components/ + +# misc +/coverage/ + +# ember-try +/.node_modules.ember-try/ +/bower.json.ember-try +/package.json.ember-try diff --git a/ui/.eslintrc.js b/ui/.eslintrc.js index f8549e8bb..ea6c16123 100644 --- a/ui/.eslintrc.js +++ b/ui/.eslintrc.js @@ -7,7 +7,8 @@ module.exports = { experimentalObjectRestSpread: true, }, }, - extends: 'eslint:recommended', + plugins: ['ember'], + extends: ['eslint:recommended', 'plugin:ember/recommended'], env: { browser: true, es6: true, @@ -19,4 +20,26 @@ module.exports = { TextEncoderLite: true, TextDecoderLite: true, }, + overrides: [ + // node files + { + files: [ + '.template-lintrc.js', + 'ember-cli-build.js', + 'testem.js', + 'blueprints/*/index.js', + 'config/**/*.js', + 'lib/*/index.js', + 'scripts/start-vault.js', + ], + parserOptions: { + sourceType: 'script', + ecmaVersion: 2015, + }, + env: { + browser: false, + node: true, + }, + }, + ], }; diff --git a/ui/.gitignore b/ui/.gitignore index 8fa39a63c..29c9bc65a 100644 --- a/ui/.gitignore +++ b/ui/.gitignore @@ -1,23 +1,23 @@ # See https://help.github.com/ignore-files/ for more about ignoring files. # compiled output -/dist -/tmp +/dist/ +/tmp/ # dependencies -/node_modules -/bower_components +/bower_components/ +/node_modules/ # misc /.sass-cache /connect.lock -/coverage/* +/coverage/ /libpeerconnection.log -npm-debug.log* -yarn-error.log -testem.log +/npm-debug.log* +/testem.log +/yarn-error.log # ember-try -.node_modules.ember-try/ -bower.json.ember-try -package.json.ember-try +/.node_modules.ember-try/ +/bower.json.ember-try +/package.json.ember-try diff --git a/ui/.template-lintrc.js b/ui/.template-lintrc.js new file mode 100644 index 000000000..dede57c2c --- /dev/null +++ b/ui/.template-lintrc.js @@ -0,0 +1,27 @@ +'use strict'; + +module.exports = { + extends: 'recommended', + rules: { + // should definitely move to template only + // glimmer components for this one + 'no-partial': false, + + // these need to be looked into, but + // may be a bigger change + 'no-invalid-interactive': false, + 'simple-unless': false, + + 'self-closing-void-elements': false, + 'no-unnecessary-concat': false, + 'no-quoteless-attributes': false, + 'no-nested-interactive': false, + + // not sure we'll ever want these on, + // would be nice but if prettier isn't doing + // it for us, then not sure it's worth it + 'attribute-indentation': false, + 'block-indentation': false, + quotes: false, + }, +}; diff --git a/ui/.travis.yml b/ui/.travis.yml deleted file mode 100644 index d98801699..000000000 --- a/ui/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -language: node_js -node_js: - - "4" - -sudo: false - -cache: - directories: - - $HOME/.npm - - $HOME/.cache # includes bowers cache - -before_install: - - npm config set spin false - - npm install -g bower - - bower --version - - npm install phantomjs-prebuilt - - node_modules/phantomjs-prebuilt/bin/phantomjs --version - -install: - - npm install - - bower install - -script: - - npm test diff --git a/ui/README.md b/ui/README.md index 36e562dd1..97ba60b37 100644 --- a/ui/README.md +++ b/ui/README.md @@ -9,6 +9,7 @@ You will need the following things properly installed on your computer. * [Node.js](https://nodejs.org/) (with NPM) * [Yarn](https://yarnpkg.com/en/) +* [Git](https://git-scm.com/) * [Ember CLI](https://ember-cli.com/) @@ -47,6 +48,12 @@ acceptance tests then run, proxing requests back to that server. * `yarn run test -f="policies"` to filter the tests that are run. `-f` gets passed into [QUnit's `filter` config](https://api.qunitjs.com/config/QUnit.config#qunitconfigfilter-string--default-undefined) +### Linting + +* `yarn lint:hbs` +* `yarn lint:js` +* `yarn lint:js -- --fix` + ### Building Vault UI into a Vault Binary We use `go-bindata-assetfs` to build the static assets of the Ember application into a Vault binary. diff --git a/ui/app/adapters/application.js b/ui/app/adapters/application.js index eec635537..caa4d1f77 100644 --- a/ui/app/adapters/application.js +++ b/ui/app/adapters/application.js @@ -1,18 +1,20 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { assign } from '@ember/polyfills'; +import { set } from '@ember/object'; +import RSVP from 'rsvp'; import DS from 'ember-data'; import fetch from 'fetch'; import config from '../config/environment'; const { APP } = config; const { POLLING_URLS, NAMESPACE_ROOT_URLS } = APP; -const { inject, assign, set, RSVP } = Ember; export default DS.RESTAdapter.extend({ - auth: inject.service(), - namespaceService: inject.service('namespace'), - controlGroup: inject.service(), + auth: service(), + namespaceService: service('namespace'), + controlGroup: service(), - flashMessages: inject.service(), + flashMessages: service(), namespace: 'v1/sys', diff --git a/ui/app/adapters/auth-method.js b/ui/app/adapters/auth-method.js index 5f36329df..759d3a96b 100644 --- a/ui/app/adapters/auth-method.js +++ b/ui/app/adapters/auth-method.js @@ -1,4 +1,5 @@ -import Ember from 'ember'; +import { assign } from '@ember/polyfills'; +import { get, set } from '@ember/object'; import ApplicationAdapter from './application'; import DS from 'ember-data'; @@ -14,7 +15,7 @@ export default ApplicationAdapter.extend({ }, findAll(store, type, sinceToken, snapshotRecordArray) { - let isUnauthenticated = Ember.get(snapshotRecordArray || {}, 'adapterOptions.unauthenticated'); + let isUnauthenticated = get(snapshotRecordArray || {}, 'adapterOptions.unauthenticated'); if (isUnauthenticated) { let url = `/${this.urlPrefix()}/internal/ui/mounts`; return this.ajax(url, 'GET', { @@ -33,7 +34,7 @@ export default ApplicationAdapter.extend({ } return this.ajax(this.url(), 'GET').catch(e => { if (e instanceof DS.AdapterError) { - Ember.set(e, 'policyPath', 'sys/auth'); + set(e, 'policyPath', 'sys/auth'); } throw e; }); @@ -47,7 +48,7 @@ export default ApplicationAdapter.extend({ return this.ajax(this.url(path), 'POST', { data }).then(() => { // ember data doesn't like 204s if it's not a DELETE return { - data: Ember.assign({}, data, { path: path + '/', id: path }), + data: assign({}, data, { path: path + '/', id: path }), }; }); }, diff --git a/ui/app/adapters/capabilities.js b/ui/app/adapters/capabilities.js index ffdc51aae..f966cb544 100644 --- a/ui/app/adapters/capabilities.js +++ b/ui/app/adapters/capabilities.js @@ -1,6 +1,6 @@ +import { set } from '@ember/object'; import ApplicationAdapter from './application'; import DS from 'ember-data'; -import Ember from 'ember'; export default ApplicationAdapter.extend({ pathForType() { @@ -10,7 +10,7 @@ export default ApplicationAdapter.extend({ findRecord(store, type, id) { return this.ajax(this.buildURL(type), 'POST', { data: { paths: [id] } }).catch(e => { if (e instanceof DS.AdapterError) { - Ember.set(e, 'policyPath', 'sys/capabilities-self'); + set(e, 'policyPath', 'sys/capabilities-self'); } throw e; }); diff --git a/ui/app/adapters/cluster.js b/ui/app/adapters/cluster.js index 97d2f2105..ac5ff7bd3 100644 --- a/ui/app/adapters/cluster.js +++ b/ui/app/adapters/cluster.js @@ -1,9 +1,13 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { assign } from '@ember/polyfills'; +import { hash, resolve } from 'rsvp'; +import { assert } from '@ember/debug'; +import { pluralize } from 'ember-inflector'; + import ApplicationAdapter from './application'; import DS from 'ember-data'; const { AdapterError } = DS; -const { assert, inject } = Ember; const ENDPOINTS = ['health', 'seal-status', 'tokens', 'token', 'seal', 'unseal', 'init', 'capabilities-self']; @@ -19,8 +23,8 @@ const REPLICATION_ENDPOINTS = { const REPLICATION_MODES = ['dr', 'performance']; export default ApplicationAdapter.extend({ - version: inject.service(), - namespaceService: inject.service('namespace'), + version: service(), + namespaceService: service('namespace'), shouldBackgroundReloadRecord() { return true; }, @@ -32,24 +36,24 @@ export default ApplicationAdapter.extend({ if (this.get('version.isEnterprise') && this.get('namespaceService.inRootNamespace')) { fetches.replicationStatus = this.replicationStatus().catch(e => e); } - return Ember.RSVP.hash(fetches).then(({ health, sealStatus, replicationStatus }) => { + return hash(fetches).then(({ health, sealStatus, replicationStatus }) => { let ret = { id, name: snapshot.attr('name'), }; - ret = Ember.assign(ret, health); + ret = assign(ret, health); if (sealStatus instanceof AdapterError === false) { - ret = Ember.assign(ret, { nodes: [sealStatus] }); + ret = assign(ret, { nodes: [sealStatus] }); } if (replicationStatus && replicationStatus instanceof AdapterError === false) { - ret = Ember.assign(ret, replicationStatus.data); + ret = assign(ret, replicationStatus.data); } - return Ember.RSVP.resolve(ret); + return resolve(ret); }); }, pathForType(type) { - return type === 'cluster' ? 'clusters' : Ember.String.pluralize(type); + return type === 'cluster' ? 'clusters' : pluralize(type); }, health() { diff --git a/ui/app/adapters/pki-ca-certificate.js b/ui/app/adapters/pki-ca-certificate.js index f9910220a..187631f69 100644 --- a/ui/app/adapters/pki-ca-certificate.js +++ b/ui/app/adapters/pki-ca-certificate.js @@ -3,8 +3,6 @@ import ApplicationAdapter from './application'; export default ApplicationAdapter.extend({ namespace: 'v1', - defaultSerializer: 'ssh', - url(snapshot, action) { const { backend, caType, type } = snapshot.attributes(); if (action === 'sign-intermediate') { @@ -20,7 +18,7 @@ export default ApplicationAdapter.extend({ }, createRecordOrUpdate(store, type, snapshot, requestType) { - const serializer = store.serializerFor(this.get('defaultSerializer')); + const serializer = store.serializerFor('application'); const isUpload = snapshot.attr('uploadPemBundle'); const isSetSignedIntermediate = snapshot.adapterOptions.method === 'setSignedIntermediate'; let action = snapshot.adapterOptions.method === 'signIntermediate' ? 'sign-intermediate' : null; diff --git a/ui/app/adapters/pki-certificate.js b/ui/app/adapters/pki-certificate.js index 8ec9553b2..942d2610b 100644 --- a/ui/app/adapters/pki-certificate.js +++ b/ui/app/adapters/pki-certificate.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { assign } from '@ember/polyfills'; import Adapter from './pki'; export default Adapter.extend({ @@ -33,7 +33,7 @@ export default Adapter.extend({ data.id = id; data.id_for_nav = `cert/${id}`; } - return Ember.assign({}, resp, data); + return assign({}, resp, data); }); }, @@ -60,7 +60,7 @@ export default Adapter.extend({ serial_number: id, backend, }; - return Ember.assign({}, resp, data); + return assign({}, resp, data); }); }, }); diff --git a/ui/app/adapters/pki-config.js b/ui/app/adapters/pki-config.js index 86ae8ae6c..c6bc8abf4 100644 --- a/ui/app/adapters/pki-config.js +++ b/ui/app/adapters/pki-config.js @@ -1,12 +1,12 @@ +import { hash, resolve } from 'rsvp'; +import { capitalize } from '@ember/string'; +import { set } from '@ember/object'; import ApplicationAdapter from './application'; import DS from 'ember-data'; -import Ember from 'ember'; export default ApplicationAdapter.extend({ namespace: 'v1', - defaultSerializer: 'config', - urlFor(backend, section) { const urls = { tidy: `/v1/${backend}/tidy`, @@ -18,7 +18,7 @@ export default ApplicationAdapter.extend({ createOrUpdate(store, type, snapshot) { const url = this.urlFor(snapshot.record.get('backend'), snapshot.adapterOptions.method); - const serializer = store.serializerFor(this.get('defaultSerializer')); + const serializer = store.serializerFor(type.modelName); if (!url) { return; } @@ -31,7 +31,11 @@ export default ApplicationAdapter.extend({ } return data; }, {}); - return this.ajax(url, 'POST', { data }); + return this.ajax(url, 'POST', { data }).then(resp => { + let response = resp || {}; + response.id = `${snapshot.record.get('backend')}-${snapshot.adapterOptions.method}`; + return response; + }); }, createRecord() { @@ -46,10 +50,10 @@ export default ApplicationAdapter.extend({ const sections = ['cert', 'urls', 'crl', 'tidy']; if (!section || !sections.includes(section)) { const error = new DS.AdapterError(); - Ember.set(error, 'httpStatus', 404); + set(error, 'httpStatus', 404); throw error; } - return this[`fetch${Ember.String.capitalize(section)}`](backendPath); + return this[`fetch${capitalize(section)}`](backendPath); }, id(backendPath) { @@ -62,7 +66,7 @@ export default ApplicationAdapter.extend({ const pemURL = `${derURL}/pem`; const chainURL = `${derURL}_chain`; - return Ember.RSVP.hash({ + return hash({ backend: backendPath, id: this.id(backendPath), der: this.rawRequest(derURL, 'GET', { unauthenticated: true }).then(response => response.blob()), @@ -82,7 +86,7 @@ export default ApplicationAdapter.extend({ }) .catch(e => { if (e.httpStatus === 404) { - return Ember.RSVP.resolve({ id }); + return resolve({ id }); } else { throw e; } @@ -109,7 +113,7 @@ export default ApplicationAdapter.extend({ fetchTidy(backendPath) { const id = this.id(backendPath); - return Ember.RSVP.resolve({ id, backend: backendPath }); + return resolve({ id, backend: backendPath }); }, queryRecord(store, type, query) { diff --git a/ui/app/adapters/pki.js b/ui/app/adapters/pki.js index bcebb8273..7972bfd16 100644 --- a/ui/app/adapters/pki.js +++ b/ui/app/adapters/pki.js @@ -1,13 +1,11 @@ +import { assert } from '@ember/debug'; import ApplicationAdapter from './application'; -import Ember from 'ember'; export default ApplicationAdapter.extend({ namespace: 'v1', - defaultSerializer: 'ssh', - url(/*role*/) { - Ember.assert('Override the `url` method to extend the SSH adapter', false); + assert('Override the `url` method to extend the SSH adapter', false); }, createRecord(store, type, snapshot, requestType) { diff --git a/ui/app/adapters/policy.js b/ui/app/adapters/policy.js index 5846e31d9..7d86987b1 100644 --- a/ui/app/adapters/policy.js +++ b/ui/app/adapters/policy.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { assign } from '@ember/polyfills'; import ApplicationAdapter from './application'; export default ApplicationAdapter.extend({ @@ -16,7 +16,7 @@ export default ApplicationAdapter.extend({ return this.ajax(this.buildURL(type.modelName, name), 'PUT', { data }).then(() => { // doing this to make it like a Vault response - ember data doesn't like 204s if it's not a DELETE return { - data: Ember.assign({}, snapshot.record.toJSON(), { id: name }), + data: assign({}, snapshot.record.toJSON(), { id: name }), }; }); }, diff --git a/ui/app/adapters/role-aws.js b/ui/app/adapters/role-aws.js index 67f50ef77..cd3b330bf 100644 --- a/ui/app/adapters/role-aws.js +++ b/ui/app/adapters/role-aws.js @@ -1,5 +1,5 @@ +import { assign } from '@ember/polyfills'; import ApplicationAdapter from './application'; -import Ember from 'ember'; export default ApplicationAdapter.extend({ namespace: 'v1', @@ -55,7 +55,7 @@ export default ApplicationAdapter.extend({ backend, }; - return Ember.assign({}, resp, data); + return assign({}, resp, data); }); }, diff --git a/ui/app/adapters/role-pki.js b/ui/app/adapters/role-pki.js index 67f50ef77..cd3b330bf 100644 --- a/ui/app/adapters/role-pki.js +++ b/ui/app/adapters/role-pki.js @@ -1,5 +1,5 @@ +import { assign } from '@ember/polyfills'; import ApplicationAdapter from './application'; -import Ember from 'ember'; export default ApplicationAdapter.extend({ namespace: 'v1', @@ -55,7 +55,7 @@ export default ApplicationAdapter.extend({ backend, }; - return Ember.assign({}, resp, data); + return assign({}, resp, data); }); }, diff --git a/ui/app/adapters/role-ssh.js b/ui/app/adapters/role-ssh.js index 6f33ec4d3..c41c3f40b 100644 --- a/ui/app/adapters/role-ssh.js +++ b/ui/app/adapters/role-ssh.js @@ -1,5 +1,6 @@ +import { assign } from '@ember/polyfills'; +import { resolve, allSettled } from 'rsvp'; import ApplicationAdapter from './application'; -import Ember from 'ember'; export default ApplicationAdapter.extend({ namespace: 'v1', @@ -50,13 +51,13 @@ export default ApplicationAdapter.extend({ fetchByQuery(store, query) { const { id, backend } = query; - let zeroAddressAjax = Ember.RSVP.resolve(); + let zeroAddressAjax = resolve(); const queryAjax = this.ajax(this.urlForRole(backend, id), 'GET', this.optionsForQuery(id)); if (!id) { zeroAddressAjax = this.findAllZeroAddress(store, query); } - return Ember.RSVP.allSettled([queryAjax, zeroAddressAjax]).then(results => { + return allSettled([queryAjax, zeroAddressAjax]).then(results => { // query result 404d, so throw the adapterError if (!results[0].value) { throw results[0].reason; @@ -65,14 +66,15 @@ export default ApplicationAdapter.extend({ id, name: id, backend, + data: {}, }; results.forEach(result => { if (result.value) { if (result.value.data.roles) { - resp = Ember.assign({}, resp, { zero_address_roles: result.value.data.roles }); + resp.data = assign({}, resp.data, { zero_address_roles: result.value.data.roles }); } else { - resp = Ember.assign({}, resp, result.value); + resp.data = assign({}, resp.data, result.value.data); } } }); diff --git a/ui/app/adapters/secret-engine.js b/ui/app/adapters/secret-engine.js index 9f4021931..229015474 100644 --- a/ui/app/adapters/secret-engine.js +++ b/ui/app/adapters/secret-engine.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { assign } from '@ember/polyfills'; import ApplicationAdapter from './application'; export default ApplicationAdapter.extend({ @@ -27,7 +27,7 @@ export default ApplicationAdapter.extend({ return this.ajax(this.url(path), 'POST', { data }).then(() => { // ember data doesn't like 204s if it's not a DELETE return { - data: Ember.assign({}, data, { path: path + '/', id: path }), + data: assign({}, data, { path: path + '/', id: path }), }; }); }, diff --git a/ui/app/adapters/secret-v2.js b/ui/app/adapters/secret-v2.js index 158ccb6d2..d76fb2438 100644 --- a/ui/app/adapters/secret-v2.js +++ b/ui/app/adapters/secret-v2.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { isEmpty } from '@ember/utils'; import SecretAdapter from './secret'; export default SecretAdapter.extend({ @@ -14,7 +14,7 @@ export default SecretAdapter.extend({ urlForSecret(backend, id, infix = 'data') { let url = `${this.buildURL()}/${backend}/${infix}/`; - if (!Ember.isEmpty(id)) { + if (!isEmpty(id)) { url = url + id; } return url; diff --git a/ui/app/adapters/secret.js b/ui/app/adapters/secret.js index 82e652817..30721e95f 100644 --- a/ui/app/adapters/secret.js +++ b/ui/app/adapters/secret.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { isEmpty } from '@ember/utils'; import ApplicationAdapter from './application'; export default ApplicationAdapter.extend({ @@ -27,7 +27,7 @@ export default ApplicationAdapter.extend({ urlForSecret(backend, id) { let url = `${this.buildURL()}/${backend}/`; - if (!Ember.isEmpty(id)) { + if (!isEmpty(id)) { url = url + id; } diff --git a/ui/app/adapters/ssh.js b/ui/app/adapters/ssh.js index d275a43e6..5c3784ab6 100644 --- a/ui/app/adapters/ssh.js +++ b/ui/app/adapters/ssh.js @@ -1,5 +1,5 @@ +import { assert } from '@ember/debug'; import ApplicationAdapter from './application'; -import Ember from 'ember'; export default ApplicationAdapter.extend({ namespace: 'v1', @@ -7,7 +7,7 @@ export default ApplicationAdapter.extend({ defaultSerializer: 'ssh', url(/*role*/) { - Ember.assert('Override the `url` method to extend the SSH adapter', false); + assert('Override the `url` method to extend the SSH adapter', false); }, createRecord(store, type, snapshot, requestType) { diff --git a/ui/app/adapters/transit-key.js b/ui/app/adapters/transit-key.js index 520595300..876c0096a 100644 --- a/ui/app/adapters/transit-key.js +++ b/ui/app/adapters/transit-key.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; import ApplicationAdapter from './application'; +import { pluralize } from 'ember-inflector'; export default ApplicationAdapter.extend({ namespace: 'v1', @@ -40,7 +40,7 @@ export default ApplicationAdapter.extend({ path = 'secrets'; break; default: - path = Ember.String.pluralize(type); + path = pluralize(type); break; } return path; diff --git a/ui/app/app.js b/ui/app/app.js index dde117785..7d6bae3ce 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -1,11 +1,11 @@ -import Ember from 'ember'; +import Application from '@ember/application'; import Resolver from './resolver'; import loadInitializers from 'ember-load-initializers'; import config from './config/environment'; let App; -App = Ember.Application.extend({ +App = Application.extend({ modulePrefix: config.modulePrefix, podModulePrefix: config.podModulePrefix, Resolver, diff --git a/ui/app/components/auth-config-form/config.js b/ui/app/components/auth-config-form/config.js index 8dee9b840..31fd4ac0b 100644 --- a/ui/app/components/auth-config-form/config.js +++ b/ui/app/components/auth-config-form/config.js @@ -1,14 +1,13 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; import { task } from 'ember-concurrency'; import DS from 'ember-data'; -const { inject } = Ember; - -const AuthConfigBase = Ember.Component.extend({ +const AuthConfigBase = Component.extend({ tagName: '', model: null, - flashMessages: inject.service(), + flashMessages: service(), saveModel: task(function*() { try { diff --git a/ui/app/components/auth-form.js b/ui/app/components/auth-form.js index 7f9fcb5a2..ff2164030 100644 --- a/ui/app/components/auth-form.js +++ b/ui/app/components/auth-form.js @@ -1,8 +1,12 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { match, alias, or } from '@ember/object/computed'; +import { assign } from '@ember/polyfills'; +import { dasherize } from '@ember/string'; +import Component from '@ember/component'; +import { get, computed } from '@ember/object'; import { supportedAuthBackends } from 'vault/helpers/supported-auth-backends'; import { task } from 'ember-concurrency'; const BACKENDS = supportedAuthBackends(); -const { computed, inject, get } = Ember; const DEFAULTS = { token: null, @@ -11,12 +15,12 @@ const DEFAULTS = { customPath: null, }; -export default Ember.Component.extend(DEFAULTS, { - router: inject.service(), - auth: inject.service(), - flashMessages: inject.service(), - store: inject.service(), - csp: inject.service('csp-event'), +export default Component.extend(DEFAULTS, { + router: service(), + auth: service(), + flashMessages: service(), + store: service(), + csp: service('csp-event'), // set during init and potentially passed in via a query param selectedAuth: null, @@ -24,6 +28,7 @@ export default Ember.Component.extend(DEFAULTS, { cluster: null, redirectTo: null, namespace: null, + wrappedToken: null, // internal oldNamespace: null, didReceiveAttrs() { @@ -50,30 +55,24 @@ export default Ember.Component.extend(DEFAULTS, { didRender() { this._super(...arguments); + let firstMethod = this.firstMethod(); // on very narrow viewports the active tab may be overflowed, so we scroll it into view here let activeEle = this.element.querySelector('li.is-active'); if (activeEle) { activeEle.scrollIntoView(); } - // this is here because we're changing the `with` attr and there's no way to short-circuit rendering, - // so we'll just nav -> get new attrs -> re-render + // set `with` to the first method if ( - (this.get('fetchMethods.isIdle') && !this.get('selectedAuth')) || + (this.get('fetchMethods.isIdle') && firstMethod && !this.get('selectedAuth')) || (this.get('selectedAuth') && !this.get('selectedAuthBackend')) ) { - this.set('selectedAuth', this.firstMethod()); - this.get('router').replaceWith({ - queryParams: { - with: this.firstMethod(), - wrappedToken: this.get('wrappedToken'), - namespace: this.get('namespace'), - }, - }); + this.set('selectedAuth', firstMethod); } }, firstMethod() { let firstMethod = this.get('methodsToShow.firstObject'); + if (!firstMethod) return; // prefer backends with a path over those with a type return get(firstMethod, 'path') || get(firstMethod, 'type'); }, @@ -82,34 +81,28 @@ export default Ember.Component.extend(DEFAULTS, { this.setProperties(DEFAULTS); }, - selectedAuthIsPath: computed.match('selectedAuth', /\/$/), - selectedAuthBackend: Ember.computed( - 'methods', - 'methods.[]', - 'selectedAuth', - 'selectedAuthIsPath', - function() { - let methods = this.get('methods'); - let selectedAuth = this.get('selectedAuth'); - let keyIsPath = this.get('selectedAuthIsPath'); - if (!methods) { - return {}; - } - if (keyIsPath) { - return methods.findBy('path', selectedAuth); - } - return BACKENDS.findBy('type', selectedAuth); + selectedAuthIsPath: match('selectedAuth', /\/$/), + selectedAuthBackend: computed('methods', 'methods.[]', 'selectedAuth', 'selectedAuthIsPath', function() { + let methods = this.get('methods'); + let selectedAuth = this.get('selectedAuth'); + let keyIsPath = this.get('selectedAuthIsPath'); + if (!methods) { + return {}; } - ), + if (keyIsPath) { + return methods.findBy('path', selectedAuth); + } + return BACKENDS.findBy('type', selectedAuth); + }), providerPartialName: computed('selectedAuthBackend', function() { let type = this.get('selectedAuthBackend.type') || 'token'; type = type.toLowerCase(); - let templateName = Ember.String.dasherize(type); + let templateName = dasherize(type); return `partials/auth-form/${templateName}`; }), - hasCSPError: computed.alias('csp.connectionViolations.firstObject'), + hasCSPError: alias('csp.connectionViolations.firstObject'), cspErrorText: `This is a standby Vault node but can't communicate with the active node via request forwarding. Sign in at the active node to use the Vault UI.`, @@ -159,7 +152,7 @@ export default Ember.Component.extend(DEFAULTS, { } }), - showLoading: computed.or('fetchMethods.isRunning', 'unwrapToken.isRunning'), + showLoading: or('fetchMethods.isRunning', 'unwrapToken.isRunning'), handleError(e) { this.set('loading', false); @@ -186,25 +179,27 @@ export default Ember.Component.extend(DEFAULTS, { ); let attributes = get(backendMeta || {}, 'formAttributes') || {}; - data = Ember.assign(data, this.getProperties(...attributes)); + data = assign(data, this.getProperties(...attributes)); if (this.get('customPath') || get(backend, 'id')) { data.path = this.get('customPath') || get(backend, 'id'); } const clusterId = this.get('cluster.id'); - this.get('auth').authenticate({ clusterId, backend: get(backend, 'type'), data }).then( - ({ isRoot, namespace }) => { - this.set('loading', false); - const transition = this.get('router').transitionTo(targetRoute, { queryParams: { namespace } }); - if (isRoot) { - transition.followRedirects().then(() => { - this.get('flashMessages').warning( - 'You have logged in with a root token. As a security precaution, this root token will not be stored by your browser and you will need to re-authenticate after the window is closed or refreshed.' - ); - }); - } - }, - (...errArgs) => this.handleError(...errArgs) - ); + this.get('auth') + .authenticate({ clusterId, backend: get(backend, 'type'), data }) + .then( + ({ isRoot, namespace }) => { + this.set('loading', false); + const transition = this.get('router').transitionTo(targetRoute, { queryParams: { namespace } }); + if (isRoot) { + transition.followRedirects().then(() => { + this.get('flashMessages').warning( + 'You have logged in with a root token. As a security precaution, this root token will not be stored by your browser and you will need to re-authenticate after the window is closed or refreshed.' + ); + }); + } + }, + (...errArgs) => this.handleError(...errArgs) + ); }, }, }); diff --git a/ui/app/components/auth-info.js b/ui/app/components/auth-info.js index 50e9b3c49..d9127feac 100644 --- a/ui/app/components/auth-info.js +++ b/ui/app/components/auth-info.js @@ -1,19 +1,19 @@ -import Ember from 'ember'; - -const { Component, inject, computed, run } = Ember; +import { inject as service } from '@ember/service'; +import { or } from '@ember/object/computed'; +import Component from '@ember/component'; +import { run } from '@ember/runloop'; export default Component.extend({ - auth: inject.service(), - wizard: inject.service(), - routing: inject.service('-routing'), + auth: service(), + wizard: service(), + router: service(), transitionToRoute: function() { - var router = this.get('routing.router'); - router.transitionTo.apply(router, arguments); + this.get('router').transitionTo(...arguments); }, classNames: 'user-menu auth-info', - isRenewing: computed.or('fakeRenew', 'auth.isRenewing'), + isRenewing: or('fakeRenew', 'auth.isRenewing'), actions: { restartGuide() { @@ -28,9 +28,11 @@ export default Component.extend({ }, revokeToken() { - this.get('auth').revokeCurrentToken().then(() => { - this.transitionToRoute('vault.cluster.logout'); - }); + this.get('auth') + .revokeCurrentToken() + .then(() => { + this.transitionToRoute('vault.cluster.logout'); + }); }, }, }); diff --git a/ui/app/components/b64-toggle.js b/ui/app/components/b64-toggle.js index a84995e84..6013f266d 100644 --- a/ui/app/components/b64-toggle.js +++ b/ui/app/components/b64-toggle.js @@ -1,10 +1,12 @@ -import Ember from 'ember'; +import { equal } from '@ember/object/computed'; +import { isBlank } from '@ember/utils'; +import Component from '@ember/component'; +import { set, get, computed } from '@ember/object'; import { encodeString, decodeString } from 'vault/utils/b64'; -const { computed, get, set } = Ember; const B64 = 'base64'; const UTF8 = 'utf-8'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: 'button', attributeBindings: ['type'], type: 'button', @@ -72,7 +74,7 @@ export default Ember.Component.extend({ * @private * @type boolean */ - isBase64: computed.equal('currentEncoding', B64), + isBase64: equal('currentEncoding', B64), /* * Does the current value match the cached _value, i.e. has the input been mutated since we encoded. @@ -82,7 +84,7 @@ export default Ember.Component.extend({ */ valuesMatch: computed('value', '_value', function() { const { value, _value } = this.getProperties('value', '_value'); - const anyBlank = Ember.isBlank(value) || Ember.isBlank(_value); + const anyBlank = isBlank(value) || isBlank(_value); return !anyBlank && value === _value; }), diff --git a/ui/app/components/config-pki-ca.js b/ui/app/components/config-pki-ca.js index 6eed7d2da..7c4c63e86 100644 --- a/ui/app/components/config-pki-ca.js +++ b/ui/app/components/config-pki-ca.js @@ -1,11 +1,12 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { not } from '@ember/object/computed'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; -const { computed, inject } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ classNames: 'config-pki-ca', - store: inject.service('store'), - flashMessages: inject.service(), + store: service('store'), + flashMessages: service(), /* * @param boolean @@ -34,7 +35,7 @@ export default Ember.Component.extend({ * * true when there's no CA cert currently configured */ - needsConfig: computed.not('config.pem'), + needsConfig: not('config.pem'), /* * @param DS.Model @@ -62,7 +63,7 @@ export default Ember.Component.extend({ * function that gets called to refresh the config model * */ - onRefresh: () => {}, + onRefresh() {}, loading: false, @@ -148,6 +149,9 @@ export default Ember.Component.extend({ ); } }) + .catch(() => { + // handle promise rejection - error will be shown by message-error component + }) .finally(() => { this.set('loading', false); }); diff --git a/ui/app/components/config-pki.js b/ui/app/components/config-pki.js index dd3a2165b..e0893994f 100644 --- a/ui/app/components/config-pki.js +++ b/ui/app/components/config-pki.js @@ -1,10 +1,10 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; +import { get } from '@ember/object'; -const { get, inject } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ classNames: 'config-pki', - flashMessages: inject.service(), + flashMessages: service(), /* * @@ -32,7 +32,7 @@ export default Ember.Component.extend({ * function that gets called to refresh the config model * */ - onRefresh: () => {}, + onRefresh() {}, loading: false, @@ -55,6 +55,9 @@ export default Ember.Component.extend({ } this.send('refresh'); }) + .catch(() => { + // handle promise rejection - error will be shown by message-error component + }) .finally(() => { this.set('loading', false); }); diff --git a/ui/app/components/confirm-action.js b/ui/app/components/confirm-action.js index d3532584d..f36c613fc 100644 --- a/ui/app/components/confirm-action.js +++ b/ui/app/components/confirm-action.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Component from '@ember/component'; import hbs from 'htmlbars-inline-precompile'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: 'span', classNames: ['confirm-action'], layout: hbs` diff --git a/ui/app/components/console/command-input.js b/ui/app/components/console/command-input.js index 3e9d59a5e..228122fe6 100644 --- a/ui/app/components/console/command-input.js +++ b/ui/app/components/console/command-input.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Component from '@ember/component'; import keys from 'vault/lib/keycodes'; -export default Ember.Component.extend({ +export default Component.extend({ onExecuteCommand() {}, onFullscreen() {}, onValueUpdate() {}, diff --git a/ui/app/components/console/log-command.js b/ui/app/components/console/log-command.js index 6e705e676..557064773 100644 --- a/ui/app/components/console/log-command.js +++ b/ui/app/components/console/log-command.js @@ -1,3 +1,3 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({}); +export default Component.extend({}); diff --git a/ui/app/components/console/log-error.js b/ui/app/components/console/log-error.js index 6e705e676..557064773 100644 --- a/ui/app/components/console/log-error.js +++ b/ui/app/components/console/log-error.js @@ -1,3 +1,3 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({}); +export default Component.extend({}); diff --git a/ui/app/components/console/log-help.js b/ui/app/components/console/log-help.js index 6e705e676..557064773 100644 --- a/ui/app/components/console/log-help.js +++ b/ui/app/components/console/log-help.js @@ -1,3 +1,3 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({}); +export default Component.extend({}); diff --git a/ui/app/components/console/log-json.js b/ui/app/components/console/log-json.js index 2d97144cd..2eef304e8 100644 --- a/ui/app/components/console/log-json.js +++ b/ui/app/components/console/log-json.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-component': 'console/log-json', }); diff --git a/ui/app/components/console/log-list.js b/ui/app/components/console/log-list.js index fcca15f27..8da580793 100644 --- a/ui/app/components/console/log-list.js +++ b/ui/app/components/console/log-list.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; -const { computed } = Ember; +import Component from '@ember/component'; +import { computed } from '@ember/object'; -export default Ember.Component.extend({ +export default Component.extend({ content: null, list: computed('content', function() { return this.get('content').keys; diff --git a/ui/app/components/console/log-object.js b/ui/app/components/console/log-object.js index 275f1edb7..d59ed8e9b 100644 --- a/ui/app/components/console/log-object.js +++ b/ui/app/components/console/log-object.js @@ -1,6 +1,7 @@ -import Ember from 'ember'; +import { capitalize } from '@ember/string'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import columnify from 'columnify'; -const { computed } = Ember; export function stringifyObjectValues(data) { Object.keys(data).forEach(item => { @@ -12,7 +13,7 @@ export function stringifyObjectValues(data) { }); } -export default Ember.Component.extend({ +export default Component.extend({ content: null, columns: computed('content', function() { let data = this.get('content'); @@ -21,7 +22,7 @@ export default Ember.Component.extend({ return columnify(data, { preserveNewLines: true, headingTransform: function(heading) { - return Ember.String.capitalize(heading); + return capitalize(heading); }, }); }), diff --git a/ui/app/components/console/log-success.js b/ui/app/components/console/log-success.js index 6e705e676..557064773 100644 --- a/ui/app/components/console/log-success.js +++ b/ui/app/components/console/log-success.js @@ -1,3 +1,3 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({}); +export default Component.extend({}); diff --git a/ui/app/components/console/log-text.js b/ui/app/components/console/log-text.js index b51ce621b..227e2c872 100644 --- a/ui/app/components/console/log-text.js +++ b/ui/app/components/console/log-text.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-component': 'console/log-text', }); diff --git a/ui/app/components/console/output-log.js b/ui/app/components/console/output-log.js index a4c209e24..b5f686448 100644 --- a/ui/app/components/console/output-log.js +++ b/ui/app/components/console/output-log.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-component': 'console/output-log', log: null, }); diff --git a/ui/app/components/console/ui-panel.js b/ui/app/components/console/ui-panel.js index 11fb41397..11487462b 100644 --- a/ui/app/components/console/ui-panel.js +++ b/ui/app/components/console/ui-panel.js @@ -1,4 +1,8 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { alias, or } from '@ember/object/computed'; +import Component from '@ember/component'; +import { getOwner } from '@ember/application'; +import { run } from '@ember/runloop'; import { task } from 'ember-concurrency'; import ControlGroupError from 'vault/lib/control-group-error'; import { @@ -10,19 +14,17 @@ import { executeUICommand, } from 'vault/lib/console-helpers'; -const { inject, computed, getOwner, run } = Ember; - -export default Ember.Component.extend({ - console: inject.service(), - router: inject.service(), - controlGroup: inject.service(), - store: inject.service(), +export default Component.extend({ + console: service(), + router: service(), + controlGroup: service(), + store: service(), classNames: 'console-ui-panel-scroller', classNameBindings: ['isFullscreen:fullscreen'], isFullscreen: false, inputValue: null, - log: computed.alias('console.log'), + log: alias('console.log'), didRender() { this._super(...arguments); @@ -34,7 +36,7 @@ export default Ember.Component.extend({ run.schedule('afterRender', () => this.scrollToBottom()); }, - isRunning: computed.or('executeCommand.isRunning', 'refreshRoute.isRunning'), + isRunning: or('executeCommand.isRunning', 'refreshRoute.isRunning'), executeCommand: task(function*(command, shouldThrow = false) { this.set('inputValue', ''); diff --git a/ui/app/components/control-group-success.js b/ui/app/components/control-group-success.js index 797d5a250..d5659e619 100644 --- a/ui/app/components/control-group-success.js +++ b/ui/app/components/control-group-success.js @@ -1,12 +1,11 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; import { task } from 'ember-concurrency'; -const { inject } = Ember; - -export default Ember.Component.extend({ - router: inject.service(), - controlGroup: inject.service(), - store: inject.service(), +export default Component.extend({ + router: service(), + controlGroup: service(), + store: service(), // public attrs model: null, diff --git a/ui/app/components/control-group.js b/ui/app/components/control-group.js index 785c413bb..0e20bdaec 100644 --- a/ui/app/components/control-group.js +++ b/ui/app/components/control-group.js @@ -1,12 +1,13 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { alias, or } from '@ember/object/computed'; +import Component from '@ember/component'; +import { computed, get } from '@ember/object'; import { task } from 'ember-concurrency'; -const { get, computed, inject } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', - auth: inject.service(), - controlGroup: inject.service(), + auth: service(), + controlGroup: service(), // public API model: null, @@ -18,7 +19,7 @@ export default Ember.Component.extend({ this.set('controlGroupResponse', data); }, - currentUserEntityId: computed.alias('auth.authData.entity_id'), + currentUserEntityId: alias('auth.authData.entity_id'), currentUserIsRequesting: computed('currentUserEntityId', 'model.requestEntity.id', function() { return this.get('currentUserEntityId') === this.get('model.requestEntity.id'); @@ -29,7 +30,7 @@ export default Ember.Component.extend({ return Boolean(authorizations.findBy('id', this.get('currentUserEntityId'))); }), - isSuccess: computed.or('currentUserHasAuthorized', 'model.approved'), + isSuccess: or('currentUserHasAuthorized', 'model.approved'), requestorName: computed('currentUserIsRequesting', 'model.requestEntity', function() { let entity = this.get('model.requestEntity'); diff --git a/ui/app/components/doc-link.js b/ui/app/components/doc-link.js index 6a2a90887..2bc9bb163 100644 --- a/ui/app/components/doc-link.js +++ b/ui/app/components/doc-link.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import hbs from 'htmlbars-inline-precompile'; -const { Component, computed } = Ember; - export default Component.extend({ tagName: 'a', classNames: ['doc-link'], diff --git a/ui/app/components/download-button.js b/ui/app/components/download-button.js index 4ba0c338e..46ce12198 100644 --- a/ui/app/components/download-button.js +++ b/ui/app/components/download-button.js @@ -1,9 +1,8 @@ -import Ember from 'ember'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import hbs from 'htmlbars-inline-precompile'; -const { computed } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ layout: hbs`{{#if hasBlock}} {{yield}} {{else}} {{actionText}} {{/if}}`, tagName: 'a', role: 'button', diff --git a/ui/app/components/edit-form.js b/ui/app/components/edit-form.js index caf7f76f4..eb0950bd8 100644 --- a/ui/app/components/edit-form.js +++ b/ui/app/components/edit-form.js @@ -1,10 +1,10 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; import { task } from 'ember-concurrency'; import DS from 'ember-data'; -const { inject } = Ember; -export default Ember.Component.extend({ - flashMessages: inject.service(), +export default Component.extend({ + flashMessages: service(), // public API model: null, diff --git a/ui/app/components/edition-badge.js b/ui/app/components/edition-badge.js index a7b6146b8..025f657be 100644 --- a/ui/app/components/edition-badge.js +++ b/ui/app/components/edition-badge.js @@ -1,10 +1,11 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: 'span', classNames: 'tag is-outlined edition-badge', attributeBindings: ['edition:aria-label'], - icon: Ember.computed('edition', function() { + icon: computed('edition', function() { const edition = this.get('edition'); const entEditions = ['Enterprise', 'Premium', 'Pro']; diff --git a/ui/app/components/flash-message.js b/ui/app/components/flash-message.js index 02753442d..30379488d 100644 --- a/ui/app/components/flash-message.js +++ b/ui/app/components/flash-message.js @@ -1,8 +1,6 @@ -import Ember from 'ember'; +import { getWithDefault, computed } from '@ember/object'; import FlashMessage from 'ember-cli-flash/components/flash-message'; -const { computed, getWithDefault } = Ember; - export default FlashMessage.extend({ // override alertType to get Bulma specific prefix //https://github.com/poteto/ember-cli-flash/blob/master/addon/components/flash-message.js#L35 diff --git a/ui/app/components/flex-table-column.js b/ui/app/components/flex-table-column.js index 8c57d221e..361dd21b6 100644 --- a/ui/app/components/flex-table-column.js +++ b/ui/app/components/flex-table-column.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ classNames: 'column', header: null, content: null, diff --git a/ui/app/components/form-field-groups.js b/ui/app/components/form-field-groups.js index 86c32730d..29341dcdb 100644 --- a/ui/app/components/form-field-groups.js +++ b/ui/app/components/form-field-groups.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; -const { computed } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', /* diff --git a/ui/app/components/form-field.js b/ui/app/components/form-field.js index b37dc6810..893862069 100644 --- a/ui/app/components/form-field.js +++ b/ui/app/components/form-field.js @@ -1,10 +1,10 @@ -import Ember from 'ember'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import { capitalize } from 'vault/helpers/capitalize'; import { humanize } from 'vault/helpers/humanize'; import { dasherize } from 'vault/helpers/dasherize'; -const { computed } = Ember; -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-field': true, classNames: ['field'], @@ -42,7 +42,7 @@ export default Ember.Component.extend({ * Computed property used in the label element next to the form element * */ - labelString: computed('attr.name', 'attr.options.label', function() { + labelString: computed('attr.{name,options.label}', function() { const label = this.get('attr.options.label'); const name = this.get('attr.name'); if (label) { @@ -61,7 +61,7 @@ export default Ember.Component.extend({ * Computed property used to set values on the passed model * */ - valuePath: computed('attr.name', 'attr.options.fieldValue', function() { + valuePath: computed('attr.{name,options.fieldValue}', function() { return this.get('attr.options.fieldValue') || this.get('attr.name'); }), @@ -80,7 +80,9 @@ export default Ember.Component.extend({ * * Used by the pgp-file component when an attr is editType of 'file' */ - file: { value: '' }, + file: computed(function() { + return { value: '' }; + }), emptyData: '{\n}', actions: { diff --git a/ui/app/components/generate-credentials.js b/ui/app/components/generate-credentials.js index d6851ad94..159d7350b 100644 --- a/ui/app/components/generate-credentials.js +++ b/ui/app/components/generate-credentials.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; - -const { get, set, computed, Component, inject } = Ember; +import { inject as service } from '@ember/service'; +import { computed, set } from '@ember/object'; +import Component from '@ember/component'; const MODEL_TYPES = { 'ssh-sign': { @@ -26,13 +26,14 @@ const MODEL_TYPES = { }; export default Component.extend({ - wizard: inject.service(), - store: inject.service(), - routing: inject.service('-routing'), + wizard: service(), + store: service(), + router: service(), // set on the component - backend: null, + backendType: null, + backendPath: null, + roleName: null, action: null, - role: null, model: null, loading: false, @@ -44,13 +45,12 @@ export default Component.extend({ return type.model; } // if we don't have a mode for that type then redirect them back to the backend list - const router = this.get('routing.router'); - router.transitionTo.call(router, 'vault.cluster.secrets.backend.list-root', this.get('model.backend')); + this.get('router').transitionTo('vault.cluster.secrets.backend.list-root', this.get('backendPath')); }, - options: computed('action', 'backend.type', function() { + options: computed('action', 'backendType', function() { const action = this.get('action') || 'creds'; - return MODEL_TYPES[`${this.get('backend.type')}-${action}`]; + return MODEL_TYPES[`${this.get('backendType')}-${action}`]; }), init() { @@ -63,7 +63,7 @@ export default Component.extend({ this.get('wizard').transitionFeatureMachine( this.get('wizard.featureState'), 'CONTINUE', - this.get('backend.type') + this.get('backendType') ); } }, @@ -76,7 +76,8 @@ export default Component.extend({ createOrReplaceModel() { const modelType = this.modelForType(); const model = this.get('model'); - const roleModel = this.get('role'); + const roleName = this.get('roleName'); + const backendPath = this.get('backendPath'); if (!modelType) { return; } @@ -84,8 +85,11 @@ export default Component.extend({ model.unloadRecord(); } const attrs = { - role: roleModel, - id: `${get(roleModel, 'backend')}-${get(roleModel, 'name')}`, + role: { + backend: backendPath, + name: roleName, + }, + id: `${backendPath}-${roleName}`, }; const newModel = this.get('store').createRecord(modelType, attrs); this.set('model', newModel); @@ -102,7 +106,7 @@ export default Component.extend({ this.get('wizard').transitionFeatureMachine( this.get('wizard.featureState'), 'ERROR', - this.get('backend.type') + this.get('backendType') ); } }) diff --git a/ui/app/components/home-link.js b/ui/app/components/home-link.js index 98d8964f5..1322d3a31 100644 --- a/ui/app/components/home-link.js +++ b/ui/app/components/home-link.js @@ -1,6 +1,5 @@ -import Ember from 'ember'; - -const { Component, computed } = Ember; +import Component from '@ember/component'; +import { computed } from '@ember/object'; export default Component.extend({ tagName: '', diff --git a/ui/app/components/hover-copy-button.js b/ui/app/components/hover-copy-button.js index 52c59f2f3..8c4f08ee3 100644 --- a/ui/app/components/hover-copy-button.js +++ b/ui/app/components/hover-copy-button.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-hover-copy': true, classNameBindings: 'alwaysShow:hover-copy-button-static:hover-copy-button', copyValue: null, diff --git a/ui/app/components/i-con.js b/ui/app/components/i-con.js index cc82e8f51..e57f1fe44 100644 --- a/ui/app/components/i-con.js +++ b/ui/app/components/i-con.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import { camelize } from '@ember/string'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import hbs from 'htmlbars-inline-precompile'; -const { computed } = Ember; const GLYPHS_WITH_SVG_TAG = [ 'learn', 'video', @@ -23,7 +24,7 @@ const GLYPHS_WITH_SVG_TAG = [ 'edition-oss', ]; -export default Ember.Component.extend({ +export default Component.extend({ layout: hbs` {{#if excludeSVG}} {{partial partialName}} @@ -54,6 +55,6 @@ export default Ember.Component.extend({ partialName: computed('glyph', function() { const glyph = this.get('glyph'); - return `svg/icons/${Ember.String.camelize(glyph)}`; + return `svg/icons/${camelize(glyph)}`; }), }); diff --git a/ui/app/components/identity/_popup-base.js b/ui/app/components/identity/_popup-base.js index c74803ade..eaf8f0be9 100644 --- a/ui/app/components/identity/_popup-base.js +++ b/ui/app/components/identity/_popup-base.js @@ -1,9 +1,10 @@ -import Ember from 'ember'; -const { assert, inject, Component } = Ember; +import { inject as service } from '@ember/service'; +import { assert } from '@ember/debug'; +import Component from '@ember/component'; export default Component.extend({ tagName: '', - flashMessages: inject.service(), + flashMessages: service(), params: null, successMessage() { return 'Save was successful'; diff --git a/ui/app/components/identity/edit-form.js b/ui/app/components/identity/edit-form.js index 59e6173b5..0890486b9 100644 --- a/ui/app/components/identity/edit-form.js +++ b/ui/app/components/identity/edit-form.js @@ -1,10 +1,11 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import { task } from 'ember-concurrency'; import { humanize } from 'vault/helpers/humanize'; -const { computed, inject } = Ember; -export default Ember.Component.extend({ - flashMessages: inject.service(), +export default Component.extend({ + flashMessages: service(), 'data-test-component': 'identity-edit-form', model: null, diff --git a/ui/app/components/identity/item-details.js b/ui/app/components/identity/item-details.js index fc06e9746..929668288 100644 --- a/ui/app/components/identity/item-details.js +++ b/ui/app/components/identity/item-details.js @@ -1,9 +1,8 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; -const { inject } = Ember; - -export default Ember.Component.extend({ - flashMessages: inject.service(), +export default Component.extend({ + flashMessages: service(), actions: { enable(model) { diff --git a/ui/app/components/identity/lookup-input.js b/ui/app/components/identity/lookup-input.js index 9dbc9cb16..2e83204a6 100644 --- a/ui/app/components/identity/lookup-input.js +++ b/ui/app/components/identity/lookup-input.js @@ -1,13 +1,12 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; import { task } from 'ember-concurrency'; import { underscore } from 'vault/helpers/underscore'; -const { inject } = Ember; - -export default Ember.Component.extend({ - store: inject.service(), - flashMessages: inject.service(), - routing: inject.service('-routing'), +export default Component.extend({ + store: service(), + flashMessages: service(), + router: service(), // Public API - either 'entity' or 'group' // this will determine which adapter is used to make the lookup call @@ -21,10 +20,12 @@ export default Ember.Component.extend({ init() { this._super(...arguments); - this.get('store').findAll('auth-method').then(methods => { - this.set('authMethods', methods); - this.set('aliasMountAccessor', methods.get('firstObject.accessor')); - }); + this.get('store') + .findAll('auth-method') + .then(methods => { + this.set('authMethods', methods); + this.set('aliasMountAccessor', methods.get('firstObject.accessor')); + }); }, adapter() { @@ -63,11 +64,7 @@ export default Ember.Component.extend({ return; } if (response) { - return this.get('routing.router').transitionTo( - 'vault.cluster.access.identity.show', - response.id, - 'details' - ); + return this.get('router').transitionTo('vault.cluster.access.identity.show', response.id, 'details'); } else { flash.danger(`We were unable to find an identity ${type} with a "${param}" of "${paramValue}".`); } diff --git a/ui/app/components/identity/popup-members.js b/ui/app/components/identity/popup-members.js index 6c096916f..560a4b1ce 100644 --- a/ui/app/components/identity/popup-members.js +++ b/ui/app/components/identity/popup-members.js @@ -1,9 +1,9 @@ +import { alias } from '@ember/object/computed'; +import { computed } from '@ember/object'; import Base from './_popup-base'; -import Ember from 'ember'; -const { computed } = Ember; export default Base.extend({ - model: computed.alias('params.firstObject'), + model: alias('params.firstObject'), groupArray: computed('params', function() { return this.get('params').objectAt(1); diff --git a/ui/app/components/identity/popup-policy.js b/ui/app/components/identity/popup-policy.js index b626b23c2..303081850 100644 --- a/ui/app/components/identity/popup-policy.js +++ b/ui/app/components/identity/popup-policy.js @@ -1,9 +1,9 @@ +import { alias } from '@ember/object/computed'; +import { computed } from '@ember/object'; import Base from './_popup-base'; -import Ember from 'ember'; -const { computed } = Ember; export default Base.extend({ - model: computed.alias('params.firstObject'), + model: alias('params.firstObject'), policyName: computed('params', function() { return this.get('params').objectAt(1); }), diff --git a/ui/app/components/info-table-row.js b/ui/app/components/info-table-row.js index 0c12595f1..1be591196 100644 --- a/ui/app/components/info-table-row.js +++ b/ui/app/components/info-table-row.js @@ -1,9 +1,12 @@ -import Ember from 'ember'; +import { typeOf } from '@ember/utils'; +import { computed } from '@ember/object'; +import { or } from '@ember/object/computed'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-component': 'info-table-row', classNames: ['info-table-row'], - isVisible: Ember.computed.or('alwaysRender', 'value'), + isVisible: or('alwaysRender', 'value'), /* * @param boolean @@ -25,7 +28,7 @@ export default Ember.Component.extend({ */ value: null, - valueIsBoolean: Ember.computed('value', function() { - return Ember.typeOf(this.get('value')) === 'boolean'; + valueIsBoolean: computed('value', function() { + return typeOf(this.get('value')) === 'boolean'; }), }); diff --git a/ui/app/components/info-tooltip.js b/ui/app/components/info-tooltip.js index f7e144d45..f39f4bc58 100644 --- a/ui/app/components/info-tooltip.js +++ b/ui/app/components/info-tooltip.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-component': 'info-tooltip', tagName: 'span', classNames: ['is-inline-block'], diff --git a/ui/app/components/json-editor.js b/ui/app/components/json-editor.js index df1285fda..62de07dc6 100644 --- a/ui/app/components/json-editor.js +++ b/ui/app/components/json-editor.js @@ -1,7 +1,5 @@ +import { assign } from '@ember/polyfills'; import IvyCodemirrorComponent from './ivy-codemirror'; -import Ember from 'ember'; - -const { assign } = Ember; const JSON_EDITOR_DEFAULTS = { // IMPORTANT: `gutters` must come before `lint` since the presence of // `gutters` is cached internally when `lint` is toggled diff --git a/ui/app/components/key-value-header.js b/ui/app/components/key-value-header.js index 998c72240..24498e99a 100644 --- a/ui/app/components/key-value-header.js +++ b/ui/app/components/key-value-header.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import Component from '@ember/component'; import utils from 'vault/lib/key-utils'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: 'nav', classNames: 'key-value-header breadcrumb', ariaLabel: 'breadcrumbs', @@ -16,7 +17,7 @@ export default Ember.Component.extend({ return str[str.length - 1] === '/' ? str.slice(0, -1) : str; }, - currentPath: Ember.computed('mode', 'path', 'showCurrent', function() { + currentPath: computed('mode', 'path', 'showCurrent', function() { const mode = this.get('mode'); const path = this.get('path'); const showCurrent = this.get('showCurrent'); @@ -26,7 +27,7 @@ export default Ember.Component.extend({ return `vault.cluster.secrets.backend.${mode}`; }), - secretPath: Ember.computed('baseKey', 'baseKey.display', 'baseKey.id', 'root', 'showCurrent', function() { + secretPath: computed('baseKey', 'baseKey.{display,id}', 'root', 'showCurrent', function() { let crumbs = []; const root = this.get('root'); const baseKey = this.get('baseKey.display') || this.get('baseKey.id'); diff --git a/ui/app/components/key-version-select.js b/ui/app/components/key-version-select.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/key-version-select.js +++ b/ui/app/components/key-version-select.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/kv-object-editor.js b/ui/app/components/kv-object-editor.js index 0603998ea..07333cca3 100644 --- a/ui/app/components/kv-object-editor.js +++ b/ui/app/components/kv-object-editor.js @@ -1,8 +1,10 @@ -import Ember from 'ember'; +import { isNone } from '@ember/utils'; +import { assert } from '@ember/debug'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; +import { guidFor } from '@ember/object/internals'; import KVObject from 'vault/lib/kv-object'; -const { assert, Component, computed, guidFor } = Ember; - export default Component.extend({ 'data-test-component': 'kv-object-editor', classNames: ['field', 'form-section'], @@ -39,7 +41,7 @@ export default Component.extend({ addRow() { let data = this.get('kvData'); let newObj = { name: '', value: '' }; - if (!Ember.isNone(data.findBy('name', ''))) { + if (!isNone(data.findBy('name', ''))) { return; } guidFor(newObj); diff --git a/ui/app/components/link-to.js b/ui/app/components/link-to.js index 872a2ffac..3e2893a15 100644 --- a/ui/app/components/link-to.js +++ b/ui/app/components/link-to.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import LinkComponent from '@ember/routing/link-component'; -Ember.LinkComponent.reopen({ +LinkComponent.reopen({ activeClass: 'is-active', }); -export default Ember.LinkComponent; +export default LinkComponent; diff --git a/ui/app/components/linked-block.js b/ui/app/components/linked-block.js index cdbaa6c09..d9b459ba8 100644 --- a/ui/app/components/linked-block.js +++ b/ui/app/components/linked-block.js @@ -1,12 +1,14 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; import hbs from 'htmlbars-inline-precompile'; -let LinkedBlockComponent = Ember.Component.extend({ +let LinkedBlockComponent = Component.extend({ + router: service(), + layout: hbs`{{yield}}`, classNames: 'linked-block', - routing: Ember.inject.service('-routing'), queryParams: null, click(event) { @@ -17,13 +19,12 @@ let LinkedBlockComponent = Ember.Component.extend({ $target.closest('button', event.currentTarget).length > 0 || $target.closest('a', event.currentTarget).length > 0; if (!isAnchorOrButton) { - const router = this.get('routing.router'); const params = this.get('params'); const queryParams = this.get('queryParams'); if (queryParams) { params.push({ queryParams }); } - router.transitionTo.apply(router, params); + this.get('router').transitionTo(...params); } }, }); diff --git a/ui/app/components/list-item.js b/ui/app/components/list-item.js index c5d85896f..e4f1f0c0f 100644 --- a/ui/app/components/list-item.js +++ b/ui/app/components/list-item.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; import { task } from 'ember-concurrency'; -const { inject } = Ember; -export default Ember.Component.extend({ - flashMessages: inject.service(), +export default Component.extend({ + flashMessages: service(), tagName: '', linkParams: null, componentName: null, diff --git a/ui/app/components/list-item/content.js b/ui/app/components/list-item/content.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/list-item/content.js +++ b/ui/app/components/list-item/content.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/list-item/popup-menu.js b/ui/app/components/list-item/popup-menu.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/list-item/popup-menu.js +++ b/ui/app/components/list-item/popup-menu.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/list-pagination.js b/ui/app/components/list-pagination.js index 163a253b9..d973566c1 100644 --- a/ui/app/components/list-pagination.js +++ b/ui/app/components/list-pagination.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import { gt } from '@ember/object/computed'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import { range } from 'ember-composable-helpers/helpers/range'; -const { computed } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ classNames: ['box', 'is-shadowless', 'list-pagination'], page: null, lastPage: null, @@ -18,7 +18,7 @@ export default Ember.Component.extend({ return this.get('page') > 1; }), - segmentLinks: computed.gt('lastPage', 10), + segmentLinks: gt('lastPage', 10), pageRange: computed('page', 'lastPage', function() { const { spread, page, lastPage } = this.getProperties('spread', 'page', 'lastPage'); diff --git a/ui/app/components/list-view.js b/ui/app/components/list-view.js index ca6784fdf..47b6c92ea 100644 --- a/ui/app/components/list-view.js +++ b/ui/app/components/list-view.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import { pluralize } from 'ember-inflector'; -const { computed } = Ember; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', items: null, itemNoun: 'item', diff --git a/ui/app/components/logo-splash.js b/ui/app/components/logo-splash.js index 48e3f15c1..0e2733fac 100644 --- a/ui/app/components/logo-splash.js +++ b/ui/app/components/logo-splash.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; -const { inject } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', - version: inject.service(), + version: service(), }); diff --git a/ui/app/components/masked-input.js b/ui/app/components/masked-input.js index 66e38e916..6e47fc8c0 100644 --- a/ui/app/components/masked-input.js +++ b/ui/app/components/masked-input.js @@ -1,51 +1,49 @@ -import Ember from 'ember'; -const { computed } = Ember; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import autosize from 'autosize'; - -export default Ember.Component.extend({ - value: null, - didInsertElement(){ - this._super(...arguments); - autosize(this.element.querySelector('textarea')); - }, - didUpdate(){ - this._super(...arguments); - autosize.update(this.element.querySelector('textarea')); - }, - willDestroyElement(){ - this._super(...arguments); - autosize.destroy(this.element.querySelector('textarea')); - }, - shouldObscure: computed("isMasked", "isFocused", "value", function(){ - if(this.get('value') === "" ){ - return false; - } - if(this.get('isFocused') === true){ - return false; - } - return this.get('isMasked'); - }), - displayValue: computed("shouldObscure", function(){ - if(this.get("shouldObscure")){ - return "■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■"; - } - else{ - return this.get('value'); - } - }), - isMasked: true, - isFocused: false, - displayOnly: false, - onKeyDown(){}, - onChange(){}, - actions: { - toggleMask(){ - this.toggleProperty('isMasked'); - }, - updateValue(e){ - this.set('value', e.target.value); - this.onChange(); - }, - } +export default Component.extend({ + value: null, + didInsertElement() { + this._super(...arguments); + autosize(this.element.querySelector('textarea')); + }, + didUpdate() { + this._super(...arguments); + autosize.update(this.element.querySelector('textarea')); + }, + willDestroyElement() { + this._super(...arguments); + autosize.destroy(this.element.querySelector('textarea')); + }, + shouldObscure: computed('isMasked', 'isFocused', 'value', function() { + if (this.get('value') === '') { + return false; + } + if (this.get('isFocused') === true) { + return false; + } + return this.get('isMasked'); + }), + displayValue: computed('shouldObscure', function() { + if (this.get('shouldObscure')) { + return '■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■'; + } else { + return this.get('value'); + } + }), + isMasked: true, + isFocused: false, + displayOnly: false, + onKeyDown() {}, + onChange() {}, + actions: { + toggleMask() { + this.toggleProperty('isMasked'); + }, + updateValue(e) { + this.set('value', e.target.value); + this.onChange(); + }, + }, }); diff --git a/ui/app/components/menu-sidebar.js b/ui/app/components/menu-sidebar.js index 0382ad413..819ff0a81 100644 --- a/ui/app/components/menu-sidebar.js +++ b/ui/app/components/menu-sidebar.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ classNames: ['column', 'is-sidebar'], classNameBindings: ['isActive:is-active'], isActive: false, diff --git a/ui/app/components/message-error.js b/ui/app/components/message-error.js index 9c5fc7c5d..6003dce9f 100644 --- a/ui/app/components/message-error.js +++ b/ui/app/components/message-error.js @@ -1,15 +1,16 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ model: null, - errors: [], + errors: computed(function() { + return []; + }), errorMessage: null, - displayErrors: Ember.computed( + displayErrors: computed( 'errorMessage', - 'model.isError', - 'model.adapterError.message', - 'model.adapterError.errors.@each', + 'model.{isError,adapterError.message,adapterError.errors.@each}', 'errors', 'errors.@each', function() { diff --git a/ui/app/components/message-in-page.js b/ui/app/components/message-in-page.js index 736739ab3..e5e5c59c7 100644 --- a/ui/app/components/message-in-page.js +++ b/ui/app/components/message-in-page.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import { messageTypes } from 'vault/helpers/message-types'; -const { computed } = Ember; -export default Ember.Component.extend({ +export default Component.extend({ type: null, yieldWithoutColumn: false, diff --git a/ui/app/components/mount-accessor-select.js b/ui/app/components/mount-accessor-select.js index bdd5d7c97..ea4c9a704 100644 --- a/ui/app/components/mount-accessor-select.js +++ b/ui/app/components/mount-accessor-select.js @@ -1,10 +1,9 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; import { task } from 'ember-concurrency'; -const { inject } = Ember; - -export default Ember.Component.extend({ - store: inject.service(), +export default Component.extend({ + store: service(), // Public API //value for the external mount selector diff --git a/ui/app/components/mount-backend-form.js b/ui/app/components/mount-backend-form.js index 54de0825b..6427bd509 100644 --- a/ui/app/components/mount-backend-form.js +++ b/ui/app/components/mount-backend-form.js @@ -1,17 +1,17 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { computed } from '@ember/object'; +import Component from '@ember/component'; import { task } from 'ember-concurrency'; import { methods } from 'vault/helpers/mountable-auth-methods'; import { engines } from 'vault/helpers/mountable-secret-engines'; -const { inject, computed, Component } = Ember; const METHODS = methods(); const ENGINES = engines(); export default Component.extend({ - store: inject.service(), - wizard: inject.service(), - flashMessages: inject.service(), - routing: inject.service('-routing'), + store: service(), + wizard: service(), + flashMessages: service(), /* * @param Function @@ -20,8 +20,8 @@ export default Component.extend({ * Optional param to call a function upon successfully mounting a backend * */ - onMountSuccess: () => {}, - onConfigError: () => {}, + onMountSuccess() {}, + onConfigError() {}, /* * @param String * @public @@ -81,7 +81,7 @@ export default Component.extend({ return; } let configRef = mount.hasMany('authConfigs').value(); - let currentConfig = configRef.get('firstObject'); + let currentConfig = configRef && configRef.get('firstObject'); if (currentConfig) { // rollbackAttributes here will remove the the config model from the store // because `isNew` will be true @@ -125,18 +125,26 @@ export default Component.extend({ yield this.get('saveConfig').perform(mountModel); }).drop(), + advanceWizard() { + this.get('wizard').transitionFeatureMachine( + this.get('wizard.featureState'), + 'CONTINUE', + this.get('mountModel').get('type') + ); + }, saveConfig: task(function*(mountModel) { const configRef = mountModel.hasMany('authConfigs').value(); - const config = configRef.get('firstObject'); const { type, path } = mountModel.getProperties('type', 'path'); + if (!configRef) { + this.advanceWizard(); + yield this.get('onMountSuccess')(type, path); + return; + } + const config = configRef.get('firstObject'); try { if (config && Object.keys(config.changedAttributes()).length) { yield config.save(); - this.get('wizard').transitionFeatureMachine( - this.get('wizard.featureState'), - 'CONTINUE', - this.get('mountModel').get('type') - ); + this.advanceWizard(); this.get('flashMessages').success( `The config for ${type} ${this.get('mountType')} method at ${path} was saved successfully.` ); diff --git a/ui/app/components/mount-filter-config-list.js b/ui/app/components/mount-filter-config-list.js index d05f7ac4e..ceb86ef03 100644 --- a/ui/app/components/mount-filter-config-list.js +++ b/ui/app/components/mount-filter-config-list.js @@ -1,13 +1,14 @@ -import Ember from 'ember'; +import Component from '@ember/component'; +import { set, get, computed } from '@ember/object'; -const { get, set } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ config: null, mounts: null, // singleton mounts are not eligible for per-mount-filtering - singletonMountTypes: ['cubbyhole', 'system', 'token', 'identity', 'ns_system', 'ns_identity'], + singletonMountTypes: computed(function() { + return ['cubbyhole', 'system', 'token', 'identity', 'ns_system', 'ns_identity']; + }), actions: { addOrRemovePath(path, e) { diff --git a/ui/app/components/namespace-link.js b/ui/app/components/namespace-link.js index adad03d1c..d078d4f96 100644 --- a/ui/app/components/namespace-link.js +++ b/ui/app/components/namespace-link.js @@ -1,10 +1,11 @@ -import Ember from 'ember'; - -const { Component, computed, inject } = Ember; +import { inject as service } from '@ember/service'; +import { alias } from '@ember/object/computed'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; export default Component.extend({ - namespaceService: inject.service('namespace'), - currentNamespace: computed.alias('namespaceService.path'), + namespaceService: service('namespace'), + currentNamespace: alias('namespaceService.path'), tagName: '', //public api diff --git a/ui/app/components/namespace-picker.js b/ui/app/components/namespace-picker.js index da8721dfa..e448d1371 100644 --- a/ui/app/components/namespace-picker.js +++ b/ui/app/components/namespace-picker.js @@ -1,17 +1,19 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { alias, gt } from '@ember/object/computed'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import keyUtils from 'vault/lib/key-utils'; import pathToTree from 'vault/lib/path-to-tree'; import { task, timeout } from 'ember-concurrency'; const { ancestorKeysForKey } = keyUtils; -const { Component, computed, inject } = Ember; const DOT_REPLACEMENT = '☃'; const ANIMATION_DURATION = 250; export default Component.extend({ tagName: '', - namespaceService: inject.service('namespace'), - auth: inject.service(), + namespaceService: service('namespace'), + auth: service(), namespace: null, init() { @@ -55,14 +57,14 @@ export default Component.extend({ this.set('lastMenuLeaves', leaves); }).drop(), - isAnimating: computed.alias('setForAnimation.isRunning'), + isAnimating: alias('setForAnimation.isRunning'), - namespacePath: computed.alias('namespaceService.path'), + namespacePath: alias('namespaceService.path'), // this is an array of namespace paths that the current user // has access to - accessibleNamespaces: computed.alias('namespaceService.accessibleNamespaces'), - inRootNamespace: computed.alias('namespaceService.inRootNamespace'), + accessibleNamespaces: alias('namespaceService.accessibleNamespaces'), + inRootNamespace: alias('namespaceService.inRootNamespace'), namespaceTree: computed('accessibleNamespaces', function() { let nsList = this.get('accessibleNamespaces'); @@ -124,8 +126,8 @@ export default Component.extend({ return leaves; }), - currentLeaf: computed.alias('lastMenuLeaves.lastObject'), - canAccessMultipleNamespaces: computed.gt('accessibleNamespaces.length', 1), + currentLeaf: alias('lastMenuLeaves.lastObject'), + canAccessMultipleNamespaces: gt('accessibleNamespaces.length', 1), isUserRootNamespace: computed('auth.authData.userRootNamespace', 'namespacePath', function() { return this.get('auth.authData.userRootNamespace') === this.get('namespacePath'); }), diff --git a/ui/app/components/namespace-reminder.js b/ui/app/components/namespace-reminder.js index 7659d9b62..464f4b6c6 100644 --- a/ui/app/components/namespace-reminder.js +++ b/ui/app/components/namespace-reminder.js @@ -1,10 +1,11 @@ -import Ember from 'ember'; - -const { Component, inject, computed } = Ember; +import { inject as service } from '@ember/service'; +import { not } from '@ember/object/computed'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; export default Component.extend({ - namespace: inject.service(), - showMessage: computed.not('namespace.inRootNamespace'), + namespace: service(), + showMessage: not('namespace.inRootNamespace'), //public API noun: null, mode: 'edit', diff --git a/ui/app/components/nav-header.js b/ui/app/components/nav-header.js index f36a904a1..15a4ae2f5 100644 --- a/ui/app/components/nav-header.js +++ b/ui/app/components/nav-header.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-navheader': true, tagName: 'header', }); diff --git a/ui/app/components/nav-header/home.js b/ui/app/components/nav-header/home.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/nav-header/home.js +++ b/ui/app/components/nav-header/home.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/nav-header/items.js b/ui/app/components/nav-header/items.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/nav-header/items.js +++ b/ui/app/components/nav-header/items.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/nav-header/main.js b/ui/app/components/nav-header/main.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/nav-header/main.js +++ b/ui/app/components/nav-header/main.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/navigate-input.js b/ui/app/components/navigate-input.js index f56c22750..f642b6d1b 100644 --- a/ui/app/components/navigate-input.js +++ b/ui/app/components/navigate-input.js @@ -1,4 +1,7 @@ -import Ember from 'ember'; +import { schedule, debounce } from '@ember/runloop'; +import { observer } from '@ember/object'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; import utils from 'vault/lib/key-utils'; import keys from 'vault/lib/keycodes'; import FocusOnInsertMixin from 'vault/mixins/focus-on-insert'; @@ -22,7 +25,9 @@ const routeFor = function(type, mode) { return useSuffix ? modeVal + '.' + typeVal : modeVal; }; -export default Ember.Component.extend(FocusOnInsertMixin, { +export default Component.extend(FocusOnInsertMixin, { + router: service(), + classNames: ['navigate-filter'], // these get passed in from the outside @@ -38,18 +43,15 @@ export default Ember.Component.extend(FocusOnInsertMixin, { filterMatchesKey: null, firstPartialMatch: null, - routing: Ember.inject.service('-routing'), - transitionToRoute: function() { - var router = this.get('routing.router'); - router.transitionTo.apply(router, arguments); + this.get('router').transitionTo(...arguments); }, shouldFocus: false, - focusFilter: Ember.observer('filter', function() { + focusFilter: observer('filter', function() { if (!this.get('filter')) return; - Ember.run.schedule('afterRender', this, 'forceFocus'); + schedule('afterRender', this, 'forceFocus'); }).on('didInsertElement'), keyForNav(key) { @@ -164,7 +166,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, { handleInput: function(event) { var filter = event.target.value; this.get('filterDidChange')(filter); - Ember.run.debounce(this, 'filterUpdated', filter, 200); + debounce(this, 'filterUpdated', filter, 200); }, setFilterFocused: function(isFocused) { diff --git a/ui/app/components/not-found.js b/ui/app/components/not-found.js index 5d76dd583..9304562f6 100644 --- a/ui/app/components/not-found.js +++ b/ui/app/components/not-found.js @@ -1,12 +1,12 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { alias } from '@ember/object/computed'; +import Component from '@ember/component'; -const { computed, inject } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ // public model: null, tagName: '', - routing: inject.service('-routing'), - path: computed.alias('routing.router.currentURL'), + router: service(), + path: alias('router.currentURL'), }); diff --git a/ui/app/components/outer-html.js b/ui/app/components/outer-html.js index f071ff551..096229835 100644 --- a/ui/app/components/outer-html.js +++ b/ui/app/components/outer-html.js @@ -1,9 +1,9 @@ // THIS COMPONENT IS ONLY FOR EXTENDING // You should use this component if you want to use outerHTML symantics // in your components - this is the default for upcoming Glimmer components -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/page-header-level-left.js b/ui/app/components/page-header-level-left.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/page-header-level-left.js +++ b/ui/app/components/page-header-level-left.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/page-header-level-right.js b/ui/app/components/page-header-level-right.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/page-header-level-right.js +++ b/ui/app/components/page-header-level-right.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/page-header-top.js b/ui/app/components/page-header-top.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/page-header-top.js +++ b/ui/app/components/page-header-top.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/page-header.js b/ui/app/components/page-header.js index 0c8a391ee..9a92d1667 100644 --- a/ui/app/components/page-header.js +++ b/ui/app/components/page-header.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', hasLevel: true, }); diff --git a/ui/app/components/pgp-file.js b/ui/app/components/pgp-file.js index 43735afce..a8e1d1c55 100644 --- a/ui/app/components/pgp-file.js +++ b/ui/app/components/pgp-file.js @@ -1,9 +1,8 @@ -import Ember from 'ember'; - -const { set } = Ember; +import Component from '@ember/component'; +import { set } from '@ember/object'; const BASE_64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gi; -export default Ember.Component.extend({ +export default Component.extend({ classNames: ['box', 'is-fullwidth', 'is-marginless', 'is-shadowless'], key: null, index: null, diff --git a/ui/app/components/pgp-list.js b/ui/app/components/pgp-list.js index b8aed1c78..cd14a91c7 100644 --- a/ui/app/components/pgp-list.js +++ b/ui/app/components/pgp-list.js @@ -1,8 +1,9 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ onDataUpdate: () => {}, - listData: Ember.computed('listLength', function() { + listData: computed('listLength', function() { let num = this.get('listLength'); if (num) { num = parseInt(num, 10); diff --git a/ui/app/components/pki-cert-popup.js b/ui/app/components/pki-cert-popup.js index 64faaeb59..6f4da8d1e 100644 --- a/ui/app/components/pki-cert-popup.js +++ b/ui/app/components/pki-cert-popup.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ /* * @public * @param DS.Model diff --git a/ui/app/components/popup-menu.js b/ui/app/components/popup-menu.js index ced037466..3f263270c 100644 --- a/ui/app/components/popup-menu.js +++ b/ui/app/components/popup-menu.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: 'span', }); diff --git a/ui/app/components/radial-progress.js b/ui/app/components/radial-progress.js index 4ad0d8ddb..4c70f641d 100644 --- a/ui/app/components/radial-progress.js +++ b/ui/app/components/radial-progress.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; -const { computed } = Ember; +import Component from '@ember/component'; +import { computed } from '@ember/object'; -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-radial-progress': true, tagName: 'svg', classNames: 'radial-progress', diff --git a/ui/app/components/replication-actions.js b/ui/app/components/replication-actions.js index 2e1b22a90..f71640057 100644 --- a/ui/app/components/replication-actions.js +++ b/ui/app/components/replication-actions.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import ReplicationActions from 'vault/mixins/replication-actions'; -const { computed } = Ember; - const DEFAULTS = { token: null, primary_api_addr: null, @@ -12,7 +12,7 @@ const DEFAULTS = { replicationMode: null, }; -export default Ember.Component.extend(ReplicationActions, DEFAULTS, { +export default Component.extend(ReplicationActions, DEFAULTS, { replicationMode: null, selectedAction: null, tagName: 'form', @@ -22,7 +22,7 @@ export default Ember.Component.extend(ReplicationActions, DEFAULTS, { }, model: null, - cluster: computed.alias('model'), + cluster: alias('model'), loading: false, onSubmit: null, diff --git a/ui/app/components/replication-mode-summary.js b/ui/app/components/replication-mode-summary.js index 8c5510437..cd7716b8e 100644 --- a/ui/app/components/replication-mode-summary.js +++ b/ui/app/components/replication-mode-summary.js @@ -1,5 +1,7 @@ -import Ember from 'ember'; -const { computed, get, getProperties, Component, inject } = Ember; +import { inject as service } from '@ember/service'; +import { equal } from '@ember/object/computed'; +import { getProperties, get, computed } from '@ember/object'; +import Component from '@ember/component'; const replicationAttr = function(attr) { return computed('mode', `cluster.{dr,performance}.${attr}`, function() { @@ -8,13 +10,13 @@ const replicationAttr = function(attr) { }); }; export default Component.extend({ - version: inject.service(), - router: inject.service(), - namespace: inject.service(), + version: service(), + router: service(), + namespace: service(), classNameBindings: ['isMenu::box', 'isMenu::level'], attributeBindings: ['href', 'target'], display: 'banner', - isMenu: computed.equal('display', 'menu'), + isMenu: equal('display', 'menu'), href: computed('display', 'mode', 'replicationEnabled', 'version.hasPerfReplication', function() { const display = this.get('display'); const mode = this.get('mode'); @@ -37,9 +39,9 @@ export default Component.extend({ return null; }), internalLink: false, - isPerformance: computed.equal('mode', 'performance'), + isPerformance: equal('mode', 'performance'), replicationEnabled: replicationAttr('replicationEnabled'), - replicationUnsupported: computed.equal('cluster.mode', 'unsupported'), + replicationUnsupported: equal('cluster.mode', 'unsupported'), replicationDisabled: replicationAttr('replicationDisabled'), syncProgressPercent: replicationAttr('syncProgressPercent'), syncProgress: replicationAttr('syncProgress'), diff --git a/ui/app/components/replication-secondaries.js b/ui/app/components/replication-secondaries.js index c13704b15..c1f862976 100644 --- a/ui/app/components/replication-secondaries.js +++ b/ui/app/components/replication-secondaries.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; -const { computed } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ cluster: null, replicationMode: null, secondaries: null, diff --git a/ui/app/components/replication-summary.js b/ui/app/components/replication-summary.js index 3e68265e7..745722a6d 100644 --- a/ui/app/components/replication-summary.js +++ b/ui/app/components/replication-summary.js @@ -1,8 +1,10 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { alias } from '@ember/object/computed'; +import { get, computed } from '@ember/object'; +import Component from '@ember/component'; import decodeConfigFromJWT from 'vault/utils/decode-config-from-jwt'; import ReplicationActions from 'vault/mixins/replication-actions'; - -const { computed, get, Component, inject } = Ember; +import { task } from 'ember-concurrency'; const DEFAULTS = { mode: 'primary', @@ -18,8 +20,8 @@ const DEFAULTS = { }; export default Component.extend(ReplicationActions, DEFAULTS, { - wizard: inject.service(), - version: inject.service(), + wizard: service(), + version: service(), didReceiveAttrs() { this._super(...arguments); const initialReplicationMode = this.get('initialReplicationMode'); @@ -31,7 +33,7 @@ export default Component.extend(ReplicationActions, DEFAULTS, { initialReplicationMode: null, cluster: null, - replicationAttrs: computed.alias('cluster.replicationAttrs'), + replicationAttrs: alias('cluster.replicationAttrs'), tokenIncludesAPIAddr: computed('token', function() { const config = decodeConfigFromJWT(get(this, 'token')); @@ -64,14 +66,15 @@ export default Component.extend(ReplicationActions, DEFAULTS, { this.setProperties(DEFAULTS); }, + submit: task(function*() { + yield this.submitHandler(...arguments); + let wizard = this.get('wizard'); + wizard.transitionFeatureMachine(wizard.get('featureState'), 'ENABLEREPLICATION'); + }), + actions: { onSubmit(/*action, mode, data, event*/) { - let promise = this.submitHandler(...arguments); - let wizard = this.get('wizard'); - promise.then(() => { - wizard.transitionFeatureMachine(wizard.get('featureState'), 'ENABLEREPLICATION'); - }); - return promise; + this.get('submit').perform(...arguments); }, clear() { diff --git a/ui/app/components/role-aws-edit.js b/ui/app/components/role-aws-edit.js index 4021ce46b..d7e570434 100644 --- a/ui/app/components/role-aws-edit.js +++ b/ui/app/components/role-aws-edit.js @@ -1,7 +1,6 @@ +import { isBlank } from '@ember/utils'; +import { set, get } from '@ember/object'; import RoleEdit from './role-edit'; -import Ember from 'ember'; - -const { get, set } = Ember; const SHOW_ROUTE = 'vault.cluster.secrets.backend.show'; export default RoleEdit.extend({ @@ -12,7 +11,7 @@ export default RoleEdit.extend({ const modelId = this.get('model.id'); // prevent from submitting if there's no key // maybe do something fancier later - if (type === 'create' && Ember.isBlank(modelId)) { + if (type === 'create' && isBlank(modelId)) { return; } diff --git a/ui/app/components/role-edit.js b/ui/app/components/role-edit.js index dd179d685..929127644 100644 --- a/ui/app/components/role-edit.js +++ b/ui/app/components/role-edit.js @@ -1,20 +1,25 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { or } from '@ember/object/computed'; +import { isBlank } from '@ember/utils'; +import $ from 'jquery'; +import Component from '@ember/component'; +import { set, get } from '@ember/object'; import FocusOnInsertMixin from 'vault/mixins/focus-on-insert'; import keys from 'vault/lib/keycodes'; -const { get, set, computed, inject } = Ember; const LIST_ROOT_ROUTE = 'vault.cluster.secrets.backend.list-root'; const SHOW_ROUTE = 'vault.cluster.secrets.backend.show'; -export default Ember.Component.extend(FocusOnInsertMixin, { +export default Component.extend(FocusOnInsertMixin, { + router: service(), + wizard: service(), + mode: null, emptyData: '{\n}', - onDataChange: () => {}, - refresh: 'refresh', + onDataChange() {}, + onRefresh() {}, model: null, - routing: inject.service('-routing'), - wizard: inject.service(), - requestInFlight: computed.or('model.isLoading', 'model.isReloading', 'model.isSaving'), + requestInFlight: or('model.isLoading', 'model.isReloading', 'model.isSaving'), didReceiveAttrs() { this._super(...arguments); @@ -37,26 +42,24 @@ export default Ember.Component.extend(FocusOnInsertMixin, { } }, + didInsertElement() { + this._super(...arguments); + $(document).on('keyup.keyEdit', this.onEscape.bind(this)); + }, + willDestroyElement() { + this._super(...arguments); const model = this.get('model'); if (get(model, 'isError')) { model.rollbackAttributes(); } + $(document).off('keyup.keyEdit'); }, transitionToRoute() { - const router = this.get('routing.router'); - router.transitionTo.apply(router, arguments); + this.get('router').transitionTo(...arguments); }, - bindKeys: Ember.on('didInsertElement', function() { - Ember.$(document).on('keyup.keyEdit', this.onEscape.bind(this)); - }), - - unbindKeys: Ember.on('willDestroyElement', function() { - Ember.$(document).off('keyup.keyEdit'); - }), - onEscape(e) { if (e.keyCode !== keys.ESC || this.get('mode') !== 'show') { return; @@ -71,7 +74,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, { persist(method, successCallback) { const model = get(this, 'model'); return model[method]().then(() => { - if (!Ember.get(model, 'isError')) { + if (!get(model, 'isError')) { if (this.get('wizard.featureState') === 'role') { this.get('wizard').transitionFeatureMachine('role', 'CONTINUE', this.get('backendType')); } @@ -99,7 +102,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, { const modelId = this.get('model.id'); // prevent from submitting if there's no key // maybe do something fancier later - if (type === 'create' && Ember.isBlank(modelId)) { + if (type === 'create' && isBlank(modelId)) { return; } @@ -118,7 +121,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, { }, refresh() { - this.sendAction('refresh'); + this.get('onRefresh')(); }, delete() { diff --git a/ui/app/components/secret-edit.js b/ui/app/components/secret-edit.js index 8d673dc7b..cfa3b5d65 100644 --- a/ui/app/components/secret-edit.js +++ b/ui/app/components/secret-edit.js @@ -1,4 +1,9 @@ -import Ember from 'ember'; +import { or } from '@ember/object/computed'; +import { isBlank, isNone } from '@ember/utils'; +import $ from 'jquery'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; +import { computed, get } from '@ember/object'; import FocusOnInsertMixin from 'vault/mixins/focus-on-insert'; import keys from 'vault/lib/keycodes'; import KVObject from 'vault/lib/kv-object'; @@ -6,9 +11,11 @@ import KVObject from 'vault/lib/kv-object'; const LIST_ROUTE = 'vault.cluster.secrets.backend.list'; const LIST_ROOT_ROUTE = 'vault.cluster.secrets.backend.list-root'; const SHOW_ROUTE = 'vault.cluster.secrets.backend.show'; -const { get, computed, inject } = Ember; -export default Ember.Component.extend(FocusOnInsertMixin, { +export default Component.extend(FocusOnInsertMixin, { + wizard: service(), + router: service(), + // a key model key: null, @@ -22,7 +29,9 @@ export default Ember.Component.extend(FocusOnInsertMixin, { secretData: null, // called with a bool indicating if there's been a change in the secretData - onDataChange: () => {}, + onDataChange() {}, + onRefresh() {}, + onToggleAdvancedEdit() {}, // did user request advanced mode preferAdvancedEdit: false, @@ -36,8 +45,6 @@ export default Ember.Component.extend(FocusOnInsertMixin, { hasLintError: false, - wizard: inject.service(), - init() { this._super(...arguments); const secrets = this.get('key.secretData'); @@ -58,24 +65,29 @@ export default Ember.Component.extend(FocusOnInsertMixin, { } }, + didInsertElement() { + this._super(...arguments); + $(document).on('keyup.keyEdit', this.onEscape.bind(this)); + }, + willDestroyElement() { + this._super(...arguments); const key = this.get('key'); if (get(key, 'isError') && !key.isDestroyed) { key.rollbackAttributes(); } + $(document).off('keyup.keyEdit'); }, - partialName: Ember.computed('mode', function() { + partialName: computed('mode', function() { return `partials/secret-form-${this.get('mode')}`; }), - routing: Ember.inject.service('-routing'), + showPrefix: or('key.initialParentKey', 'key.parentKey'), - showPrefix: computed.or('key.initialParentKey', 'key.parentKey'), + requestInFlight: or('key.isLoading', 'key.isReloading', 'key.isSaving'), - requestInFlight: computed.or('key.isLoading', 'key.isReloading', 'key.isSaving'), - - buttonDisabled: computed.or( + buttonDisabled: or( 'requestInFlight', 'key.isFolder', 'key.isError', @@ -111,18 +123,9 @@ export default Ember.Component.extend(FocusOnInsertMixin, { }), transitionToRoute() { - const router = this.get('routing.router'); - router.transitionTo.apply(router, arguments); + this.get('router').transitionTo(...arguments); }, - bindKeys: Ember.on('didInsertElement', function() { - Ember.$(document).on('keyup.keyEdit', this.onEscape.bind(this)); - }), - - unbindKeys: Ember.on('willDestroyElement', function() { - Ember.$(document).off('keyup.keyEdit'); - }), - onEscape(e) { if (e.keyCode !== keys.ESC || this.get('mode') !== 'show') { return; @@ -152,7 +155,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, { } return model[method]().then(() => { - if (!Ember.get(model, 'isError')) { + if (!get(model, 'isError')) { if (this.get('wizard.featureState') === 'secret') { this.get('wizard').transitionFeatureMachine('secret', 'CONTINUE'); } @@ -192,7 +195,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, { // prevent from submitting if there's no key // maybe do something fancier later - if (type === 'create' && Ember.isBlank(this.get('key.id'))) { + if (type === 'create' && isBlank(this.get('key.id'))) { return; } @@ -213,12 +216,12 @@ export default Ember.Component.extend(FocusOnInsertMixin, { }, refresh() { - this.attrs.onRefresh(); + this.get('onRefresh')(); }, addRow() { const data = this.get('secretData'); - if (Ember.isNone(data.findBy('name', ''))) { + if (isNone(data.findBy('name', ''))) { data.pushObject({ name: '', value: '' }); this.set('codemirrorString', data.toJSONString(true)); } @@ -229,7 +232,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, { deleteRow(name) { const data = this.get('secretData'); const item = data.findBy('name', name); - if (Ember.isBlank(item.name)) { + if (isBlank(item.name)) { return; } data.removeObject(item); @@ -240,7 +243,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, { }, toggleAdvanced(bool) { - this.sendAction('toggleAdvancedEdit', bool); + this.get('onToggleAdvancedEdit')(bool); }, codemirrorUpdated(val, codemirror) { diff --git a/ui/app/components/secret-form-header.js b/ui/app/components/secret-form-header.js index 1a20cb820..d8b27ca6e 100644 --- a/ui/app/components/secret-form-header.js +++ b/ui/app/components/secret-form-header.js @@ -1,13 +1,14 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import Component from '@ember/component'; import hbs from 'htmlbars-inline-precompile'; -export default Ember.Component.extend({ +export default Component.extend({ key: null, mode: null, path: null, actionClass: null, - title: Ember.computed.alias('key.keyWithoutParent'), + title: alias('key.keyWithoutParent'), layout: hbs`
diff --git a/ui/app/components/secret-link.js b/ui/app/components/secret-link.js index 4020be486..e563a5900 100644 --- a/ui/app/components/secret-link.js +++ b/ui/app/components/secret-link.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; -const { computed, Component } = Ember; +import { computed } from '@ember/object'; +import Component from '@ember/component'; export function linkParams({ mode, secret, queryParams }) { let params; diff --git a/ui/app/components/secret-list-header.js b/ui/app/components/secret-list-header.js index 3835ff8ad..ef8ee1113 100644 --- a/ui/app/components/secret-list-header.js +++ b/ui/app/components/secret-list-header.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', // api diff --git a/ui/app/components/section-tabs.js b/ui/app/components/section-tabs.js index c90cb5503..8cf2aa5c9 100644 --- a/ui/app/components/section-tabs.js +++ b/ui/app/components/section-tabs.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -const SectionTabs = Ember.Component.extend({ +const SectionTabs = Component.extend({ tagName: '', model: null, diff --git a/ui/app/components/shamir-flow.js b/ui/app/components/shamir-flow.js index 48cd5ab12..3d915b6d8 100644 --- a/ui/app/components/shamir-flow.js +++ b/ui/app/components/shamir-flow.js @@ -1,9 +1,10 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { gt } from '@ember/object/computed'; +import { camelize } from '@ember/string'; +import Component from '@ember/component'; +import { get, computed } from '@ember/object'; import base64js from 'base64-js'; -const { Component, inject, computed, get } = Ember; -const { camelize } = Ember.String; - const DEFAULTS = { key: null, loading: false, @@ -20,7 +21,7 @@ const DEFAULTS = { export default Component.extend(DEFAULTS, { tagName: '', - store: inject.service(), + store: service(), formText: null, fetchOnInit: false, buttonText: 'Submit', @@ -58,7 +59,7 @@ export default Component.extend(DEFAULTS, { this.setProperties(DEFAULTS); }, - hasProgress: computed.gt('progress', 0), + hasProgress: gt('progress', 0), actionSuccess(resp) { let { onUpdate, isComplete, onShamirSuccess, thresholdPath } = this.getProperties( diff --git a/ui/app/components/shamir-progress.js b/ui/app/components/shamir-progress.js index bd0fe758d..477d738d9 100644 --- a/ui/app/components/shamir-progress.js +++ b/ui/app/components/shamir-progress.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; -const { computed } = Ember; +import Component from '@ember/component'; +import { computed } from '@ember/object'; -export default Ember.Component.extend({ +export default Component.extend({ threshold: null, progress: null, classNames: ['shamir-progress'], diff --git a/ui/app/components/splash-page.js b/ui/app/components/splash-page.js index 708ff64b7..b69b76ffb 100644 --- a/ui/app/components/splash-page.js +++ b/ui/app/components/splash-page.js @@ -1,11 +1,11 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; -const { computed, inject } = Ember; - -export default Ember.Component.extend({ - version: inject.service(), - auth: inject.service(), - store: inject.service(), +export default Component.extend({ + version: service(), + auth: service(), + store: service(), tagName: '', activeCluster: computed('auth.activeCluster', function() { diff --git a/ui/app/components/splash-page/splash-content.js b/ui/app/components/splash-page/splash-content.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/splash-page/splash-content.js +++ b/ui/app/components/splash-page/splash-content.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/splash-page/splash-footer.js b/ui/app/components/splash-page/splash-footer.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/splash-page/splash-footer.js +++ b/ui/app/components/splash-page/splash-footer.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/splash-page/splash-header.js b/ui/app/components/splash-page/splash-header.js index e3ac4fb5c..479865264 100644 --- a/ui/app/components/splash-page/splash-header.js +++ b/ui/app/components/splash-page/splash-header.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ tagName: '', }); diff --git a/ui/app/components/status-menu.js b/ui/app/components/status-menu.js index 205448a3b..492a302d8 100644 --- a/ui/app/components/status-menu.js +++ b/ui/app/components/status-menu.js @@ -1,11 +1,12 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { alias } from '@ember/object/computed'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; -const { inject, computed } = Ember; - -export default Ember.Component.extend({ - currentCluster: inject.service('current-cluster'), - cluster: computed.alias('currentCluster.cluster'), - auth: inject.service(), +export default Component.extend({ + currentCluster: service('current-cluster'), + cluster: alias('currentCluster.cluster'), + auth: service(), type: 'cluster', itemTag: null, partialName: computed('type', function() { diff --git a/ui/app/components/string-list.js b/ui/app/components/string-list.js index 277200987..310e367d2 100644 --- a/ui/app/components/string-list.js +++ b/ui/app/components/string-list.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import ArrayProxy from '@ember/array/proxy'; +import Component from '@ember/component'; +import { set, computed } from '@ember/object'; -const { computed, set } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-component': 'string-list', classNames: ['field', 'string-list', 'form-section'], @@ -33,7 +33,9 @@ export default Ember.Component.extend({ * Defaults to an empty array. * */ - inputValue: [], + inputValue: computed(function() { + return []; + }), /* * @@ -60,7 +62,7 @@ export default Ember.Component.extend({ * */ inputList: computed(function() { - return Ember.ArrayProxy.create({ + return ArrayProxy.create({ content: [], // trim the `value` when accessing objects objectAtContent: function(idx) { @@ -89,7 +91,9 @@ export default Ember.Component.extend({ }, toVal() { - const inputs = this.get('inputList').filter(x => x.value).mapBy('value'); + const inputs = this.get('inputList') + .filter(x => x.value) + .mapBy('value'); if (this.get('format') === 'string') { return inputs.join(','); } diff --git a/ui/app/components/text-file.js b/ui/app/components/text-file.js index eba0e4d6e..42a4b885b 100644 --- a/ui/app/components/text-file.js +++ b/ui/app/components/text-file.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; +import Component from '@ember/component'; +import { set } from '@ember/object'; -const { set } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-component': 'text-file', classNames: ['box', 'is-fullwidth', 'is-marginless', 'is-shadowless'], classNameBindings: ['inputOnly:is-paddingless'], diff --git a/ui/app/components/toggle-button.js b/ui/app/components/toggle-button.js index 56c68413a..4e87ac2dd 100644 --- a/ui/app/components/toggle-button.js +++ b/ui/app/components/toggle-button.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; +import Component from '@ember/component'; +import { set, get, defineProperty, computed } from '@ember/object'; -const { get, set } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ tagName: 'button', type: 'button', toggleTarget: null, @@ -16,12 +15,12 @@ export default Ember.Component.extend({ init() { this._super(...arguments); const toggleAttr = this.get('toggleAttr'); - Ember.defineProperty( + defineProperty( this, 'isOpen', - Ember.computed(`toggleTarget.${toggleAttr}`, () => { + computed(`toggleTarget.${toggleAttr}`, () => { const props = this.getProperties('toggleTarget', 'toggleAttr'); - return Ember.get(props.toggleTarget, props.toggleAttr); + return get(props.toggleTarget, props.toggleAttr); }) ); }, diff --git a/ui/app/components/token-expire-warning.js b/ui/app/components/token-expire-warning.js index dcd4c88f0..a09b9d90b 100644 --- a/ui/app/components/token-expire-warning.js +++ b/ui/app/components/token-expire-warning.js @@ -1,14 +1,13 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; -export default Ember.Component.extend({ +export default Component.extend({ + auth: service(), + router: service(), classNames: 'token-expire-warning', - auth: Ember.inject.service(), - - routing: Ember.inject.service('-routing'), transitionToRoute: function() { - var router = this.get('routing.router'); - router.transitionTo.apply(router, arguments); + this.get('router').transitionTo(...arguments); }, isDismissed: false, diff --git a/ui/app/components/tool-actions-form.js b/ui/app/components/tool-actions-form.js index 916a1a29b..e17d7ab74 100644 --- a/ui/app/components/tool-actions-form.js +++ b/ui/app/components/tool-actions-form.js @@ -1,8 +1,10 @@ -import Ember from 'ember'; +import { match } from '@ember/object/computed'; +import { assign } from '@ember/polyfills'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; +import { setProperties, computed, set, get } from '@ember/object'; import moment from 'moment'; -const { get, set, computed, setProperties } = Ember; - const DEFAULTS = { token: null, rewrap_token: null, @@ -20,9 +22,9 @@ const DEFAULTS = { const WRAPPING_ENDPOINTS = ['lookup', 'wrap', 'unwrap', 'rewrap']; -export default Ember.Component.extend(DEFAULTS, { - store: Ember.inject.service(), - wizard: Ember.inject.service(), +export default Component.extend(DEFAULTS, { + store: service(), + wizard: service(), // putting these attrs here so they don't get reset when you click back //random bytes: 32, @@ -56,7 +58,7 @@ export default Ember.Component.extend(DEFAULTS, { set(this, 'oldSelectedAction', currentAction); }, - dataIsEmpty: computed.match('data', new RegExp(DEFAULTS.data)), + dataIsEmpty: match('data', new RegExp(DEFAULTS.data)), expirationDate: computed('creation_time', 'creation_ttl', function() { const { creation_time, creation_ttl } = this.getProperties('creation_time', 'creation_ttl'); @@ -74,12 +76,12 @@ export default Ember.Component.extend(DEFAULTS, { let props = {}; let secret = (resp && resp.data) || resp.auth; if (secret && action === 'unwrap') { - props = Ember.assign({}, props, { unwrap_data: secret }); + props = assign({}, props, { unwrap_data: secret }); } - props = Ember.assign({}, props, secret); + props = assign({}, props, secret); if (resp && resp.wrap_info) { const keyName = action === 'rewrap' ? 'rewrap_token' : 'token'; - props = Ember.assign({}, props, { [keyName]: resp.wrap_info.token }); + props = assign({}, props, { [keyName]: resp.wrap_info.token }); } if (props.token || props.rewrap_token || props.unwrap_data || action === 'lookup') { this.get('wizard').transitionFeatureMachine(this.get('wizard.featureState'), 'CONTINUE'); diff --git a/ui/app/components/transit-edit.js b/ui/app/components/transit-edit.js index 3928b86dd..9c465c472 100644 --- a/ui/app/components/transit-edit.js +++ b/ui/app/components/transit-edit.js @@ -1,44 +1,46 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { or } from '@ember/object/computed'; +import { isBlank } from '@ember/utils'; +import $ from 'jquery'; +import Component from '@ember/component'; +import { set, get } from '@ember/object'; import FocusOnInsertMixin from 'vault/mixins/focus-on-insert'; import keys from 'vault/lib/keycodes'; -const { get, set, computed, inject } = Ember; const LIST_ROOT_ROUTE = 'vault.cluster.secrets.backend.list-root'; const SHOW_ROUTE = 'vault.cluster.secrets.backend.show'; -export default Ember.Component.extend(FocusOnInsertMixin, { +export default Component.extend(FocusOnInsertMixin, { + router: service(), + wizard: service(), mode: null, - onDataChange: null, - refresh: 'refresh', + onDataChange() {}, + onRefresh() {}, key: null, - routing: inject.service('-routing'), - requestInFlight: computed.or('key.isLoading', 'key.isReloading', 'key.isSaving'), - wizard: inject.service(), + requestInFlight: or('key.isLoading', 'key.isReloading', 'key.isSaving'), init() { this._super(...arguments); }, + didInsertElement() { + this._super(...arguments); + $(document).on('keyup.keyEdit', this.onEscape.bind(this)); + }, + willDestroyElement() { + this._super(...arguments); const key = this.get('key'); if (get(key, 'isError')) { key.rollbackAttributes(); } + $(document).off('keyup.keyEdit'); }, transitionToRoute() { - const router = this.get('routing.router'); - router.transitionTo.apply(router, arguments); + this.get('router').transitionTo(...arguments); }, - bindKeys: Ember.on('didInsertElement', function() { - Ember.$(document).on('keyup.keyEdit', this.onEscape.bind(this)); - }), - - unbindKeys: Ember.on('willDestroyElement', function() { - Ember.$(document).off('keyup.keyEdit'); - }), - onEscape(e) { if (e.keyCode !== keys.ESC || this.get('mode') !== 'show') { return; @@ -53,7 +55,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, { persistKey(method, successCallback) { const key = get(this, 'key'); return key[method]().then(() => { - if (!Ember.get(key, 'isError')) { + if (!get(key, 'isError')) { if (this.get('wizard.featureState') === 'secret') { this.get('wizard').transitionFeatureMachine('secret', 'CONTINUE'); } else { @@ -85,7 +87,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, { const keyId = this.get('key.id'); // prevent from submitting if there's no key // maybe do something fancier later - if (type === 'create' && Ember.isBlank(keyId)) { + if (type === 'create' && isBlank(keyId)) { return; } @@ -116,7 +118,7 @@ export default Ember.Component.extend(FocusOnInsertMixin, { }, refresh() { - this.sendAction('refresh'); + this.get('onRefresh')(); }, deleteKey() { diff --git a/ui/app/components/transit-key-actions.js b/ui/app/components/transit-key-actions.js index 971960592..4b14995ae 100644 --- a/ui/app/components/transit-key-actions.js +++ b/ui/app/components/transit-key-actions.js @@ -1,5 +1,9 @@ -import Ember from 'ember'; -const { get, set } = Ember; +import { assign } from '@ember/polyfills'; +import { copy } from 'ember-copy'; +import { assert } from '@ember/debug'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; +import { set, get, computed } from '@ember/object'; const TRANSIT_PARAMS = { hash_algorithm: 'sha2-256', @@ -37,22 +41,21 @@ const PARAMS_FOR_ACTION = { decrypt: ['ciphertext', 'context', 'nonce'], rewrap: ['ciphertext', 'context', 'nonce', 'key_version'], }; -export default Ember.Component.extend(TRANSIT_PARAMS, { - store: Ember.inject.service(), +export default Component.extend(TRANSIT_PARAMS, { + store: service(), // public attrs selectedAction: null, key: null, - refresh: 'refresh', - + onRefresh() {}, init() { this._super(...arguments); if (get(this, 'selectedAction')) { return; } set(this, 'selectedAction', get(this, 'key.supportedActions.firstObject')); - Ember.assert('`key` is required for `' + this.toString() + '`.', this.getModelInfo()); + assert('`key` is required for `' + this.toString() + '`.', this.getModelInfo()); }, didReceiveAttrs() { @@ -72,7 +75,7 @@ export default Ember.Component.extend(TRANSIT_PARAMS, { }); }, - keyIsRSA: Ember.computed('key.type', function() { + keyIsRSA: computed('key.type', function() { let type = get(this, 'key.type'); return type === 'rsa-2048' || type === 'rsa-4096'; }), @@ -100,7 +103,7 @@ export default Ember.Component.extend(TRANSIT_PARAMS, { }, resetParams(oldAction, action) { - let params = Ember.copy(TRANSIT_PARAMS); + let params = copy(TRANSIT_PARAMS); let paramsToKeep; let clearWithoutCheck = !oldAction || @@ -134,14 +137,14 @@ export default Ember.Component.extend(TRANSIT_PARAMS, { const { keys, type, name } = resp.data; resp.data.keys = { keys, type, name }; } - props = Ember.assign({}, props, resp.data); + props = assign({}, props, resp.data); } if (options.wrapTTL) { - props = Ember.assign({}, props, { wrappedToken: resp.wrap_info.token }); + props = assign({}, props, { wrappedToken: resp.wrap_info.token }); } this.setProperties(props); if (action === 'rotate') { - this.sendAction('refresh'); + this.get('onRefresh')(); } }, diff --git a/ui/app/components/ttl-picker.js b/ui/app/components/ttl-picker.js index 25d2ff5a0..a49f5e31c 100644 --- a/ui/app/components/ttl-picker.js +++ b/ui/app/components/ttl-picker.js @@ -1,9 +1,10 @@ -import Ember from 'ember'; +import { typeOf } from '@ember/utils'; +import EmberError from '@ember/error'; +import Component from '@ember/component'; +import { set, get, computed } from '@ember/object'; import Duration from 'Duration.js'; -const { computed, get, set } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ 'data-test-component': 'ttl-picker', classNames: 'field', setDefaultValue: true, @@ -13,12 +14,14 @@ export default Ember.Component.extend({ time: 30, unit: 'm', initialValue: null, - unitOptions: [ - { label: 'seconds', value: 's' }, - { label: 'minutes', value: 'm' }, - { label: 'hours', value: 'h' }, - { label: 'days', value: 'd' }, - ], + unitOptions: computed(function() { + return [ + { label: 'seconds', value: 's' }, + { label: 'minutes', value: 'm' }, + { label: 'hours', value: 'h' }, + { label: 'days', value: 'd' }, + ]; + }), ouputSeconds: false, @@ -54,7 +57,7 @@ export default Ember.Component.extend({ init() { this._super(...arguments); if (!get(this, 'onChange')) { - throw new Ember.Error('`onChange` handler is a required attr in `' + this.toString() + '`.'); + throw new EmberError('`onChange` handler is a required attr in `' + this.toString() + '`.'); } if (get(this, 'initialValue') != undefined) { this.parseAndSetTime(); @@ -63,7 +66,7 @@ export default Ember.Component.extend({ parseAndSetTime() { const value = get(this, 'initialValue'); - const seconds = Ember.typeOf(value) === 'number' ? value : Duration.parse(value).seconds(); + const seconds = typeOf(value) === 'number' ? value : Duration.parse(value).seconds(); this.set('time', seconds); this.set('unit', 's'); diff --git a/ui/app/components/ui-wizard.js b/ui/app/components/ui-wizard.js index 82a028cf3..3ed52b8cf 100644 --- a/ui/app/components/ui-wizard.js +++ b/ui/app/components/ui-wizard.js @@ -1,23 +1,24 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { alias } from '@ember/object/computed'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import { matchesState } from 'xstate'; -const { inject, computed } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ classNames: ['ui-wizard-container'], - wizard: inject.service(), - auth: inject.service(), + wizard: service(), + auth: service(), shouldRender: computed('wizard.showWhenUnauthenticated', 'auth.currentToken', function() { return this.get('auth.currentToken') || this.get('wizard.showWhenUnauthenticated'); }), - currentState: computed.alias('wizard.currentState'), - featureState: computed.alias('wizard.featureState'), - featureComponent: computed.alias('wizard.featureComponent'), - tutorialComponent: computed.alias('wizard.tutorialComponent'), - componentState: computed.alias('wizard.componentState'), - nextFeature: computed.alias('wizard.nextFeature'), - nextStep: computed.alias('wizard.nextStep'), + currentState: alias('wizard.currentState'), + featureState: alias('wizard.featureState'), + featureComponent: alias('wizard.featureComponent'), + tutorialComponent: alias('wizard.tutorialComponent'), + componentState: alias('wizard.componentState'), + nextFeature: alias('wizard.nextFeature'), + nextStep: alias('wizard.nextStep'), actions: { dismissWizard() { diff --git a/ui/app/components/upgrade-link.js b/ui/app/components/upgrade-link.js index 26007f9ab..b9ac938e6 100644 --- a/ui/app/components/upgrade-link.js +++ b/ui/app/components/upgrade-link.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import { later } from '@ember/runloop'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; -const { computed } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ modalContainer: computed('isActive', function() { return document.getElementById('modal-wormhole'); }), @@ -20,7 +20,7 @@ export default Ember.Component.extend({ actions: { openOverlay() { this.set('isActive', true); - Ember.run.later( + later( this, function() { this.set('isAnimated', true); @@ -30,7 +30,7 @@ export default Ember.Component.extend({ }, closeOverlay() { this.set('isAnimated', false); - Ember.run.later( + later( this, function() { this.set('isActive', false); diff --git a/ui/app/components/upgrade-page.js b/ui/app/components/upgrade-page.js index 590b55dfd..c9c974507 100644 --- a/ui/app/components/upgrade-page.js +++ b/ui/app/components/upgrade-page.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; -const { computed } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ title: 'Vault Enterprise', featureName: computed('title', function() { let title = this.get('title'); diff --git a/ui/app/components/wizard-content.js b/ui/app/components/wizard-content.js index 402c0b7fd..7d1112fd8 100644 --- a/ui/app/components/wizard-content.js +++ b/ui/app/components/wizard-content.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; - -const { Component, inject } = Ember; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; export default Component.extend({ - wizard: inject.service(), + wizard: service(), classNames: ['ui-wizard'], glyph: null, headerText: null, diff --git a/ui/app/components/wizard/features-selection.js b/ui/app/components/wizard/features-selection.js index dabc23e87..6e6f7f590 100644 --- a/ui/app/components/wizard/features-selection.js +++ b/ui/app/components/wizard/features-selection.js @@ -1,10 +1,10 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; -const { inject, computed } = Ember; - -export default Ember.Component.extend({ - wizard: inject.service(), - version: inject.service(), +export default Component.extend({ + wizard: service(), + version: service(), init() { this._super(...arguments); this.maybeHideFeatures(); @@ -36,7 +36,12 @@ export default Ember.Component.extend({ { key: 'policies', name: 'Policies', - steps: ['Choosing a policy type', 'Creating a policy', 'Deleting your policy', 'Other types of policies'], + steps: [ + 'Choosing a policy type', + 'Creating a policy', + 'Deleting your policy', + 'Other types of policies', + ], selected: false, show: true, }, @@ -57,12 +62,14 @@ export default Ember.Component.extend({ ]; }), - showReplication: computed('version.hasPerfReplication', 'version.hasDRReplication', function() { + showReplication: computed('version.{hasPerfReplication,hasDRReplication}', function() { return this.get('version.hasPerfReplication') || this.get('version.hasDRReplication'); }), selectedFeatures: computed('allFeatures.@each.selected', function() { - return this.get('allFeatures').filterBy('selected').mapBy('key'); + return this.get('allFeatures') + .filterBy('selected') + .mapBy('key'); }), actions: { diff --git a/ui/app/components/wizard/mounts-wizard.js b/ui/app/components/wizard/mounts-wizard.js index 1a8edb58a..2c7ca1165 100644 --- a/ui/app/components/wizard/mounts-wizard.js +++ b/ui/app/components/wizard/mounts-wizard.js @@ -1,27 +1,29 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { alias } from '@ember/object/computed'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; import { engines } from 'vault/helpers/mountable-secret-engines'; import { methods } from 'vault/helpers/mountable-auth-methods'; import { supportedSecretBackends } from 'vault/helpers/supported-secret-backends'; const supportedSecrets = supportedSecretBackends(); import { supportedAuthBackends } from 'vault/helpers/supported-auth-backends'; const supportedAuth = supportedAuthBackends(); -const { inject, computed } = Ember; -export default Ember.Component.extend({ - wizard: inject.service(), - featureState: computed.alias('wizard.featureState'), - currentState: computed.alias('wizard.currentState'), - currentMachine: computed.alias('wizard.currentMachine'), - mountSubtype: computed.alias('wizard.componentState'), - fullNextStep: computed.alias('wizard.nextStep'), - nextFeature: computed.alias('wizard.nextFeature'), +export default Component.extend({ + wizard: service(), + featureState: alias('wizard.featureState'), + currentState: alias('wizard.currentState'), + currentMachine: alias('wizard.currentMachine'), + mountSubtype: alias('wizard.componentState'), + fullNextStep: alias('wizard.nextStep'), + nextFeature: alias('wizard.nextFeature'), nextStep: computed('fullNextStep', function() { return this.get('fullNextStep').split('.').lastObject; }), needsEncryption: computed('mountSubtype', function() { return this.get('mountSubtype') === 'transit'; }), - stepComponent: computed.alias('wizard.stepComponent'), + stepComponent: alias('wizard.stepComponent'), detailsComponent: computed('mountSubtype', function() { let suffix = this.get('currentMachine') === 'secrets' ? 'engine' : 'method'; return this.get('mountSubtype') ? `wizard/${this.get('mountSubtype')}-${suffix}` : null; diff --git a/ui/app/components/wrap-ttl.js b/ui/app/components/wrap-ttl.js index 7e7402a3e..7ef473f5e 100644 --- a/ui/app/components/wrap-ttl.js +++ b/ui/app/components/wrap-ttl.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import { assert } from '@ember/debug'; +import Component from '@ember/component'; +import { set, get, computed } from '@ember/object'; import hbs from 'htmlbars-inline-precompile'; -const { computed, get, set } = Ember; - -export default Ember.Component.extend({ +export default Component.extend({ // passed from outside onChange: null, wrapResponse: true, @@ -22,10 +22,7 @@ export default Ember.Component.extend({ init() { this._super(...arguments); - Ember.assert( - '`onChange` handler is a required attr in `' + this.toString() + '`.', - get(this, 'onChange') - ); + assert('`onChange` handler is a required attr in `' + this.toString() + '`.', get(this, 'onChange')); }, layout: hbs` diff --git a/ui/app/controllers/application.js b/ui/app/controllers/application.js index 93d3fc949..85336b43b 100644 --- a/ui/app/controllers/application.js +++ b/ui/app/controllers/application.js @@ -1,13 +1,15 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; +import { computed } from '@ember/object'; import config from '../config/environment'; -const { Controller, computed, inject } = Ember; export default Controller.extend({ env: config.environment, - auth: inject.service(), - store: inject.service(), + auth: service(), + store: service(), activeCluster: computed('auth.activeCluster', function() { - return this.get('store').peekRecord('cluster', this.get('auth.activeCluster')); + let id = this.get('auth.activeCluster'); + return id ? this.get('store').peekRecord('cluster', id) : null; }), activeClusterName: computed('activeCluster', function() { const activeCluster = this.get('activeCluster'); diff --git a/ui/app/controllers/vault.js b/ui/app/controllers/vault.js index 7de935e36..156be6736 100644 --- a/ui/app/controllers/vault.js +++ b/ui/app/controllers/vault.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Controller from '@ember/controller'; -export default Ember.Controller.extend({ +export default Controller.extend({ queryParams: [ { wrappedToken: 'wrapped_token', diff --git a/ui/app/controllers/vault/cluster.js b/ui/app/controllers/vault/cluster.js index 6e88764d9..a928fbe90 100644 --- a/ui/app/controllers/vault/cluster.js +++ b/ui/app/controllers/vault/cluster.js @@ -1,14 +1,15 @@ -import Ember from 'ember'; - -const { Controller, computed, observer, inject } = Ember; +import { inject as service } from '@ember/service'; +import { alias } from '@ember/object/computed'; +import Controller from '@ember/controller'; +import { observer, computed } from '@ember/object'; export default Controller.extend({ - auth: inject.service(), - store: inject.service(), - media: inject.service(), - namespaceService: inject.service('namespace'), + auth: service(), + store: service(), + media: service(), + namespaceService: service('namespace'), - vaultVersion: inject.service('version'), - console: inject.service(), + vaultVersion: service('version'), + console: service(), queryParams: [ { @@ -25,7 +26,7 @@ export default Controller.extend({ this.get('namespaceService').setNamespace(this.get('namespaceQueryParam')); }), - consoleOpen: computed.alias('console.isOpen'), + consoleOpen: alias('console.isOpen'), activeCluster: computed('auth.activeCluster', function() { return this.get('store').peekRecord('cluster', this.get('auth.activeCluster')); @@ -39,8 +40,7 @@ export default Controller.extend({ showNav: computed( 'activeClusterName', 'auth.currentToken', - 'activeCluster.dr.isSecondary', - 'activeCluster.{needsInit,sealed}', + 'activeCluster.{dr.isSecondary,needsInit,sealed}', function() { if ( this.get('activeCluster.dr.isSecondary') || diff --git a/ui/app/controllers/vault/cluster/access/identity/aliases/index.js b/ui/app/controllers/vault/cluster/access/identity/aliases/index.js index 10d097392..bac858c14 100644 --- a/ui/app/controllers/vault/cluster/access/identity/aliases/index.js +++ b/ui/app/controllers/vault/cluster/access/identity/aliases/index.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Controller from '@ember/controller'; import ListController from 'vault/mixins/list-controller'; -export default Ember.Controller.extend(ListController, { +export default Controller.extend(ListController, { actions: { onDelete() { this.send('reload'); diff --git a/ui/app/controllers/vault/cluster/access/identity/create.js b/ui/app/controllers/vault/cluster/access/identity/create.js index a94bf3b4b..89940cb4a 100644 --- a/ui/app/controllers/vault/cluster/access/identity/create.js +++ b/ui/app/controllers/vault/cluster/access/identity/create.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Controller from '@ember/controller'; import { task } from 'ember-concurrency'; -export default Ember.Controller.extend({ +export default Controller.extend({ showRoute: 'vault.cluster.access.identity.show', showTab: 'details', navAfterSave: task(function*({ saveType, model }) { diff --git a/ui/app/controllers/vault/cluster/access/identity/index.js b/ui/app/controllers/vault/cluster/access/identity/index.js index 88f71bbf2..088cdcc7d 100644 --- a/ui/app/controllers/vault/cluster/access/identity/index.js +++ b/ui/app/controllers/vault/cluster/access/identity/index.js @@ -1,10 +1,9 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; import ListController from 'vault/mixins/list-controller'; -const { inject } = Ember; - -export default Ember.Controller.extend(ListController, { - flashMessages: inject.service(), +export default Controller.extend(ListController, { + flashMessages: service(), actions: { delete(model) { diff --git a/ui/app/controllers/vault/cluster/access/leases/index.js b/ui/app/controllers/vault/cluster/access/leases/index.js index cbe007a32..001ce0451 100644 --- a/ui/app/controllers/vault/cluster/access/leases/index.js +++ b/ui/app/controllers/vault/cluster/access/leases/index.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Controller from '@ember/controller'; -export default Ember.Controller.extend({ +export default Controller.extend({ actions: { lookupLease(id) { this.transitionToRoute('vault.cluster.access.leases.show', id); diff --git a/ui/app/controllers/vault/cluster/access/leases/list.js b/ui/app/controllers/vault/cluster/access/leases/list.js index feaa06b7f..2f01cbbef 100644 --- a/ui/app/controllers/vault/cluster/access/leases/list.js +++ b/ui/app/controllers/vault/cluster/access/leases/list.js @@ -1,11 +1,12 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { computed } from '@ember/object'; +import Controller, { inject as controller } from '@ember/controller'; import utils from 'vault/lib/key-utils'; -const { inject, computed, Controller } = Ember; export default Controller.extend({ - flashMessages: inject.service(), - store: inject.service(), - clusterController: inject.controller('vault.cluster'), + flashMessages: service(), + store: service(), + clusterController: controller('vault.cluster'), queryParams: { page: 'page', pageFilter: 'pageFilter', diff --git a/ui/app/controllers/vault/cluster/access/leases/show.js b/ui/app/controllers/vault/cluster/access/leases/show.js index 74bff6913..a0112b7cc 100644 --- a/ui/app/controllers/vault/cluster/access/leases/show.js +++ b/ui/app/controllers/vault/cluster/access/leases/show.js @@ -1,9 +1,12 @@ -import Ember from 'ember'; +import { next } from '@ember/runloop'; +import { inject as service } from '@ember/service'; +import { computed } from '@ember/object'; +import Controller, { inject as controller } from '@ember/controller'; -export default Ember.Controller.extend({ - clusterController: Ember.inject.controller('vault.cluster'), +export default Controller.extend({ + clusterController: controller('vault.cluster'), - backendCrumb: Ember.computed(function() { + backendCrumb: computed(function() { return { label: 'leases', text: 'leases', @@ -12,7 +15,7 @@ export default Ember.Controller.extend({ }; }), - flashMessages: Ember.inject.service(), + flashMessages: service(), actions: { revokeLease(model) { @@ -29,7 +32,7 @@ export default Ember.Controller.extend({ .then(() => { this.send('refreshModel'); // lol this is terrible, but there's no way to get the promise from the route refresh - Ember.run.next(() => { + next(() => { flash.success(`The lease ${model.id} was successfully renewed.`); }); }) diff --git a/ui/app/controllers/vault/cluster/access/methods.js b/ui/app/controllers/vault/cluster/access/methods.js index 51ba59bb8..9bee381f6 100644 --- a/ui/app/controllers/vault/cluster/access/methods.js +++ b/ui/app/controllers/vault/cluster/access/methods.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Controller from '@ember/controller'; import { task } from 'ember-concurrency'; -export default Ember.Controller.extend({ +export default Controller.extend({ queryParams: { page: 'page', pageFilter: 'pageFilter', diff --git a/ui/app/controllers/vault/cluster/access/namespaces/create.js b/ui/app/controllers/vault/cluster/access/namespaces/create.js index 141bfce74..a0d3ab9b6 100644 --- a/ui/app/controllers/vault/cluster/access/namespaces/create.js +++ b/ui/app/controllers/vault/cluster/access/namespaces/create.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; - -const { inject, Controller } = Ember; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; export default Controller.extend({ - namespaceService: inject.service('namespace'), + namespaceService: service('namespace'), actions: { onSave({ saveType }) { if (saveType === 'save') { diff --git a/ui/app/controllers/vault/cluster/access/namespaces/index.js b/ui/app/controllers/vault/cluster/access/namespaces/index.js index f2d38c799..6044aba2d 100644 --- a/ui/app/controllers/vault/cluster/access/namespaces/index.js +++ b/ui/app/controllers/vault/cluster/access/namespaces/index.js @@ -1,10 +1,10 @@ -import Ember from 'ember'; - -const { computed, inject, Controller } = Ember; +import { inject as service } from '@ember/service'; +import { alias } from '@ember/object/computed'; +import Controller from '@ember/controller'; export default Controller.extend({ - namespaceService: inject.service('namespace'), - accessibleNamespaces: computed.alias('namespaceService.accessibleNamespaces'), - currentNamespace: computed.alias('namespaceService.path'), + namespaceService: service('namespace'), + accessibleNamespaces: alias('namespaceService.accessibleNamespaces'), + currentNamespace: alias('namespaceService.path'), actions: { refreshNamespaceList() { // fetch new namespaces for the namespace picker diff --git a/ui/app/controllers/vault/cluster/auth.js b/ui/app/controllers/vault/cluster/auth.js index 32e79e8a0..2230db646 100644 --- a/ui/app/controllers/vault/cluster/auth.js +++ b/ui/app/controllers/vault/cluster/auth.js @@ -1,14 +1,15 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { alias } from '@ember/object/computed'; +import Controller, { inject as controller } from '@ember/controller'; import { task, timeout } from 'ember-concurrency'; -const { inject, computed, Controller } = Ember; export default Controller.extend({ - vaultController: inject.controller('vault'), - clusterController: inject.controller('vault.cluster'), - namespaceService: inject.service('namespace'), - namespaceQueryParam: computed.alias('clusterController.namespaceQueryParam'), + vaultController: controller('vault'), + clusterController: controller('vault.cluster'), + namespaceService: service('namespace'), + namespaceQueryParam: alias('clusterController.namespaceQueryParam'), queryParams: [{ authMethod: 'with' }], - wrappedToken: computed.alias('vaultController.wrappedToken'), + wrappedToken: alias('vaultController.wrappedToken'), authMethod: '', redirectTo: null, diff --git a/ui/app/controllers/vault/cluster/init.js b/ui/app/controllers/vault/cluster/init.js index 4b1638945..ae6a66c2e 100644 --- a/ui/app/controllers/vault/cluster/init.js +++ b/ui/app/controllers/vault/cluster/init.js @@ -1,4 +1,6 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; const DEFAULTS = { keyData: null, @@ -9,8 +11,8 @@ const DEFAULTS = { loading: false, }; -export default Ember.Controller.extend(DEFAULTS, { - wizard: Ember.inject.service(), +export default Controller.extend(DEFAULTS, { + wizard: service(), reset() { this.setProperties(DEFAULTS); @@ -32,7 +34,7 @@ export default Ember.Controller.extend(DEFAULTS, { } }, - keyFilename: Ember.computed('model.name', function() { + keyFilename: computed('model.name', function() { return `vault-cluster-${this.get('model.name')}`; }), diff --git a/ui/app/controllers/vault/cluster/policies/create.js b/ui/app/controllers/vault/cluster/policies/create.js index 862d146bb..7965ae2d5 100644 --- a/ui/app/controllers/vault/cluster/policies/create.js +++ b/ui/app/controllers/vault/cluster/policies/create.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import Controller from '@ember/controller'; import trimRight from 'vault/utils/trim-right'; import PolicyEditController from 'vault/mixins/policy-edit-controller'; -export default Ember.Controller.extend(PolicyEditController, { +export default Controller.extend(PolicyEditController, { showFileUpload: false, file: null, actions: { diff --git a/ui/app/controllers/vault/cluster/policies/index.js b/ui/app/controllers/vault/cluster/policies/index.js index 14934a2e1..925bb518f 100644 --- a/ui/app/controllers/vault/cluster/policies/index.js +++ b/ui/app/controllers/vault/cluster/policies/index.js @@ -1,9 +1,10 @@ -import Ember from 'ember'; -let { inject } = Ember; +import { inject as service } from '@ember/service'; +import { computed } from '@ember/object'; +import Controller from '@ember/controller'; -export default Ember.Controller.extend({ - flashMessages: inject.service(), - wizard: inject.service(), +export default Controller.extend({ + flashMessages: service(), + wizard: service(), queryParams: { page: 'page', @@ -19,13 +20,13 @@ export default Ember.Controller.extend({ // set via the route `loading` action isLoading: false, - filterMatchesKey: Ember.computed('filter', 'model', 'model.[]', function() { + filterMatchesKey: computed('filter', 'model', 'model.[]', function() { var filter = this.get('filter'); var content = this.get('model'); return !!(content && content.length && content.findBy('id', filter)); }), - firstPartialMatch: Ember.computed('filter', 'model', 'model.[]', 'filterMatchesKey', function() { + firstPartialMatch: computed('filter', 'model', 'model.[]', 'filterMatchesKey', function() { var filter = this.get('filter'); var content = this.get('model'); if (!content) { @@ -54,12 +55,12 @@ export default Ember.Controller.extend({ model .destroyRecord() .then(() => { + // this will clear the dataset cache on the store + this.send('reload'); flash.success(`${policyType.toUpperCase()} policy "${name}" was successfully deleted.`); if (this.get('wizard.featureState') === 'delete') { this.get('wizard').transitionFeatureMachine('delete', 'CONTINUE', policyType); } - // this will clear the dataset cache on the store - this.send('willTransition'); }) .catch(e => { let errors = e.errors ? e.errors.join('') : e.message; diff --git a/ui/app/controllers/vault/cluster/policy/edit.js b/ui/app/controllers/vault/cluster/policy/edit.js index 93c6cefe0..8a14b3c90 100644 --- a/ui/app/controllers/vault/cluster/policy/edit.js +++ b/ui/app/controllers/vault/cluster/policy/edit.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import Controller from '@ember/controller'; import PolicyEditController from 'vault/mixins/policy-edit-controller'; -export default Ember.Controller.extend(PolicyEditController); +export default Controller.extend(PolicyEditController); diff --git a/ui/app/controllers/vault/cluster/replication-dr-promote.js b/ui/app/controllers/vault/cluster/replication-dr-promote.js index 578007d98..35ca35f0e 100644 --- a/ui/app/controllers/vault/cluster/replication-dr-promote.js +++ b/ui/app/controllers/vault/cluster/replication-dr-promote.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Controller from '@ember/controller'; -export default Ember.Controller.extend({ +export default Controller.extend({ queryParams: ['action'], action: '', }); diff --git a/ui/app/controllers/vault/cluster/replication.js b/ui/app/controllers/vault/cluster/replication.js index 80a7e9d40..be9c1dbda 100644 --- a/ui/app/controllers/vault/cluster/replication.js +++ b/ui/app/controllers/vault/cluster/replication.js @@ -1,4 +1,7 @@ -import Ember from 'ember'; +import { isPresent } from '@ember/utils'; +import { alias } from '@ember/object/computed'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; const DEFAULTS = { token: null, @@ -14,10 +17,10 @@ const DEFAULTS = { }, }; -export default Ember.Controller.extend(DEFAULTS, { - store: Ember.inject.service(), - rm: Ember.inject.service('replication-mode'), - replicationMode: Ember.computed.alias('rm.mode'), +export default Controller.extend(DEFAULTS, { + store: service(), + rm: service('replication-mode'), + replicationMode: alias('rm.mode'), submitError(e) { if (e.errors) { @@ -75,7 +78,7 @@ export default Ember.Controller.extend(DEFAULTS, { if (event && event.preventDefault) { event.preventDefault(); } - if (data && Ember.isPresent(data.saveFilterConfig)) { + if (data && isPresent(data.saveFilterConfig)) { saveFilterConfig = data.saveFilterConfig; delete data.saveFilterConfig; } @@ -86,7 +89,7 @@ export default Ember.Controller.extend(DEFAULTS, { if (data) { data = Object.keys(data).reduce((newData, key) => { var val = data[key]; - if (Ember.isPresent(val)) { + if (isPresent(val)) { newData[key] = val; } return newData; diff --git a/ui/app/controllers/vault/cluster/replication/mode/secondaries/config-edit.js b/ui/app/controllers/vault/cluster/replication/mode/secondaries/config-edit.js index 4ff135647..f4a6ee2fb 100644 --- a/ui/app/controllers/vault/cluster/replication/mode/secondaries/config-edit.js +++ b/ui/app/controllers/vault/cluster/replication/mode/secondaries/config-edit.js @@ -1,14 +1,16 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; const CONFIG_DEFAULTS = { mode: 'whitelist', paths: [], }; -export default Ember.Controller.extend({ - flashMessages: Ember.inject.service(), - rm: Ember.inject.service('replication-mode'), - replicationMode: Ember.computed.alias('rm.mode'), +export default Controller.extend({ + flashMessages: service(), + rm: service('replication-mode'), + replicationMode: alias('rm.mode'), actions: { resetConfig(config) { if (config.get('isNew')) { diff --git a/ui/app/controllers/vault/cluster/replication/mode/secondaries/config-show.js b/ui/app/controllers/vault/cluster/replication/mode/secondaries/config-show.js index f0dddae6f..b5b82ad76 100644 --- a/ui/app/controllers/vault/cluster/replication/mode/secondaries/config-show.js +++ b/ui/app/controllers/vault/cluster/replication/mode/secondaries/config-show.js @@ -1,6 +1,8 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; -export default Ember.Controller.extend({ - rm: Ember.inject.service('replication-mode'), - replicationMode: Ember.computed.alias('rm.mode'), +export default Controller.extend({ + rm: service('replication-mode'), + replicationMode: alias('rm.mode'), }); diff --git a/ui/app/controllers/vault/cluster/replication/replication-mode.js b/ui/app/controllers/vault/cluster/replication/replication-mode.js index f0dddae6f..b5b82ad76 100644 --- a/ui/app/controllers/vault/cluster/replication/replication-mode.js +++ b/ui/app/controllers/vault/cluster/replication/replication-mode.js @@ -1,6 +1,8 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; -export default Ember.Controller.extend({ - rm: Ember.inject.service('replication-mode'), - replicationMode: Ember.computed.alias('rm.mode'), +export default Controller.extend({ + rm: service('replication-mode'), + replicationMode: alias('rm.mode'), }); diff --git a/ui/app/controllers/vault/cluster/secrets/backend.js b/ui/app/controllers/vault/cluster/secrets/backend.js new file mode 100644 index 000000000..adace5240 --- /dev/null +++ b/ui/app/controllers/vault/cluster/secrets/backend.js @@ -0,0 +1,5 @@ +import Controller from '@ember/controller'; + +export default Controller.extend({ + preferAdvancedEdit: false, +}); diff --git a/ui/app/controllers/vault/cluster/secrets/backend/actions.js b/ui/app/controllers/vault/cluster/secrets/backend/actions.js index 81393e4b6..49f5834df 100644 --- a/ui/app/controllers/vault/cluster/secrets/backend/actions.js +++ b/ui/app/controllers/vault/cluster/secrets/backend/actions.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Controller from '@ember/controller'; import BackendCrumbMixin from 'vault/mixins/backend-crumb'; -export default Ember.Controller.extend(BackendCrumbMixin, { +export default Controller.extend(BackendCrumbMixin, { queryParams: { selectedAction: 'action', }, diff --git a/ui/app/controllers/vault/cluster/secrets/backend/create.js b/ui/app/controllers/vault/cluster/secrets/backend/create.js index 383aaa025..e50b8e2d8 100644 --- a/ui/app/controllers/vault/cluster/secrets/backend/create.js +++ b/ui/app/controllers/vault/cluster/secrets/backend/create.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import Controller, { inject as controller } from '@ember/controller'; import BackendCrumbMixin from 'vault/mixins/backend-crumb'; -export default Ember.Controller.extend(BackendCrumbMixin, { +export default Controller.extend(BackendCrumbMixin, { + backendController: controller('vault.cluster.secrets.backend'), queryParams: ['initialKey'], initialKey: '', @@ -13,5 +14,9 @@ export default Ember.Controller.extend(BackendCrumbMixin, { hasChanges(hasChanges) { this.send('hasDataChanges', hasChanges); }, + toggleAdvancedEdit(bool) { + this.set('preferAdvancedEdit', bool); + this.get('backendController').set('preferAdvancedEdit', bool); + }, }, }); diff --git a/ui/app/controllers/vault/cluster/secrets/backend/credentials.js b/ui/app/controllers/vault/cluster/secrets/backend/credentials.js index bb0f79adf..a885d7989 100644 --- a/ui/app/controllers/vault/cluster/secrets/backend/credentials.js +++ b/ui/app/controllers/vault/cluster/secrets/backend/credentials.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Controller from '@ember/controller'; -export default Ember.Controller.extend({ +export default Controller.extend({ queryParams: ['action'], action: '', reset() { diff --git a/ui/app/controllers/vault/cluster/secrets/backend/edit.js b/ui/app/controllers/vault/cluster/secrets/backend/edit.js index 35e181111..47bbcfa66 100644 --- a/ui/app/controllers/vault/cluster/secrets/backend/edit.js +++ b/ui/app/controllers/vault/cluster/secrets/backend/edit.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import Controller, { inject as controller } from '@ember/controller'; import BackendCrumbMixin from 'vault/mixins/backend-crumb'; -export default Ember.Controller.extend(BackendCrumbMixin, { +export default Controller.extend(BackendCrumbMixin, { + backendController: controller('vault.cluster.secrets.backend'), actions: { refresh: function() { // closure actions don't bubble to routes, @@ -12,5 +13,10 @@ export default Ember.Controller.extend(BackendCrumbMixin, { hasChanges(hasChanges) { this.send('hasDataChanges', hasChanges); }, + + toggleAdvancedEdit(bool) { + this.set('preferAdvancedEdit', bool); + this.get('backendController').set('preferAdvancedEdit', bool); + }, }, }); diff --git a/ui/app/controllers/vault/cluster/secrets/backend/list.js b/ui/app/controllers/vault/cluster/secrets/backend/list.js index 3f540baf8..57a56fce5 100644 --- a/ui/app/controllers/vault/cluster/secrets/backend/list.js +++ b/ui/app/controllers/vault/cluster/secrets/backend/list.js @@ -1,9 +1,11 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; import utils from 'vault/lib/key-utils'; import BackendCrumbMixin from 'vault/mixins/backend-crumb'; -export default Ember.Controller.extend(BackendCrumbMixin, { - flashMessages: Ember.inject.service(), +export default Controller.extend(BackendCrumbMixin, { + flashMessages: service(), queryParams: ['page', 'pageFilter', 'tab'], tab: '', @@ -14,13 +16,13 @@ export default Ember.Controller.extend(BackendCrumbMixin, { // set via the route `loading` action isLoading: false, - filterMatchesKey: Ember.computed('filter', 'model', 'model.[]', function() { + filterMatchesKey: computed('filter', 'model', 'model.[]', function() { var filter = this.get('filter'); var content = this.get('model'); return !!(content.length && content.findBy('id', filter)); }), - firstPartialMatch: Ember.computed('filter', 'model', 'model.[]', 'filterMatchesKey', function() { + firstPartialMatch: computed('filter', 'model', 'model.[]', 'filterMatchesKey', function() { var filter = this.get('filter'); var content = this.get('model'); var filterMatchesKey = this.get('filterMatchesKey'); @@ -32,7 +34,7 @@ export default Ember.Controller.extend(BackendCrumbMixin, { }); }), - filterIsFolder: Ember.computed('filter', function() { + filterIsFolder: computed('filter', function() { return !!utils.keyIsFolder(this.get('filter')); }), diff --git a/ui/app/controllers/vault/cluster/secrets/backend/show.js b/ui/app/controllers/vault/cluster/secrets/backend/show.js index d72f6bdc8..3f9c26242 100644 --- a/ui/app/controllers/vault/cluster/secrets/backend/show.js +++ b/ui/app/controllers/vault/cluster/secrets/backend/show.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import Controller, { inject as controller } from '@ember/controller'; import BackendCrumbMixin from 'vault/mixins/backend-crumb'; -export default Ember.Controller.extend(BackendCrumbMixin, { +export default Controller.extend(BackendCrumbMixin, { + backendController: controller('vault.cluster.secrets.backend'), queryParams: ['tab'], tab: '', reset() { @@ -17,5 +18,10 @@ export default Ember.Controller.extend(BackendCrumbMixin, { hasChanges(hasChanges) { this.send('hasDataChanges', hasChanges); }, + + toggleAdvancedEdit(bool) { + this.set('preferAdvancedEdit', bool); + this.get('backendController').set('preferAdvancedEdit', bool); + }, }, }); diff --git a/ui/app/controllers/vault/cluster/secrets/backend/sign.js b/ui/app/controllers/vault/cluster/secrets/backend/sign.js index 5e5e3bd47..68174b29f 100644 --- a/ui/app/controllers/vault/cluster/secrets/backend/sign.js +++ b/ui/app/controllers/vault/cluster/secrets/backend/sign.js @@ -1,8 +1,9 @@ -import Ember from 'ember'; -const { get, set } = Ember; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; +import { set, get } from '@ember/object'; -export default Ember.Controller.extend({ - store: Ember.inject.service(), +export default Controller.extend({ + store: service(), loading: false, emptyData: '{\n}', actions: { diff --git a/ui/app/controllers/vault/cluster/secrets/backends.js b/ui/app/controllers/vault/cluster/secrets/backends.js index 8b5b024b9..98cea196f 100644 --- a/ui/app/controllers/vault/cluster/secrets/backends.js +++ b/ui/app/controllers/vault/cluster/secrets/backends.js @@ -1,10 +1,11 @@ -import Ember from 'ember'; +import { filterBy } from '@ember/object/computed'; +import { computed } from '@ember/object'; +import Controller from '@ember/controller'; import { supportedSecretBackends } from 'vault/helpers/supported-secret-backends'; -const { computed, Controller } = Ember; const LINKED_BACKENDS = supportedSecretBackends(); export default Controller.extend({ - displayableBackends: computed.filterBy('model', 'shouldIncludeInList'), + displayableBackends: filterBy('model', 'shouldIncludeInList'), supportedBackends: computed('displayableBackends', 'displayableBackends.[]', function() { return (this.get('displayableBackends') || []) diff --git a/ui/app/controllers/vault/cluster/settings.js b/ui/app/controllers/vault/cluster/settings.js index 74a5a3625..40a25dbb2 100644 --- a/ui/app/controllers/vault/cluster/settings.js +++ b/ui/app/controllers/vault/cluster/settings.js @@ -1,6 +1,5 @@ -import Ember from 'ember'; - -const { inject, Controller } = Ember; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; export default Controller.extend({ - namespaceService: inject.service('namespace'), + namespaceService: service('namespace'), }); diff --git a/ui/app/controllers/vault/cluster/settings/auth/enable.js b/ui/app/controllers/vault/cluster/settings/auth/enable.js index 3756cd716..d5dd984c3 100644 --- a/ui/app/controllers/vault/cluster/settings/auth/enable.js +++ b/ui/app/controllers/vault/cluster/settings/auth/enable.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; -export default Ember.Controller.extend({ - wizard: Ember.inject.service(), +export default Controller.extend({ + wizard: service(), actions: { onMountSuccess: function(type) { let transition = this.transitionToRoute('vault.cluster.access.methods'); diff --git a/ui/app/controllers/vault/cluster/settings/configure-secret-backend.js b/ui/app/controllers/vault/cluster/settings/configure-secret-backend.js index a2401f0ad..bbef44ced 100644 --- a/ui/app/controllers/vault/cluster/settings/configure-secret-backend.js +++ b/ui/app/controllers/vault/cluster/settings/configure-secret-backend.js @@ -1,4 +1,6 @@ -import Ember from 'ember'; +import { isPresent } from '@ember/utils'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; const CONFIG_ATTRS = { // ssh @@ -12,10 +14,10 @@ const CONFIG_ATTRS = { region: '', }; -export default Ember.Controller.extend(CONFIG_ATTRS, { +export default Controller.extend(CONFIG_ATTRS, { queryParams: ['tab'], tab: '', - flashMessages: Ember.inject.service(), + flashMessages: service(), loading: false, reset() { this.get('model').rollbackAttributes(); @@ -26,23 +28,25 @@ export default Ember.Controller.extend(CONFIG_ATTRS, { const isDelete = options.delete; if (this.get('model.type') === 'ssh') { this.set('loading', true); - this.get('model').saveCA({ isDelete }).then(() => { - this.set('loading', false); - this.send('refreshRoute'); - this.set('configured', !isDelete); - if (isDelete) { - this.get('flashMessages').success('SSH Certificate Authority Configuration deleted!'); - } else { - this.get('flashMessages').success('SSH Certificate Authority Configuration saved!'); - } - }); + this.get('model') + .saveCA({ isDelete }) + .then(() => { + this.set('loading', false); + this.send('refreshRoute'); + this.set('configured', !isDelete); + if (isDelete) { + this.get('flashMessages').success('SSH Certificate Authority Configuration deleted!'); + } else { + this.get('flashMessages').success('SSH Certificate Authority Configuration saved!'); + } + }); } }, save(method, data) { this.set('loading', true); const hasData = Object.keys(data).some(key => { - return Ember.isPresent(data[key]); + return isPresent(data[key]); }); if (!hasData) { return; diff --git a/ui/app/controllers/vault/cluster/settings/control-groups.js b/ui/app/controllers/vault/cluster/settings/control-groups.js index 7b836c3c0..847ad46ca 100644 --- a/ui/app/controllers/vault/cluster/settings/control-groups.js +++ b/ui/app/controllers/vault/cluster/settings/control-groups.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Controller from '@ember/controller'; -export default Ember.Controller.extend({ +export default Controller.extend({ actions: { onSave({ saveType }) { if (saveType === 'destroyRecord') { diff --git a/ui/app/controllers/vault/cluster/settings/mount-secret-backend.js b/ui/app/controllers/vault/cluster/settings/mount-secret-backend.js index eeabc2ef8..432d5f32f 100644 --- a/ui/app/controllers/vault/cluster/settings/mount-secret-backend.js +++ b/ui/app/controllers/vault/cluster/settings/mount-secret-backend.js @@ -1,12 +1,11 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; import { supportedSecretBackends } from 'vault/helpers/supported-secret-backends'; const SUPPORTED_BACKENDS = supportedSecretBackends(); -const { inject, Controller } = Ember; - export default Controller.extend({ - wizard: inject.service(), + wizard: service(), actions: { onMountSuccess: function(type, path) { let transition; diff --git a/ui/app/controllers/vault/cluster/settings/seal.js b/ui/app/controllers/vault/cluster/settings/seal.js index 53017f39e..db4139101 100644 --- a/ui/app/controllers/vault/cluster/settings/seal.js +++ b/ui/app/controllers/vault/cluster/settings/seal.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; -export default Ember.Controller.extend({ - auth: Ember.inject.service(), +export default Controller.extend({ + auth: service(), actions: { seal() { diff --git a/ui/app/controllers/vault/cluster/unseal.js b/ui/app/controllers/vault/cluster/unseal.js index 5abcc4a8c..52744af09 100644 --- a/ui/app/controllers/vault/cluster/unseal.js +++ b/ui/app/controllers/vault/cluster/unseal.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Controller from '@ember/controller'; -export default Ember.Controller.extend({ - wizard: Ember.inject.service(), +export default Controller.extend({ + wizard: service(), actions: { transitionToCluster(resp) { diff --git a/ui/app/helpers/add.js b/ui/app/helpers/add.js index 0f2a78a20..df06eeb39 100644 --- a/ui/app/helpers/add.js +++ b/ui/app/helpers/add.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; export function add(params) { return params.reduce((sum, param) => parseInt(param, 0) + sum, 0); } -export default Ember.Helper.helper(add); +export default buildHelper(add); diff --git a/ui/app/helpers/aws-regions.js b/ui/app/helpers/aws-regions.js index 5901e157d..90e187ba1 100644 --- a/ui/app/helpers/aws-regions.js +++ b/ui/app/helpers/aws-regions.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; //list from http://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region const REGIONS = [ @@ -22,4 +22,4 @@ export function regions() { return REGIONS.slice(0); } -export default Ember.Helper.helper(regions); +export default buildHelper(regions); diff --git a/ui/app/helpers/coerce-eq.js b/ui/app/helpers/coerce-eq.js index c53ef23a7..fb11338c0 100644 --- a/ui/app/helpers/coerce-eq.js +++ b/ui/app/helpers/coerce-eq.js @@ -1,8 +1,8 @@ /*jshint eqeqeq: false */ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; export function coerceEq(params) { return params[0] == params[1]; } -export default Ember.Helper.helper(coerceEq); +export default buildHelper(coerceEq); diff --git a/ui/app/helpers/has-feature.js b/ui/app/helpers/has-feature.js index bc463367e..e88a50668 100644 --- a/ui/app/helpers/has-feature.js +++ b/ui/app/helpers/has-feature.js @@ -1,5 +1,7 @@ -import Ember from 'ember'; -const { Helper, inject, observer } = Ember; +import { inject as service } from '@ember/service'; +import { assert } from '@ember/debug'; +import Helper from '@ember/component/helper'; +import { observer } from '@ember/object'; const FEATURES = [ 'HSM', @@ -16,14 +18,14 @@ const FEATURES = [ export function hasFeature(featureName, features) { if (!FEATURES.includes(featureName)) { - Ember.assert(`${featureName} is not one of the available values for Vault Enterprise features.`, false); + assert(`${featureName} is not one of the available values for Vault Enterprise features.`, false); return false; } return features ? features.includes(featureName) : false; } export default Helper.extend({ - version: inject.service(), + version: service(), onFeaturesChange: observer('version.features.[]', function() { this.recompute(); }), diff --git a/ui/app/helpers/includes.js b/ui/app/helpers/includes.js index 7e460fc24..ff61d3586 100644 --- a/ui/app/helpers/includes.js +++ b/ui/app/helpers/includes.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; export function includes([haystack, needle]) { return haystack.includes(needle); } -export default Ember.Helper.helper(includes); +export default buildHelper(includes); diff --git a/ui/app/helpers/is-active-route.js b/ui/app/helpers/is-active-route.js index 1f5a0709a..ec462eab7 100644 --- a/ui/app/helpers/is-active-route.js +++ b/ui/app/helpers/is-active-route.js @@ -1,19 +1,20 @@ -import Ember from 'ember'; - -const { Helper, inject, observer } = Ember; +import { inject as service } from '@ember/service'; +import { isArray } from '@ember/array'; +import Helper from '@ember/component/helper'; +import { observer } from '@ember/object'; const exact = (a, b) => a === b; const startsWith = (a, b) => a.indexOf(b) === 0; export default Helper.extend({ - routing: inject.service('-routing'), + router: service(), - onRouteChange: observer('routing.router.currentURL', 'routing.router.currentRouteName', function() { + onRouteChange: observer('router.currentURL', 'router.currentRouteName', function() { this.recompute(); }), compute([routeName, model], { isExact }) { - const router = this.get('routing.router'); + const router = this.get('router'); const currentRoute = router.get('currentRouteName'); let currentURL = router.get('currentURL'); // if we have any query params we want to discard them @@ -22,11 +23,11 @@ export default Helper.extend({ if (!currentRoute) { return false; } - if (Ember.isArray(routeName)) { + if (isArray(routeName)) { return routeName.some(name => comparator(currentRoute, name)); } else if (model) { // slice off the rootURL from the generated route - return comparator(currentURL, router.generate(routeName, model).slice(router.rootURL.length - 1)); + return comparator(currentURL, router.urlFor(routeName, model).slice(router.rootURL.length - 1)); } else { return comparator(currentRoute, routeName); } diff --git a/ui/app/helpers/is-version.js b/ui/app/helpers/is-version.js index 85bd65242..065710026 100644 --- a/ui/app/helpers/is-version.js +++ b/ui/app/helpers/is-version.js @@ -1,14 +1,16 @@ -import Ember from 'ember'; -const { Helper, inject, observer } = Ember; +import { inject as service } from '@ember/service'; +import { assert } from '@ember/debug'; +import Helper from '@ember/component/helper'; +import { observer } from '@ember/object'; export default Helper.extend({ - version: inject.service(), + version: service(), onFeaturesChange: observer('version.version', function() { this.recompute(); }), compute([sku]) { if (sku !== 'OSS' && sku !== 'Enterprise') { - Ember.assert(`${sku} is not one of the available values for Vault versions.`, false); + assert(`${sku} is not one of the available values for Vault versions.`, false); return false; } return this.get(`version.is${sku}`); diff --git a/ui/app/helpers/jsonify.js b/ui/app/helpers/jsonify.js index 259c8d470..ce01a4a3d 100644 --- a/ui/app/helpers/jsonify.js +++ b/ui/app/helpers/jsonify.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; export function jsonify([target]) { return JSON.parse(target); } -export default Ember.Helper.helper(jsonify); +export default buildHelper(jsonify); diff --git a/ui/app/helpers/message-types.js b/ui/app/helpers/message-types.js index ea01ef1bb..e86f836db 100644 --- a/ui/app/helpers/message-types.js +++ b/ui/app/helpers/message-types.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; const MESSAGE_TYPES = { info: { @@ -31,4 +31,4 @@ export function messageTypes([type]) { return MESSAGE_TYPES[type]; } -export default Ember.Helper.helper(messageTypes); +export default buildHelper(messageTypes); diff --git a/ui/app/helpers/mountable-auth-methods.js b/ui/app/helpers/mountable-auth-methods.js index e24cdbfac..d5dd98f08 100644 --- a/ui/app/helpers/mountable-auth-methods.js +++ b/ui/app/helpers/mountable-auth-methods.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; const MOUNTABLE_AUTH_METHODS = [ { @@ -88,4 +88,4 @@ export function methods() { return MOUNTABLE_AUTH_METHODS.slice(); } -export default Ember.Helper.helper(methods); +export default buildHelper(methods); diff --git a/ui/app/helpers/mountable-secret-engines.js b/ui/app/helpers/mountable-secret-engines.js index 2b5936764..7d348985a 100644 --- a/ui/app/helpers/mountable-secret-engines.js +++ b/ui/app/helpers/mountable-secret-engines.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; const MOUNTABLE_SECRET_ENGINES = [ { @@ -85,4 +85,4 @@ export function engines() { return MOUNTABLE_SECRET_ENGINES.slice(); } -export default Ember.Helper.helper(engines); +export default buildHelper(engines); diff --git a/ui/app/helpers/multi-line-join.js b/ui/app/helpers/multi-line-join.js index cd22380f1..9607d4e60 100644 --- a/ui/app/helpers/multi-line-join.js +++ b/ui/app/helpers/multi-line-join.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; export function multiLineJoin([arr]) { return arr.join('\n'); } -export default Ember.Helper.helper(multiLineJoin); +export default buildHelper(multiLineJoin); diff --git a/ui/app/helpers/nav-to-route.js b/ui/app/helpers/nav-to-route.js index df0e740b1..e314456d9 100644 --- a/ui/app/helpers/nav-to-route.js +++ b/ui/app/helpers/nav-to-route.js @@ -1,9 +1,8 @@ -import Ember from 'ember'; - -const { Helper, inject } = Ember; +import { inject as service } from '@ember/service'; +import Helper from '@ember/component/helper'; export default Helper.extend({ - router: inject.service(), + router: service(), compute([routeName, ...models], { replace = false }) { return () => { diff --git a/ui/app/helpers/options-for-backend.js b/ui/app/helpers/options-for-backend.js index da626cb57..1a2111e1c 100644 --- a/ui/app/helpers/options-for-backend.js +++ b/ui/app/helpers/options-for-backend.js @@ -1,4 +1,6 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; +import { capitalize } from '@ember/string'; +import { assign } from '@ember/polyfills'; const DEFAULT_DISPLAY = { searchPlaceholder: 'Filter secrets', @@ -70,15 +72,15 @@ export function optionsForBackend([backend, tab]) { if (selected && selected.tabs) { let tabData = selected.tabs.findBy('name', tab) || selected.tabs.findBy('modelPrefix', tab) || selected.tabs[0]; - backendOptions = Ember.assign({}, selected, tabData); + backendOptions = assign({}, selected, tabData); } else if (selected) { backendOptions = selected; } else { - backendOptions = Ember.assign({}, DEFAULT_DISPLAY, { - displayName: backend === 'kv' ? 'KV' : Ember.String.capitalize(backend), + backendOptions = assign({}, DEFAULT_DISPLAY, { + displayName: backend === 'kv' ? 'KV' : capitalize(backend), }); } return backendOptions; } -export default Ember.Helper.helper(optionsForBackend); +export default buildHelper(optionsForBackend); diff --git a/ui/app/helpers/reduce-to-array.js b/ui/app/helpers/reduce-to-array.js index bca0c1978..b6d76d9e2 100644 --- a/ui/app/helpers/reduce-to-array.js +++ b/ui/app/helpers/reduce-to-array.js @@ -1,11 +1,12 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; +import { isNone, typeOf } from '@ember/utils'; export function reduceToArray(params) { return params.reduce(function(result, param) { - if (Ember.isNone(param)) { + if (isNone(param)) { return result; } - if (Ember.typeOf(param) === 'array') { + if (typeOf(param) === 'array') { return result.concat(param); } else { return result.concat([param]); @@ -13,4 +14,4 @@ export function reduceToArray(params) { }, []); } -export default Ember.Helper.helper(reduceToArray); +export default buildHelper(reduceToArray); diff --git a/ui/app/helpers/replication-action-for-mode.js b/ui/app/helpers/replication-action-for-mode.js index 8abd86c7e..82c198d24 100644 --- a/ui/app/helpers/replication-action-for-mode.js +++ b/ui/app/helpers/replication-action-for-mode.js @@ -1,4 +1,5 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; +import { get } from '@ember/object'; const ACTIONS = { performance: { primary: ['disable', 'demote', 'recover', 'reindex'], @@ -13,7 +14,7 @@ const ACTIONS = { }; export function replicationActionForMode([replicationMode, clusterMode] /*, hash*/) { - return Ember.get(ACTIONS, `${replicationMode}.${clusterMode}`); + return get(ACTIONS, `${replicationMode}.${clusterMode}`); } -export default Ember.Helper.helper(replicationActionForMode); +export default buildHelper(replicationActionForMode); diff --git a/ui/app/helpers/set-flash-message.js b/ui/app/helpers/set-flash-message.js index be5126065..e56059111 100644 --- a/ui/app/helpers/set-flash-message.js +++ b/ui/app/helpers/set-flash-message.js @@ -1,9 +1,8 @@ -import Ember from 'ember'; - -const { Helper, inject } = Ember; +import { inject as service } from '@ember/service'; +import Helper from '@ember/component/helper'; export default Helper.extend({ - flashMessages: inject.service(), + flashMessages: service(), compute([message, type]) { return () => { diff --git a/ui/app/helpers/sha2-digest-sizes.js b/ui/app/helpers/sha2-digest-sizes.js index 3eb1624ff..99bd6f171 100644 --- a/ui/app/helpers/sha2-digest-sizes.js +++ b/ui/app/helpers/sha2-digest-sizes.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; const SHA2_DIGEST_SIZES = ['sha2-224', 'sha2-256', 'sha2-384', 'sha2-512']; @@ -6,4 +6,4 @@ export function sha2DigestSizes() { return SHA2_DIGEST_SIZES; } -export default Ember.Helper.helper(sha2DigestSizes); +export default buildHelper(sha2DigestSizes); diff --git a/ui/app/helpers/stringify.js b/ui/app/helpers/stringify.js index a49427025..d51441f0f 100644 --- a/ui/app/helpers/stringify.js +++ b/ui/app/helpers/stringify.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; export function stringify([target], { skipFormat }) { if (skipFormat) { @@ -7,4 +7,4 @@ export function stringify([target], { skipFormat }) { return JSON.stringify(target, null, 2); } -export default Ember.Helper.helper(stringify); +export default buildHelper(stringify); diff --git a/ui/app/helpers/supported-auth-backends.js b/ui/app/helpers/supported-auth-backends.js index ac4959516..36ff7c453 100644 --- a/ui/app/helpers/supported-auth-backends.js +++ b/ui/app/helpers/supported-auth-backends.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; const SUPPORTED_AUTH_BACKENDS = [ { @@ -47,4 +47,4 @@ export function supportedAuthBackends() { return SUPPORTED_AUTH_BACKENDS; } -export default Ember.Helper.helper(supportedAuthBackends); +export default buildHelper(supportedAuthBackends); diff --git a/ui/app/helpers/supported-secret-backends.js b/ui/app/helpers/supported-secret-backends.js index b2f8dc78e..748ab5abb 100644 --- a/ui/app/helpers/supported-secret-backends.js +++ b/ui/app/helpers/supported-secret-backends.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; const SUPPORTED_SECRET_BACKENDS = ['aws', 'cubbyhole', 'generic', 'kv', 'pki', 'ssh', 'transit']; @@ -6,4 +6,4 @@ export function supportedSecretBackends() { return SUPPORTED_SECRET_BACKENDS; } -export default Ember.Helper.helper(supportedSecretBackends); +export default buildHelper(supportedSecretBackends); diff --git a/ui/app/helpers/tabs-for-auth-section.js b/ui/app/helpers/tabs-for-auth-section.js index 9e146d721..4aaf54fcc 100644 --- a/ui/app/helpers/tabs-for-auth-section.js +++ b/ui/app/helpers/tabs-for-auth-section.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; const TABS_FOR_SETTINGS = { aws: [ @@ -88,4 +88,4 @@ export function tabsForAuthSection([methodType, sectionType = 'authSettings']) { return tabs; } -export default Ember.Helper.helper(tabsForAuthSection); +export default buildHelper(tabsForAuthSection); diff --git a/ui/app/helpers/tabs-for-identity-show.js b/ui/app/helpers/tabs-for-identity-show.js index ced7696cf..f51c6ded7 100644 --- a/ui/app/helpers/tabs-for-identity-show.js +++ b/ui/app/helpers/tabs-for-identity-show.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; export const TABS = { entity: ['details', 'aliases', 'policies', 'groups', 'metadata'], @@ -18,4 +18,4 @@ export function tabsForIdentityShow([modelType, groupType]) { return TABS[key]; } -export default Ember.Helper.helper(tabsForIdentityShow); +export default buildHelper(tabsForIdentityShow); diff --git a/ui/app/helpers/to-label.js b/ui/app/helpers/to-label.js index a1691a795..b784f8ef8 100644 --- a/ui/app/helpers/to-label.js +++ b/ui/app/helpers/to-label.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; import { capitalize } from 'vault/helpers/capitalize'; import { humanize } from 'vault/helpers/humanize'; import { dasherize } from 'vault/helpers/dasherize'; @@ -7,4 +7,4 @@ export function toLabel(val) { return capitalize([humanize([dasherize(val)])]); } -export default Ember.Helper.helper(toLabel); +export default buildHelper(toLabel); diff --git a/ui/app/helpers/tools-actions.js b/ui/app/helpers/tools-actions.js index 83b5bae4a..32f36cf2d 100644 --- a/ui/app/helpers/tools-actions.js +++ b/ui/app/helpers/tools-actions.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { helper as buildHelper } from '@ember/component/helper'; const TOOLS_ACTIONS = ['wrap', 'lookup', 'unwrap', 'rewrap', 'random', 'hash']; @@ -6,4 +6,4 @@ export function toolsActions() { return TOOLS_ACTIONS; } -export default Ember.Helper.helper(toolsActions); +export default buildHelper(toolsActions); diff --git a/ui/app/lib/control-group-error.js b/ui/app/lib/control-group-error.js index 4e2c2c420..525fe41f9 100644 --- a/ui/app/lib/control-group-error.js +++ b/ui/app/lib/control-group-error.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import EmberError from '@ember/error'; -export default class ControlGroupError extends Ember.Error { +export default class ControlGroupError extends EmberError { constructor(wrapInfo) { - let {accessor, creation_path, creation_time, token, ttl} = wrapInfo; + let { accessor, creation_path, creation_time, token, ttl } = wrapInfo; super(); this.message = 'Control Group encountered'; diff --git a/ui/app/lib/kv-object.js b/ui/app/lib/kv-object.js index 4c6ec8a3b..27207ee64 100644 --- a/ui/app/lib/kv-object.js +++ b/ui/app/lib/kv-object.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import ArrayProxy from '@ember/array/proxy'; +import { typeOf } from '@ember/utils'; +import { guidFor } from '@ember/object/internals'; -const { typeOf, guidFor } = Ember; - -export default Ember.ArrayProxy.extend({ +export default ArrayProxy.extend({ fromJSON(json) { if (json && typeOf(json) !== 'object') { throw new Error('Vault expects data to be formatted as an JSON object.'); diff --git a/ui/app/mixins/backend-crumb.js b/ui/app/mixins/backend-crumb.js index 8409d60f2..2a780a630 100644 --- a/ui/app/mixins/backend-crumb.js +++ b/ui/app/mixins/backend-crumb.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import Mixin from '@ember/object/mixin'; -export default Ember.Mixin.create({ - backendCrumb: Ember.computed('backend', function() { +export default Mixin.create({ + backendCrumb: computed('backend', function() { const backend = this.get('backend'); if (backend === undefined) { diff --git a/ui/app/mixins/cluster-route.js b/ui/app/mixins/cluster-route.js index 05d2aa064..72d6de988 100644 --- a/ui/app/mixins/cluster-route.js +++ b/ui/app/mixins/cluster-route.js @@ -1,6 +1,7 @@ -import Ember from 'ember'; - -const { get, inject, Mixin, RSVP } = Ember; +import { inject as service } from '@ember/service'; +import { get } from '@ember/object'; +import Mixin from '@ember/object/mixin'; +import RSVP from 'rsvp'; const INIT = 'vault.cluster.init'; const UNSEAL = 'vault.cluster.unseal'; const AUTH = 'vault.cluster.auth'; @@ -10,7 +11,7 @@ const DR_REPLICATION_SECONDARY = 'vault.cluster.replication-dr-promote'; export { INIT, UNSEAL, AUTH, CLUSTER, DR_REPLICATION_SECONDARY }; export default Mixin.create({ - auth: inject.service(), + auth: service(), transitionToTargetRoute() { const targetRoute = this.targetRouteName(); diff --git a/ui/app/mixins/focus-on-insert.js b/ui/app/mixins/focus-on-insert.js index 97f4871e1..def2f1021 100644 --- a/ui/app/mixins/focus-on-insert.js +++ b/ui/app/mixins/focus-on-insert.js @@ -1,6 +1,8 @@ -import Ember from 'ember'; +import { schedule } from '@ember/runloop'; +import { on } from '@ember/object/evented'; +import Mixin from '@ember/object/mixin'; -export default Ember.Mixin.create({ +export default Mixin.create({ // selector passed to `this.$()` to find the element to focus // defaults to `'input'` focusOnInsertSelector: null, @@ -8,8 +10,8 @@ export default Ember.Mixin.create({ // uses Ember.on so that we don't have to worry about calling _super if // didInsertElement is overridden - focusOnInsert: Ember.on('didInsertElement', function() { - Ember.run.schedule('afterRender', this, 'focusOnInsertFocus'); + focusOnInsert: on('didInsertElement', function() { + schedule('afterRender', this, 'focusOnInsertFocus'); }), focusOnInsertFocus() { diff --git a/ui/app/mixins/list-controller.js b/ui/app/mixins/list-controller.js index 039d24dc1..2c6e4ad5a 100644 --- a/ui/app/mixins/list-controller.js +++ b/ui/app/mixins/list-controller.js @@ -1,6 +1,7 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import Mixin from '@ember/object/mixin'; -export default Ember.Mixin.create({ +export default Mixin.create({ queryParams: { page: 'page', pageFilter: 'pageFilter', @@ -12,13 +13,13 @@ export default Ember.Mixin.create({ isLoading: false, - filterMatchesKey: Ember.computed('filter', 'model', 'model.[]', function() { + filterMatchesKey: computed('filter', 'model', 'model.[]', function() { var filter = this.get('filter'); var content = this.get('model'); return !!(content.length && content.findBy('id', filter)); }), - firstPartialMatch: Ember.computed('filter', 'model', 'model.[]', 'filterMatchesKey', function() { + firstPartialMatch: computed('filter', 'model', 'model.[]', 'filterMatchesKey', function() { var filter = this.get('filter'); var content = this.get('model'); var filterMatchesKey = this.get('filterMatchesKey'); diff --git a/ui/app/mixins/list-route.js b/ui/app/mixins/list-route.js index 16e5248d4..eb1e71301 100644 --- a/ui/app/mixins/list-route.js +++ b/ui/app/mixins/list-route.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Mixin from '@ember/object/mixin'; -export default Ember.Mixin.create({ +export default Mixin.create({ queryParams: { page: { refreshModel: true, diff --git a/ui/app/mixins/model-boundary-route.js b/ui/app/mixins/model-boundary-route.js index d38dc8a08..50bf10dde 100644 --- a/ui/app/mixins/model-boundary-route.js +++ b/ui/app/mixins/model-boundary-route.js @@ -8,40 +8,45 @@ // route will cause all `datacenter` models to get unloaded when the // infrastructure route is navigated away from. -import Ember from 'ember'; +import Route from '@ember/routing/route'; -export default Ember.Mixin.create({ +import { isPresent } from '@ember/utils'; +import { warn } from '@ember/debug'; +import { on } from '@ember/object/evented'; +import Mixin from '@ember/object/mixin'; + +export default Mixin.create({ modelType: null, modelTypes: null, - verifyProps: Ember.on('init', function() { + verifyProps: on('init', function() { var modelType = this.get('modelType'); var modelTypes = this.get('modelTypes'); - Ember.warn( + warn( 'No `modelType` or `modelTypes` specified for `' + this.toString() + '`. Check to make sure you still need to use the `model-boundary-route` mixin.', - Ember.isPresent(modelType) || Ember.isPresent(modelTypes), + isPresent(modelType) || isPresent(modelTypes), { id: 'model-boundary-init' } ); - Ember.warn( + warn( 'Expected `model-boundary-route` to be used on an Ember.Route, not `' + this.toString() + '`.', - this instanceof Ember.Route, + this instanceof Route, { id: 'mode-boundary-is-route' } ); }), - clearModelCache: Ember.on('deactivate', function() { + clearModelCache: on('deactivate', function() { var modelType = this.get('modelType'); var modelTypes = this.get('modelTypes'); if (!modelType && !modelTypes) { - Ember.warn( + warn( 'Attempted to clear store clear store cache when leaving `' + this.routeName + '`, but no `modelType` or `modelTypes` was specified.', - Ember.isPresent(modelType), + isPresent(modelType), { id: 'model-boundary-clear' } ); return; diff --git a/ui/app/mixins/policy-edit-controller.js b/ui/app/mixins/policy-edit-controller.js index a353c6d8a..36ba97e49 100644 --- a/ui/app/mixins/policy-edit-controller.js +++ b/ui/app/mixins/policy-edit-controller.js @@ -1,10 +1,9 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Mixin from '@ember/object/mixin'; -let { inject } = Ember; - -export default Ember.Mixin.create({ - flashMessages: inject.service(), - wizard: inject.service(), +export default Mixin.create({ + flashMessages: service(), + wizard: service(), actions: { deletePolicy(model) { let policyType = model.get('policyType'); @@ -28,13 +27,19 @@ export default Ember.Mixin.create({ let flash = this.get('flashMessages'); let policyType = model.get('policyType'); let name = model.get('name'); - model.save().then(m => { - flash.success(`${policyType.toUpperCase()} policy "${name}" was successfully saved.`); - if (this.get('wizard.featureState') === 'create') { - this.get('wizard').transitionFeatureMachine('create', 'CONTINUE', policyType); - } - return this.transitionToRoute('vault.cluster.policy.show', m.get('policyType'), m.get('name')); - }); + model + .save() + .then(m => { + flash.success(`${policyType.toUpperCase()} policy "${name}" was successfully saved.`); + if (this.get('wizard.featureState') === 'create') { + this.get('wizard').transitionFeatureMachine('create', 'CONTINUE', policyType); + } + return this.transitionToRoute('vault.cluster.policy.show', m.get('policyType'), m.get('name')); + }) + .catch(() => { + // do nothing here... + // message-error component will show errors + }); }, setModelName(model, e) { diff --git a/ui/app/mixins/replication-actions.js b/ui/app/mixins/replication-actions.js index 0fe0466b2..a2ab65237 100644 --- a/ui/app/mixins/replication-actions.js +++ b/ui/app/mixins/replication-actions.js @@ -1,23 +1,25 @@ -import Ember from 'ember'; -const { inject, computed } = Ember; +import { inject as service } from '@ember/service'; +import { or } from '@ember/object/computed'; +import { isPresent } from '@ember/utils'; +import Mixin from '@ember/object/mixin'; +import { task } from 'ember-concurrency'; -export default Ember.Mixin.create({ - store: inject.service(), - routing: inject.service('-routing'), - router: computed.alias('routing.router'), +export default Mixin.create({ + store: service(), + router: service(), + loading: or('save.isRunning', 'submitSuccess.isRunning'), submitHandler(action, clusterMode, data, event) { let replicationMode = (data && data.replicationMode) || this.get('replicationMode'); if (event && event.preventDefault) { event.preventDefault(); } this.setProperties({ - loading: true, errors: [], }); if (data) { data = Object.keys(data).reduce((newData, key) => { var val = data[key]; - if (Ember.isPresent(val)) { + if (isPresent(val)) { newData[key] = val; } return newData; @@ -25,18 +27,22 @@ export default Ember.Mixin.create({ delete data.replicationMode; } - return this.get('store') - .adapterFor('cluster') - .replicationAction(action, replicationMode, clusterMode, data) - .then( - resp => { - return this.submitSuccess(resp, action, clusterMode); - }, - (...args) => this.submitError(...args) - ); + return this.get('save').perform(action, replicationMode, clusterMode, data); }, - submitSuccess(resp, action, mode) { + save: task(function*(action, replicationMode, clusterMode, data) { + let resp; + try { + resp = yield this.get('store') + .adapterFor('cluster') + .replicationAction(action, replicationMode, clusterMode, data); + } catch (e) { + return this.submitError(e); + } + yield this.get('submitSuccess').perform(resp, action, clusterMode); + }).drop(), + + submitSuccess: task(function*(resp, action, mode) { const cluster = this.get('cluster'); const replicationMode = this.get('selectedReplicationMode') || this.get('replicationMode'); const store = this.get('store'); @@ -72,24 +78,22 @@ export default Ember.Mixin.create({ } const router = this.get('router'); if (action === 'disable') { - return router.transitionTo.call(router, 'vault.cluster.replication.mode', replicationMode); + yield router.transitionTo('vault.cluster.replication.mode', replicationMode); + } + try { + yield cluster.reload(); + } catch (e) { + // no error handling here + } + cluster.rollbackAttributes(); + if (action === 'enable') { + yield router.transitionTo('vault.cluster.replication.mode', replicationMode); } - return cluster - .reload() - .then(() => { - cluster.rollbackAttributes(); - if (action === 'enable') { - return router.transitionTo.call(router, 'vault.cluster.replication.mode', replicationMode); - } - if (mode === 'secondary' && replicationMode === 'dr') { - return router.transitionTo.call(router, 'vault.cluster'); - } - }) - .finally(() => { - this.set('loading', false); - }); - }, + if (mode === 'secondary' && replicationMode === 'dr') { + yield router.transitionTo('vault.cluster'); + } + }).drop(), submitError(e) { if (e.errors) { diff --git a/ui/app/mixins/unload-model-route.js b/ui/app/mixins/unload-model-route.js index 87a397edd..244079895 100644 --- a/ui/app/mixins/unload-model-route.js +++ b/ui/app/mixins/unload-model-route.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import Mixin from '@ember/object/mixin'; // removes Ember Data records from the cache when the model // changes or you move away from the current route -export default Ember.Mixin.create({ +export default Mixin.create({ modelPath: 'model', unloadModel() { const model = this.controller.get(this.get('modelPath')); diff --git a/ui/app/mixins/unsaved-model-route.js b/ui/app/mixins/unsaved-model-route.js index 89f5c2297..37a85cccb 100644 --- a/ui/app/mixins/unsaved-model-route.js +++ b/ui/app/mixins/unsaved-model-route.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; -const { get } = Ember; +import Mixin from '@ember/object/mixin'; +import { get } from '@ember/object'; // this mixin relies on `unload-model-route` also being used -export default Ember.Mixin.create({ +export default Mixin.create({ actions: { willTransition(transition) { const model = this.controller.get('model'); diff --git a/ui/app/models/auth-config/aws/client.js b/ui/app/models/auth-config/aws/client.js index 0bb13bb96..7568371f5 100644 --- a/ui/app/models/auth-config/aws/client.js +++ b/ui/app/models/auth-config/aws/client.js @@ -1,10 +1,9 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import AuthConfig from '../../auth-config'; import fieldToAttrs from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; export default AuthConfig.extend({ secretKey: attr('string'), diff --git a/ui/app/models/auth-config/aws/tidy.js b/ui/app/models/auth-config/aws/tidy.js index daf3949e4..fc4e1a0e0 100644 --- a/ui/app/models/auth-config/aws/tidy.js +++ b/ui/app/models/auth-config/aws/tidy.js @@ -1,10 +1,9 @@ +import { computed } from '@ember/object'; import DS from 'ember-data'; -import Ember from 'ember'; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; import AuthConfig from '../../auth-config'; const { attr } = DS; -const { computed } = Ember; export default AuthConfig.extend({ safetyBuffer: attr({ diff --git a/ui/app/models/auth-config/azure.js b/ui/app/models/auth-config/azure.js index ab2a64a88..1949d20e8 100644 --- a/ui/app/models/auth-config/azure.js +++ b/ui/app/models/auth-config/azure.js @@ -1,11 +1,10 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import AuthConfig from '../auth-config'; import fieldToAttrs from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; export default AuthConfig.extend({ tenantId: attr('string', { diff --git a/ui/app/models/auth-config/gcp.js b/ui/app/models/auth-config/gcp.js index 6d306e4f0..9185fb297 100644 --- a/ui/app/models/auth-config/gcp.js +++ b/ui/app/models/auth-config/gcp.js @@ -1,11 +1,10 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import AuthConfig from '../auth-config'; import fieldToAttrs from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; export default AuthConfig.extend({ credentials: attr('string', { diff --git a/ui/app/models/auth-config/github.js b/ui/app/models/auth-config/github.js index 4ffa743b8..0c5465383 100644 --- a/ui/app/models/auth-config/github.js +++ b/ui/app/models/auth-config/github.js @@ -1,11 +1,10 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import AuthConfig from '../auth-config'; import fieldToAttrs from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; export default AuthConfig.extend({ organization: attr('string'), diff --git a/ui/app/models/auth-config/jwt.js b/ui/app/models/auth-config/jwt.js index a99d9ea0b..091e717d1 100644 --- a/ui/app/models/auth-config/jwt.js +++ b/ui/app/models/auth-config/jwt.js @@ -1,10 +1,9 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import AuthConfig from '../auth-config'; import fieldToAttrs from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; export default AuthConfig.extend({ oidcDiscoveryUrl: attr('string', { diff --git a/ui/app/models/auth-config/kubernetes.js b/ui/app/models/auth-config/kubernetes.js index f7a40214e..4d8da679a 100644 --- a/ui/app/models/auth-config/kubernetes.js +++ b/ui/app/models/auth-config/kubernetes.js @@ -1,11 +1,10 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import AuthConfig from '../auth-config'; import fieldToAttrs from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; export default AuthConfig.extend({ kubernetesHost: attr('string', { diff --git a/ui/app/models/auth-config/ldap.js b/ui/app/models/auth-config/ldap.js index bd8b8ffcb..5266e4d83 100644 --- a/ui/app/models/auth-config/ldap.js +++ b/ui/app/models/auth-config/ldap.js @@ -1,11 +1,10 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import AuthConfig from '../auth-config'; import fieldToAttrs from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; export default AuthConfig.extend({ url: attr('string', { diff --git a/ui/app/models/auth-config/okta.js b/ui/app/models/auth-config/okta.js index 969db3d91..8796db7c5 100644 --- a/ui/app/models/auth-config/okta.js +++ b/ui/app/models/auth-config/okta.js @@ -1,10 +1,9 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import AuthConfig from '../auth-config'; import fieldToAttrs from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; export default AuthConfig.extend({ orgName: attr('string', { diff --git a/ui/app/models/auth-config/radius.js b/ui/app/models/auth-config/radius.js index c595427cb..c47351f3d 100644 --- a/ui/app/models/auth-config/radius.js +++ b/ui/app/models/auth-config/radius.js @@ -1,10 +1,9 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import AuthConfig from '../auth-config'; import fieldToAttrs from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; export default AuthConfig.extend({ host: attr('string'), diff --git a/ui/app/models/auth-method.js b/ui/app/models/auth-method.js index 06e5768e7..9d12f4f8f 100644 --- a/ui/app/models/auth-method.js +++ b/ui/app/models/auth-method.js @@ -1,4 +1,5 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import { fragment } from 'ember-data-model-fragments/attributes'; import { queryRecord } from 'ember-computed-query'; @@ -7,7 +8,6 @@ import { memberAction } from 'ember-api-actions'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; const { attr, hasMany } = DS; -const { computed } = Ember; const configPath = function configPath(strings, key) { return function(...values) { @@ -61,28 +61,32 @@ export default DS.Model.extend({ urlType: 'updateRecord', }), - formFields: [ - 'type', - 'path', - 'description', - 'accessor', - 'local', - 'sealWrap', - 'config.{listingVisibility,defaultLeaseTtl,maxLeaseTtl,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}', - ], + formFields: computed(function() { + return [ + 'type', + 'path', + 'description', + 'accessor', + 'local', + 'sealWrap', + 'config.{listingVisibility,defaultLeaseTtl,maxLeaseTtl,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}', + ]; + }), - formFieldGroups: [ - { default: ['path'] }, - { - 'Method Options': [ - 'description', - 'config.listingVisibility', - 'local', - 'sealWrap', - 'config.{defaultLeaseTtl,maxLeaseTtl,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}', - ], - }, - ], + formFieldGroups: computed(function() { + return [ + { default: ['path'] }, + { + 'Method Options': [ + 'description', + 'config.listingVisibility', + 'local', + 'sealWrap', + 'config.{defaultLeaseTtl,maxLeaseTtl,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}', + ], + }, + ]; + }), attrs: computed('formFields', function() { return expandAttributeMeta(this, this.get('formFields')); @@ -114,6 +118,6 @@ export default DS.Model.extend({ ), deletePath: lazyCapabilities(apiPath`sys/auth/${'id'}`, 'id'), - canDisable: computed.alias('deletePath.canDelete'), - canEdit: computed.alias('configPath.canUpdate'), + canDisable: alias('deletePath.canDelete'), + canEdit: alias('configPath.canUpdate'), }); diff --git a/ui/app/models/aws-credential.js b/ui/app/models/aws-credential.js index 3771272b8..3d0340145 100644 --- a/ui/app/models/aws-credential.js +++ b/ui/app/models/aws-credential.js @@ -1,8 +1,7 @@ +import { computed } from '@ember/object'; import DS from 'ember-data'; -import Ember from 'ember'; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; const CREATE_FIELDS = ['ttl', 'roleArn']; const DISPLAY_FIELDS = ['accessKey', 'secretKey', 'securityToken', 'leaseId', 'renewable', 'leaseDuration']; diff --git a/ui/app/models/capabilities.js b/ui/app/models/capabilities.js index 72af44e83..2fea24ba7 100644 --- a/ui/app/models/capabilities.js +++ b/ui/app/models/capabilities.js @@ -2,7 +2,7 @@ // `path` is also the primaryId // https://www.vaultproject.io/docs/concepts/policies.html#capabilities -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; const { attr } = DS; @@ -20,7 +20,7 @@ const SUDO_PATH_PREFIXES = ['sys/leases/revoke-prefix', 'sys/leases/revoke-force export { SUDO_PATHS, SUDO_PATH_PREFIXES }; const computedCapability = function(capability) { - return Ember.computed('path', 'capabilities', 'capabilities.[]', function() { + return computed('path', 'capabilities', 'capabilities.[]', function() { const capabilities = this.get('capabilities'); const path = this.get('path'); if (!capabilities) { diff --git a/ui/app/models/cluster.js b/ui/app/models/cluster.js index 9eac03c4e..e065d7483 100644 --- a/ui/app/models/cluster.js +++ b/ui/app/models/cluster.js @@ -1,12 +1,12 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { not, gte, alias, and, or } from '@ember/object/computed'; +import { get, computed } from '@ember/object'; import DS from 'ember-data'; import { fragment } from 'ember-data-model-fragments/attributes'; const { hasMany, attr } = DS; -const { computed, get, inject } = Ember; -const { alias, gte, not } = computed; export default DS.Model.extend({ - version: inject.service(), + version: service(), nodes: hasMany('nodes', { async: false }), name: attr('string'), @@ -22,7 +22,7 @@ export default DS.Model.extend({ return this.constructor.modelName; }), - unsealed: computed('nodes', 'nodes.[]', 'nodes.@each.sealed', function() { + unsealed: computed('nodes', 'nodes.{[],@each.sealed}', function() { // unsealed if there's at least one unsealed node return !!this.get('nodes').findBy('sealed', false); }), @@ -45,9 +45,9 @@ export default DS.Model.extend({ //replication mode - will only ever be 'unsupported' //otherwise the particular mode will have the relevant mode attr through replication-attributes mode: attr('string'), - allReplicationDisabled: computed.and('{dr,performance}.replicationDisabled'), + allReplicationDisabled: and('{dr,performance}.replicationDisabled'), - anyReplicationEnabled: computed.or('{dr,performance}.replicationEnabled'), + anyReplicationEnabled: or('{dr,performance}.replicationEnabled'), stateDisplay(state) { if (!state) { @@ -95,8 +95,8 @@ export default DS.Model.extend({ performance: fragment('replication-attributes'), // this service exposes what mode the UI is currently viewing // replicationAttrs will then return the relevant `replication-attributes` fragment - rm: Ember.inject.service('replication-mode'), - replicationMode: computed.alias('rm.mode'), + rm: service('replication-mode'), + replicationMode: alias('rm.mode'), replicationAttrs: computed('dr.mode', 'performance.mode', 'replicationMode', function() { const replicationMode = this.get('replicationMode'); return replicationMode ? get(this, replicationMode) : null; diff --git a/ui/app/models/control-group-config.js b/ui/app/models/control-group-config.js index f8c5591b4..e1049c7a1 100644 --- a/ui/app/models/control-group-config.js +++ b/ui/app/models/control-group-config.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; const { attr } = DS; -const { computed } = Ember; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; export default DS.Model.extend({ @@ -12,7 +12,7 @@ export default DS.Model.extend({ }), configurePath: lazyCapabilities(apiPath`sys/config/control-group`), - canDelete: computed.alias('configurePath.canDelete'), + canDelete: alias('configurePath.canDelete'), maxTtl: attr({ defaultValue: 0, editType: 'ttl', diff --git a/ui/app/models/control-group.js b/ui/app/models/control-group.js index d0e84adfa..a5e05a022 100644 --- a/ui/app/models/control-group.js +++ b/ui/app/models/control-group.js @@ -1,9 +1,8 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; import DS from 'ember-data'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; const { attr, belongsTo, hasMany } = DS; -const { computed } = Ember; export default DS.Model.extend({ approved: attr('boolean'), @@ -12,7 +11,7 @@ export default DS.Model.extend({ authorizations: hasMany('identity/entity', { async: false }), authorizePath: lazyCapabilities(apiPath`sys/control-group/authorize`), - canAuthorize: computed.alias('authorizePath.canUpdate'), + canAuthorize: alias('authorizePath.canUpdate'), configurePath: lazyCapabilities(apiPath`sys/config/control-group`), - canConfigure: computed.alias('configurePath.canUpdate'), + canConfigure: alias('configurePath.canUpdate'), }); diff --git a/ui/app/models/identity/_base.js b/ui/app/models/identity/_base.js index e4e5fdd33..9c0c6d51b 100644 --- a/ui/app/models/identity/_base.js +++ b/ui/app/models/identity/_base.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import { assert } from '@ember/debug'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; -const { assert, computed } = Ember; export default DS.Model.extend({ formFields: computed(function() { return assert('formFields should be overridden', false); diff --git a/ui/app/models/identity/entity-alias.js b/ui/app/models/identity/entity-alias.js index 10ac88d8b..8210a7565 100644 --- a/ui/app/models/identity/entity-alias.js +++ b/ui/app/models/identity/entity-alias.js @@ -1,13 +1,15 @@ +import { computed } from '@ember/object'; +import { alias } from '@ember/object/computed'; import IdentityModel from './_base'; import DS from 'ember-data'; -import Ember from 'ember'; import identityCapabilities from 'vault/macros/identity-capabilities'; const { attr, belongsTo } = DS; -const { computed } = Ember; export default IdentityModel.extend({ parentType: 'entity', - formFields: ['name', 'mountAccessor'], + formFields: computed(function() { + return ['name', 'mountAccessor']; + }), entity: belongsTo('identity/entity', { readOnly: true, async: false }), name: attr('string'), @@ -34,6 +36,6 @@ export default IdentityModel.extend({ mergedFromCanonicalIds: attr(), updatePath: identityCapabilities(), - canDelete: computed.alias('updatePath.canDelete'), - canEdit: computed.alias('updatePath.canUpdate'), + canDelete: alias('updatePath.canDelete'), + canEdit: alias('updatePath.canUpdate'), }); diff --git a/ui/app/models/identity/entity-merge.js b/ui/app/models/identity/entity-merge.js index c66293818..a5df0b9e0 100644 --- a/ui/app/models/identity/entity-merge.js +++ b/ui/app/models/identity/entity-merge.js @@ -1,9 +1,12 @@ -import IdentityModel from './_base'; +import { computed } from '@ember/object'; import DS from 'ember-data'; +import IdentityModel from './_base'; const { attr } = DS; export default IdentityModel.extend({ - formFields: ['toEntityId', 'fromEntityIds', 'force'], + formFields: computed(function() { + return ['toEntityId', 'fromEntityIds', 'force']; + }), toEntityId: attr('string', { label: 'Entity to merge to', }), diff --git a/ui/app/models/identity/entity.js b/ui/app/models/identity/entity.js index 03eaa819e..d6e3ec4cd 100644 --- a/ui/app/models/identity/entity.js +++ b/ui/app/models/identity/entity.js @@ -1,15 +1,16 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import { alias } from '@ember/object/computed'; import IdentityModel from './_base'; import DS from 'ember-data'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; import identityCapabilities from 'vault/macros/identity-capabilities'; -const { computed } = Ember; - const { attr, hasMany } = DS; export default IdentityModel.extend({ - formFields: ['name', 'disabled', 'policies', 'metadata'], + formFields: computed(function() { + return ['name', 'disabled', 'policies', 'metadata']; + }), name: attr('string'), disabled: attr('boolean', { defaultValue: false, @@ -41,10 +42,10 @@ export default IdentityModel.extend({ }), updatePath: identityCapabilities(), - canDelete: computed.alias('updatePath.canDelete'), - canEdit: computed.alias('updatePath.canUpdate'), - canRead: computed.alias('updatePath.canRead'), + canDelete: alias('updatePath.canDelete'), + canEdit: alias('updatePath.canUpdate'), + canRead: alias('updatePath.canRead'), aliasPath: lazyCapabilities(apiPath`identity/entity-alias`), - canAddAlias: computed.alias('aliasPath.canCreate'), + canAddAlias: alias('aliasPath.canCreate'), }); diff --git a/ui/app/models/identity/group-alias.js b/ui/app/models/identity/group-alias.js index 47a74ebb2..c132d40d1 100644 --- a/ui/app/models/identity/group-alias.js +++ b/ui/app/models/identity/group-alias.js @@ -1,14 +1,16 @@ +import { computed } from '@ember/object'; +import { alias } from '@ember/object/computed'; import IdentityModel from './_base'; import DS from 'ember-data'; -import Ember from 'ember'; import identityCapabilities from 'vault/macros/identity-capabilities'; const { attr, belongsTo } = DS; -const { computed } = Ember; export default IdentityModel.extend({ parentType: 'group', - formFields: ['name', 'mountAccessor'], + formFields: computed(function() { + return ['name', 'mountAccessor']; + }), group: belongsTo('identity/group', { readOnly: true, async: false }), name: attr('string'), @@ -33,6 +35,6 @@ export default IdentityModel.extend({ }), updatePath: identityCapabilities(), - canDelete: computed.alias('updatePath.canDelete'), - canEdit: computed.alias('updatePath.canUpdate'), + canDelete: alias('updatePath.canDelete'), + canEdit: alias('updatePath.canUpdate'), }); diff --git a/ui/app/models/identity/group.js b/ui/app/models/identity/group.js index ca13e28aa..1e813032b 100644 --- a/ui/app/models/identity/group.js +++ b/ui/app/models/identity/group.js @@ -1,10 +1,10 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { computed } from '@ember/object'; import IdentityModel from './_base'; import DS from 'ember-data'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; import identityCapabilities from 'vault/macros/identity-capabilities'; -const { computed } = Ember; const { attr, belongsTo } = DS; export default IdentityModel.extend({ @@ -65,8 +65,8 @@ export default IdentityModel.extend({ alias: belongsTo('identity/group-alias', { async: false, readOnly: true }), updatePath: identityCapabilities(), - canDelete: computed.alias('updatePath.canDelete'), - canEdit: computed.alias('updatePath.canUpdate'), + canDelete: alias('updatePath.canDelete'), + canEdit: alias('updatePath.canUpdate'), aliasPath: lazyCapabilities(apiPath`identity/group-alias`), canAddAlias: computed('aliasPath.canCreate', 'type', 'alias', function() { diff --git a/ui/app/models/key-mixin.js b/ui/app/models/key-mixin.js index 694e8ce06..8b505ece5 100644 --- a/ui/app/models/key-mixin.js +++ b/ui/app/models/key-mixin.js @@ -1,24 +1,25 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import Mixin from '@ember/object/mixin'; import utils from '../lib/key-utils'; -export default Ember.Mixin.create({ +export default Mixin.create({ flags: null, initialParentKey: null, - isCreating: Ember.computed('initialParentKey', function() { + isCreating: computed('initialParentKey', function() { return this.get('initialParentKey') != null; }), - isFolder: Ember.computed('id', function() { + isFolder: computed('id', function() { return utils.keyIsFolder(this.get('id')); }), - keyParts: Ember.computed('id', function() { + keyParts: computed('id', function() { return utils.keyPartsForKey(this.get('id')); }), - parentKey: Ember.computed('id', 'isCreating', { + parentKey: computed('id', 'isCreating', { get: function() { return this.get('isCreating') ? this.get('initialParentKey') : utils.parentKeyForKey(this.get('id')); }, @@ -27,7 +28,7 @@ export default Ember.Mixin.create({ }, }), - keyWithoutParent: Ember.computed('id', 'parentKey', { + keyWithoutParent: computed('id', 'parentKey', { get: function() { var key = this.get('id'); return key ? key.replace(this.get('parentKey'), '') : null; diff --git a/ui/app/models/lease.js b/ui/app/models/lease.js index 4f0991188..bbf271ad6 100644 --- a/ui/app/models/lease.js +++ b/ui/app/models/lease.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { match } from '@ember/object/computed'; import DS from 'ember-data'; import KeyMixin from './key-mixin'; const { attr } = DS; @@ -21,5 +21,5 @@ export default DS.Model.extend(KeyMixin, { lastRenewal: attr('string'), renewable: attr('boolean'), ttl: attr('number'), - isAuthLease: Ember.computed.match('id', /^auth/), + isAuthLease: match('id', /^auth/), }); diff --git a/ui/app/models/namespace.js b/ui/app/models/namespace.js index 3329cb910..8fbdaa87b 100644 --- a/ui/app/models/namespace.js +++ b/ui/app/models/namespace.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; const { attr } = DS; -const { computed } = Ember; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; export default DS.Model.extend({ diff --git a/ui/app/models/node.js b/ui/app/models/node.js index 5d9b648c9..29c1937b6 100644 --- a/ui/app/models/node.js +++ b/ui/app/models/node.js @@ -1,10 +1,8 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import { alias, and, equal } from '@ember/object/computed'; import DS from 'ember-data'; const { attr } = DS; -const { computed } = Ember; -const { equal, and, alias } = computed; - export default DS.Model.extend({ name: attr('string'), //https://www.vaultproject.io/docs/http/sys-health.html @@ -32,7 +30,7 @@ export default DS.Model.extend({ isSelf: attr('boolean'), leaderAddress: attr('string'), - type: Ember.computed(function() { + type: computed(function() { return this.constructor.modelName; }), }); diff --git a/ui/app/models/pki-ca-certificate-sign.js b/ui/app/models/pki-ca-certificate-sign.js index 25617eec9..ca88f787f 100644 --- a/ui/app/models/pki-ca-certificate-sign.js +++ b/ui/app/models/pki-ca-certificate-sign.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import { copy } from 'ember-copy'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import Certificate from './pki-certificate-sign'; const { attr } = DS; -const { computed } = Ember; export default Certificate.extend({ backend: attr('string', { @@ -72,6 +72,6 @@ export default Certificate.extend({ groups = groups.concat(options); } - return this.fieldsToAttrs(Ember.copy(groups, true)); + return this.fieldsToAttrs(copy(groups, true)); }), }); diff --git a/ui/app/models/pki-ca-certificate.js b/ui/app/models/pki-ca-certificate.js index aef41986a..043c018a6 100644 --- a/ui/app/models/pki-ca-certificate.js +++ b/ui/app/models/pki-ca-certificate.js @@ -1,22 +1,24 @@ +import { and } from '@ember/object/computed'; +import { computed } from '@ember/object'; import Certificate from './pki-certificate'; -import Ember from 'ember'; import DS from 'ember-data'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; -const { computed } = Ember; const { attr } = DS; export default Certificate.extend({ - DISPLAY_FIELDS: [ - 'csr', - 'certificate', - 'expiration', - 'issuingCa', - 'caChain', - 'privateKey', - 'privateKeyType', - 'serialNumber', - ], + DISPLAY_FIELDS: computed(function() { + return [ + 'csr', + 'certificate', + 'expiration', + 'issuingCa', + 'caChain', + 'privateKey', + 'privateKeyType', + 'serialNumber', + ]; + }), backend: attr('string', { readOnly: true, }), @@ -146,6 +148,6 @@ export default Certificate.extend({ }), expiration: attr(), - deletePath: lazyCapabilities( apiPath`${'backend'}/root`, 'backend'), - canDeleteRoot: computed.and('deletePath.canDelete', 'deletePath.canSudo'), + deletePath: lazyCapabilities(apiPath`${'backend'}/root`, 'backend'), + canDeleteRoot: and('deletePath.canDelete', 'deletePath.canSudo'), }); diff --git a/ui/app/models/pki-certificate-sign.js b/ui/app/models/pki-certificate-sign.js index 9fa95dc9e..58bf2c35b 100644 --- a/ui/app/models/pki-certificate-sign.js +++ b/ui/app/models/pki-certificate-sign.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import { copy } from 'ember-copy'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import Certificate from './pki-certificate'; const { attr } = DS; -const { computed } = Ember; export default Certificate.extend({ signVerbatim: attr('boolean', { @@ -27,6 +27,6 @@ export default Certificate.extend({ groups.push(options); } - return this.fieldsToAttrs(Ember.copy(groups, true)); + return this.fieldsToAttrs(copy(groups, true)); }), }); diff --git a/ui/app/models/pki-certificate.js b/ui/app/models/pki-certificate.js index 4b4685ca6..5bcd2dc94 100644 --- a/ui/app/models/pki-certificate.js +++ b/ui/app/models/pki-certificate.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; import fieldToAttrs, { expandAttributeMeta } from 'vault/utils/field-to-attrs'; -const { computed } = Ember; const { attr } = DS; export default DS.Model.extend({ @@ -16,15 +16,17 @@ export default DS.Model.extend({ idForNav: attr('string', { readOnly: true, }), - DISPLAY_FIELDS: [ - 'certificate', - 'issuingCa', - 'caChain', - 'privateKey', - 'privateKeyType', - 'serialNumber', - 'revocationTime', - ], + DISPLAY_FIELDS: computed(function() { + return [ + 'certificate', + 'issuingCa', + 'caChain', + 'privateKey', + 'privateKeyType', + 'serialNumber', + 'revocationTime', + ]; + }), role: attr('object', { readOnly: true, }), @@ -91,7 +93,7 @@ export default DS.Model.extend({ }), attrs: computed('certificate', 'csr', function() { - let keys = this.get('certificate') || this.get('csr') ? this.DISPLAY_FIELDS.slice(0) : []; + let keys = this.get('certificate') || this.get('csr') ? this.get('DISPLAY_FIELDS').slice(0) : []; return expandAttributeMeta(this, keys); }), @@ -125,5 +127,5 @@ export default DS.Model.extend({ ), revokePath: lazyCapabilities(apiPath`${'backend'}/revoke`, 'backend'), - canRevoke: computed.alias('revokePath.canUpdate'), + canRevoke: alias('revokePath.canUpdate'), }); diff --git a/ui/app/models/pki-config.js b/ui/app/models/pki-config.js index 2994b5ffb..bc1bfabd5 100644 --- a/ui/app/models/pki-config.js +++ b/ui/app/models/pki-config.js @@ -1,9 +1,8 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; export default DS.Model.extend({ backend: attr('string'), diff --git a/ui/app/models/policy.js b/ui/app/models/policy.js index 72a3c81e0..102ebf470 100644 --- a/ui/app/models/policy.js +++ b/ui/app/models/policy.js @@ -1,9 +1,9 @@ +import { alias } from '@ember/object/computed'; +import { computed } from '@ember/object'; import DS from 'ember-data'; -import Ember from 'ember'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; let { attr } = DS; -let { computed } = Ember; export default DS.Model.extend({ name: attr('string'), @@ -13,9 +13,9 @@ export default DS.Model.extend({ }), updatePath: lazyCapabilities(apiPath`sys/policies/${'policyType'}/${'id'}`, 'id', 'policyType'), - canDelete: computed.alias('updatePath.canDelete'), - canEdit: computed.alias('updatePath.canUpdate'), - canRead: computed.alias('updatePath.canRead'), + canDelete: alias('updatePath.canDelete'), + canEdit: alias('updatePath.canUpdate'), + canRead: alias('updatePath.canRead'), format: computed('policy', function() { let policy = this.get('policy'); let isJSON; diff --git a/ui/app/models/policy/egp.js b/ui/app/models/policy/egp.js index d6dece528..7a70778aa 100644 --- a/ui/app/models/policy/egp.js +++ b/ui/app/models/policy/egp.js @@ -1,11 +1,10 @@ +import { computed } from '@ember/object'; import DS from 'ember-data'; -import Ember from 'ember'; import PolicyModel from './rgp'; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; let { attr } = DS; -let { computed } = Ember; export default PolicyModel.extend({ paths: attr({ diff --git a/ui/app/models/policy/rgp.js b/ui/app/models/policy/rgp.js index 361d669b3..112e6e823 100644 --- a/ui/app/models/policy/rgp.js +++ b/ui/app/models/policy/rgp.js @@ -1,11 +1,10 @@ +import { computed } from '@ember/object'; import DS from 'ember-data'; -import Ember from 'ember'; import PolicyModel from '../policy'; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; let { attr } = DS; -let { computed } = Ember; export default PolicyModel.extend({ enforcementLevel: attr('string', { diff --git a/ui/app/models/replication-attributes.js b/ui/app/models/replication-attributes.js index a2a981e3a..24c2f464e 100644 --- a/ui/app/models/replication-attributes.js +++ b/ui/app/models/replication-attributes.js @@ -1,10 +1,8 @@ -import Ember from 'ember'; +import { match, not } from '@ember/object/computed'; +import { computed } from '@ember/object'; import attr from 'ember-data/attr'; import Fragment from 'ember-data-model-fragments/fragment'; -const { computed } = Ember; -const { match } = computed; - export default Fragment.extend({ clusterId: attr('string'), clusterIdDisplay: computed('mode', function() { @@ -14,7 +12,7 @@ export default Fragment.extend({ mode: attr('string'), replicationDisabled: match('mode', /disabled|unsupported/), replicationUnsupported: match('mode', /unsupported/), - replicationEnabled: computed.not('replicationDisabled'), + replicationEnabled: not('replicationDisabled'), // primary attrs isPrimary: match('mode', /primary/), diff --git a/ui/app/models/role-aws.js b/ui/app/models/role-aws.js index 9022d0b88..a5be5a82d 100644 --- a/ui/app/models/role-aws.js +++ b/ui/app/models/role-aws.js @@ -1,10 +1,10 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; const CREDENTIAL_TYPES = [ { @@ -64,10 +64,10 @@ export default DS.Model.extend({ }), updatePath: lazyCapabilities(apiPath`${'backend'}/roles/${'id'}`, 'backend', 'id'), - canDelete: computed.alias('updatePath.canDelete'), - canEdit: computed.alias('updatePath.canUpdate'), - canRead: computed.alias('updatePath.canRead'), + canDelete: alias('updatePath.canDelete'), + canEdit: alias('updatePath.canUpdate'), + canRead: alias('updatePath.canRead'), generatePath: lazyCapabilities(apiPath`${'backend'}/creds/${'id'}`, 'backend', 'id'), - canGenerate: computed.alias('generatePath.canUpdate'), + canGenerate: alias('generatePath.canUpdate'), }); diff --git a/ui/app/models/role-pki.js b/ui/app/models/role-pki.js index 02c7a942d..af3936ab4 100644 --- a/ui/app/models/role-pki.js +++ b/ui/app/models/role-pki.js @@ -1,10 +1,10 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; import fieldToAttrs from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; export default DS.Model.extend({ backend: attr('string', { @@ -106,18 +106,18 @@ export default DS.Model.extend({ }), updatePath: lazyCapabilities(apiPath`${'backend'}/roles/${'id'}`, 'backend', 'id'), - canDelete: computed.alias('updatePath.canDelete'), - canEdit: computed.alias('updatePath.canUpdate'), - canRead: computed.alias('updatePath.canRead'), + canDelete: alias('updatePath.canDelete'), + canEdit: alias('updatePath.canUpdate'), + canRead: alias('updatePath.canRead'), generatePath: lazyCapabilities(apiPath`${'backend'}/issue/${'id'}`, 'backend', 'id'), - canGenerate: computed.alias('generatePath.canUpdate'), + canGenerate: alias('generatePath.canUpdate'), signPath: lazyCapabilities(apiPath`${'backend'}/sign/${'id'}`, 'backend', 'id'), - canSign: computed.alias('signPath.canUpdate'), + canSign: alias('signPath.canUpdate'), signVerbatimPath: lazyCapabilities(apiPath`${'backend'}/sign-verbatim/${'id'}`, 'backend', 'id'), - canSignVerbatim: computed.alias('signVerbatimPath.canUpdate'), + canSignVerbatim: alias('signVerbatimPath.canUpdate'), fieldGroups: computed(function() { const groups = [ diff --git a/ui/app/models/role-ssh.js b/ui/app/models/role-ssh.js index 9f4e536b6..1bb553ab5 100644 --- a/ui/app/models/role-ssh.js +++ b/ui/app/models/role-ssh.js @@ -1,10 +1,10 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; // these arrays define the order in which the fields will be displayed // see @@ -129,16 +129,16 @@ export default DS.Model.extend({ }), updatePath: lazyCapabilities(apiPath`${'backend'}/roles/${'id'}`, 'backend', 'id'), - canDelete: computed.alias('updatePath.canDelete'), - canEdit: computed.alias('updatePath.canUpdate'), - canRead: computed.alias('updatePath.canRead'), + canDelete: alias('updatePath.canDelete'), + canEdit: alias('updatePath.canUpdate'), + canRead: alias('updatePath.canRead'), generatePath: lazyCapabilities(apiPath`${'backend'}/creds/${'id'}`, 'backend', 'id'), - canGenerate: computed.alias('generatePath.canUpdate'), + canGenerate: alias('generatePath.canUpdate'), signPath: lazyCapabilities(apiPath`${'backend'}/sign/${'id'}`, 'backend', 'id'), - canSign: computed.alias('signPath.canUpdate'), + canSign: alias('signPath.canUpdate'), zeroAddressPath: lazyCapabilities(apiPath`${'backend'}/config/zeroaddress`, 'backend'), - canEditZeroAddress: computed.alias('zeroAddressPath.canUpdate'), + canEditZeroAddress: alias('zeroAddressPath.canUpdate'), }); diff --git a/ui/app/models/secret-engine.js b/ui/app/models/secret-engine.js index f1f15b6f3..89ceef238 100644 --- a/ui/app/models/secret-engine.js +++ b/ui/app/models/secret-engine.js @@ -1,12 +1,10 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; -import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; import { fragment } from 'ember-data-model-fragments/attributes'; import fieldToAttrs, { expandAttributeMeta } from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; //identity will be managed separately and the inclusion //of the system backend is an implementation detail @@ -98,7 +96,7 @@ export default DS.Model.extend({ return !LIST_EXCLUDED_BACKENDS.includes(this.get('engineType')); }), - localDisplay: Ember.computed('local', function() { + localDisplay: computed('local', function() { return this.get('local') ? 'local' : 'replicated'; }), @@ -137,9 +135,6 @@ export default DS.Model.extend({ }); }, - zeroAddressPath: lazyCapabilities(apiPath`${'id'}/config/zeroaddress`, 'id'), - canEditZeroAddress: computed.alias('zeroAddressPath.canUpdate'), - // aws backend attrs lease: attr('string'), leaseMax: attr('string'), diff --git a/ui/app/models/secret.js b/ui/app/models/secret.js index 3a1783cca..4e1e7abcb 100644 --- a/ui/app/models/secret.js +++ b/ui/app/models/secret.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; import DS from 'ember-data'; import KeyMixin from './key-mixin'; const { attr } = DS; -const { computed } = Ember; export default DS.Model.extend(KeyMixin, { auth: attr('string'), diff --git a/ui/app/models/ssh-otp-credential.js b/ui/app/models/ssh-otp-credential.js index aebe582ba..3664c0fb2 100644 --- a/ui/app/models/ssh-otp-credential.js +++ b/ui/app/models/ssh-otp-credential.js @@ -1,8 +1,7 @@ +import { computed } from '@ember/object'; import DS from 'ember-data'; -import Ember from 'ember'; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; const CREATE_FIELDS = ['username', 'ip']; const DISPLAY_FIELDS = ['username', 'ip', 'key', 'keyType', 'port']; diff --git a/ui/app/models/ssh-sign.js b/ui/app/models/ssh-sign.js index 53dfc5c86..6368b9109 100644 --- a/ui/app/models/ssh-sign.js +++ b/ui/app/models/ssh-sign.js @@ -1,8 +1,7 @@ +import { computed } from '@ember/object'; import DS from 'ember-data'; -import Ember from 'ember'; import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; const { attr } = DS; -const { computed } = Ember; const CREATE_FIELDS = [ 'publicKey', 'keyId', diff --git a/ui/app/models/transit-key.js b/ui/app/models/transit-key.js index e7a5a592a..8a1c2ffd2 100644 --- a/ui/app/models/transit-key.js +++ b/ui/app/models/transit-key.js @@ -1,10 +1,10 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { set, get, computed } from '@ember/object'; import DS from 'ember-data'; import clamp from 'vault/utils/clamp'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; const { attr } = DS; -const { computed, get, set } = Ember; const ACTION_VALUES = { encrypt: 'supportsEncryption', @@ -121,5 +121,5 @@ export default DS.Model.extend({ }), rotatePath: lazyCapabilities(apiPath`${'backend'}/keys/${'id'}/rotate`, 'backend', 'id'), - canRotate: computed.alias('rotatePath.canUpdate'), + canRotate: alias('rotatePath.canUpdate'), }); diff --git a/ui/app/router.js b/ui/app/router.js index 3cd78b590..9f1c0e812 100644 --- a/ui/app/router.js +++ b/ui/app/router.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import EmberRouter from '@ember/routing/router'; import config from './config/environment'; -const Router = Ember.Router.extend({ +const Router = EmberRouter.extend({ location: config.locationType, rootURL: config.rootURL, }); @@ -32,7 +32,7 @@ Router.map(function() { }); this.route('unseal'); this.route('tools', function() { - this.route('tool', { path: '/:selectedAction' }); + this.route('tool', { path: '/:selected_action' }); }); this.route('access', function() { this.route('methods', { path: '/' }); diff --git a/ui/app/routes/application.js b/ui/app/routes/application.js index 010c6f812..c7f00d71c 100644 --- a/ui/app/routes/application.js +++ b/ui/app/routes/application.js @@ -1,12 +1,13 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { next } from '@ember/runloop'; +import Route from '@ember/routing/route'; import ControlGroupError from 'vault/lib/control-group-error'; -const { inject } = Ember; -export default Ember.Route.extend({ - controlGroup: inject.service(), - routing: inject.service('router'), - wizard: inject.service(), - namespaceService: inject.service('namespace'), +export default Route.extend({ + controlGroup: service(), + routing: service('router'), + wizard: service(), + namespaceService: service('namespace'), actions: { willTransition() { @@ -62,7 +63,7 @@ export default Ember.Route.extend({ if (wizard.get('currentState') !== 'active.feature') { return true; } - Ember.run.next(() => { + next(() => { let applicationURL = this.get('routing.currentURL'); let activeRoute = this.get('routing.currentRouteName'); diff --git a/ui/app/routes/vault.js b/ui/app/routes/vault.js index 9a2326ec0..30d7e5826 100644 --- a/ui/app/routes/vault.js +++ b/ui/app/routes/vault.js @@ -1,8 +1,12 @@ +import { later } from '@ember/runloop'; +import { Promise } from 'rsvp'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import Ember from 'ember'; const SPLASH_DELAY = Ember.testing ? 0 : 300; -export default Ember.Route.extend({ - version: Ember.inject.service(), +export default Route.extend({ + version: service(), beforeModel() { return this.get('version').fetchVersion(); }, @@ -18,8 +22,8 @@ export default Ember.Route.extend({ }, }; this.store.push(fixture); - return new Ember.RSVP.Promise(resolve => { - Ember.run.later(() => { + return new Promise(resolve => { + later(() => { resolve(this.store.peekAll('cluster')); }, SPLASH_DELAY); }); diff --git a/ui/app/routes/vault/cluster.js b/ui/app/routes/vault/cluster.js index 4ee9f1012..cd297d218 100644 --- a/ui/app/routes/vault/cluster.js +++ b/ui/app/routes/vault/cluster.js @@ -1,18 +1,28 @@ +import { inject as service } from '@ember/service'; +import { cancel, later } from '@ember/runloop'; +import { computed } from '@ember/object'; +import { on } from '@ember/object/evented'; +import { reject } from 'rsvp'; +import Route from '@ember/routing/route'; +import { getOwner } from '@ember/application'; import Ember from 'ember'; import ClusterRoute from 'vault/mixins/cluster-route'; import ModelBoundaryRoute from 'vault/mixins/model-boundary-route'; const POLL_INTERVAL_MS = 10000; -const { inject, Route, getOwner } = Ember; export default Route.extend(ModelBoundaryRoute, ClusterRoute, { - namespaceService: inject.service('namespace'), - version: inject.service(), - store: inject.service(), - auth: inject.service(), - currentCluster: inject.service(), - modelTypes: ['node', 'secret', 'secret-engine'], - globalNamespaceModels: ['node', 'cluster'], + namespaceService: service('namespace'), + version: service(), + store: service(), + auth: service(), + currentCluster: service(), + modelTypes: computed(function() { + return ['node', 'secret', 'secret-engine']; + }), + globalNamespaceModels: computed(function() { + return ['node', 'cluster']; + }), queryParams: { namespaceQueryParam: { @@ -31,7 +41,9 @@ export default Route.extend(ModelBoundaryRoute, ClusterRoute, { // the model types blacklisted in `globalNamespaceModels` let store = this.store; let modelsToKeep = this.get('globalNamespaceModels'); - for (let model of getOwner(this).lookup('data-adapter:main').getModelTypes()) { + for (let model of getOwner(this) + .lookup('data-adapter:main') + .getModelTypes()) { let { name } = model; if (modelsToKeep.includes(name)) { return; @@ -49,7 +61,7 @@ export default Route.extend(ModelBoundaryRoute, ClusterRoute, { this.get('auth').setCluster(id); return this.get('version').fetchFeatures(); } else { - return Ember.RSVP.reject({ httpStatus: 404, message: 'not found', path: params.cluster_name }); + return reject({ httpStatus: 404, message: 'not found', path: params.cluster_name }); } }, @@ -59,8 +71,8 @@ export default Route.extend(ModelBoundaryRoute, ClusterRoute, { return this.get('store').findRecord('cluster', id); }, - stopPoll: Ember.on('deactivate', function() { - Ember.run.cancel(this.get('timer')); + stopPoll: on('deactivate', function() { + cancel(this.get('timer')); }), poll() { @@ -68,16 +80,19 @@ export default Route.extend(ModelBoundaryRoute, ClusterRoute, { // to get around that, we just disable the poll in tests return Ember.testing ? null - : Ember.run.later(() => { - this.controller.get('model').reload().then( - () => { - this.set('timer', this.poll()); - return this.transitionToTargetRoute(); - }, - () => { - this.set('timer', this.poll()); - } - ); + : later(() => { + this.controller + .get('model') + .reload() + .then( + () => { + this.set('timer', this.poll()); + return this.transitionToTargetRoute(); + }, + () => { + this.set('timer', this.poll()); + } + ); }, POLL_INTERVAL_MS); }, diff --git a/ui/app/routes/vault/cluster/access.js b/ui/app/routes/vault/cluster/access.js index babefdbc0..46c91a794 100644 --- a/ui/app/routes/vault/cluster/access.js +++ b/ui/app/routes/vault/cluster/access.js @@ -1,9 +1,12 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import Route from '@ember/routing/route'; import ClusterRoute from 'vault/mixins/cluster-route'; import ModelBoundaryRoute from 'vault/mixins/model-boundary-route'; -export default Ember.Route.extend(ModelBoundaryRoute, ClusterRoute, { - modelTypes: ['capabilities', 'control-group', 'identity/group', 'identity/group-alias', 'identity/alias'], +export default Route.extend(ModelBoundaryRoute, ClusterRoute, { + modelTypes: computed(function() { + return ['capabilities', 'control-group', 'identity/group', 'identity/group-alias', 'identity/alias']; + }), model() { return {}; }, diff --git a/ui/app/routes/vault/cluster/access/control-group-accessor.js b/ui/app/routes/vault/cluster/access/control-group-accessor.js index 3ceaa104a..9faf89c33 100644 --- a/ui/app/routes/vault/cluster/access/control-group-accessor.js +++ b/ui/app/routes/vault/cluster/access/control-group-accessor.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import UnloadModel from 'vault/mixins/unload-model-route'; -const { inject } = Ember; -export default Ember.Route.extend(UnloadModel, { - version: inject.service(), +export default Route.extend(UnloadModel, { + version: service(), beforeModel() { return this.get('version').fetchFeatures().then(() => { diff --git a/ui/app/routes/vault/cluster/access/control-groups.js b/ui/app/routes/vault/cluster/access/control-groups.js index 26cd741c0..07ab02d4c 100644 --- a/ui/app/routes/vault/cluster/access/control-groups.js +++ b/ui/app/routes/vault/cluster/access/control-groups.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import UnloadModel from 'vault/mixins/unload-model-route'; -const { inject } = Ember; -export default Ember.Route.extend(UnloadModel, { - version: inject.service(), +export default Route.extend(UnloadModel, { + version: service(), beforeModel() { return this.get('version').fetchFeatures().then(() => { diff --git a/ui/app/routes/vault/cluster/access/identity.js b/ui/app/routes/vault/cluster/access/identity.js index 88254bc17..2cdd0478b 100644 --- a/ui/app/routes/vault/cluster/access/identity.js +++ b/ui/app/routes/vault/cluster/access/identity.js @@ -1,4 +1,5 @@ -import Ember from 'ember'; +import { set } from '@ember/object'; +import Route from '@ember/routing/route'; import DS from 'ember-data'; const MODEL_FROM_PARAM = { @@ -6,12 +7,12 @@ const MODEL_FROM_PARAM = { groups: 'group', }; -export default Ember.Route.extend({ +export default Route.extend({ model(params) { let model = MODEL_FROM_PARAM[params.item_type]; if (!model) { const error = new DS.AdapterError(); - Ember.set(error, 'httpStatus', 404); + set(error, 'httpStatus', 404); throw error; } return model; diff --git a/ui/app/routes/vault/cluster/access/identity/aliases/add.js b/ui/app/routes/vault/cluster/access/identity/aliases/add.js index bfd9ce6dc..375e88622 100644 --- a/ui/app/routes/vault/cluster/access/identity/aliases/add.js +++ b/ui/app/routes/vault/cluster/access/identity/aliases/add.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import UnloadModelRoute from 'vault/mixins/unload-model-route'; import UnsavedModelRoute from 'vault/mixins/unsaved-model-route'; -export default Ember.Route.extend(UnloadModelRoute, UnsavedModelRoute, { +export default Route.extend(UnloadModelRoute, UnsavedModelRoute, { model(params) { let itemType = this.modelFor('vault.cluster.access.identity'); let modelType = `identity/${itemType}-alias`; diff --git a/ui/app/routes/vault/cluster/access/identity/aliases/edit.js b/ui/app/routes/vault/cluster/access/identity/aliases/edit.js index 9c2c87eb2..7561f7cb1 100644 --- a/ui/app/routes/vault/cluster/access/identity/aliases/edit.js +++ b/ui/app/routes/vault/cluster/access/identity/aliases/edit.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import UnloadModelRoute from 'vault/mixins/unload-model-route'; import UnsavedModelRoute from 'vault/mixins/unsaved-model-route'; -export default Ember.Route.extend(UnloadModelRoute, UnsavedModelRoute, { +export default Route.extend(UnloadModelRoute, UnsavedModelRoute, { model(params) { let itemType = this.modelFor('vault.cluster.access.identity'); let modelType = `identity/${itemType}-alias`; diff --git a/ui/app/routes/vault/cluster/access/identity/aliases/index.js b/ui/app/routes/vault/cluster/access/identity/aliases/index.js index b0b27d0e3..46b134329 100644 --- a/ui/app/routes/vault/cluster/access/identity/aliases/index.js +++ b/ui/app/routes/vault/cluster/access/identity/aliases/index.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import ListRoute from 'vault/mixins/list-route'; -export default Ember.Route.extend(ListRoute, { +export default Route.extend(ListRoute, { model(params) { let itemType = this.modelFor('vault.cluster.access.identity'); let modelType = `identity/${itemType}-alias`; diff --git a/ui/app/routes/vault/cluster/access/identity/aliases/show.js b/ui/app/routes/vault/cluster/access/identity/aliases/show.js index 21318791e..073a1f81c 100644 --- a/ui/app/routes/vault/cluster/access/identity/aliases/show.js +++ b/ui/app/routes/vault/cluster/access/identity/aliases/show.js @@ -1,8 +1,10 @@ -import Ember from 'ember'; +import { hash } from 'rsvp'; +import { set } from '@ember/object'; +import Route from '@ember/routing/route'; import DS from 'ember-data'; import { TABS } from 'vault/helpers/tabs-for-identity-show'; -export default Ember.Route.extend({ +export default Route.extend({ model(params) { let { section } = params; let itemType = this.modelFor('vault.cluster.access.identity') + '-alias'; @@ -10,11 +12,11 @@ export default Ember.Route.extend({ let modelType = `identity/${itemType}`; if (!tabs.includes(section)) { const error = new DS.AdapterError(); - Ember.set(error, 'httpStatus', 404); + set(error, 'httpStatus', 404); throw error; } // TODO peekRecord here to see if we have the record already - return Ember.RSVP.hash({ + return hash({ model: this.store.findRecord(modelType, params.item_alias_id), section, }); diff --git a/ui/app/routes/vault/cluster/access/identity/create.js b/ui/app/routes/vault/cluster/access/identity/create.js index c0231a009..cf50fb39b 100644 --- a/ui/app/routes/vault/cluster/access/identity/create.js +++ b/ui/app/routes/vault/cluster/access/identity/create.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import UnloadModelRoute from 'vault/mixins/unload-model-route'; import UnsavedModelRoute from 'vault/mixins/unsaved-model-route'; -export default Ember.Route.extend(UnloadModelRoute, UnsavedModelRoute, { +export default Route.extend(UnloadModelRoute, UnsavedModelRoute, { model() { let itemType = this.modelFor('vault.cluster.access.identity'); let modelType = `identity/${itemType}`; diff --git a/ui/app/routes/vault/cluster/access/identity/edit.js b/ui/app/routes/vault/cluster/access/identity/edit.js index 495e5e9aa..0df6a00e3 100644 --- a/ui/app/routes/vault/cluster/access/identity/edit.js +++ b/ui/app/routes/vault/cluster/access/identity/edit.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import UnloadModelRoute from 'vault/mixins/unload-model-route'; import UnsavedModelRoute from 'vault/mixins/unsaved-model-route'; -export default Ember.Route.extend(UnloadModelRoute, UnsavedModelRoute, { +export default Route.extend(UnloadModelRoute, UnsavedModelRoute, { model(params) { let itemType = this.modelFor('vault.cluster.access.identity'); let modelType = `identity/${itemType}`; diff --git a/ui/app/routes/vault/cluster/access/identity/index.js b/ui/app/routes/vault/cluster/access/identity/index.js index 4b19fcb80..2d453df15 100644 --- a/ui/app/routes/vault/cluster/access/identity/index.js +++ b/ui/app/routes/vault/cluster/access/identity/index.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import ListRoute from 'vault/mixins/list-route'; -export default Ember.Route.extend(ListRoute, { +export default Route.extend(ListRoute, { model(params) { let itemType = this.modelFor('vault.cluster.access.identity'); let modelType = `identity/${itemType}`; diff --git a/ui/app/routes/vault/cluster/access/identity/merge.js b/ui/app/routes/vault/cluster/access/identity/merge.js index 5274646dc..c38dfbc85 100644 --- a/ui/app/routes/vault/cluster/access/identity/merge.js +++ b/ui/app/routes/vault/cluster/access/identity/merge.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import UnloadModelRoute from 'vault/mixins/unload-model-route'; -export default Ember.Route.extend(UnloadModelRoute, { +export default Route.extend(UnloadModelRoute, { beforeModel() { let itemType = this.modelFor('vault.cluster.access.identity'); if (itemType !== 'entity') { diff --git a/ui/app/routes/vault/cluster/access/identity/show.js b/ui/app/routes/vault/cluster/access/identity/show.js index 11361085e..e409aa738 100644 --- a/ui/app/routes/vault/cluster/access/identity/show.js +++ b/ui/app/routes/vault/cluster/access/identity/show.js @@ -1,8 +1,11 @@ -import Ember from 'ember'; +import { next } from '@ember/runloop'; +import { hash } from 'rsvp'; +import { set } from '@ember/object'; +import Route from '@ember/routing/route'; import DS from 'ember-data'; import { TABS } from 'vault/helpers/tabs-for-identity-show'; -export default Ember.Route.extend({ +export default Route.extend({ model(params) { let { section } = params; let itemType = this.modelFor('vault.cluster.access.identity'); @@ -10,7 +13,7 @@ export default Ember.Route.extend({ let modelType = `identity/${itemType}`; if (!tabs.includes(section)) { const error = new DS.AdapterError(); - Ember.set(error, 'httpStatus', 404); + set(error, 'httpStatus', 404); throw error; } @@ -27,7 +30,7 @@ export default Ember.Route.extend({ model = this.store.findRecord(modelType, params.item_id); } - return Ember.RSVP.hash({ + return hash({ model, section, }); @@ -37,7 +40,7 @@ export default Ember.Route.extend({ // if we're just entering the route, and it's not a hard reload // reload to make sure we have the newest info if (this.currentModel) { - Ember.run.next(() => { + next(() => { this.controller.get('model').reload(); }); } diff --git a/ui/app/routes/vault/cluster/access/leases.js b/ui/app/routes/vault/cluster/access/leases.js index 019c1fdd5..63f3bb0e9 100644 --- a/ui/app/routes/vault/cluster/access/leases.js +++ b/ui/app/routes/vault/cluster/access/leases.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import ClusterRoute from 'vault/mixins/cluster-route'; -export default Ember.Route.extend(ClusterRoute, { +export default Route.extend(ClusterRoute, { model() { return this.store.findRecord('capabilities', 'sys/leases/lookup/'); }, diff --git a/ui/app/routes/vault/cluster/access/leases/index.js b/ui/app/routes/vault/cluster/access/leases/index.js index f423ca2b6..ae716fd52 100644 --- a/ui/app/routes/vault/cluster/access/leases/index.js +++ b/ui/app/routes/vault/cluster/access/leases/index.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ beforeModel(transition) { if ( this.modelFor('vault.cluster.access.leases').get('canList') && diff --git a/ui/app/routes/vault/cluster/access/leases/list.js b/ui/app/routes/vault/cluster/access/leases/list.js index e92bfcc67..7c417c778 100644 --- a/ui/app/routes/vault/cluster/access/leases/list.js +++ b/ui/app/routes/vault/cluster/access/leases/list.js @@ -1,6 +1,8 @@ -import Ember from 'ember'; +import { set } from '@ember/object'; +import { hash } from 'rsvp'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ queryParams: { page: { refreshModel: true, @@ -15,7 +17,7 @@ export default Ember.Route.extend({ model(params) { const prefix = params.prefix || ''; if (this.modelFor('vault.cluster.access.leases').get('canList')) { - return Ember.RSVP.hash({ + return hash({ leases: this.store .lazyPaginatedQuery('lease', { prefix, @@ -35,7 +37,7 @@ export default Ember.Route.extend({ throw err; } }), - capabilities: Ember.RSVP.hash({ + capabilities: hash({ revokePrefix: this.store.findRecord('capabilities', `sys/leases/revoke-prefix/${prefix}`), forceRevokePrefix: this.store.findRecord('capabilities', `sys/leases/revoke-force/${prefix}`), }), @@ -80,7 +82,7 @@ export default Ember.Route.extend({ error(error, transition) { const { prefix } = this.paramsFor(this.routeName); - Ember.set(error, 'keyId', prefix); + set(error, 'keyId', prefix); const hasModel = this.controllerFor(this.routeName).get('hasModel'); // only swallow the error if we have a previous model if (hasModel && error.httpStatus === 404) { diff --git a/ui/app/routes/vault/cluster/access/leases/show.js b/ui/app/routes/vault/cluster/access/leases/show.js index 4d05b5c38..2af259eb1 100644 --- a/ui/app/routes/vault/cluster/access/leases/show.js +++ b/ui/app/routes/vault/cluster/access/leases/show.js @@ -1,9 +1,11 @@ -import Ember from 'ember'; +import { set } from '@ember/object'; +import { hash } from 'rsvp'; +import Route from '@ember/routing/route'; import UnloadModelRoute from 'vault/mixins/unload-model-route'; import utils from 'vault/lib/key-utils'; -export default Ember.Route.extend(UnloadModelRoute, { +export default Route.extend(UnloadModelRoute, { beforeModel() { const { lease_id: leaseId } = this.paramsFor(this.routeName); const parentKey = utils.parentKeyForKey(leaseId); @@ -18,11 +20,11 @@ export default Ember.Route.extend(UnloadModelRoute, { model(params) { const { lease_id } = params; - return Ember.RSVP.hash({ + return hash({ lease: this.store.queryRecord('lease', { lease_id, }), - capabilities: Ember.RSVP.hash({ + capabilities: hash({ renew: this.store.findRecord('capabilities', 'sys/leases/renew'), revoke: this.store.findRecord('capabilities', 'sys/leases/revoke'), leases: this.modelFor('vault.cluster.access.leases'), @@ -43,7 +45,7 @@ export default Ember.Route.extend(UnloadModelRoute, { actions: { error(error) { const { lease_id } = this.paramsFor(this.routeName); - Ember.set(error, 'keyId', lease_id); + set(error, 'keyId', lease_id); return true; }, diff --git a/ui/app/routes/vault/cluster/access/method.js b/ui/app/routes/vault/cluster/access/method.js index 0291f08ca..d6c69ba5f 100644 --- a/ui/app/routes/vault/cluster/access/method.js +++ b/ui/app/routes/vault/cluster/access/method.js @@ -1,14 +1,15 @@ -import Ember from 'ember'; +import { set } from '@ember/object'; +import Route from '@ember/routing/route'; import DS from 'ember-data'; -export default Ember.Route.extend({ +export default Route.extend({ model(params) { const { path } = params; return this.store.findAll('auth-method').then(modelArray => { const model = modelArray.findBy('id', path); if (!model) { const error = new DS.AdapterError(); - Ember.set(error, 'httpStatus', 404); + set(error, 'httpStatus', 404); throw error; } return model; diff --git a/ui/app/routes/vault/cluster/access/method/index.js b/ui/app/routes/vault/cluster/access/method/index.js index 4bcfbd1f5..58b2fa477 100644 --- a/ui/app/routes/vault/cluster/access/method/index.js +++ b/ui/app/routes/vault/cluster/access/method/index.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ beforeModel() { return this.transitionTo('vault.cluster.access.method.section', 'configuration'); }, diff --git a/ui/app/routes/vault/cluster/access/method/section.js b/ui/app/routes/vault/cluster/access/method/section.js index 04edcdc71..52053fe39 100644 --- a/ui/app/routes/vault/cluster/access/method/section.js +++ b/ui/app/routes/vault/cluster/access/method/section.js @@ -1,13 +1,15 @@ -import Ember from 'ember'; +import { set } from '@ember/object'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import DS from 'ember-data'; -export default Ember.Route.extend({ - wizard: Ember.inject.service(), +export default Route.extend({ + wizard: service(), model(params) { const { section_name: section } = params; if (section !== 'configuration') { const error = new DS.AdapterError(); - Ember.set(error, 'httpStatus', 404); + set(error, 'httpStatus', 404); throw error; } let backend = this.modelFor('vault.cluster.access.method'); diff --git a/ui/app/routes/vault/cluster/access/methods.js b/ui/app/routes/vault/cluster/access/methods.js index 84e53dccf..018a574f1 100644 --- a/ui/app/routes/vault/cluster/access/methods.js +++ b/ui/app/routes/vault/cluster/access/methods.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ queryParams: { page: { refreshModel: true, diff --git a/ui/app/routes/vault/cluster/access/namespaces/create.js b/ui/app/routes/vault/cluster/access/namespaces/create.js index 3fd4363d6..1934e09ba 100644 --- a/ui/app/routes/vault/cluster/access/namespaces/create.js +++ b/ui/app/routes/vault/cluster/access/namespaces/create.js @@ -1,10 +1,9 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import UnloadModel from 'vault/mixins/unload-model-route'; -const { inject } = Ember; - -export default Ember.Route.extend(UnloadModel, { - version: inject.service(), +export default Route.extend(UnloadModel, { + version: service(), beforeModel() { return this.get('version').fetchFeatures().then(() => { return this._super(...arguments); diff --git a/ui/app/routes/vault/cluster/access/namespaces/index.js b/ui/app/routes/vault/cluster/access/namespaces/index.js index 8f1ae9b9a..b61da3106 100644 --- a/ui/app/routes/vault/cluster/access/namespaces/index.js +++ b/ui/app/routes/vault/cluster/access/namespaces/index.js @@ -1,10 +1,9 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import UnloadModel from 'vault/mixins/unload-model-route'; -const { inject } = Ember; - -export default Ember.Route.extend(UnloadModel, { - version: inject.service(), +export default Route.extend(UnloadModel, { + version: service(), beforeModel() { this.store.unloadAll('namespace'); return this.get('version').fetchFeatures().then(() => { diff --git a/ui/app/routes/vault/cluster/auth.js b/ui/app/routes/vault/cluster/auth.js index 978e425df..2ac997372 100644 --- a/ui/app/routes/vault/cluster/auth.js +++ b/ui/app/routes/vault/cluster/auth.js @@ -1,13 +1,16 @@ +import { inject as service } from '@ember/service'; import ClusterRouteBase from './cluster-route-base'; -import Ember from 'ember'; import config from 'vault/config/environment'; -const { inject } = Ember; - export default ClusterRouteBase.extend({ - flashMessages: inject.service(), - version: inject.service(), - wizard: inject.service(), + queryParams: { + authMethod: { + replace: true, + }, + }, + flashMessages: service(), + version: service(), + wizard: service(), beforeModel() { return this._super().then(() => { return this.get('version').fetchFeatures(); diff --git a/ui/app/routes/vault/cluster/cluster-route-base.js b/ui/app/routes/vault/cluster/cluster-route-base.js index f8e876d83..d4387968d 100644 --- a/ui/app/routes/vault/cluster/cluster-route-base.js +++ b/ui/app/routes/vault/cluster/cluster-route-base.js @@ -1,10 +1,10 @@ // this is the base route for // all of the CLUSTER_ROUTES that are states before you can use vault // -import Ember from 'ember'; +import Route from '@ember/routing/route'; import ClusterRoute from 'vault/mixins/cluster-route'; -export default Ember.Route.extend(ClusterRoute, { +export default Route.extend(ClusterRoute, { model() { return this.modelFor('vault.cluster'); }, diff --git a/ui/app/routes/vault/cluster/index.js b/ui/app/routes/vault/cluster/index.js index 0b5995841..13f8d4911 100644 --- a/ui/app/routes/vault/cluster/index.js +++ b/ui/app/routes/vault/cluster/index.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ beforeModel() { return this.transitionTo('vault.cluster.secrets'); }, diff --git a/ui/app/routes/vault/cluster/init.js b/ui/app/routes/vault/cluster/init.js index 2972d08af..a6fc4920b 100644 --- a/ui/app/routes/vault/cluster/init.js +++ b/ui/app/routes/vault/cluster/init.js @@ -1,10 +1,8 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; import ClusterRoute from './cluster-route-base'; -const { inject } = Ember; - export default ClusterRoute.extend({ - wizard: inject.service(), + wizard: service(), activate() { // always start from idle instead of using the current state diff --git a/ui/app/routes/vault/cluster/logout.js b/ui/app/routes/vault/cluster/logout.js index ef63e72e9..b7f41a392 100644 --- a/ui/app/routes/vault/cluster/logout.js +++ b/ui/app/routes/vault/cluster/logout.js @@ -1,14 +1,17 @@ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import ModelBoundaryRoute from 'vault/mixins/model-boundary-route'; -const { inject } = Ember; -export default Ember.Route.extend(ModelBoundaryRoute, { - auth: inject.service(), - controlGroup: inject.service(), - flashMessages: inject.service(), - console: inject.service(), +export default Route.extend(ModelBoundaryRoute, { + auth: service(), + controlGroup: service(), + flashMessages: service(), + console: service(), - modelTypes: ['secret', 'secret-engine'], + modelTypes: computed(function() { + return ['secret', 'secret-engine']; + }), beforeModel() { this.get('auth').deleteCurrentToken(); diff --git a/ui/app/routes/vault/cluster/policies.js b/ui/app/routes/vault/cluster/policies.js index 401e74c64..0018f752a 100644 --- a/ui/app/routes/vault/cluster/policies.js +++ b/ui/app/routes/vault/cluster/policies.js @@ -1,11 +1,11 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import ClusterRoute from 'vault/mixins/cluster-route'; const ALLOWED_TYPES = ['acl', 'egp', 'rgp']; -const { inject } = Ember; -export default Ember.Route.extend(ClusterRoute, { - version: inject.service(), +export default Route.extend(ClusterRoute, { + version: service(), beforeModel() { return this.get('version').fetchFeatures().then(() => { diff --git a/ui/app/routes/vault/cluster/policies/create.js b/ui/app/routes/vault/cluster/policies/create.js index a5a1f4141..c7a1f1746 100644 --- a/ui/app/routes/vault/cluster/policies/create.js +++ b/ui/app/routes/vault/cluster/policies/create.js @@ -1,11 +1,11 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import UnloadModelRoute from 'vault/mixins/unload-model-route'; import UnsavedModelRoute from 'vault/mixins/unsaved-model-route'; -const { inject } = Ember; -export default Ember.Route.extend(UnloadModelRoute, UnsavedModelRoute, { - version: inject.service(), - wizard: inject.service(), +export default Route.extend(UnloadModelRoute, UnsavedModelRoute, { + version: service(), + wizard: service(), model() { let policyType = this.policyType(); if ( diff --git a/ui/app/routes/vault/cluster/policies/index.js b/ui/app/routes/vault/cluster/policies/index.js index 389ab9fd1..831d7725d 100644 --- a/ui/app/routes/vault/cluster/policies/index.js +++ b/ui/app/routes/vault/cluster/policies/index.js @@ -1,19 +1,11 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import ClusterRoute from 'vault/mixins/cluster-route'; +import ListRoute from 'vault/mixins/list-route'; -const { inject } = Ember; - -export default Ember.Route.extend(ClusterRoute, { - version: inject.service(), - wizard: inject.service(), - queryParams: { - page: { - refreshModel: true, - }, - pageFilter: { - refreshModel: true, - }, - }, +export default Route.extend(ClusterRoute, ListRoute, { + version: service(), + wizard: service(), activate() { if (this.get('wizard.featureState') === 'details') { @@ -78,6 +70,10 @@ export default Ember.Route.extend(ClusterRoute, { } return true; }, + reload() { + this.store.clearAllDatasets(); + this.refresh(); + }, }, policyType() { diff --git a/ui/app/routes/vault/cluster/policy.js b/ui/app/routes/vault/cluster/policy.js index 9e2996fc6..7e7aa9e6f 100644 --- a/ui/app/routes/vault/cluster/policy.js +++ b/ui/app/routes/vault/cluster/policy.js @@ -1,11 +1,11 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import ClusterRoute from 'vault/mixins/cluster-route'; const ALLOWED_TYPES = ['acl', 'egp', 'rgp']; -const { inject } = Ember; -export default Ember.Route.extend(ClusterRoute, { - version: inject.service(), +export default Route.extend(ClusterRoute, { + version: service(), beforeModel() { return this.get('version').fetchFeatures().then(() => { return this._super(...arguments); diff --git a/ui/app/routes/vault/cluster/policy/index.js b/ui/app/routes/vault/cluster/policy/index.js index 2e6e24994..47b03d9db 100644 --- a/ui/app/routes/vault/cluster/policy/index.js +++ b/ui/app/routes/vault/cluster/policy/index.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ beforeModel() { return this.transitionTo('vault.cluster.policies', 'acl'); }, diff --git a/ui/app/routes/vault/cluster/policy/show.js b/ui/app/routes/vault/cluster/policy/show.js index f6a34066e..ff6b9d9b2 100644 --- a/ui/app/routes/vault/cluster/policy/show.js +++ b/ui/app/routes/vault/cluster/policy/show.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import { hash } from 'rsvp'; +import Route from '@ember/routing/route'; import UnloadModelRoute from 'vault/mixins/unload-model-route'; -export default Ember.Route.extend(UnloadModelRoute, { +export default Route.extend(UnloadModelRoute, { beforeModel() { const params = this.paramsFor(this.routeName); let policyType = this.policyType(); @@ -12,7 +13,7 @@ export default Ember.Route.extend(UnloadModelRoute, { model(params) { let type = this.policyType(); - return Ember.RSVP.hash({ + return hash({ policy: this.store.findRecord(`policy/${type}`, params.policy_name), capabilities: this.store.findRecord('capabilities', `sys/policies/${type}/${params.policy_name}`), }); diff --git a/ui/app/routes/vault/cluster/replication-dr-promote.js b/ui/app/routes/vault/cluster/replication-dr-promote.js index 967e8ab5b..84de8c588 100644 --- a/ui/app/routes/vault/cluster/replication-dr-promote.js +++ b/ui/app/routes/vault/cluster/replication-dr-promote.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; import Base from './cluster-route-base'; export default Base.extend({ - replicationMode: Ember.inject.service(), + replicationMode: service(), beforeModel() { this._super(...arguments); this.get('replicationMode').setMode('dr'); diff --git a/ui/app/routes/vault/cluster/replication.js b/ui/app/routes/vault/cluster/replication.js index 083bca7bb..54d0b563e 100644 --- a/ui/app/routes/vault/cluster/replication.js +++ b/ui/app/routes/vault/cluster/replication.js @@ -1,9 +1,11 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { setProperties } from '@ember/object'; +import { hash } from 'rsvp'; +import Route from '@ember/routing/route'; import ClusterRoute from 'vault/mixins/cluster-route'; -const { inject } = Ember; -export default Ember.Route.extend(ClusterRoute, { - version: inject.service(), +export default Route.extend(ClusterRoute, { + version: service(), beforeModel() { return this.get('version').fetchFeatures().then(() => { @@ -16,21 +18,19 @@ export default Ember.Route.extend(ClusterRoute, { }, afterModel(model) { - return Ember.RSVP - .hash({ - canEnablePrimary: this.store - .findRecord('capabilities', 'sys/replication/primary/enable') - .then(c => c.get('canUpdate')), - canEnableSecondary: this.store - .findRecord('capabilities', 'sys/replication/secondary/enable') - .then(c => c.get('canUpdate')), - }) - .then(({ canEnablePrimary, canEnableSecondary }) => { - Ember.setProperties(model, { - canEnablePrimary, - canEnableSecondary, - }); - return model; + return hash({ + canEnablePrimary: this.store + .findRecord('capabilities', 'sys/replication/primary/enable') + .then(c => c.get('canUpdate')), + canEnableSecondary: this.store + .findRecord('capabilities', 'sys/replication/secondary/enable') + .then(c => c.get('canUpdate')), + }).then(({ canEnablePrimary, canEnableSecondary }) => { + setProperties(model, { + canEnablePrimary, + canEnableSecondary, }); + return model; + }); }, }); diff --git a/ui/app/routes/vault/cluster/replication/index.js b/ui/app/routes/vault/cluster/replication/index.js index ca621413a..5aabd99f7 100644 --- a/ui/app/routes/vault/cluster/replication/index.js +++ b/ui/app/routes/vault/cluster/replication/index.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ - replicationMode: Ember.inject.service(), +export default Route.extend({ + replicationMode: service(), beforeModel() { this.get('replicationMode').setMode(null); }, diff --git a/ui/app/routes/vault/cluster/replication/mode.js b/ui/app/routes/vault/cluster/replication/mode.js index 810c12c7e..1494760c1 100644 --- a/ui/app/routes/vault/cluster/replication/mode.js +++ b/ui/app/routes/vault/cluster/replication/mode.js @@ -1,9 +1,11 @@ -import Ember from 'ember'; +import { on } from '@ember/object/evented'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; const SUPPORTED_REPLICATION_MODES = ['dr', 'performance']; -export default Ember.Route.extend({ - replicationMode: Ember.inject.service(), +export default Route.extend({ + replicationMode: service(), beforeModel() { const replicationMode = this.paramsFor(this.routeName).replication_mode; @@ -18,7 +20,7 @@ export default Ember.Route.extend({ return this.modelFor('vault.cluster.replication'); }, - setReplicationMode: Ember.on('activate', 'enter', function() { + setReplicationMode: on('activate', 'enter', function() { const replicationMode = this.paramsFor(this.routeName).replication_mode; this.get('replicationMode').setMode(replicationMode); }), diff --git a/ui/app/routes/vault/cluster/replication/mode/index.js b/ui/app/routes/vault/cluster/replication/mode/index.js index 72dabdd5c..b26637879 100644 --- a/ui/app/routes/vault/cluster/replication/mode/index.js +++ b/ui/app/routes/vault/cluster/replication/mode/index.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ - replicationMode: Ember.inject.service(), +export default Route.extend({ + replicationMode: service(), beforeModel() { const replicationMode = this.paramsFor('vault.cluster.replication.mode').replication_mode; this.get('replicationMode').setMode(replicationMode); diff --git a/ui/app/routes/vault/cluster/replication/mode/manage.js b/ui/app/routes/vault/cluster/replication/mode/manage.js index 83e48e3fc..9a30216d3 100644 --- a/ui/app/routes/vault/cluster/replication/mode/manage.js +++ b/ui/app/routes/vault/cluster/replication/mode/manage.js @@ -1,4 +1,7 @@ -import Ember from 'ember'; +import { camelize } from '@ember/string'; +import { all } from 'rsvp'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import { replicationActionForMode } from 'vault/helpers/replication-action-for-mode'; const pathForAction = (action, replicationMode, clusterMode) => { @@ -11,8 +14,8 @@ const pathForAction = (action, replicationMode, clusterMode) => { return path; }; -export default Ember.Route.extend({ - store: Ember.inject.service(), +export default Route.extend({ + store: service(), model() { const store = this.get('store'); const model = this.modelFor('vault.cluster.replication.mode'); @@ -20,17 +23,15 @@ export default Ember.Route.extend({ const replicationMode = this.paramsFor('vault.cluster.replication.mode').replication_mode; const clusterMode = model.get(replicationMode).get('modeForUrl'); const actions = replicationActionForMode([replicationMode, clusterMode]); - return Ember.RSVP - .all( - actions.map(action => { - return store.findRecord('capabilities', pathForAction(action)).then(capability => { - model.set(`can${Ember.String.camelize(action)}`, capability.get('canUpdate')); - }); - }) - ) - .then(() => { - return model; - }); + return all( + actions.map(action => { + return store.findRecord('capabilities', pathForAction(action)).then(capability => { + model.set(`can${camelize(action)}`, capability.get('canUpdate')); + }); + }) + ).then(() => { + return model; + }); }, beforeModel() { diff --git a/ui/app/routes/vault/cluster/replication/mode/secondaries.js b/ui/app/routes/vault/cluster/replication/mode/secondaries.js index 30b1d2e4b..d952f773b 100644 --- a/ui/app/routes/vault/cluster/replication/mode/secondaries.js +++ b/ui/app/routes/vault/cluster/replication/mode/secondaries.js @@ -1,26 +1,26 @@ -import Ember from 'ember'; +import { setProperties } from '@ember/object'; +import { hash } from 'rsvp'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ model() { const replicationMode = this.paramsFor('vault.cluster.replication.mode').replication_mode; - return Ember.RSVP - .hash({ - cluster: this.modelFor('vault.cluster.replication.mode'), - canAddSecondary: this.store - .findRecord('capabilities', `sys/replication/${replicationMode}/primary/secondary-token`) - .then(c => c.get('canUpdate')), - canRevokeSecondary: this.store - .findRecord('capabilities', `sys/replication/${replicationMode}/primary/revoke-secondary`) - .then(c => c.get('canUpdate')), - }) - .then(({ cluster, canAddSecondary, canRevokeSecondary }) => { - Ember.setProperties(cluster, { - canRevokeSecondary, - canAddSecondary, - }); - return cluster; + return hash({ + cluster: this.modelFor('vault.cluster.replication.mode'), + canAddSecondary: this.store + .findRecord('capabilities', `sys/replication/${replicationMode}/primary/secondary-token`) + .then(c => c.get('canUpdate')), + canRevokeSecondary: this.store + .findRecord('capabilities', `sys/replication/${replicationMode}/primary/revoke-secondary`) + .then(c => c.get('canUpdate')), + }).then(({ cluster, canAddSecondary, canRevokeSecondary }) => { + setProperties(cluster, { + canRevokeSecondary, + canAddSecondary, }); + return cluster; + }); }, afterModel(model) { const replicationMode = this.paramsFor('vault.cluster.replication.mode').replication_mode; diff --git a/ui/app/routes/vault/cluster/replication/mode/secondaries/add.js b/ui/app/routes/vault/cluster/replication/mode/secondaries/add.js index 2436e0da0..04843f225 100644 --- a/ui/app/routes/vault/cluster/replication/mode/secondaries/add.js +++ b/ui/app/routes/vault/cluster/replication/mode/secondaries/add.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import { hash } from 'rsvp'; import Base from '../../replication-base'; export default Base.extend({ model() { - return Ember.RSVP.hash({ + return hash({ cluster: this.modelFor('vault.cluster.replication.mode.secondaries'), mounts: this.fetchMounts(), }); diff --git a/ui/app/routes/vault/cluster/replication/mode/secondaries/config-create.js b/ui/app/routes/vault/cluster/replication/mode/secondaries/config-create.js index 67dfcf505..c39fe8b63 100644 --- a/ui/app/routes/vault/cluster/replication/mode/secondaries/config-create.js +++ b/ui/app/routes/vault/cluster/replication/mode/secondaries/config-create.js @@ -1,8 +1,9 @@ -import Ember from 'ember'; +import { hash } from 'rsvp'; +import { inject as service } from '@ember/service'; import Base from '../../replication-base'; export default Base.extend({ - flashMessages: Ember.inject.service(), + flashMessages: service(), modelPath: 'model.config', @@ -45,7 +46,7 @@ export default Base.extend({ }, model(params) { - return Ember.RSVP.hash({ + return hash({ cluster: this.modelFor('vault.cluster.replication.mode'), config: this.findOrCreate(params.secondary_id), mounts: this.fetchMounts(), diff --git a/ui/app/routes/vault/cluster/replication/mode/secondaries/config-edit.js b/ui/app/routes/vault/cluster/replication/mode/secondaries/config-edit.js index 4c82b19e9..f2fd220c1 100644 --- a/ui/app/routes/vault/cluster/replication/mode/secondaries/config-edit.js +++ b/ui/app/routes/vault/cluster/replication/mode/secondaries/config-edit.js @@ -1,11 +1,11 @@ -import Ember from 'ember'; +import { hash } from 'rsvp'; import Base from '../../replication-base'; export default Base.extend({ modelPath: 'model.config', model(params) { - return Ember.RSVP.hash({ + return hash({ cluster: this.modelFor('vault.cluster.replication.mode.secondaries'), config: this.store.findRecord('mount-filter-config', params.secondary_id), mounts: this.fetchMounts(), diff --git a/ui/app/routes/vault/cluster/replication/mode/secondaries/config-show.js b/ui/app/routes/vault/cluster/replication/mode/secondaries/config-show.js index 44d164ff8..de7b644d3 100644 --- a/ui/app/routes/vault/cluster/replication/mode/secondaries/config-show.js +++ b/ui/app/routes/vault/cluster/replication/mode/secondaries/config-show.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { hash, resolve } from 'rsvp'; import Base from '../../replication-base'; export default Base.extend({ @@ -6,12 +6,12 @@ export default Base.extend({ model(params) { const id = params.secondary_id; - return Ember.RSVP.hash({ + return hash({ cluster: this.modelFor('vault.cluster.replication'), config: this.store.findRecord('mount-filter-config', id).catch(e => { if (e.httpStatus === 404) { // return an empty obj to let them nav to create - return Ember.RSVP.resolve({ id }); + return resolve({ id }); } else { throw e; } diff --git a/ui/app/routes/vault/cluster/replication/replication-base.js b/ui/app/routes/vault/cluster/replication/replication-base.js index 9749412ce..f2cab56d7 100644 --- a/ui/app/routes/vault/cluster/replication/replication-base.js +++ b/ui/app/routes/vault/cluster/replication/replication-base.js @@ -1,20 +1,21 @@ -import Ember from 'ember'; +import { alias } from '@ember/object/computed'; +import { inject as service } from '@ember/service'; +import { hash, resolve } from 'rsvp'; +import Route from '@ember/routing/route'; import UnloadModelRouteMixin from 'vault/mixins/unload-model-route'; -export default Ember.Route.extend(UnloadModelRouteMixin, { +export default Route.extend(UnloadModelRouteMixin, { modelPath: 'model.config', fetchMounts() { - return Ember.RSVP - .hash({ - mounts: this.store.findAll('secret-engine'), - auth: this.store.findAll('auth-method'), - }) - .then(({ mounts, auth }) => { - return Ember.RSVP.resolve(mounts.toArray().concat(auth.toArray())); - }); + return hash({ + mounts: this.store.findAll('secret-engine'), + auth: this.store.findAll('auth-method'), + }).then(({ mounts, auth }) => { + return resolve(mounts.toArray().concat(auth.toArray())); + }); }, - version: Ember.inject.service(), - rm: Ember.inject.service('replication-mode'), - replicationMode: Ember.computed.alias('rm.mode'), + version: service(), + rm: service('replication-mode'), + replicationMode: alias('rm.mode'), }); diff --git a/ui/app/routes/vault/cluster/secrets.js b/ui/app/routes/vault/cluster/secrets.js index faca1fd5f..e0b62295b 100644 --- a/ui/app/routes/vault/cluster/secrets.js +++ b/ui/app/routes/vault/cluster/secrets.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import ClusterRoute from 'vault/mixins/cluster-route'; -export default Ember.Route.extend(ClusterRoute); +export default Route.extend(ClusterRoute); diff --git a/ui/app/routes/vault/cluster/secrets/backend.js b/ui/app/routes/vault/cluster/secrets/backend.js index 71c10ee90..c7769c9f5 100644 --- a/ui/app/routes/vault/cluster/secrets/backend.js +++ b/ui/app/routes/vault/cluster/secrets/backend.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; -const { inject } = Ember; -export default Ember.Route.extend({ - flashMessages: inject.service(), +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; +export default Route.extend({ + flashMessages: service(), model(params) { let { backend } = params; return this.store diff --git a/ui/app/routes/vault/cluster/secrets/backend/configuration.js b/ui/app/routes/vault/cluster/secrets/backend/configuration.js index bb0aaabb7..3b89ec30f 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/configuration.js +++ b/ui/app/routes/vault/cluster/secrets/backend/configuration.js @@ -1,7 +1,8 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ - wizard: Ember.inject.service(), +export default Route.extend({ + wizard: service(), model() { let backend = this.modelFor('vault.cluster.secrets.backend'); if (this.get('wizard.featureState') === 'list') { diff --git a/ui/app/routes/vault/cluster/secrets/backend/create.js b/ui/app/routes/vault/cluster/secrets/backend/create.js index 159e9ac28..9f9a188cf 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/create.js +++ b/ui/app/routes/vault/cluster/secrets/backend/create.js @@ -1,8 +1,10 @@ -import Ember from 'ember'; +import { hash } from 'rsvp'; +import { inject as service } from '@ember/service'; +import EmberObject from '@ember/object'; import EditBase from './secret-edit'; import KeyMixin from 'vault/models/key-mixin'; -var SecretProxy = Ember.Object.extend(KeyMixin, { +var SecretProxy = EmberObject.extend(KeyMixin, { store: null, toModel() { @@ -20,7 +22,7 @@ var SecretProxy = Ember.Object.extend(KeyMixin, { }); export default EditBase.extend({ - wizard: Ember.inject.service(), + wizard: service(), createModel(transition, parentKey) { const { backend } = this.paramsFor('vault.cluster.secrets.backend'); const modelType = this.modelType(backend); @@ -49,7 +51,7 @@ export default EditBase.extend({ model(params, transition) { const parentKey = params.secret ? params.secret : ''; - return Ember.RSVP.hash({ + return hash({ secret: this.createModel(transition, parentKey), capabilities: {}, }); diff --git a/ui/app/routes/vault/cluster/secrets/backend/credentials.js b/ui/app/routes/vault/cluster/secrets/backend/credentials.js index 20219f018..655577ca9 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/credentials.js +++ b/ui/app/routes/vault/cluster/secrets/backend/credentials.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; -import UnloadModel from 'vault/mixins/unload-model-route'; +import { resolve } from 'rsvp'; +import Route from '@ember/routing/route'; const SUPPORTED_DYNAMIC_BACKENDS = ['ssh', 'aws', 'pki']; -export default Ember.Route.extend(UnloadModel, { +export default Route.extend({ templateName: 'vault/cluster/secrets/backend/credentials', backendModel() { @@ -11,25 +11,21 @@ export default Ember.Route.extend(UnloadModel, { }, model(params) { - const role = params.secret; - const backendModel = this.backendModel(); - const backend = backendModel.get('id'); + let role = params.secret; + let backendModel = this.backendModel(); + let backendPath = backendModel.get('id'); + let backendType = backendModel.get('type'); if (!SUPPORTED_DYNAMIC_BACKENDS.includes(backendModel.get('type'))) { - return this.transitionTo('vault.cluster.secrets.backend.list-root', backend); + return this.transitionTo('vault.cluster.secrets.backend.list-root', backendPath); } - return Ember.RSVP.resolve({ - backend, - id: role, - name: role, + return resolve({ + backendPath, + backendType, + roleName: role, }); }, - setupController(controller) { - this._super(...arguments); - controller.set('backend', this.backendModel()); - }, - resetController(controller) { controller.reset(); }, diff --git a/ui/app/routes/vault/cluster/secrets/backend/index.js b/ui/app/routes/vault/cluster/secrets/backend/index.js index 67782f890..d370ba08e 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/index.js +++ b/ui/app/routes/vault/cluster/secrets/backend/index.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ beforeModel() { return this.replaceWith('vault.cluster.secrets.backend.list-root'); }, diff --git a/ui/app/routes/vault/cluster/secrets/backend/list.js b/ui/app/routes/vault/cluster/secrets/backend/list.js index 812ba5550..6f8694cd7 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/list.js +++ b/ui/app/routes/vault/cluster/secrets/backend/list.js @@ -1,9 +1,11 @@ -import Ember from 'ember'; +import { set } from '@ember/object'; +import { hash, all } from 'rsvp'; +import Route from '@ember/routing/route'; import { supportedSecretBackends } from 'vault/helpers/supported-secret-backends'; const SUPPORTED_BACKENDS = supportedSecretBackends(); -export default Ember.Route.extend({ +export default Route.extend({ queryParams: { page: { refreshModel: true, @@ -29,6 +31,7 @@ export default Ember.Route.extend({ if (this.routeName === 'vault.cluster.secrets.backend.list' && !secret.endsWith('/')) { return this.replaceWith('vault.cluster.secrets.backend.list', secret + '/'); } + this.store.unloadAll('capabilities'); }, getModelType(backend, tab) { @@ -51,7 +54,7 @@ export default Ember.Route.extend({ const secret = params.secret ? params.secret : ''; const { backend } = this.paramsFor('vault.cluster.secrets.backend'); const backendModel = this.modelFor('vault.cluster.secrets.backend'); - return Ember.RSVP.hash({ + return hash({ secret, secrets: this.store .lazyPaginatedQuery(this.getModelType(backend, params.tab), { @@ -82,23 +85,21 @@ export default Ember.Route.extend({ if (!tab || tab !== 'certs') { return; } - return Ember.RSVP - .all( - // these ids are treated specially by vault's api, but it's also - // possible that there is no certificate for them in order to know, - // we fetch them specifically on the list page, and then unload the - // records if there is no `certificate` attribute on the resultant model - ['ca', 'crl', 'ca_chain'].map(id => this.store.queryRecord('pki-certificate', { id, backend })) - ) - .then( - results => { - results.rejectBy('certificate').forEach(record => record.unloadRecord()); - return model; - }, - () => { - return model; - } - ); + return all( + // these ids are treated specially by vault's api, but it's also + // possible that there is no certificate for them in order to know, + // we fetch them specifically on the list page, and then unload the + // records if there is no `certificate` attribute on the resultant model + ['ca', 'crl', 'ca_chain'].map(id => this.store.queryRecord('pki-certificate', { id, backend })) + ).then( + results => { + results.rejectBy('certificate').forEach(record => record.unloadRecord()); + return model; + }, + () => { + return model; + } + ); }, setupController(controller, resolvedModel) { @@ -144,9 +145,9 @@ export default Ember.Route.extend({ const { secret } = this.paramsFor(this.routeName); const { backend } = this.paramsFor('vault.cluster.secrets.backend'); - Ember.set(error, 'secret', secret); - Ember.set(error, 'isRoot', true); - Ember.set(error, 'backend', backend); + set(error, 'secret', secret); + set(error, 'isRoot', true); + set(error, 'backend', backend); const hasModel = this.controllerFor(this.routeName).get('hasModel'); // only swallow the error if we have a previous model if (hasModel && error.httpStatus === 404) { diff --git a/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js b/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js index fd5b9322d..fb0cbb64a 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js +++ b/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js @@ -1,8 +1,10 @@ -import Ember from 'ember'; +import { set } from '@ember/object'; +import { hash } from 'rsvp'; +import Route from '@ember/routing/route'; import utils from 'vault/lib/key-utils'; import UnloadModelRoute from 'vault/mixins/unload-model-route'; -export default Ember.Route.extend(UnloadModelRoute, { +export default Route.extend(UnloadModelRoute, { capabilities(secret) { const { backend } = this.paramsFor('vault.cluster.secrets.backend'); let backendModel = this.modelFor('vault.cluster.secrets.backend'); @@ -69,7 +71,7 @@ export default Ember.Route.extend(UnloadModelRoute, { if (modelType === 'pki-certificate') { secret = secret.replace('cert/', ''); } - return Ember.RSVP.hash({ + return hash({ secret: this.store.queryRecord(modelType, { id: secret, backend }), capabilities: this.capabilities(secret), }); @@ -88,7 +90,10 @@ export default Ember.Route.extend(UnloadModelRoute, { capabilities: model.capabilities, baseKey: { id: secret }, // mode will be 'show', 'edit', 'create' - mode: this.routeName.split('.').pop().replace('-root', ''), + mode: this.routeName + .split('.') + .pop() + .replace('-root', ''), backend, preferAdvancedEdit, backendType, @@ -105,8 +110,8 @@ export default Ember.Route.extend(UnloadModelRoute, { error(error) { const { secret } = this.paramsFor(this.routeName); const { backend } = this.paramsFor('vault.cluster.secrets.backend'); - Ember.set(error, 'keyId', backend + '/' + secret); - Ember.set(error, 'backend', backend); + set(error, 'keyId', backend + '/' + secret); + set(error, 'backend', backend); return true; }, @@ -115,10 +120,6 @@ export default Ember.Route.extend(UnloadModelRoute, { }, willTransition(transition) { - const mode = this.routeName.split('.').pop(); - if (mode === 'show') { - return transition; - } if (this.get('hasChanges')) { if ( window.confirm( @@ -127,21 +128,17 @@ export default Ember.Route.extend(UnloadModelRoute, { ) { this.unloadModel(); this.set('hasChanges', false); - return transition; + return true; } else { transition.abort(); return false; } } + return this._super(...arguments); }, hasDataChanges(hasChanges) { this.set('hasChanges', hasChanges); }, - - toggleAdvancedEdit(bool) { - this.controller.set('preferAdvancedEdit', bool); - this.controllerFor('vault.cluster.secrets.backend').set('preferAdvancedEdit', bool); - }, }, }); diff --git a/ui/app/routes/vault/cluster/secrets/backend/sign.js b/ui/app/routes/vault/cluster/secrets/backend/sign.js index 8e645dd83..8c33298b0 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/sign.js +++ b/ui/app/routes/vault/cluster/secrets/backend/sign.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import UnloadModel from 'vault/mixins/unload-model-route'; -export default Ember.Route.extend(UnloadModel, { +export default Route.extend(UnloadModel, { templateName: 'vault/cluster/secrets/backend/sign', backendModel() { diff --git a/ui/app/routes/vault/cluster/secrets/backends.js b/ui/app/routes/vault/cluster/secrets/backends.js index ceb3edd5b..5cfb27658 100644 --- a/ui/app/routes/vault/cluster/secrets/backends.js +++ b/ui/app/routes/vault/cluster/secrets/backends.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ model() { return this.store.query('secret-engine', {}); }, diff --git a/ui/app/routes/vault/cluster/settings.js b/ui/app/routes/vault/cluster/settings.js index 212fac094..669017080 100644 --- a/ui/app/routes/vault/cluster/settings.js +++ b/ui/app/routes/vault/cluster/settings.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import ClusterRoute from 'vault/mixins/cluster-route'; -export default Ember.Route.extend(ClusterRoute, { +export default Route.extend(ClusterRoute, { model() { return {}; }, diff --git a/ui/app/routes/vault/cluster/settings/auth/configure.js b/ui/app/routes/vault/cluster/settings/auth/configure.js index 33e1e5b4b..26cc8b91e 100644 --- a/ui/app/routes/vault/cluster/settings/auth/configure.js +++ b/ui/app/routes/vault/cluster/settings/auth/configure.js @@ -1,11 +1,12 @@ -import Ember from 'ember'; +import { set } from '@ember/object'; +import Route from '@ember/routing/route'; import DS from 'ember-data'; import { methods } from 'vault/helpers/mountable-auth-methods'; const METHODS = methods(); -export default Ember.Route.extend({ +export default Route.extend({ model() { const { method } = this.paramsFor(this.routeName); return this.store.findAll('auth-method').then(() => { @@ -13,7 +14,7 @@ export default Ember.Route.extend({ const modelType = model && model.get('methodType'); if (!model || (modelType !== 'token' && !METHODS.findBy('type', modelType))) { const error = new DS.AdapterError(); - Ember.set(error, 'httpStatus', 404); + set(error, 'httpStatus', 404); throw error; } return model; diff --git a/ui/app/routes/vault/cluster/settings/auth/configure/index.js b/ui/app/routes/vault/cluster/settings/auth/configure/index.js index 438ffeb14..e8db754ab 100644 --- a/ui/app/routes/vault/cluster/settings/auth/configure/index.js +++ b/ui/app/routes/vault/cluster/settings/auth/configure/index.js @@ -1,9 +1,8 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; +import { get } from '@ember/object'; import { tabsForAuthSection } from 'vault/helpers/tabs-for-auth-section'; -const { get } = Ember; - -export default Ember.Route.extend({ +export default Route.extend({ beforeModel() { const type = this.modelFor('vault.cluster.settings.auth.configure').get('type'); const section = get(tabsForAuthSection([type]), 'firstObject.routeParams.lastObject'); diff --git a/ui/app/routes/vault/cluster/settings/auth/configure/section.js b/ui/app/routes/vault/cluster/settings/auth/configure/section.js index 3a5c7316f..cc7c358d0 100644 --- a/ui/app/routes/vault/cluster/settings/auth/configure/section.js +++ b/ui/app/routes/vault/cluster/settings/auth/configure/section.js @@ -1,11 +1,13 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import { set } from '@ember/object'; +import Route from '@ember/routing/route'; +import RSVP from 'rsvp'; import DS from 'ember-data'; import UnloadModelRoute from 'vault/mixins/unload-model-route'; -const { RSVP, inject } = Ember; -export default Ember.Route.extend(UnloadModelRoute, { +export default Route.extend(UnloadModelRoute, { modelPath: 'model.model', - wizard: inject.service(), + wizard: service(), modelType(backendType, section) { const MODELS = { 'aws-client': 'auth-config/aws/client', @@ -40,7 +42,7 @@ export default Ember.Route.extend(UnloadModelRoute, { const modelType = this.modelType(backend.get('type'), section); if (!modelType) { const error = new DS.AdapterError(); - Ember.set(error, 'httpStatus', 404); + set(error, 'httpStatus', 404); throw error; } const model = this.store.peekRecord(modelType, backend.id); diff --git a/ui/app/routes/vault/cluster/settings/auth/index.js b/ui/app/routes/vault/cluster/settings/auth/index.js index 0e8ce4270..798b2f1cf 100644 --- a/ui/app/routes/vault/cluster/settings/auth/index.js +++ b/ui/app/routes/vault/cluster/settings/auth/index.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ beforeModel() { return this.replaceWith('vault.cluster.settings.auth.enable'); }, diff --git a/ui/app/routes/vault/cluster/settings/configure-secret-backend.js b/ui/app/routes/vault/cluster/settings/configure-secret-backend.js index bf813726f..71e595ec2 100644 --- a/ui/app/routes/vault/cluster/settings/configure-secret-backend.js +++ b/ui/app/routes/vault/cluster/settings/configure-secret-backend.js @@ -1,16 +1,17 @@ -import Ember from 'ember'; +import { set } from '@ember/object'; +import Route from '@ember/routing/route'; import DS from 'ember-data'; const CONFIGURABLE_BACKEND_TYPES = ['aws', 'ssh', 'pki']; -export default Ember.Route.extend({ +export default Route.extend({ model() { const { backend } = this.paramsFor(this.routeName); return this.store.query('secret-engine', { path: backend }).then(modelList => { let model = modelList && modelList.get('firstObject'); if (!model || !CONFIGURABLE_BACKEND_TYPES.includes(model.get('type'))) { const error = new DS.AdapterError(); - Ember.set(error, 'httpStatus', 404); + set(error, 'httpStatus', 404); throw error; } return this.store.findRecord('secret-engine', backend).then( diff --git a/ui/app/routes/vault/cluster/settings/configure-secret-backend/index.js b/ui/app/routes/vault/cluster/settings/configure-secret-backend/index.js index 245a2d4fe..9023f5e4c 100644 --- a/ui/app/routes/vault/cluster/settings/configure-secret-backend/index.js +++ b/ui/app/routes/vault/cluster/settings/configure-secret-backend/index.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ beforeModel(transition) { const type = this.modelFor('vault.cluster.settings.configure-secret-backend').get('type'); if (type === 'pki' && transition.targetName === this.routeName) { diff --git a/ui/app/routes/vault/cluster/settings/configure-secret-backend/section.js b/ui/app/routes/vault/cluster/settings/configure-secret-backend/section.js index 4e0b30e79..013724d8f 100644 --- a/ui/app/routes/vault/cluster/settings/configure-secret-backend/section.js +++ b/ui/app/routes/vault/cluster/settings/configure-secret-backend/section.js @@ -1,10 +1,11 @@ -import Ember from 'ember'; +import { set } from '@ember/object'; +import Route from '@ember/routing/route'; import DS from 'ember-data'; const SECTIONS_FOR_TYPE = { pki: ['cert', 'urls', 'crl', 'tidy'], }; -export default Ember.Route.extend({ +export default Route.extend({ fetchModel() { const { section_name: sectionName } = this.paramsFor(this.routeName); const backendModel = this.modelFor('vault.cluster.settings.configure-secret-backend'); @@ -28,7 +29,7 @@ export default Ember.Route.extend({ const hasSection = sections.includes(sectionName); if (!backendModel || !hasSection) { const error = new DS.AdapterError(); - Ember.set(error, 'httpStatus', 404); + set(error, 'httpStatus', 404); throw error; } return this.fetchModel(); diff --git a/ui/app/routes/vault/cluster/settings/control-groups.js b/ui/app/routes/vault/cluster/settings/control-groups.js index f61cdb5fb..7e861e28e 100644 --- a/ui/app/routes/vault/cluster/settings/control-groups.js +++ b/ui/app/routes/vault/cluster/settings/control-groups.js @@ -1,9 +1,9 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import UnloadModel from 'vault/mixins/unload-model-route'; -const { inject } = Ember; -export default Ember.Route.extend(UnloadModel, { - version: inject.service(), +export default Route.extend(UnloadModel, { + version: service(), beforeModel() { return this.get('version').fetchFeatures().then(() => { diff --git a/ui/app/routes/vault/cluster/settings/index.js b/ui/app/routes/vault/cluster/settings/index.js index 779430929..286bcbf2a 100644 --- a/ui/app/routes/vault/cluster/settings/index.js +++ b/ui/app/routes/vault/cluster/settings/index.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ beforeModel: function(transition) { if (transition.targetName === this.routeName) { transition.abort(); diff --git a/ui/app/routes/vault/cluster/settings/mount-secret-backend.js b/ui/app/routes/vault/cluster/settings/mount-secret-backend.js index 42208967e..acd9fb2e6 100644 --- a/ui/app/routes/vault/cluster/settings/mount-secret-backend.js +++ b/ui/app/routes/vault/cluster/settings/mount-secret-backend.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import UnloadModelRoute from 'vault/mixins/unload-model-route'; import UnsavedModelRoute from 'vault/mixins/unsaved-model-route'; -export default Ember.Route.extend(UnloadModelRoute, UnsavedModelRoute, { +export default Route.extend(UnloadModelRoute, UnsavedModelRoute, { // intentionally blank - we don't want a model until one is // created via the form in the controller model() { diff --git a/ui/app/routes/vault/cluster/settings/seal.js b/ui/app/routes/vault/cluster/settings/seal.js index d64a10305..f162b5c76 100644 --- a/ui/app/routes/vault/cluster/settings/seal.js +++ b/ui/app/routes/vault/cluster/settings/seal.js @@ -1,8 +1,9 @@ -import Ember from 'ember'; +import { hash } from 'rsvp'; +import Route from '@ember/routing/route'; -export default Ember.Route.extend({ +export default Route.extend({ model() { - return Ember.RSVP.hash({ + return hash({ cluster: this.modelFor('vault.cluster'), seal: this.store.findRecord('capabilities', 'sys/seal'), }); diff --git a/ui/app/routes/vault/cluster/tools.js b/ui/app/routes/vault/cluster/tools.js index 18552ac11..b44d690a2 100644 --- a/ui/app/routes/vault/cluster/tools.js +++ b/ui/app/routes/vault/cluster/tools.js @@ -1,7 +1,7 @@ -import Ember from 'ember'; +import Route from '@ember/routing/route'; import ClusterRoute from 'vault/mixins/cluster-route'; -export default Ember.Route.extend(ClusterRoute, { +export default Route.extend(ClusterRoute, { model() { return this.modelFor('vault.cluster'); }, diff --git a/ui/app/routes/vault/cluster/tools/index.js b/ui/app/routes/vault/cluster/tools/index.js index 8ecc01051..07740abfe 100644 --- a/ui/app/routes/vault/cluster/tools/index.js +++ b/ui/app/routes/vault/cluster/tools/index.js @@ -1,8 +1,9 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import { toolsActions } from 'vault/helpers/tools-actions'; -export default Ember.Route.extend({ - currentCluster: Ember.inject.service(), +export default Route.extend({ + currentCluster: service(), beforeModel(transition) { const currentCluster = this.get('currentCluster.cluster.name'); const supportedActions = toolsActions(); diff --git a/ui/app/routes/vault/cluster/tools/tool.js b/ui/app/routes/vault/cluster/tools/tool.js index f315186b1..98b0f6d72 100644 --- a/ui/app/routes/vault/cluster/tools/tool.js +++ b/ui/app/routes/vault/cluster/tools/tool.js @@ -1,18 +1,28 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; +import Route from '@ember/routing/route'; import { toolsActions } from 'vault/helpers/tools-actions'; -export default Ember.Route.extend({ - wizard: Ember.inject.service(), +export default Route.extend({ + wizard: service(), beforeModel(transition) { const supportedActions = toolsActions(); - const { selectedAction } = this.paramsFor(this.routeName); + const { selected_action: selectedAction } = this.paramsFor(this.routeName); if (!selectedAction || !supportedActions.includes(selectedAction)) { transition.abort(); return this.transitionTo(this.routeName, supportedActions[0]); } }, - model() {}, + + model(params) { + return params.selected_action; + }, + + setupController(controller, model) { + this._super(...arguments); + controller.set('selectedAction', model); + }, + actions: { didTransition() { const params = this.paramsFor(this.routeName); diff --git a/ui/app/routes/vault/cluster/unseal.js b/ui/app/routes/vault/cluster/unseal.js index 55f4e3ee8..ed061a8d3 100644 --- a/ui/app/routes/vault/cluster/unseal.js +++ b/ui/app/routes/vault/cluster/unseal.js @@ -1,10 +1,8 @@ -import Ember from 'ember'; +import { inject as service } from '@ember/service'; import ClusterRoute from './cluster-route-base'; -const { inject } = Ember; - export default ClusterRoute.extend({ - wizard: inject.service(), + wizard: service(), activate() { this.get('wizard').set('initEvent', 'UNSEAL'); diff --git a/ui/app/serializers/application.js b/ui/app/serializers/application.js index 44147344a..d19241e28 100644 --- a/ui/app/serializers/application.js +++ b/ui/app/serializers/application.js @@ -1,6 +1,7 @@ +import { isNone, isBlank } from '@ember/utils'; +import { assign } from '@ember/polyfills'; +import { decamelize } from '@ember/string'; import DS from 'ember-data'; -import Ember from 'ember'; -const { decamelize } = Ember.String; export default DS.JSONSerializer.extend({ keyForAttribute: function(attr) { @@ -18,7 +19,7 @@ export default DS.JSONSerializer.extend({ }); return models; } - Ember.assign(payload, payload.data); + assign(payload, payload.data); delete payload.data; return payload; }, @@ -44,8 +45,8 @@ export default DS.JSONSerializer.extend({ serializeAttribute(snapshot, json, key, attributes) { const val = snapshot.attr(key); - const valHasNotChanged = Ember.isNone(snapshot.changedAttributes()[key]); - const valIsBlank = Ember.isBlank(val); + const valHasNotChanged = isNone(snapshot.changedAttributes()[key]); + const valIsBlank = isBlank(val); if (attributes.options.readOnly) { return; } diff --git a/ui/app/serializers/cluster.js b/ui/app/serializers/cluster.js index 5c552381a..8f1d3bfea 100644 --- a/ui/app/serializers/cluster.js +++ b/ui/app/serializers/cluster.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; +import { assign } from '@ember/polyfills'; +import { decamelize } from '@ember/string'; import DS from 'ember-data'; -const { decamelize } = Ember.String; - export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, { keyForAttribute: function(attr) { return decamelize(attr); @@ -26,7 +25,7 @@ export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, { normalizeResponse(store, primaryModelClass, payload, id, requestType) { // FIXME when multiple clusters lands const transformedPayload = { - clusters: Ember.assign({ id: '1' }, payload.data || payload), + clusters: assign({ id: '1' }, payload.data || payload), }; return this._super(store, primaryModelClass, transformedPayload, id, requestType); diff --git a/ui/app/serializers/config.js b/ui/app/serializers/config.js index 80314d93c..7c005a360 100644 --- a/ui/app/serializers/config.js +++ b/ui/app/serializers/config.js @@ -1,6 +1,6 @@ +import { assign } from '@ember/polyfills'; +import { decamelize } from '@ember/string'; import DS from 'ember-data'; -import Ember from 'ember'; -const { decamelize } = Ember.String; export default DS.RESTSerializer.extend({ keyForAttribute: function(attr) { @@ -9,7 +9,7 @@ export default DS.RESTSerializer.extend({ normalizeAll(payload) { if (payload.data) { - const data = Ember.assign({}, payload, payload.data); + const data = assign({}, payload, payload.data); return [data]; } return [payload]; diff --git a/ui/app/serializers/control-group.js b/ui/app/serializers/control-group.js index 4eb6d8809..4046c365b 100644 --- a/ui/app/serializers/control-group.js +++ b/ui/app/serializers/control-group.js @@ -1,8 +1,6 @@ +import { get } from '@ember/object'; import DS from 'ember-data'; import ApplicationSerializer from './application'; -import Ember from 'ember'; - -const { get } = Ember; export default ApplicationSerializer.extend(DS.EmbeddedRecordsMixin, { attrs: { diff --git a/ui/app/serializers/identity/_base.js b/ui/app/serializers/identity/_base.js index 9c6de8b95..261acbd0b 100644 --- a/ui/app/serializers/identity/_base.js +++ b/ui/app/serializers/identity/_base.js @@ -1,12 +1,12 @@ +import { assign } from '@ember/polyfills'; import ApplicationSerializer from '../application'; -import Ember from 'ember'; export default ApplicationSerializer.extend({ normalizeItems(payload) { if (payload.data.keys && Array.isArray(payload.data.keys)) { return payload.data.keys; } - Ember.assign(payload, payload.data); + assign(payload, payload.data); delete payload.data; return payload; }, diff --git a/ui/app/serializers/lease.js b/ui/app/serializers/lease.js index 41765bc20..2271d2278 100644 --- a/ui/app/serializers/lease.js +++ b/ui/app/serializers/lease.js @@ -1,6 +1,5 @@ +import { decamelize } from '@ember/string'; import DS from 'ember-data'; -import Ember from 'ember'; -const { decamelize } = Ember.String; export default DS.RESTSerializer.extend({ keyForAttribute: function(attr) { diff --git a/ui/app/serializers/mount-filter-config.js b/ui/app/serializers/mount-filter-config.js index 1effd5741..d2a9ab9c3 100644 --- a/ui/app/serializers/mount-filter-config.js +++ b/ui/app/serializers/mount-filter-config.js @@ -1,6 +1,5 @@ +import { decamelize } from '@ember/string'; import DS from 'ember-data'; -import Ember from 'ember'; -const { decamelize } = Ember.String; export default DS.RESTSerializer.extend({ keyForAttribute: function(attr) { diff --git a/ui/app/serializers/node.js b/ui/app/serializers/node.js index e75baae9c..b2ee54b0f 100644 --- a/ui/app/serializers/node.js +++ b/ui/app/serializers/node.js @@ -1,8 +1,7 @@ -import Ember from 'ember'; +import { assign } from '@ember/polyfills'; +import { decamelize } from '@ember/string'; import DS from 'ember-data'; -const { decamelize } = Ember.String; - export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, { keyForAttribute: function(attr) { return decamelize(attr); @@ -21,7 +20,7 @@ export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, { nodeFromObject(name, payload) { const nodeObj = payload.nodes[name]; - return Ember.assign(nodeObj, { + return assign(nodeObj, { name, id: name, }); @@ -30,7 +29,7 @@ export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, { normalizeResponse(store, primaryModelClass, payload, id, requestType) { const nodes = payload.nodes ? Object.keys(payload.nodes).map(name => this.nodeFromObject(name, payload)) - : [Ember.assign(payload, { id: '1' })]; + : [assign(payload, { id: '1' })]; const transformedPayload = { nodes: nodes }; diff --git a/ui/app/serializers/pki-certificate.js b/ui/app/serializers/pki-certificate.js index 4588eb238..6f37c51e2 100644 --- a/ui/app/serializers/pki-certificate.js +++ b/ui/app/serializers/pki-certificate.js @@ -1,6 +1,7 @@ +import { isNone, isBlank } from '@ember/utils'; +import { assign } from '@ember/polyfills'; +import { decamelize } from '@ember/string'; import DS from 'ember-data'; -import Ember from 'ember'; -const { decamelize } = Ember.String; export default DS.RESTSerializer.extend({ keyForAttribute: function(attr) { @@ -32,7 +33,7 @@ export default DS.RESTSerializer.extend({ }); return ret; } - Ember.assign(payload, payload.data); + assign(payload, payload.data); delete payload.data; return payload; }, @@ -46,8 +47,8 @@ export default DS.RESTSerializer.extend({ serializeAttribute(snapshot, json, key, attributes) { const val = snapshot.attr(key); - const valHasNotChanged = Ember.isNone(snapshot.changedAttributes()[key]); - const valIsBlank = Ember.isBlank(val); + const valHasNotChanged = isNone(snapshot.changedAttributes()[key]); + const valIsBlank = isBlank(val); if (attributes.options.readOnly) { return; } diff --git a/ui/app/serializers/pki-config.js b/ui/app/serializers/pki-config.js new file mode 100644 index 000000000..7c005a360 --- /dev/null +++ b/ui/app/serializers/pki-config.js @@ -0,0 +1,29 @@ +import { assign } from '@ember/polyfills'; +import { decamelize } from '@ember/string'; +import DS from 'ember-data'; + +export default DS.RESTSerializer.extend({ + keyForAttribute: function(attr) { + return decamelize(attr); + }, + + normalizeAll(payload) { + if (payload.data) { + const data = assign({}, payload, payload.data); + return [data]; + } + return [payload]; + }, + + normalizeResponse(store, primaryModelClass, payload, id, requestType) { + const records = this.normalizeAll(payload); + const { modelName } = primaryModelClass; + let transformedPayload = { [modelName]: records }; + // just return the single object because ember is picky + if (requestType === 'queryRecord') { + transformedPayload = { [modelName]: records[0] }; + } + + return this._super(store, primaryModelClass, transformedPayload, id, requestType); + }, +}); diff --git a/ui/app/serializers/replication-attributes.js b/ui/app/serializers/replication-attributes.js index 558e1a95e..7077efd32 100644 --- a/ui/app/serializers/replication-attributes.js +++ b/ui/app/serializers/replication-attributes.js @@ -1,8 +1,6 @@ -import Ember from 'ember'; +import { decamelize } from '@ember/string'; import DS from 'ember-data'; -const { decamelize } = Ember.String; - export default DS.RESTSerializer.extend({ keyForAttribute: function(attr) { return decamelize(attr); diff --git a/ui/app/serializers/role-pki.js b/ui/app/serializers/role-pki.js index af9f7c23d..d36af6b2f 100644 --- a/ui/app/serializers/role-pki.js +++ b/ui/app/serializers/role-pki.js @@ -1,66 +1,3 @@ -import DS from 'ember-data'; -import Ember from 'ember'; -const { decamelize } = Ember.String; +import RoleSerializer from './role'; -export default DS.RESTSerializer.extend({ - keyForAttribute: function(attr) { - return decamelize(attr); - }, - - normalizeItems(payload) { - if (payload.data.keys && Array.isArray(payload.data.keys)) { - let ret = payload.data.keys.map(key => { - let model = { - id: key, - }; - if (payload.backend) { - model.backend = payload.backend; - } - return model; - }); - return ret; - } - Ember.assign(payload, payload.data); - delete payload.data; - return [payload]; - }, - modelNameFromPayloadKey(payloadType) { - return payloadType; - }, - - normalizeResponse(store, primaryModelClass, payload, id, requestType) { - const nullResponses = ['updateRecord', 'createRecord', 'deleteRecord']; - const responseJSON = nullResponses.includes(requestType) ? { id } : this.normalizeItems(payload); - const { modelName } = primaryModelClass; - let transformedPayload = { [modelName]: responseJSON }; - // just return the single object because ember is picky - if (requestType === 'queryRecord') { - transformedPayload = { [modelName]: responseJSON[0] }; - } - - return this._super(store, primaryModelClass, transformedPayload, id, requestType); - }, - - serializeAttribute(snapshot, json, key, attributes) { - const val = snapshot.attr(key); - if (attributes.options.readOnly) { - return; - } - if ( - attributes.type === 'object' && - val && - Object.keys(val).length > 0 && - Ember.isNone(snapshot.changedAttributes()[key]) - ) { - return; - } - if (Ember.isBlank(val) && Ember.isNone(snapshot.changedAttributes()[key])) { - return; - } - - this._super(snapshot, json, key, attributes); - }, - serialize() { - return this._super(...arguments); - }, -}); +export default RoleSerializer.extend(); diff --git a/ui/app/serializers/role.js b/ui/app/serializers/role.js index b8f86a1d2..69ba365cf 100644 --- a/ui/app/serializers/role.js +++ b/ui/app/serializers/role.js @@ -1,12 +1,6 @@ -import DS from 'ember-data'; -import Ember from 'ember'; -const { decamelize } = Ember.String; - -export default DS.RESTSerializer.extend({ - keyForAttribute: function(attr) { - return decamelize(attr); - }, +import ApplicationSerializer from './application'; +export default ApplicationSerializer.extend({ extractLazyPaginatedData(payload) { let ret; if (payload.zero_address_roles) { @@ -15,6 +9,7 @@ export default DS.RESTSerializer.extend({ payload.data.key_info[role].zero_address = true; }); } + if (!payload.data.key_info) return payload.data.keys; ret = payload.data.keys.map(key => { let model = { id: key, @@ -29,52 +24,4 @@ export default DS.RESTSerializer.extend({ delete payload.data.key_info; return ret; }, - - normalizeItems(payload) { - if (payload.data.keys && Array.isArray(payload.data.keys)) { - return payload.data.keys; - } - Ember.assign(payload, payload.data); - delete payload.data; - return [payload]; - }, - modelNameFromPayloadKey(payloadType) { - return payloadType; - }, - - normalizeResponse(store, primaryModelClass, payload, id, requestType) { - const nullResponses = ['updateRecord', 'createRecord', 'deleteRecord']; - const responseJSON = nullResponses.includes(requestType) ? { id } : this.normalizeItems(payload); - const { modelName } = primaryModelClass; - let transformedPayload = { [modelName]: responseJSON }; - // just return the single object because ember is picky - if (requestType === 'queryRecord') { - transformedPayload = { [modelName]: responseJSON[0] }; - } - - return this._super(store, primaryModelClass, transformedPayload, id, requestType); - }, - - serializeAttribute(snapshot, json, key, attributes) { - const val = snapshot.attr(key); - if (attributes.options.readOnly) { - return; - } - if ( - attributes.type === 'object' && - val && - Object.keys(val).length > 0 && - Ember.isNone(snapshot.changedAttributes()[key]) - ) { - return; - } - if (Ember.isBlank(val) && Ember.isNone(snapshot.changedAttributes()[key])) { - return; - } - - this._super(snapshot, json, key, attributes); - }, - serialize() { - return this._super(...arguments); - }, }); diff --git a/ui/app/serializers/secret-engine.js b/ui/app/serializers/secret-engine.js index a90321473..2486e5a4b 100644 --- a/ui/app/serializers/secret-engine.js +++ b/ui/app/serializers/secret-engine.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { assign } from '@ember/polyfills'; import ApplicationSerializer from './application'; export default ApplicationSerializer.extend({ @@ -13,7 +13,7 @@ export default ApplicationSerializer.extend({ } if (struct.data) { - struct = Ember.assign({}, struct, struct.data); + struct = assign({}, struct, struct.data); delete struct.data; } // strip the trailing slash off of the path so we diff --git a/ui/app/serializers/secret.js b/ui/app/serializers/secret.js index b5c4bf2ea..eb7bc024e 100644 --- a/ui/app/serializers/secret.js +++ b/ui/app/serializers/secret.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { get } from '@ember/object'; import ApplicationSerializer from './application'; export default ApplicationSerializer.extend({ @@ -25,7 +25,7 @@ export default ApplicationSerializer.extend({ let path = this.get('secretDataPath'); // move response that is the contents of the secret from the dataPath // to `secret_data` so it will be `secretData` in the model - payload.secret_data = Ember.get(payload, path); + payload.secret_data = get(payload, path); delete payload[path]; // return the payload if it's expecting a single object or wrap // it as an array if not diff --git a/ui/app/serializers/ssh.js b/ui/app/serializers/ssh.js index a49f045af..154fc8ef9 100644 --- a/ui/app/serializers/ssh.js +++ b/ui/app/serializers/ssh.js @@ -1,6 +1,7 @@ +import { isNone, isBlank } from '@ember/utils'; +import { assign } from '@ember/polyfills'; +import { decamelize } from '@ember/string'; import DS from 'ember-data'; -import Ember from 'ember'; -const { decamelize } = Ember.String; export default DS.RESTSerializer.extend({ keyForAttribute: function(attr) { @@ -19,7 +20,7 @@ export default DS.RESTSerializer.extend({ }, normalizeItems(payload) { - Ember.assign(payload, payload.data); + assign(payload, payload.data); delete payload.data; return payload; }, @@ -41,11 +42,11 @@ export default DS.RESTSerializer.extend({ attributes.type === 'object' && val && Object.keys(val).length > 0 && - Ember.isNone(snapshot.changedAttributes()[key]) + isNone(snapshot.changedAttributes()[key]) ) { return; } - if (Ember.isBlank(val) && Ember.isNone(snapshot.changedAttributes()[key])) { + if (isBlank(val) && isNone(snapshot.changedAttributes()[key])) { return; } diff --git a/ui/app/serializers/transit-key.js b/ui/app/serializers/transit-key.js index 5ace36a78..684f78906 100644 --- a/ui/app/serializers/transit-key.js +++ b/ui/app/serializers/transit-key.js @@ -1,6 +1,6 @@ +import { assign } from '@ember/polyfills'; +import { decamelize } from '@ember/string'; import DS from 'ember-data'; -import Ember from 'ember'; -const { decamelize } = Ember.String; export default DS.RESTSerializer.extend({ primaryKey: 'name', @@ -14,7 +14,7 @@ export default DS.RESTSerializer.extend({ const secrets = payload.data.keys.map(secret => ({ name: secret })); return secrets; } - Ember.assign(payload, payload.data); + assign(payload, payload.data); delete payload.data; return [payload]; }, diff --git a/ui/app/services/auth.js b/ui/app/services/auth.js index 633283b96..b4bd43ff2 100644 --- a/ui/app/services/auth.js +++ b/ui/app/services/auth.js @@ -1,10 +1,14 @@ -import Ember from 'ember'; +import { resolve } from 'rsvp'; +import { assign } from '@ember/polyfills'; +import $ from 'jquery'; +import { isArray } from '@ember/array'; +import { computed, get } from '@ember/object'; +import { getOwner } from '@ember/application'; +import Service, { inject as service } from '@ember/service'; import getStorage from '../lib/token-storage'; import ENV from 'vault/config/environment'; import { supportedAuthBackends } from 'vault/helpers/supported-auth-backends'; -const { get, isArray, computed, getOwner, Service, inject } = Ember; - const TOKEN_SEPARATOR = '☃'; const TOKEN_PREFIX = 'vault-'; const ROOT_PREFIX = '🗝'; @@ -14,7 +18,7 @@ const BACKENDS = supportedAuthBackends(); export { TOKEN_SEPARATOR, TOKEN_PREFIX, ROOT_PREFIX }; export default Service.extend({ - namespace: inject.service(), + namespace: service(), expirationCalcTS: null, init() { this._super(...arguments); @@ -76,7 +80,7 @@ export default Service.extend({ if (namespace) { defaults.headers['X-Vault-Namespace'] = namespace; } - return Ember.$.ajax(Ember.assign(defaults, options)); + return $.ajax(assign(defaults, options)); }, renewCurrentToken() { @@ -165,7 +169,7 @@ export default Service.extend({ ); if (resp.renewable) { - Ember.assign(data, this.calculateExpiration(resp)); + assign(data, this.calculateExpiration(resp)); } if (!data.displayName) { @@ -175,7 +179,7 @@ export default Service.extend({ this.set('tokens', tokens); this.set('allowExpiration', false); this.setTokenData(tokenName, data); - return Ember.RSVP.resolve({ + return resolve({ namespace: currentNamespace || data.userRootNamespace, token: tokenName, isRoot: policies.includes('root'), @@ -318,7 +322,7 @@ export default Service.extend({ const backend = this.backendFromTokenName(token); const stored = this.getTokenData(token); - return Ember.assign(stored, { + return assign(stored, { backend: BACKENDS.findBy('type', backend), }); }), diff --git a/ui/app/services/console.js b/ui/app/services/console.js index 407f7064a..f9f5afd2b 100644 --- a/ui/app/services/console.js +++ b/ui/app/services/console.js @@ -1,9 +1,10 @@ // Low level service that allows users to input paths to make requests to vault // this service provides the UI synecdote to the cli commands read, write, delete, and list -import Ember from 'ember'; -import { shiftCommandIndex } from 'vault/lib/console-helpers'; +import Service from '@ember/service'; -const { Service, getOwner, computed } = Ember; +import { getOwner } from '@ember/application'; +import { computed } from '@ember/object'; +import { shiftCommandIndex } from 'vault/lib/console-helpers'; export function sanitizePath(path) { //remove whitespace + remove trailing and leading slashes diff --git a/ui/app/services/control-group.js b/ui/app/services/control-group.js index 4a15d2882..a843058ea 100644 --- a/ui/app/services/control-group.js +++ b/ui/app/services/control-group.js @@ -1,10 +1,11 @@ -import Ember from 'ember'; +import { get } from '@ember/object'; +import Service, { inject as service } from '@ember/service'; +import RSVP from 'rsvp'; import ControlGroupError from 'vault/lib/control-group-error'; import getStorage from 'vault/lib/token-storage'; const CONTROL_GROUP_PREFIX = 'vault:cg-'; const TOKEN_SEPARATOR = '☃'; -const { Service, inject, RSVP } = Ember; // list of endpoints that return wrapped responses // without `wrap-ttl` @@ -21,8 +22,8 @@ const storageKey = (accessor, path) => { export { storageKey, CONTROL_GROUP_PREFIX, TOKEN_SEPARATOR }; export default Service.extend({ - version: inject.service(), - router: inject.service(), + version: service(), + router: service(), storage() { return getStorage(); @@ -80,7 +81,7 @@ export default Service.extend({ }, checkForControlGroup(callbackArgs, response, wasWrapTTLRequested) { - let creationPath = response && Ember.get(response, 'wrap_info.creation_path'); + let creationPath = response && get(response, 'wrap_info.creation_path'); if ( this.get('version.isOSS') || wasWrapTTLRequested || diff --git a/ui/app/services/csp-event.js b/ui/app/services/csp-event.js index 5d986a25a..7cfceae0f 100644 --- a/ui/app/services/csp-event.js +++ b/ui/app/services/csp-event.js @@ -1,12 +1,15 @@ /*eslint-disable no-constant-condition*/ -import Ember from 'ember'; +import { computed } from '@ember/object'; +import { filterBy } from '@ember/object/computed'; + +import Service from '@ember/service'; import { task, waitForEvent } from 'ember-concurrency'; -const { Service, computed } = Ember; - export default Service.extend({ - events: [], - connectionViolations: computed.filterBy('events', 'violatedDirective', 'connect-src'), + events: computed(function() { + return []; + }), + connectionViolations: filterBy('events', 'violatedDirective', 'connect-src'), attach() { this.get('monitor').perform(); diff --git a/ui/app/services/current-cluster.js b/ui/app/services/current-cluster.js index e1bf4ba14..688896aee 100644 --- a/ui/app/services/current-cluster.js +++ b/ui/app/services/current-cluster.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Service from '@ember/service'; -export default Ember.Service.extend({ +export default Service.extend({ cluster: null, setCluster(cluster) { diff --git a/ui/app/services/namespace.js b/ui/app/services/namespace.js index dc29b2dea..c96378061 100644 --- a/ui/app/services/namespace.js +++ b/ui/app/services/namespace.js @@ -1,26 +1,26 @@ -import Ember from 'ember'; +import { alias, equal } from '@ember/object/computed'; +import Service, { inject as service } from '@ember/service'; import { task } from 'ember-concurrency'; import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; -const { Service, computed, inject } = Ember; const ROOT_NAMESPACE = ''; export default Service.extend({ - store: inject.service(), - auth: inject.service(), - userRootNamespace: computed.alias('auth.authData.userRootNamespace'), + store: service(), + auth: service(), + userRootNamespace: alias('auth.authData.userRootNamespace'), //populated by the query param on the cluster route path: null, // list of namespaces available to the current user under the // current namespace accessibleNamespaces: null, - inRootNamespace: computed.equal('path', ROOT_NAMESPACE), + inRootNamespace: equal('path', ROOT_NAMESPACE), setNamespace(path) { this.set('path', path); }, listPath: lazyCapabilities(apiPath`sys/namespaces/`, 'path'), - canList: computed.alias('listPath.canList'), + canList: alias('listPath.canList'), findNamespacesForUser: task(function*() { // uses the adapter and the raw response here since diff --git a/ui/app/services/replication-mode.js b/ui/app/services/replication-mode.js index c5a1fc9f9..58c904620 100644 --- a/ui/app/services/replication-mode.js +++ b/ui/app/services/replication-mode.js @@ -1,6 +1,6 @@ -import Ember from 'ember'; +import Service from '@ember/service'; -export default Ember.Service.extend({ +export default Service.extend({ mode: null, getMode() { diff --git a/ui/app/services/store.js b/ui/app/services/store.js index 711cbdb85..c52547422 100644 --- a/ui/app/services/store.js +++ b/ui/app/services/store.js @@ -1,21 +1,26 @@ +import { schedule } from '@ember/runloop'; +import { copy } from 'ember-copy'; +import { resolve, Promise } from 'rsvp'; +import { dasherize } from '@ember/string'; +import { assert } from '@ember/debug'; +import { set, get, computed } from '@ember/object'; import DS from 'ember-data'; -import Ember from 'ember'; import clamp from 'vault/utils/clamp'; -const { assert, computed, get, set } = Ember; - export function normalizeModelName(modelName) { - return Ember.String.dasherize(modelName); + return dasherize(modelName); } export function keyForCache(query) { /*eslint no-unused-vars: ["error", { "ignoreRestSiblings": true }]*/ // we want to ignore size, page, responsePath, and pageFilter in the cacheKey const { size, page, responsePath, pageFilter, ...queryForCache } = query; - const cacheKeyObject = Object.keys(queryForCache).sort().reduce((result, key) => { - result[key] = queryForCache[key]; - return result; - }, {}); + const cacheKeyObject = Object.keys(queryForCache) + .sort() + .reduce((result, key) => { + result[key] = queryForCache[key]; + return result; + }, {}); return JSON.stringify(cacheKeyObject); } @@ -67,7 +72,7 @@ export default DS.Store.extend({ assert('size is required', query.size); if (dataCache) { - return Ember.RSVP.resolve(this.fetchPage(modelName, query)); + return resolve(this.fetchPage(modelName, query)); } return adapter .query(this, { modelName }, query) @@ -105,7 +110,7 @@ export default DS.Store.extend({ constructResponse(modelName, query) { const { pageFilter, responsePath, size, page } = query; let { response, dataset } = this.getDataset(modelName, query); - response = Ember.copy(response, true); + response = copy(response, true); const data = this.filterData(pageFilter, dataset); const lastPage = Math.ceil(data.length / size); @@ -134,8 +139,8 @@ export default DS.Store.extend({ this.peekAll(modelName).forEach(record => { record.unloadRecord(); }); - return new Ember.RSVP.Promise(resolve => { - Ember.run.schedule('destroy', () => { + return new Promise(resolve => { + schedule('destroy', () => { this.push( this.serializerFor(modelName).normalizeResponse( this, diff --git a/ui/app/services/version.js b/ui/app/services/version.js index e392ebe3c..a846506c7 100644 --- a/ui/app/services/version.js +++ b/ui/app/services/version.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import { readOnly, match, not } from '@ember/object/computed'; +import Service, { inject as service } from '@ember/service'; +import { computed } from '@ember/object'; import { task } from 'ember-concurrency'; -const { Service, inject, computed } = Ember; - const hasFeatureMethod = (context, featureKey) => { const features = context.get('features'); if (!features) { @@ -17,9 +17,9 @@ const hasFeature = featureKey => { }; export default Service.extend({ _features: null, - features: computed.readOnly('_features'), + features: readOnly('_features'), version: null, - store: inject.service(), + store: service(), hasPerfReplication: hasFeature('Performance Replication'), @@ -28,9 +28,9 @@ export default Service.extend({ hasSentinel: hasFeature('Sentinel'), hasNamespaces: hasFeature('Namespaces'), - isEnterprise: computed.match('version', /\+.+$/), + isEnterprise: match('version', /\+.+$/), - isOSS: computed.not('isEnterprise'), + isOSS: not('isEnterprise'), setVersion(resp) { this.set('version', resp.version); diff --git a/ui/app/services/wizard.js b/ui/app/services/wizard.js index 4cddf250a..81735217b 100644 --- a/ui/app/services/wizard.js +++ b/ui/app/services/wizard.js @@ -1,8 +1,8 @@ -import Ember from 'ember'; +import { next } from '@ember/runloop'; +import { typeOf } from '@ember/utils'; +import Service, { inject as service } from '@ember/service'; import { Machine } from 'xstate'; -const { Service, inject } = Ember; - import getStorage from 'vault/lib/token-storage'; import TutorialMachineConfig from 'vault/machines/tutorial-machine'; @@ -44,7 +44,7 @@ const DEFAULTS = { }; export default Service.extend(DEFAULTS, { - router: inject.service(), + router: service(), showWhenUnauthenticated: false, init() { @@ -103,7 +103,7 @@ export default Service.extend(DEFAULTS, { state = state.value; } let stateKey = ''; - while (Ember.typeOf(state) === 'object') { + while (typeOf(state) === 'object') { let newState = Object.keys(state); stateKey += newState + '.'; state = state[newState]; @@ -178,7 +178,7 @@ export default Service.extend(DEFAULTS, { case 'routeTransition': expectedRouteName = action.params[0]; transitionURL = router.urlFor(...action.params).replace(/^\/ui/, ''); - Ember.run.next(() => { + next(() => { router.transitionTo(...action.params); }); break; diff --git a/ui/app/styles/components/ui-wizard.scss b/ui/app/styles/components/ui-wizard.scss index 888866766..7a5a8c7c8 100644 --- a/ui/app/styles/components/ui-wizard.scss +++ b/ui/app/styles/components/ui-wizard.scss @@ -143,6 +143,7 @@ padding: 0 $size-8; border-top: solid 1px $white; border-image: $dark-vault-gradient 1; + border-width: 1px 0 0; button { font-size: $size-7; font-weight: $font-weight-semibold; diff --git a/ui/app/styles/core/buttons.scss b/ui/app/styles/core/buttons.scss index 4a823f492..d317eaa90 100644 --- a/ui/app/styles/core/buttons.scss +++ b/ui/app/styles/core/buttons.scss @@ -183,8 +183,8 @@ $button-box-shadow-standard: 0 3px 1px 0 rgba($black, 0.12); .icon { &, &:first-child:last-child { - margin-left: -$size-10; - margin-right: $size-11; + position: relative; + left: -$size-10; } } } diff --git a/ui/app/templates/components/console/log-error-with-html.hbs b/ui/app/templates/components/console/log-error-with-html.hbs index 2d468ae98..625365907 100644 --- a/ui/app/templates/components/console/log-error-with-html.hbs +++ b/ui/app/templates/components/console/log-error-with-html.hbs @@ -1,3 +1,4 @@ +{{! template-lint-disable no-triple-curlies}}
{{i-con glyph="close-circled" aria-hidden="true" size=12}}
{{{content}}}
diff --git a/ui/app/templates/components/console/log-list.hbs b/ui/app/templates/components/console/log-list.hbs index d2b79b377..e1e09fbdc 100644 --- a/ui/app/templates/components/console/log-list.hbs +++ b/ui/app/templates/components/console/log-list.hbs @@ -2,6 +2,7 @@
Keys
 {{#each list as |item|}}
 {{item}}
+
 {{/each}}
 
diff --git a/ui/app/templates/components/generate-credentials.hbs b/ui/app/templates/components/generate-credentials.hbs index a5c34955e..81c0b98bf 100644 --- a/ui/app/templates/components/generate-credentials.hbs +++ b/ui/app/templates/components/generate-credentials.hbs @@ -4,20 +4,20 @@
  • / - {{#link-to "vault.cluster.secrets.backend" backend.id data-test-link="role-list"}} - {{backend.id}} + {{#link-to "vault.cluster.secrets.backend" backendPath data-test-link="role-list"}} + {{backendPath}} {{/link-to}}
  • / - {{#link-to "vault.cluster.secrets.backend" backend.id}} + {{#link-to "vault.cluster.secrets.backend" backendPath}} creds {{/link-to}}
  • / - {{#link-to "vault.cluster.secrets.backend.show" model.role.name}} - {{model.role.name}} + {{#link-to "vault.cluster.secrets.backend.show" roleName}} + {{roleName}} {{/link-to}}
@@ -73,7 +73,7 @@ {{#if options.backIsListLink}} {{#link-to "vault.cluster.secrets.backend.list-root" - backend.id + backendPath data-test-secret-generate-back=true class="button" }} @@ -121,7 +121,7 @@
{{#link-to "vault.cluster.secrets.backend.list-root" - backend.id + backendPath class="button" data-test-secret-generate-cancel=true }} diff --git a/ui/app/templates/components/namespace-picker.hbs b/ui/app/templates/components/namespace-picker.hbs index 134eeb01a..b6ba1a1f2 100644 --- a/ui/app/templates/components/namespace-picker.hbs +++ b/ui/app/templates/components/namespace-picker.hbs @@ -56,7 +56,7 @@ {{/each~}}
{{/if}} - {{#each lastMenuLeaves as |leaf index|}} + {{#each lastMenuLeaves as |leaf|}}
-
diff --git a/ui/app/templates/components/transit-key-action/encrypt.hbs b/ui/app/templates/components/transit-key-action/encrypt.hbs index e87ca1342..c68f7a87d 100644 --- a/ui/app/templates/components/transit-key-action/encrypt.hbs +++ b/ui/app/templates/components/transit-key-action/encrypt.hbs @@ -75,7 +75,7 @@
-
diff --git a/ui/app/templates/partials/replication/disable.hbs b/ui/app/templates/partials/replication/disable.hbs index be81e0ca1..466d7fbf6 100644 --- a/ui/app/templates/partials/replication/disable.hbs +++ b/ui/app/templates/partials/replication/disable.hbs @@ -3,7 +3,7 @@

- Disable {{replicationMode}} replication entirely on the cluster. + Disable {{replicationDisplayMode}} replication entirely on the cluster. {{#if model.replicationAttrs.isPrimary}} Any secondaries will no longer be able to connect. {{else if (eq model.replicationAttrs.modeForUrl 'bootstrapping')}} diff --git a/ui/app/templates/partials/role-ssh/popup-menu.hbs b/ui/app/templates/partials/role-ssh/popup-menu.hbs index edf45888c..c878908b7 100644 --- a/ui/app/templates/partials/role-ssh/popup-menu.hbs +++ b/ui/app/templates/partials/role-ssh/popup-menu.hbs @@ -74,7 +74,7 @@ {{/if}} {{/if}} - {{#if backendModel.canEditZeroAddress}} + {{#if item.canEditZeroAddress}} {{#if item.zeroAddress}}

  • diff --git a/ui/app/templates/partials/transit-form-show.hbs b/ui/app/templates/partials/transit-form-show.hbs index 4996a065a..530cc4077 100644 --- a/ui/app/templates/partials/transit-form-show.hbs +++ b/ui/app/templates/partials/transit-form-show.hbs @@ -6,6 +6,7 @@ secret=key.id mode="show" replace=true + queryParams=(query-params tab='') data-test-transit-link="details" }} Details @@ -162,8 +163,9 @@

    {{transit-key-actions key=key - selectedAction='rotate' + selectedAction="rotate" capabilities=capabilities + onRefresh=(action "refresh") }}

    {{else}} diff --git a/ui/app/templates/svg/vault-loading.hbs b/ui/app/templates/svg/vault-loading.hbs index 9402fcfe6..0c20cd015 100644 --- a/ui/app/templates/svg/vault-loading.hbs +++ b/ui/app/templates/svg/vault-loading.hbs @@ -1,3 +1,4 @@ +{{! template-lint-disable no-inline-styles}} diff --git a/ui/app/templates/vault/cluster/secrets/backend/credentials.hbs b/ui/app/templates/vault/cluster/secrets/backend/credentials.hbs index 4123d2efd..6f623b7f9 100644 --- a/ui/app/templates/vault/cluster/secrets/backend/credentials.hbs +++ b/ui/app/templates/vault/cluster/secrets/backend/credentials.hbs @@ -1,5 +1,6 @@ {{generate-credentials - role=model - backend=backend + backendPath=model.backendPath + backendType=model.backendType + roleName=model.roleName action=action -}} + }} diff --git a/ui/app/templates/vault/cluster/secrets/backend/secret-edit-layout.hbs b/ui/app/templates/vault/cluster/secrets/backend/secret-edit-layout.hbs index 294e94cdf..145605ab5 100644 --- a/ui/app/templates/vault/cluster/secrets/backend/secret-edit-layout.hbs +++ b/ui/app/templates/vault/cluster/secrets/backend/secret-edit-layout.hbs @@ -7,6 +7,7 @@ capabilities=capabilities onDataChange=(action "hasChanges") onRefresh=(action "refresh") + onToggleAdvancedEdit=(action "toggleAdvancedEdit") initialKey=initialKey baseKey=baseKey preferAdvancedEdit=preferAdvancedEdit diff --git a/ui/app/templates/vault/cluster/secrets/backend/transit-actions-layout.hbs b/ui/app/templates/vault/cluster/secrets/backend/transit-actions-layout.hbs index 70dba9879..2c5ea1d0f 100644 --- a/ui/app/templates/vault/cluster/secrets/backend/transit-actions-layout.hbs +++ b/ui/app/templates/vault/cluster/secrets/backend/transit-actions-layout.hbs @@ -46,6 +46,7 @@ backend=backend key=model capabilities=capabilities + onRefresh=(action "refresh") }}
    diff --git a/ui/app/transforms/array.js b/ui/app/transforms/array.js index cd1f94d51..9797c9942 100644 --- a/ui/app/transforms/array.js +++ b/ui/app/transforms/array.js @@ -1,4 +1,4 @@ -import Ember from 'ember'; +import { isArray, A } from '@ember/array'; import DS from 'ember-data'; /* This should go inside a globally available place for all apps @@ -7,17 +7,17 @@ import DS from 'ember-data'; */ export default DS.Transform.extend({ deserialize(value) { - if (Ember.isArray(value)) { - return Ember.A(value); + if (isArray(value)) { + return A(value); } else { - return Ember.A(); + return A(); } }, serialize(value) { - if (Ember.isArray(value)) { - return Ember.A(value); + if (isArray(value)) { + return A(value); } else { - return Ember.A(); + return A(); } }, }); diff --git a/ui/app/utils/field-to-attrs.js b/ui/app/utils/field-to-attrs.js index 812d71d2d..730c9076b 100644 --- a/ui/app/utils/field-to-attrs.js +++ b/ui/app/utils/field-to-attrs.js @@ -1,5 +1,5 @@ -import Ember from 'ember'; - +import { get } from '@ember/object'; +import { expandProperties } from '@ember/object/computed'; /* * * @param modelClass DS.Model @@ -38,11 +38,11 @@ import Ember from 'ember'; export const expandAttributeMeta = function(modelClass, attributeNames, namePrefix, map) { let fields = []; // expand all attributes - attributeNames.forEach(field => Ember.expandProperties(field, x => fields.push(x))); + attributeNames.forEach(field => expandProperties(field, x => fields.push(x))); let attributeMap = map || new Map(); modelClass.eachAttribute((name, meta) => { let fieldName = namePrefix ? namePrefix + name : name; - let maybeFragment = Ember.get(modelClass, fieldName); + let maybeFragment = get(modelClass, fieldName); if (meta.isFragment && maybeFragment) { // pass the fragment and all fields that start with // the fragment name down to get extracted from the Fragment diff --git a/ui/config/environment.js b/ui/config/environment.js index 6ee853ea4..b0d4b92ba 100644 --- a/ui/config/environment.js +++ b/ui/config/environment.js @@ -1,4 +1,5 @@ -/* jshint node: true */ +/* eslint-env node */ +'use strict'; module.exports = function(environment) { var ENV = { @@ -54,6 +55,9 @@ module.exports = function(environment) { ENV['ember-cli-mirage'] = { enabled: false, }; + ENV.APP.autoboot = false; + + ENV.flashMessageDefaults.timeout = 50; } if (environment !== 'production') { ENV.contentSecurityPolicyHeader = 'Content-Security-Policy'; @@ -67,8 +71,6 @@ module.exports = function(environment) { }; } - if (environment === 'production') { - } ENV.welcomeMessage = process.env.UI_AUTH_WELCOME; return ENV; diff --git a/ui/config/optional-features.json b/ui/config/optional-features.json new file mode 100644 index 000000000..21f1dc719 --- /dev/null +++ b/ui/config/optional-features.json @@ -0,0 +1,3 @@ +{ + "jquery-integration": true +} diff --git a/ui/config/targets.js b/ui/config/targets.js index 08d2ad4d6..f14319316 100644 --- a/ui/config/targets.js +++ b/ui/config/targets.js @@ -1,10 +1,14 @@ -/* eslint-env node */ +'use strict'; + +const browsers = ['last 1 Chrome versions', 'last 1 Firefox versions', 'last 1 Safari versions']; + +const isCI = !!process.env.CI; +const isProduction = process.env.EMBER_ENV === 'production'; + +if (isCI || isProduction) { + browsers.push('ie 11'); +} + module.exports = { - browsers: [ - 'ie 10', - 'last 2 Chrome versions', - 'last 2 Firefox versions', - 'last 2 Safari versions', - 'last 2 Edge versions', - ], + browsers, }; diff --git a/ui/ember-cli-build.js b/ui/ember-cli-build.js index 03daf4d46..515d82799 100644 --- a/ui/ember-cli-build.js +++ b/ui/ember-cli-build.js @@ -1,6 +1,7 @@ -/*jshint node:true*/ -/* global require, module */ -var EmberApp = require('ember-cli/lib/broccoli/ember-app'); +/* eslint-env node */ +'use strict'; + +const EmberApp = require('ember-cli/lib/broccoli/ember-app'); module.exports = function(defaults) { var config = defaults.project.config(EmberApp.env()); diff --git a/ui/package.json b/ui/package.json index 396a10c38..5ae64d6ff 100644 --- a/ui/package.json +++ b/ui/package.json @@ -2,18 +2,20 @@ "name": "vault", "version": "0.0.0", "description": "The official UI for Vault by HashiCorp", + "repository": "", + "author": "", "directories": { "doc": "doc", "test": "tests" }, - "author": "", - "repository": "", "scripts": { "build": "ember build -prod", "build-dev": "ember build", + "lint:hbs": "ember-template-lint .", + "lint:js": "eslint .", "start": "export VAULT_ADDR=http://localhost:8200; ember server --proxy=$VAULT_ADDR", - "start2": "ember server --proxy=http://localhost:8202 --port=4202", "test": "node scripts/start-vault.js & ember test", + "start2": "ember server --proxy=http://localhost:8202 --port=4202", "test-oss": "yarn run test -f='!enterprise'", "fmt-js": "prettier-eslint --single-quote --no-use-tabs --trailing-comma es5 --print-width=110 --write '{app,tests,config,lib,mirage}/**/*.js'", "fmt-styles": "prettier --write app/styles/**/*.*", @@ -33,11 +35,13 @@ } }, "devDependencies": { + "@ember/jquery": "^0.5.2", + "@ember/optional-features": "^0.6.3", "Duration.js": "icholy/Duration.js#golang_compatible", "autosize": "^4.0.0", "babel-plugin-transform-object-rest-spread": "^6.23.0", "base64-js": "1.2.1", - "broccoli-asset-rev": "^2.4.5", + "broccoli-asset-rev": "^2.7.0", "broccoli-sri-hash": "meirish/broccoli-sri-hash#rooturl", "bulma": "^0.5.2", "bulma-switch": "^0.0.1", @@ -45,71 +49,72 @@ "columnify": "^1.5.4", "cool-checkboxes-for-bulma.io": "^1.1.0", "deepmerge": "^2.1.1", - "ember-ajax": "^3.0.0", - "ember-angle-bracket-invocation-polyfill": "^1.0.2", + "ember-ajax": "^3.1.0", "ember-api-actions": "^0.1.8", "ember-auto-import": "^1.2.3", "ember-basic-dropdown": "^1.0.0", "ember-basic-dropdown-hover": "^0.5.0", - "ember-cli": "~2.16.0", + "ember-cli": "~3.4.2", "ember-cli-autoprefixer": "^0.8.1", - "ember-cli-babel": "^6.3.0", + "ember-cli-babel": "^6.16.0", "ember-cli-clipboard": "^0.8.0", "ember-cli-content-security-policy": "^1.0.0", - "ember-cli-dependency-checker": "^1.3.0", - "ember-cli-eslint": "4", - "ember-cli-favicon": "1.0.0-beta.4", - "ember-cli-flash": "^1.5.0", - "ember-cli-htmlbars": "^2.0.1", - "ember-cli-htmlbars-inline-precompile": "^0.4.3", - "ember-cli-inject-live-reload": "^1.4.1", + "ember-cli-dependency-checker": "^3.0.0", + "ember-cli-eslint": "^4.2.3", + "ember-cli-favicon": "~1.0.0", + "ember-cli-flash": "^1.6.6", + "ember-cli-htmlbars": "^3.0.0", + "ember-cli-htmlbars-inline-precompile": "^1.0.3", + "ember-cli-inject-live-reload": "^1.8.2", "ember-cli-mirage": "^0.4.1", - "ember-cli-moment-shim": "2.2.1", - "ember-cli-page-object": "1.14", - "ember-cli-pretender": "0.7.0", - "ember-cli-qunit": "^4.0.0", + "ember-cli-moment-shim": "^3.7.1", + "ember-cli-page-object": "1.15.0-beta.3", + "ember-cli-pretender": "^1.0.1", + "ember-cli-qunit": "^4.3.2", "ember-cli-sass": "^7.1.7", - "ember-cli-shims": "^1.1.0", "ember-cli-sri": "meirish/ember-cli-sri#rooturl", "ember-cli-string-helpers": "^1.5.0", - "ember-cli-uglify": "^1.2.0", + "ember-cli-template-lint": "^1.0.0-beta.1", + "ember-cli-uglify": "^2.1.0", "ember-composable-helpers": "^2.0.3", "ember-computed-query": "^0.1.1", "ember-concurrency": "^0.8.14", - "ember-data": "2.12.1", - "ember-data-model-fragments": "2.11.x", + "ember-copy": "^1.0.0", + "ember-data": "~3.4.0", + "ember-data-model-fragments": "^3.3.0", "ember-export-application-global": "^2.0.0", "ember-fetch": "^3.4.3", "ember-inflector": "^3.0.0", - "ember-load-initializers": "^1.0.0", + "ember-load-initializers": "^1.1.0", + "ember-maybe-import-regenerator": "^0.1.6", "ember-maybe-in-element": "^0.1.3", - "ember-moment": "7.0.0-beta.5", - "ember-qunit-assert-helpers": "^0.1.3", + "ember-moment": "^7.7.0", "ember-radio-button": "^1.1.1", - "ember-resolver": "^4.0.0", + "ember-resolver": "^5.0.1", "ember-responsive": "^3.0.0-beta.3", - "ember-router-service-polyfill": "^1.0.2", "ember-sinon": "^1.0.1", - "ember-source": "~2.14.0", - "ember-test-selectors": "^0.3.6", - "ember-truth-helpers": "1.2.0", + "ember-source": "~3.4.0", + "ember-test-selectors": "^1.0.0", + "ember-truth-helpers": "^2.1.0", + "eslint-plugin-ember": "^5.2.0", "flat": "^4.1.0", "ivy-codemirror": "2.1.0", "jsonlint": "1.6.0", - "loader.js": "^4.2.3", + "loader.js": "^4.7.0", "normalize.css": "4.1.1", - "prettier": "^1.5.3", - "prettier-eslint-cli": "^4.2.1", - "qunit-dom": "^0.6.2", + "prettier": "^1.14.3", + "prettier-eslint-cli": "^4.7.1", + "qunit-dom": "^0.7.1", "sass-svg-uri": "^1.0.0", "string.prototype.endswith": "^0.2.0", "string.prototype.startswith": "^0.2.0", "text-encoder-lite": "1.0.0", + "walk-sync": "^0.3.3", "xstate": "^3.3.3", "yargs-parser": "^10.0.0" }, "engines": { - "node": "^4.5 || 6.* || >= 7.*" + "node": "6.* || 8.* || >= 10.*" }, "private": true, "ember-addon": { diff --git a/ui/public/crossdomain.xml b/ui/public/crossdomain.xml deleted file mode 100644 index 0c16a7a07..000000000 --- a/ui/public/crossdomain.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - diff --git a/ui/scripts/list-templates.js b/ui/scripts/list-templates.js new file mode 100755 index 000000000..bda10af90 --- /dev/null +++ b/ui/scripts/list-templates.js @@ -0,0 +1,17 @@ +#!/usr/bin/env node +/* eslint-disable */ + +// We need an array in this format for all of the files +//https://github.com/ember-template-lint/ember-cli-template-lint/blob/1bc03444ecf367473108cb28208cb3123199f950/.template-lintrc.js#L9 + +var walkSync = require('walk-sync'); +var templates = walkSync('app', { globs: ['**/*.hbs'] }); + +templates = templates.map(path => { + // we want the relative path w/o the extension: + // 'app/templates/path/to/file/filename' + return `app/${path.replace(/\.hbs$/, '')}`; +}); + +// stringify because if we don't console won't output the full list lol +console.log(JSON.stringify(templates, null, 2)); diff --git a/ui/scripts/start-vault.js b/ui/scripts/start-vault.js index 7ea6701b9..b4867fdeb 100755 --- a/ui/scripts/start-vault.js +++ b/ui/scripts/start-vault.js @@ -1,6 +1,7 @@ #!/usr/bin/env node +/* eslint-disable */ -if(process.argv[2]){ +if (process.argv[2]) { process.kill(process.argv[2], 'SIGINT'); process.exit(0); } @@ -8,42 +9,45 @@ if(process.argv[2]){ process.env.TERM = 'dumb'; var fs = require('fs'); var path = require('path'); -var readline = require('readline') +var readline = require('readline'); var spawn = require('child_process').spawn; -var vault = spawn( - 'vault', - [ - 'server', - '-dev', - '-dev-ha', - '-dev-transactional', - '-dev-root-token-id=root', - '-dev-listen-address=127.0.0.1:9200' - ] -); +var vault = spawn('vault', [ + 'server', + '-dev', + '-dev-ha', + '-dev-transactional', + '-dev-root-token-id=root', + '-dev-listen-address=127.0.0.1:9200', +]); var output = ''; var unseal, root; -readline.createInterface({ - input : vault.stdout, - terminal : false -}).on('line', function(line) { - output = output + line; - console.log(line); - var unsealMatch = output.match(/Unseal Key\: (.+)$/m); - if (unsealMatch && !unseal) { unseal = unsealMatch[1] }; - var rootMatch = output.match(/Root Token\: (.+)$/m); - if (rootMatch && !root) { root = rootMatch[1] }; - if (root && unseal) { - fs.writeFile( - path.join(process.cwd(), 'tests/helpers/vault-keys.js'), - `export default ${JSON.stringify({ unseal:unseal, root:root }, null, 2)}` - ); +readline + .createInterface({ + input: vault.stdout, + terminal: false, + }) + .on('line', function(line) { + output = output + line; + console.log(line); + var unsealMatch = output.match(/Unseal Key: (.+)$/m); + if (unsealMatch && !unseal) { + unseal = unsealMatch[1]; + } + var rootMatch = output.match(/Root Token: (.+)$/m); + if (rootMatch && !root) { + root = rootMatch[1]; + } + if (root && unseal) { + fs.writeFile( + path.join(process.cwd(), 'tests/helpers/vault-keys.js'), + `export default ${JSON.stringify({ unseal: unseal, root: root }, null, 2)}` + ); - console.log('VAULT SERVER READY'); - } -}); + console.log('VAULT SERVER READY'); + } + }); vault.stderr.on('data', function(data) { console.log(data.toString()); @@ -58,7 +62,6 @@ vault.on('error', function(error) { process.exit(); }); - var pidFile = 'vault-ui-integration-server.pid'; process.on('SIGINT', function() { vault.kill('SIGINT'); diff --git a/ui/testem.js b/ui/testem.js index a30b082f8..fe34b6637 100644 --- a/ui/testem.js +++ b/ui/testem.js @@ -1,5 +1,4 @@ -/*jshint node:true*/ - +/* eslint-env node */ module.exports = { framework: 'qunit', test_page: 'tests/index.html?hidepassed', @@ -8,19 +7,19 @@ module.exports = { launch_in_ci: ['Chrome'], browser_args: { Chrome: { - mode: 'ci', - args: [ + ci: [ // --no-sandbox is needed when running Chrome inside a container - process.env.TRAVIS ? '--no-sandbox' : null, - - '--disable-gpu', + process.env.CI ? '--no-sandbox' : null, '--headless', + '--disable-gpu', + '--disable-dev-shm-usage', + '--disable-software-rasterizer', + '--mute-audio', '--remote-debugging-port=0', '--window-size=1440,900', ].filter(Boolean), }, }, - launch_in_dev: ['Chrome'], on_exit: '[ -e ../../vault-ui-integration-server.pid ] && node ../../scripts/start-vault.js `cat ../../vault-ui-integration-server.pid`; [ -e ../../vault-ui-integration-server.pid ] && rm ../../vault-ui-integration-server.pid', diff --git a/ui/tests/.eslintrc.js b/ui/tests/.eslintrc.js index 88d281d2b..1dc3d2c82 100644 --- a/ui/tests/.eslintrc.js +++ b/ui/tests/.eslintrc.js @@ -10,6 +10,5 @@ module.exports = { authLogin: false, pollCluster: false, mountSupportedSecretBackend: false, - wait: true, }, }; diff --git a/ui/tests/acceptance/access/identity/_shared-alias-tests.js b/ui/tests/acceptance/access/identity/_shared-alias-tests.js index 3c592e484..be496e65e 100644 --- a/ui/tests/acceptance/access/identity/_shared-alias-tests.js +++ b/ui/tests/acceptance/access/identity/_shared-alias-tests.js @@ -1,102 +1,106 @@ +import { currentRouteName } from '@ember/test-helpers'; import page from 'vault/tests/pages/access/identity/aliases/add'; import aliasIndexPage from 'vault/tests/pages/access/identity/aliases/index'; import aliasShowPage from 'vault/tests/pages/access/identity/aliases/show'; import createItemPage from 'vault/tests/pages/access/identity/create'; import showItemPage from 'vault/tests/pages/access/identity/show'; +import withFlash from 'vault/tests/helpers/with-flash'; -export const testAliasCRUD = (name, itemType, assert) => { +export const testAliasCRUD = async function(name, itemType, assert) { let itemID; let aliasID; + let idRow; if (itemType === 'groups') { createItemPage.createItem(itemType, 'external'); } else { createItemPage.createItem(itemType); } - andThen(() => { - let idRow = showItemPage.rows.filterBy('hasLabel').filterBy('rowLabel', 'ID')[0]; - itemID = idRow.rowValue; - page.visit({ item_type: itemType, id: itemID }); - }); - page.editForm.name(name).submit(); - andThen(() => { - let idRow = aliasShowPage.rows.filterBy('hasLabel').filterBy('rowLabel', 'ID')[0]; - aliasID = idRow.rowValue; - assert.equal( - currentRouteName(), - 'vault.cluster.access.identity.aliases.show', - 'navigates to the correct route' - ); + await withFlash(); + idRow = showItemPage.rows.filterBy('hasLabel').filterBy('rowLabel', 'ID')[0]; + itemID = idRow.rowValue; + await page.visit({ item_type: itemType, id: itemID }); + + await withFlash(page.editForm.name(name).submit(), () => { assert.ok( aliasShowPage.flashMessage.latestMessage.startsWith( 'Successfully saved', `${itemType}: shows a flash message` ) ); - assert.ok(aliasShowPage.nameContains(name), `${itemType}: renders the name on the show page`); }); - aliasIndexPage.visit({ item_type: itemType }); - andThen(() => { - assert.equal( - aliasIndexPage.items.filterBy('name', name).length, - 1, - `${itemType}: lists the entity in the entity list` - ); - aliasIndexPage.items.filterBy('name', name)[0].menu(); - }); - aliasIndexPage.delete().confirmDelete(); + idRow = aliasShowPage.rows.filterBy('hasLabel').filterBy('rowLabel', 'ID')[0]; + aliasID = idRow.rowValue; + assert.equal( + currentRouteName(), + 'vault.cluster.access.identity.aliases.show', + 'navigates to the correct route' + ); + assert.ok(aliasShowPage.nameContains(name), `${itemType}: renders the name on the show page`); - andThen(() => { - assert.equal(aliasIndexPage.items.filterBy('id', aliasID).length, 0, `${itemType}: the row is deleted`); + await aliasIndexPage.visit({ item_type: itemType }); + assert.equal( + aliasIndexPage.items.filterBy('name', name).length, + 1, + `${itemType}: lists the entity in the entity list` + ); + + let item = aliasIndexPage.items.filterBy('name', name)[0]; + await item.menu(); + + await aliasIndexPage.delete(); + await withFlash(aliasIndexPage.confirmDelete(), () => { aliasIndexPage.flashMessage.latestMessage.startsWith( 'Successfully deleted', `${itemType}: shows flash message` ); }); + + assert.equal(aliasIndexPage.items.filterBy('id', aliasID).length, 0, `${itemType}: the row is deleted`); }; -export const testAliasDeleteFromForm = (name, itemType, assert) => { +export const testAliasDeleteFromForm = async function(name, itemType, assert) { let itemID; let aliasID; + let idRow; if (itemType === 'groups') { createItemPage.createItem(itemType, 'external'); } else { createItemPage.createItem(itemType); } - andThen(() => { - let idRow = showItemPage.rows.filterBy('hasLabel').filterBy('rowLabel', 'ID')[0]; - itemID = idRow.rowValue; - page.visit({ item_type: itemType, id: itemID }); - }); - page.editForm.name(name).submit(); - andThen(() => { - let idRow = aliasShowPage.rows.filterBy('hasLabel').filterBy('rowLabel', 'ID')[0]; - aliasID = idRow.rowValue; - }); - aliasShowPage.edit(); + await withFlash(); + idRow = showItemPage.rows.filterBy('hasLabel').filterBy('rowLabel', 'ID')[0]; + itemID = idRow.rowValue; + await page.visit({ item_type: itemType, id: itemID }); - andThen(() => { - assert.equal( - currentRouteName(), - 'vault.cluster.access.identity.aliases.edit', - `${itemType}: navigates to edit on create` - ); - }); - page.editForm.delete().confirmDelete(); - andThen(() => { - assert.equal( - currentRouteName(), - 'vault.cluster.access.identity.aliases.index', - `${itemType}: navigates to list page on delete` - ); - assert.equal( - aliasIndexPage.items.filterBy('id', aliasID).length, - 0, - `${itemType}: the row does not show in the list` - ); + await withFlash(page.editForm.name(name).submit()); + + idRow = aliasShowPage.rows.filterBy('hasLabel').filterBy('rowLabel', 'ID')[0]; + aliasID = idRow.rowValue; + await aliasShowPage.edit(); + + assert.equal( + currentRouteName(), + 'vault.cluster.access.identity.aliases.edit', + `${itemType}: navigates to edit on create` + ); + await page.editForm.delete(); + + await withFlash(page.editForm.confirmDelete(), () => { aliasIndexPage.flashMessage.latestMessage.startsWith( 'Successfully deleted', `${itemType}: shows flash message` ); }); + + assert.equal( + currentRouteName(), + 'vault.cluster.access.identity.aliases.index', + `${itemType}: navigates to list page on delete` + ); + assert.equal( + aliasIndexPage.items.filterBy('id', aliasID).length, + 0, + `${itemType}: the row does not show in the list` + ); }; diff --git a/ui/tests/acceptance/access/identity/_shared-tests.js b/ui/tests/acceptance/access/identity/_shared-tests.js index e1a8371ef..ad081a820 100644 --- a/ui/tests/acceptance/access/identity/_shared-tests.js +++ b/ui/tests/acceptance/access/identity/_shared-tests.js @@ -1,71 +1,72 @@ +import { currentRouteName } from '@ember/test-helpers'; import page from 'vault/tests/pages/access/identity/create'; import showPage from 'vault/tests/pages/access/identity/show'; import indexPage from 'vault/tests/pages/access/identity/index'; +import withFlash from 'vault/tests/helpers/with-flash'; -export const testCRUD = (name, itemType, assert) => { - page.visit({ item_type: itemType }); - page.editForm.name(name).submit(); - andThen(() => { - assert.equal( - currentRouteName(), - 'vault.cluster.access.identity.show', - `${itemType}: navigates to show on create` - ); +export const testCRUD = async (name, itemType, assert) => { + await page.visit({ item_type: itemType }); + await withFlash(page.editForm.name(name).submit(), () => { assert.ok( showPage.flashMessage.latestMessage.startsWith( 'Successfully saved', `${itemType}: shows a flash message` ) ); - assert.ok(showPage.nameContains(name), `${itemType}: renders the name on the show page`); }); + assert.equal( + currentRouteName(), + 'vault.cluster.access.identity.show', + `${itemType}: navigates to show on create` + ); + assert.ok(showPage.nameContains(name), `${itemType}: renders the name on the show page`); - indexPage.visit({ item_type: itemType }); - andThen(() => { - assert.equal( - indexPage.items.filterBy('name', name).length, - 1, - `${itemType}: lists the entity in the entity list` - ); - indexPage.items.filterBy('name', name)[0].menu(); - }); - indexPage.delete().confirmDelete(); - - andThen(() => { - assert.equal(indexPage.items.filterBy('name', name).length, 0, `${itemType}: the row is deleted`); - indexPage.flashMessage.latestMessage.startsWith( - 'Successfully deleted', - `${itemType}: shows flash message` + await indexPage.visit({ item_type: itemType }); + assert.equal( + indexPage.items.filterBy('name', name).length, + 1, + `${itemType}: lists the entity in the entity list` + ); + await indexPage.items.filterBy('name', name)[0].menu(); + await indexPage.delete(); + await withFlash(indexPage.confirmDelete(), () => { + assert.ok( + indexPage.flashMessage.latestMessage.startsWith( + 'Successfully deleted', + `${itemType}: shows flash message` + ) ); }); + assert.equal(indexPage.items.filterBy('name', name).length, 0, `${itemType}: the row is deleted`); }; -export const testDeleteFromForm = (name, itemType, assert) => { - page.visit({ item_type: itemType }); - page.editForm.name(name).submit(); - showPage.edit(); - andThen(() => { - assert.equal( - currentRouteName(), - 'vault.cluster.access.identity.edit', - `${itemType}: navigates to edit on create` - ); - }); - page.editForm.delete().confirmDelete(); - andThen(() => { - assert.equal( - currentRouteName(), - 'vault.cluster.access.identity.index', - `${itemType}: navigates to list page on delete` - ); - assert.equal( - indexPage.items.filterBy('name', name).length, - 0, - `${itemType}: the row does not show in the list` - ); - indexPage.flashMessage.latestMessage.startsWith( - 'Successfully deleted', - `${itemType}: shows flash message` +export const testDeleteFromForm = async (name, itemType, assert) => { + await page.visit({ item_type: itemType }); + + await withFlash(page.editForm.name(name).submit()); + await showPage.edit(); + assert.equal( + currentRouteName(), + 'vault.cluster.access.identity.edit', + `${itemType}: navigates to edit on create` + ); + await page.editForm.delete(); + await withFlash(page.editForm.confirmDelete(), () => { + assert.ok( + indexPage.flashMessage.latestMessage.startsWith( + 'Successfully deleted', + `${itemType}: shows flash message` + ) ); }); + assert.equal( + currentRouteName(), + 'vault.cluster.access.identity.index', + `${itemType}: navigates to list page on delete` + ); + assert.equal( + indexPage.items.filterBy('name', name).length, + 0, + `${itemType}: the row does not show in the list` + ); }; diff --git a/ui/tests/acceptance/access/identity/entities/aliases/create-test.js b/ui/tests/acceptance/access/identity/entities/aliases/create-test.js index d58abe26a..ba04504ea 100644 --- a/ui/tests/acceptance/access/identity/entities/aliases/create-test.js +++ b/ui/tests/acceptance/access/identity/entities/aliases/create-test.js @@ -1,19 +1,22 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import { testAliasCRUD, testAliasDeleteFromForm } from '../../_shared-alias-tests'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | /access/identity/entities/aliases/add', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | /access/identity/entities/aliases/add', function(hooks) { + setupApplicationTest(hooks); -test('it allows create, list, delete of an entity alias', function(assert) { - let name = `alias-${Date.now()}`; - testAliasCRUD(name, 'entities', assert); -}); + hooks.beforeEach(function() { + return authPage.login(); + }); -test('it allows delete from the edit form', function(assert) { - let name = `alias-${Date.now()}`; - testAliasDeleteFromForm(name, 'entities', assert); + test('it allows create, list, delete of an entity alias', async function(assert) { + let name = `alias-${Date.now()}`; + await testAliasCRUD(name, 'entities', assert); + }); + + test('it allows delete from the edit form', async function(assert) { + let name = `alias-${Date.now()}`; + await testAliasDeleteFromForm(name, 'entities', assert); + }); }); diff --git a/ui/tests/acceptance/access/identity/entities/create-test.js b/ui/tests/acceptance/access/identity/entities/create-test.js index fd953e750..f3ef99367 100644 --- a/ui/tests/acceptance/access/identity/entities/create-test.js +++ b/ui/tests/acceptance/access/identity/entities/create-test.js @@ -1,31 +1,33 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/access/identity/create'; import { testCRUD, testDeleteFromForm } from '../_shared-tests'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | /access/identity/entities/create', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | /access/identity/entities/create', function(hooks) { + setupApplicationTest(hooks); -test('it visits the correct page', function(assert) { - page.visit({ item_type: 'entities' }); - andThen(() => { + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it visits the correct page', async function(assert) { + await page.visit({ item_type: 'entities' }); assert.equal( currentRouteName(), 'vault.cluster.access.identity.create', 'navigates to the correct route' ); }); -}); -test('it allows create, list, delete of an entity', function(assert) { - let name = `entity-${Date.now()}`; - testCRUD(name, 'entities', assert); -}); + test('it allows create, list, delete of an entity', async function(assert) { + let name = `entity-${Date.now()}`; + await testCRUD(name, 'entities', assert); + }); -test('it can be deleted from the edit form', function(assert) { - let name = `entity-${Date.now()}`; - testDeleteFromForm(name, 'entities', assert); + test('it can be deleted from the edit form', async function(assert) { + let name = `entity-${Date.now()}`; + await testDeleteFromForm(name, 'entities', assert); + }); }); diff --git a/ui/tests/acceptance/access/identity/entities/index-test.js b/ui/tests/acceptance/access/identity/entities/index-test.js index e5190868d..d92fff433 100644 --- a/ui/tests/acceptance/access/identity/entities/index-test.js +++ b/ui/tests/acceptance/access/identity/entities/index-test.js @@ -1,23 +1,23 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/access/identity/index'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | /access/identity/entities', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | /access/identity/entities', function(hooks) { + setupApplicationTest(hooks); -test('it renders the entities page', function(assert) { - page.visit({ item_type: 'entities' }); - andThen(() => { - assert.equal(currentRouteName(), 'vault.cluster.access.identity.index', 'navigates to the correct route'); - }); -}); - -test('it renders the groups page', function(assert) { - page.visit({ item_type: 'groups' }); - andThen(() => { + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it renders the entities page', async function(assert) { + await page.visit({ item_type: 'entities' }); + assert.equal(currentRouteName(), 'vault.cluster.access.identity.index', 'navigates to the correct route'); + }); + + test('it renders the groups page', async function(assert) { + await page.visit({ item_type: 'groups' }); assert.equal(currentRouteName(), 'vault.cluster.access.identity.index', 'navigates to the correct route'); }); }); diff --git a/ui/tests/acceptance/access/identity/groups/aliases/create-test.js b/ui/tests/acceptance/access/identity/groups/aliases/create-test.js index 4a09df8be..139d8d6ca 100644 --- a/ui/tests/acceptance/access/identity/groups/aliases/create-test.js +++ b/ui/tests/acceptance/access/identity/groups/aliases/create-test.js @@ -1,19 +1,22 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import { testAliasCRUD, testAliasDeleteFromForm } from '../../_shared-alias-tests'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | /access/identity/groups/aliases/add', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | /access/identity/groups/aliases/add', function(hooks) { + setupApplicationTest(hooks); -test('it allows create, list, delete of an entity alias', function(assert) { - let name = `alias-${Date.now()}`; - testAliasCRUD(name, 'groups', assert); -}); + hooks.beforeEach(function() { + return authPage.login(); + }); -test('it allows delete from the edit form', function(assert) { - let name = `alias-${Date.now()}`; - testAliasDeleteFromForm(name, 'groups', assert); + test('it allows create, list, delete of an entity alias', async function(assert) { + let name = `alias-${Date.now()}`; + await testAliasCRUD(name, 'groups', assert); + }); + + test('it allows delete from the edit form', async function(assert) { + let name = `alias-${Date.now()}`; + await testAliasDeleteFromForm(name, 'groups', assert); + }); }); diff --git a/ui/tests/acceptance/access/identity/groups/create-test.js b/ui/tests/acceptance/access/identity/groups/create-test.js index 484f623d8..89e6f1d47 100644 --- a/ui/tests/acceptance/access/identity/groups/create-test.js +++ b/ui/tests/acceptance/access/identity/groups/create-test.js @@ -1,31 +1,33 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/access/identity/create'; import { testCRUD, testDeleteFromForm } from '../_shared-tests'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | /access/identity/groups/create', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | /access/identity/groups/create', function(hooks) { + setupApplicationTest(hooks); -test('it visits the correct page', function(assert) { - page.visit({ item_type: 'groups' }); - andThen(() => { + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it visits the correct page', async function(assert) { + await page.visit({ item_type: 'groups' }); assert.equal( currentRouteName(), 'vault.cluster.access.identity.create', 'navigates to the correct route' ); }); -}); -test('it allows create, list, delete of an group', function(assert) { - let name = `group-${Date.now()}`; - testCRUD(name, 'groups', assert); -}); + test('it allows create, list, delete of an group', async function(assert) { + let name = `group-${Date.now()}`; + await testCRUD(name, 'groups', assert); + }); -test('it can be deleted from the group edit form', function(assert) { - let name = `group-${Date.now()}`; - testDeleteFromForm(name, 'groups', assert); + test('it can be deleted from the group edit form', async function(assert) { + let name = `group-${Date.now()}`; + await testDeleteFromForm(name, 'groups', assert); + }); }); diff --git a/ui/tests/acceptance/access/methods-test.js b/ui/tests/acceptance/access/methods-test.js index d35c83211..d52bf92e7 100644 --- a/ui/tests/acceptance/access/methods-test.js +++ b/ui/tests/acceptance/access/methods-test.js @@ -1,18 +1,20 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/access/methods'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | /access/', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | /access/', function(hooks) { + setupApplicationTest(hooks); -test('it navigates', function(assert) { - page.visit(); - andThen(() => { + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it navigates', async function(assert) { + await page.visit(); assert.ok(currentRouteName(), 'vault.cluster.access.methods', 'navigates to the correct route'); - assert.ok(page.navLinks(0).isActive, 'the first link is active'); - assert.equal(page.navLinks(0).text, 'Auth Methods'); + assert.ok(page.navLinks.objectAt(0).isActive, 'the first link is active'); + assert.equal(page.navLinks.objectAt(0).text, 'Auth Methods'); }); }); diff --git a/ui/tests/acceptance/auth-test.js b/ui/tests/acceptance/auth-test.js index 1a9b14611..b15284abd 100644 --- a/ui/tests/acceptance/auth-test.js +++ b/ui/tests/acceptance/auth-test.js @@ -1,62 +1,60 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { click, currentURL, visit } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import { supportedAuthBackends } from 'vault/helpers/supported-auth-backends'; import authForm from '../pages/components/auth-form'; import { create } from 'ember-cli-page-object'; import apiStub from 'vault/tests/helpers/noop-all-api-requests'; +import logout from 'vault/tests/pages/logout'; const component = create(authForm); -moduleForAcceptance('Acceptance | auth', { - beforeEach() { - this.server = apiStub({ usePassthrough: true }); - return authLogout(); - }, - afterEach() { - this.server.shutdown(); - }, -}); +module('Acceptance | auth', function(hooks) { + setupApplicationTest(hooks); -test('auth query params', function(assert) { - const backends = supportedAuthBackends(); - visit('/vault/auth'); - andThen(() => { - assert.equal(currentURL(), '/vault/auth?with=token'); + hooks.beforeEach(function() { + this.server = apiStub({ usePassthrough: true }); + return logout.visit(); }); - backends.reverse().forEach(backend => { - click(`[data-test-auth-method-link="${backend.type}"]`); - andThen(() => { + + hooks.afterEach(function() { + this.server.shutdown(); + }); + + test('auth query params', async function(assert) { + let backends = supportedAuthBackends(); + await visit('/vault/auth'); + assert.equal(currentURL(), '/vault/auth?with=token'); + for (let backend of backends.reverse()) { + await click(`[data-test-auth-method-link="${backend.type}"]`); assert.equal( currentURL(), `/vault/auth?with=${backend.type}`, `has the correct URL for ${backend.type}` ); - }); + } }); -}); -test('it clears token when changing selected auth method', function(assert) { - visit('/vault/auth'); - andThen(() => { + test('it clears token when changing selected auth method', async function(assert) { + await visit('/vault/auth'); assert.equal(currentURL(), '/vault/auth?with=token'); - }); - component.token('token').tabs.filterBy('name', 'GitHub')[0].link(); - component.tabs.filterBy('name', 'Token')[0].link(); - andThen(() => { + await component + .token('token') + .tabs.filterBy('name', 'GitHub')[0] + .link(); + await component.tabs.filterBy('name', 'Token')[0].link(); assert.equal(component.tokenValue, '', 'it clears the token value when toggling methods'); }); -}); -test('it sends the right attributes when authenticating', function(assert) { - let backends = supportedAuthBackends(); - visit('/vault/auth'); - backends.reverse().forEach(backend => { - click(`[data-test-auth-method-link="${backend.type}"]`); - if (backend.type === 'github') { - component.token('token'); - } - component.login(); - andThen(() => { + test('it sends the right attributes when authenticating', async function(assert) { + let backends = supportedAuthBackends(); + await visit('/vault/auth'); + for (let backend of backends.reverse()) { + await click(`[data-test-auth-method-link="${backend.type}"]`); + if (backend.type === 'github') { + await component.token('token'); + } + await component.login(); let lastRequest = this.server.passthroughRequests[this.server.passthroughRequests.length - 1]; let body = JSON.parse(lastRequest.requestBody); if (backend.type === 'token') { @@ -69,6 +67,6 @@ test('it sends the right attributes when authenticating', function(assert) { } else { assert.ok(Object.keys(body).includes('password'), `${backend.type} includes password`); } - }); + } }); }); diff --git a/ui/tests/acceptance/aws-test.js b/ui/tests/acceptance/aws-test.js index 88c5ab932..1da097d41 100644 --- a/ui/tests/acceptance/aws-test.js +++ b/ui/tests/acceptance/aws-test.js @@ -1,102 +1,94 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { click, fillIn, findAll, currentURL, find, settled } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import authPage from 'vault/tests/pages/auth'; +import logout from 'vault/tests/pages/logout'; +import enablePage from 'vault/tests/pages/settings/mount-secret-backend'; +import withFlash from 'vault/tests/helpers/with-flash'; -moduleForAcceptance('Acceptance | aws secret backend', { - beforeEach() { - return authLogin(); - }, - afterEach() { - return authLogout(); - }, -}); +module('Acceptance | aws secret backend', function(hooks) { + setupApplicationTest(hooks); -const POLICY = { - Version: '2012-10-17', - Statement: [ - { - Effect: 'Allow', - Action: 'iam:*', - Resource: '*', - }, - ], -}; -test('aws backend', function(assert) { - const now = new Date().getTime(); - const path = `aws-${now}`; - const roleName = 'awsrole'; + hooks.beforeEach(function() { + return authPage.login(); + }); - mountSupportedSecretBackend(assert, 'aws', path); - click('[data-test-secret-backend-configure]'); - andThen(() => { + hooks.afterEach(function() { + return logout.visit(); + }); + + const POLICY = { + Version: '2012-10-17', + Statement: [ + { + Effect: 'Allow', + Action: 'iam:*', + Resource: '*', + }, + ], + }; + test('aws backend', async function(assert) { + const now = new Date().getTime(); + const path = `aws-${now}`; + const roleName = 'awsrole'; + + await enablePage.enable('aws', path); + + await click('[data-test-secret-backend-configure]'); assert.equal(currentURL(), `/vault/settings/secrets/configure/${path}`); - assert.ok(find('[data-test-aws-root-creds-form]').length, 'renders the empty root creds form'); - assert.ok(find('[data-test-aws-link="root-creds"]').length, 'renders the root creds link'); - assert.ok(find('[data-test-aws-link="leases"]').length, 'renders the leases config link'); - }); + assert.ok(findAll('[data-test-aws-root-creds-form]').length, 'renders the empty root creds form'); + assert.ok(findAll('[data-test-aws-link="root-creds"]').length, 'renders the root creds link'); + assert.ok(findAll('[data-test-aws-link="leases"]').length, 'renders the leases config link'); - fillIn('[data-test-aws-input="accessKey"]', 'foo'); - fillIn('[data-test-aws-input="secretKey"]', 'bar'); - click('[data-test-aws-input="root-save"]'); - andThen(() => { - assert.ok( - find('[data-test-flash-message]').text().trim(), - `The backend configuration saved successfully!` - ); - click('[data-test-flash-message]'); - }); - click('[data-test-aws-link="leases"]'); - click('[data-test-aws-input="lease-save"]'); + await fillIn('[data-test-aws-input="accessKey"]', 'foo'); + await fillIn('[data-test-aws-input="secretKey"]', 'bar'); - andThen(() => { - assert.ok( - find('[data-test-flash-message]').text().trim(), - `The backend configuration saved successfully!` - ); - click('[data-test-flash-message]'); - }); + await withFlash(click('[data-test-aws-input="root-save"]'), () => { + assert.ok( + find('[data-test-flash-message]').textContent.trim(), + `The backend configuration saved successfully!` + ); + }); - click('[data-test-backend-view-link]'); - //back at the roles list - andThen(() => { + await click('[data-test-aws-link="leases"]'); + await withFlash(click('[data-test-aws-input="lease-save"]'), () => { + assert.ok( + find('[data-test-flash-message]').textContent.trim(), + `The backend configuration saved successfully!` + ); + }); + + await click('[data-test-backend-view-link]'); assert.equal(currentURL(), `/vault/secrets/${path}/list`, `navigates to the roles list`); - }); - click('[ data-test-secret-create]'); - andThen(() => { - assert.ok(find('[data-test-secret-header]').text().includes('AWS Role'), `aws: renders the create page`); - }); + await click('[ data-test-secret-create]'); + assert.ok( + find('[data-test-secret-header]').textContent.includes('AWS Role'), + `aws: renders the create page` + ); - fillIn('[data-test-input="name"]', roleName); - andThen(function() { - find('.CodeMirror').get(0).CodeMirror.setValue(JSON.stringify(POLICY)); - }); + await fillIn('[data-test-input="name"]', roleName); + findAll('.CodeMirror')[0].CodeMirror.setValue(JSON.stringify(POLICY)); - // save the role - click('[data-test-role-aws-create]'); - andThen(() => { + // save the role + await click('[data-test-role-aws-create]'); assert.equal( currentURL(), `/vault/secrets/${path}/show/${roleName}`, `$aws: navigates to the show page on creation` ); - }); - click('[data-test-secret-root-link]'); + await click('[data-test-secret-root-link]'); - //back at the roles list - andThen(() => { assert.equal(currentURL(), `/vault/secrets/${path}/list`); - assert.ok(find(`[data-test-secret-link="${roleName}"]`).length, `aws: role shows in the list`); - }); + assert.ok(findAll(`[data-test-secret-link="${roleName}"]`).length, `aws: role shows in the list`); - //and delete - click(`[data-test-secret-link="${roleName}"] [data-test-popup-menu-trigger]`); - andThen(() => { - click(`[data-test-aws-role-delete="${roleName}"] button`); - }); - click(`[data-test-confirm-button]`); + //and delete + await click(`[data-test-secret-link="${roleName}"] [data-test-popup-menu-trigger]`); + await click(`[data-test-aws-role-delete="${roleName}"] button`); - andThen(() => { + await withFlash(click(`[data-test-confirm-button]`)); + await settled(); assert.dom(`[data-test-secret-link="${roleName}"]`).doesNotExist(`aws: role is no longer in the list`); }); }); diff --git a/ui/tests/acceptance/console-test.js b/ui/tests/acceptance/console-test.js index b9b58275e..4c8db0a24 100644 --- a/ui/tests/acceptance/console-test.js +++ b/ui/tests/acceptance/console-test.js @@ -1,31 +1,25 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import enginesPage from 'vault/tests/pages/secrets/backends'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | console', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | console', function(hooks) { + setupApplicationTest(hooks); -test('refresh reloads the current route\'s data', function(assert) { - let numEngines; - enginesPage.visit(); - andThen(() => { - numEngines = enginesPage.rows().count; - enginesPage.consoleToggle(); + hooks.beforeEach(function() { + return authPage.login(); + }); + + test("refresh reloads the current route's data", async function(assert) { + await enginesPage.visit(); + let numEngines = enginesPage.rows.length; + await enginesPage.consoleToggle(); let now = Date.now(); - [1, 2, 3].forEach(num => { + for (let num of [1, 2, 3]) { let inputString = `write sys/mounts/${now + num} type=kv`; - enginesPage.console.consoleInput(inputString); - enginesPage.console.enter(); - }); - }); - andThen(() => { - enginesPage.console.consoleInput('refresh'); - enginesPage.console.enter(); - }); - andThen(() => { - assert.equal(enginesPage.rows().count, numEngines + 3, 'new engines were added to the page'); + await enginesPage.console.runCommands(inputString); + } + await enginesPage.console.runCommands('refresh'); + assert.equal(enginesPage.rows.length, numEngines + 3, 'new engines were added to the page'); }); }); diff --git a/ui/tests/acceptance/enterprise-control-groups-test.js b/ui/tests/acceptance/enterprise-control-groups-test.js index f1cf548b9..e45e505a1 100644 --- a/ui/tests/acceptance/enterprise-control-groups-test.js +++ b/ui/tests/acceptance/enterprise-control-groups-test.js @@ -1,58 +1,64 @@ -import { test } from 'qunit'; +import { currentURL, currentRouteName, visit } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import { create } from 'ember-cli-page-object'; import { storageKey } from 'vault/services/control-group'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; -import console from 'vault/tests/pages/components/console/ui-panel'; +import consoleClass from 'vault/tests/pages/components/console/ui-panel'; import authForm from 'vault/tests/pages/components/auth-form'; import controlGroup from 'vault/tests/pages/components/control-group'; import controlGroupSuccess from 'vault/tests/pages/components/control-group-success'; +import authPage from 'vault/tests/pages/auth'; +import logout from 'vault/tests/pages/logout'; -const consoleComponent = create(console); +const consoleComponent = create(consoleClass); const authFormComponent = create(authForm); const controlGroupComponent = create(controlGroup); const controlGroupSuccessComponent = create(controlGroupSuccess); -moduleForAcceptance('Acceptance | Enterprise | control groups', { - beforeEach() { - return authLogin(); - }, - afterEach() { - return authLogout(); - }, -}); -const POLICY = `' - path "kv/foo" { - capabilities = ["create", "read", "update", "delete", "list"] - control_group = { - max_ttl = "24h" - factor "ops_manager" { - identity { - group_names = ["managers"] - approvals = 1 - } - } + +module('Acceptance | Enterprise | control groups', function(hooks) { + setupApplicationTest(hooks); + + hooks.beforeEach(function() { + return authPage.login(); + }); + + hooks.afterEach(function() { + return logout.visit(); + }); + + const POLICY = `' + path "kv/foo" { + capabilities = ["create", "read", "update", "delete", "list"] + control_group = { + max_ttl = "24h" + factor "ops_manager" { + identity { + group_names = ["managers"] + approvals = 1 + } + } + } } - } -'`; + '`; -const AUTHORIZER_POLICY = `' - path "sys/control-group/authorize" { - capabilities = ["update"] - } + const AUTHORIZER_POLICY = `' + path "sys/control-group/authorize" { + capabilities = ["update"] + } - path "sys/control-group/request" { - capabilities = ["update"] - } -'`; + path "sys/control-group/request" { + capabilities = ["update"] + } + '`; -const ADMIN_USER = 'authorizer'; -const ADMIN_PASSWORD = 'test'; -const setupControlGroup = context => { - let userpassAccessor; - visit('/vault/secrets'); - consoleComponent.toggle(); - andThen(() => { - consoleComponent.runCommands([ + const ADMIN_USER = 'authorizer'; + const ADMIN_PASSWORD = 'test'; + const setupControlGroup = async context => { + let userpassAccessor; + await visit('/vault/secrets'); + await consoleComponent.toggle(); + await consoleComponent.runCommands([ //enable kv mount and write some data 'write sys/mounts/kv type=kv', 'write kv/foo bar=baz', @@ -66,90 +72,62 @@ const setupControlGroup = context => { // read out mount to get the accessor 'read -field=accessor sys/internal/ui/mounts/auth/userpass', ]); - }); - andThen(() => { userpassAccessor = consoleComponent.lastTextOutput; - consoleComponent.runCommands([ + await consoleComponent.runCommands([ // lookup entity id for our authorizer `write -field=id identity/lookup/entity name=${ADMIN_USER}`, ]); - }); - - andThen(() => { let authorizerEntityId = consoleComponent.lastTextOutput; - consoleComponent.runCommands([ + await consoleComponent.runCommands([ // create alias for authorizor and add them to the managers group `write identity/alias mount_accessor=${userpassAccessor} entity_id=${authorizerEntityId} name=${ADMIN_USER}`, `write identity/group name=managers member_entity_ids=${authorizerEntityId} policies=authorizer`, // create a token to request access to kv/foo 'write -field=client_token auth/token/create policies=kv-control-group', ]); - }); - - andThen(() => { context.userToken = consoleComponent.lastLogOutput; - }); - authLogout(); - andThen(() => { - authLogin(context.userToken); - }); -}; + await logout.visit(); + await authPage.login(context.userToken); + return this; + }; -test('it redirects you if you try to navigate to a Control Group restricted path', function(assert) { - setupControlGroup(this); - visit('/vault/secrets/kv/show/foo'); - andThen(() => { + test('it redirects you if you try to navigate to a Control Group restricted path', async function(assert) { + await setupControlGroup(this); + await visit('/vault/secrets/kv/show/foo'); assert.equal( - currentPath(), + currentRouteName(), 'vault.cluster.access.control-group-accessor', 'redirects to access control group route' ); }); -}); -const workflow = (assert, context, shouldStoreToken) => { - let controlGroupToken; - let accessor; - let url = '/vault/secrets/kv/show/foo'; - setupControlGroup(context); + const workflow = async (assert, context, shouldStoreToken) => { + let controlGroupToken; + let accessor; + let url = '/vault/secrets/kv/show/foo'; + await setupControlGroup(context); - // as the requestor, go to the URL that's blocked by the control group - // and store the values - visit(url); - andThen(() => { + // as the requestor, go to the URL that's blocked by the control group + // and store the values + await visit(url); accessor = controlGroupComponent.accessor; controlGroupToken = controlGroupComponent.token; - }); - authLogout(); + await logout.visit(); - // log in as the admin, navigate to the accessor page, - // and authorize the control group request - visit('/vault/auth?with=userpass'); - andThen(() => { - authFormComponent.username(ADMIN_USER); - authFormComponent.password(ADMIN_PASSWORD); - authFormComponent.login(); - }); - andThen(() => { - visit(`/vault/access/control-groups/${accessor}`); - }); - andThen(() => { - controlGroupComponent.authorize(); - }); - andThen(() => { + // log in as the admin, navigate to the accessor page, + // and authorize the control group request + await visit('/vault/auth?with=userpass'); + await authFormComponent.username(ADMIN_USER); + await authFormComponent.password(ADMIN_PASSWORD); + await authFormComponent.login(); + await visit(`/vault/access/control-groups/${accessor}`); + await controlGroupComponent.authorize(); assert.equal(controlGroupComponent.bannerPrefix, 'Thanks!', 'text display changes'); - }); - authLogout(); + await logout.visit(); - // log _back_ in as the requestor - andThen(() => { - authLogin(context.userToken); - }); + await authPage.login(context.userToken); - if (shouldStoreToken) { - // stuff localStorage full of the necessary details - // so that they can nav back to the control group'd path in the UI - andThen(() => { + if (shouldStoreToken) { localStorage.setItem( storageKey(accessor, 'kv/foo'), JSON.stringify({ @@ -161,50 +139,30 @@ const workflow = (assert, context, shouldStoreToken) => { }, }) ); - }); - andThen(() => { - visit(`/vault/access/control-groups/${accessor}`); - }); - andThen(() => { + await visit(`/vault/access/control-groups/${accessor}`); assert.ok(controlGroupSuccessComponent.showsNavigateMessage, 'shows user the navigate message'); - }); - controlGroupSuccessComponent.navigate(); - andThen(() => { + await controlGroupSuccessComponent.navigate(); assert.equal(currentURL(), url, 'successfully loads the target url'); - }); - } else { - andThen(() => { - visit(`/vault/access/control-groups/${accessor}`); - }); - andThen(() => { - controlGroupSuccessComponent.token(controlGroupToken); - controlGroupSuccessComponent.unwrap(); - }); - andThen(() => { + } else { + await visit(`/vault/access/control-groups/${accessor}`); + await controlGroupSuccessComponent.token(controlGroupToken); + await controlGroupSuccessComponent.unwrap(); assert.ok(controlGroupSuccessComponent.showsJsonViewer, 'shows the json viewer'); - }); - } -}; + } + }; -test('it allows the full flow to work with a saved token', function(assert) { - workflow(assert, this, true); -}); - -test('it allows the full flow to work without a saved token', function(assert) { - workflow(assert, this); -}); - -test('it displays the warning in the console when making a request to a Control Group path', function( - assert -) { - setupControlGroup(this); - andThen(() => { - consoleComponent.toggle(); + test('it allows the full flow to work with a saved token', async function(assert) { + await workflow(assert, this, true); }); - andThen(() => { - consoleComponent.runCommands('read kv/foo'); + + test('it allows the full flow to work without a saved token', async function(assert) { + await workflow(assert, this); }); - andThen(() => { + + test('it displays the warning in the console when making a request to a Control Group path', async function(assert) { + await setupControlGroup(this); + await consoleComponent.toggle(); + await consoleComponent.runCommands('read kv/foo'); let output = consoleComponent.lastLogOutput; assert.ok(output.includes('A Control Group was encountered at kv/foo')); assert.ok(output.includes('The Control Group Token is')); diff --git a/ui/tests/acceptance/enterprise-replication-test.js b/ui/tests/acceptance/enterprise-replication-test.js index d722475dc..f25e4300f 100644 --- a/ui/tests/acceptance/enterprise-replication-test.js +++ b/ui/tests/acceptance/enterprise-replication-test.js @@ -1,191 +1,162 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { click, fillIn, findAll, currentURL, find, visit, settled } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import authPage from 'vault/tests/pages/auth'; +import { pollCluster } from 'vault/tests/helpers/poll-cluster'; +import withFlash from 'vault/tests/helpers/with-flash'; -const disableReplication = (type, assert) => { +const disableReplication = async (type, assert) => { // disable performance replication - visit(`/vault/replication/${type}`); - return andThen(() => { - if (find('[data-test-replication-link="manage"]').length) { - click('[data-test-replication-link="manage"]'); - click('[data-test-disable-replication] button'); - click('[data-test-confirm-button]'); + await visit(`/vault/replication/${type}`); + if (findAll('[data-test-replication-link="manage"]').length) { + await click('[data-test-replication-link="manage"]'); + await click('[data-test-disable-replication] button'); + await withFlash(click('[data-test-confirm-button]'), () => { if (assert) { - andThen(() => { - assert.equal(currentURL(), `/vault/replication/${type}`, 'redirects to the replication page'); - assert.equal( - // TODO better test selectors for flash messages - find('[data-test-flash-message-body]:contains(This cluster is having)').text().trim(), - 'This cluster is having replication disabled. Vault will be unavailable for a brief period and will resume service shortly.', - 'renders info flash when disabled' - ); - click('[data-test-flash-message-body]:contains(This cluster is having)'); - }); + assert.equal(currentURL(), `/vault/replication/${type}/manage`, 'redirects to the replication page'); + assert.equal( + // TODO better test selectors for flash messages + find('[data-test-flash-message-body]').textContent.trim(), + 'This cluster is having replication disabled. Vault will be unavailable for a brief period and will resume service shortly.', + 'renders info flash when disabled' + ); } - } else { - // do nothing, it's already off - } - }); + }); + await settled(); + } }; -moduleForAcceptance('Acceptance | Enterprise | replication', { - beforeEach() { - authLogin(); - disableReplication('dr'); - return disableReplication('performance'); - }, - afterEach() { - disableReplication('dr'); - return disableReplication('performance'); - }, -}); -test('replication', function(assert) { - const secondaryName = 'firstSecondary'; - const mode = 'blacklist'; - const mountType = 'kv'; - let mountPath; +module('Acceptance | Enterprise | replication', function(hooks) { + setupApplicationTest(hooks); - visit('/vault/replication'); - andThen(function() { + hooks.beforeEach(async function() { + await authPage.login(); + await disableReplication('dr'); + return disableReplication('performance'); + }); + + hooks.afterEach(async function() { + await disableReplication('dr'); + return disableReplication('performance'); + }); + + test('replication', async function(assert) { + const secondaryName = 'firstSecondary'; + const mode = 'blacklist'; + const mountType = 'kv'; + let mountPath; + + await visit('/vault/replication'); assert.equal(currentURL(), '/vault/replication'); - }); - // enable perf replication - click('[data-test-replication-type-select="performance"]'); - fillIn('[data-test-replication-cluster-mode-select]', 'primary'); + // enable perf replication + await click('[data-test-replication-type-select="performance"]'); + await fillIn('[data-test-replication-cluster-mode-select]', 'primary'); - click('[data-test-replication-enable]'); - andThen(() => { - pollCluster(); - }); + await withFlash(click('[data-test-replication-enable]')); + await pollCluster(this.owner); - // add a secondary with a mount filter config - click('[data-test-replication-link="secondaries"]'); - click('[data-test-secondary-add]'); - fillIn('[data-test-replication-secondary-id]', secondaryName); - //expand the config - click('[data-test-replication-secondary-token-options]'); - fillIn('[data-test-replication-filter-mount-mode]', mode); - click(`[data-test-mount-filter="${mountType}"]:eq(0)`); - andThen(() => { - mountPath = find(`[data-test-mount-filter-path-for-type="${mountType}"]`).first().text().trim(); - }); - click('[data-test-secondary-add]'); + // add a secondary with a mount filter config + await click('[data-test-replication-link="secondaries"]'); + await click('[data-test-secondary-add]'); + await fillIn('[data-test-replication-secondary-id]', secondaryName); + //expand the config + await click('[data-test-replication-secondary-token-options]'); + await fillIn('[data-test-replication-filter-mount-mode]', mode); + await click(findAll(`[data-test-mount-filter="${mountType}"]`)[0]); + mountPath = findAll(`[data-test-mount-filter-path-for-type="${mountType}"]`)[0].textContent.trim(); + await click('[data-test-secondary-add]'); - // fetch new secondaries - andThen(() => { - pollCluster(); - }); + await pollCluster(this.owner); - // click into the added secondary's mount filter config - click('[data-test-replication-link="secondaries"]'); - click('[data-test-popup-menu-trigger]'); + // click into the added secondary's mount filter config + await click('[data-test-replication-link="secondaries"]'); + await click('[data-test-popup-menu-trigger]'); - click('[data-test-replication-mount-filter-link]'); - andThen(() => { + await click('[data-test-replication-mount-filter-link]'); assert.equal(currentURL(), `/vault/replication/performance/secondaries/config/show/${secondaryName}`); assert.ok( - find('[data-test-mount-config-mode]').text().trim().toLowerCase().includes(mode), + find('[data-test-mount-config-mode]') + .textContent.trim() + .toLowerCase() + .includes(mode), 'show page renders the correct mode' ); assert .dom('[data-test-mount-config-paths]') .hasText(mountPath, 'show page renders the correct mount path'); - }); - // click edit + // click edit - // delete config - click('[data-test-replication-link="edit-mount-config"]'); - click('[data-test-delete-mount-config] button'); - click('[data-test-confirm-button]'); - andThen(() => { + // delete config + await click('[data-test-replication-link="edit-mount-config"]'); + await click('[data-test-delete-mount-config] button'); + await withFlash(click('[data-test-confirm-button]'), () => { + assert.equal( + findAll('[data-test-flash-message-body]')[0].textContent.trim(), + `The performance mount filter config for the secondary ${secondaryName} was successfully deleted.`, + 'renders success flash upon deletion' + ); + }); assert.equal( currentURL(), `/vault/replication/performance/secondaries`, 'redirects to the secondaries page' ); - assert.equal( - find('[data-test-flash-message-body]:contains(The performance mount filter)').text().trim(), - `The performance mount filter config for the secondary ${secondaryName} was successfully deleted.`, - 'renders success flash upon deletion' - ); - click('[data-test-flash-message-body]:contains(The performance mount filter)'); - }); - // nav to DR - visit('/vault/replication/dr'); - fillIn('[data-test-replication-cluster-mode-select]', 'secondary'); - andThen(() => { + // nav to DR + await visit('/vault/replication/dr'); + await fillIn('[data-test-replication-cluster-mode-select]', 'secondary'); assert.ok( - find('[data-test-replication-enable]').is(':disabled'), + find('[data-test-replication-enable]:disabled'), 'dr secondary enable is disabled when other replication modes are on' ); - }); - // disable performance replication - disableReplication('replication', assert); + // disable performance replication + await disableReplication('performance', assert); + await pollCluster(this.owner); - // enable dr replication - visit('/vault/replication/dr'); - fillIn('[data-test-replication-cluster-mode-select]', 'primary'); - click('button[type="submit"]'); - andThen(() => { - pollCluster(); - }); - andThen(() => { + // enable dr replication + await visit('vault/replication/dr'); + await fillIn('[data-test-replication-cluster-mode-select]', 'primary'); + await withFlash(click('button[type="submit"]')); + + await pollCluster(this.owner); assert.ok( - find('[data-test-replication-title]').text().includes('Disaster Recovery'), + find('[data-test-replication-title]').textContent.includes('Disaster Recovery'), 'it displays the replication type correctly' ); assert.ok( - find('[data-test-replication-mode-display]').text().includes('primary'), + find('[data-test-replication-mode-display]').textContent.includes('primary'), 'it displays the cluster mode correctly' ); - }); - // add dr secondary - click('[data-test-replication-link="secondaries"]'); - click('[data-test-secondary-add]'); - fillIn('[data-test-replication-secondary-id]', secondaryName); - click('[data-test-secondary-add]'); - andThen(() => { - pollCluster(); - }); - click('[data-test-replication-link="secondaries"]'); - andThen(() => { + // add dr secondary + await click('[data-test-replication-link="secondaries"]'); + await click('[data-test-secondary-add]'); + await fillIn('[data-test-replication-secondary-id]', secondaryName); + await click('[data-test-secondary-add]'); + await pollCluster(this.owner); + await pollCluster(this.owner); + await click('[data-test-replication-link="secondaries"]'); assert .dom('[data-test-secondary-name]') .hasText(secondaryName, 'it displays the secondary in the list of known secondaries'); }); - // disable dr replication - disableReplication('dr', assert); - return wait(); -}); - -test('disabling dr primary when perf replication is enabled', function(assert) { - visit('/vault/replication/performance'); - // enable perf replication - fillIn('[data-test-replication-cluster-mode-select]', 'primary'); - - click('[data-test-replication-enable]'); - andThen(() => { - pollCluster(); - }); - - // enable dr replication - visit('/vault/replication/dr'); - fillIn('[data-test-replication-cluster-mode-select]', 'primary'); - click('[data-test-replication-enable]'); - andThen(() => { - pollCluster(); - }); - visit('/vault/replication/dr/manage'); - andThen(() => { - assert.ok(find('[data-test-demote-warning]').length, 'displays the demotion warning'); - }); - - // disable replication - disableReplication('performance', assert); - disableReplication('dr', assert); - return wait(); + test('disabling dr primary when perf replication is enabled', async function(assert) { + await visit('vault/replication/performance'); + // enable perf replication + await fillIn('[data-test-replication-cluster-mode-select]', 'primary'); + + await withFlash(click('[data-test-replication-enable]')); + await pollCluster(this.owner); + + // enable dr replication + await visit('/vault/replication/dr'); + await fillIn('[data-test-replication-cluster-mode-select]', 'primary'); + await withFlash(click('[data-test-replication-enable]')); + await pollCluster(this.owner); + await visit('/vault/replication/dr/manage'); + assert.ok(findAll('[data-test-demote-warning]').length, 'displays the demotion warning'); + }); }); diff --git a/ui/tests/acceptance/leases-test.js b/ui/tests/acceptance/leases-test.js index 9ef3e7248..1843dcf35 100644 --- a/ui/tests/acceptance/leases-test.js +++ b/ui/tests/acceptance/leases-test.js @@ -1,57 +1,58 @@ +import { click, currentRouteName, visit } from '@ember/test-helpers'; // TESTS HERE ARE SKPPED // running vault with -dev-leased-kv flag lets you run some of these tests // but generating leases programmatically is currently difficult // // TODO revisit this when it's easier to create leases -import { skip } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { module, skip } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import secretList from 'vault/tests/pages/secrets/backend/list'; import secretEdit from 'vault/tests/pages/secrets/backend/kv/edit-secret'; import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend'; -import Ember from 'ember'; +import authPage from 'vault/tests/pages/auth'; +import logout from 'vault/tests/pages/logout'; -let adapterException; -// testing error states is terrible in ember acceptance tests so these weird Ember bits are to work around that -// adapted from https://github.com/emberjs/ember.js/issues/12791#issuecomment-244934786 -moduleForAcceptance('Acceptance | leases', { - beforeEach() { - adapterException = Ember.Test.adapter.exception; - Ember.Test.adapter.exception = () => null; +module('Acceptance | leases', function(hooks) { + setupApplicationTest(hooks); - authLogin(); + hooks.beforeEach(async function() { + await authPage.login(); this.enginePath = `kv-for-lease-${new Date().getTime()}`; // need a version 1 mount for leased secrets here - return mountSecrets.visit().path(this.enginePath).type('kv').version(1).submit(); - }, - afterEach() { - Ember.Test.adapter.exception = adapterException; - return authLogout(); - }, -}); + return mountSecrets + .visit() + .path(this.enginePath) + .type('kv') + .version(1) + .submit(); + }); -const createSecret = (context, isRenewable) => { - context.name = `secret-${new Date().getTime()}`; - secretList.visitRoot({ backend: context.enginePath }); - secretList.create(); - if (isRenewable) { - secretEdit.createSecret(context.name, 'ttl', '30h'); - } else { - secretEdit.createSecret(context.name, 'foo', 'bar'); - } -}; + hooks.afterEach(function() { + return logout.visit(); + }); -const navToDetail = context => { - visit('/vault/access/leases/'); - click(`[data-test-lease-link="${context.enginePath}/"]`); - click(`[data-test-lease-link="${context.enginePath}/${context.name}/"]`); - click(`[data-test-lease-link]:eq(0)`); -}; + const createSecret = async (context, isRenewable) => { + context.name = `secret-${new Date().getTime()}`; + await secretList.visitRoot({ backend: context.enginePath }); + await secretList.create(); + if (isRenewable) { + await secretEdit.createSecret(context.name, 'ttl', '30h'); + } else { + await secretEdit.createSecret(context.name, 'foo', 'bar'); + } + }; -skip('it renders the show page', function(assert) { - createSecret(this); - navToDetail(this); - return andThen(() => { + const navToDetail = async context => { + await visit('/vault/access/leases/'); + await click(`[data-test-lease-link="${context.enginePath}/"]`); + await click(`[data-test-lease-link="${context.enginePath}/${context.name}/"]`); + await click(`[data-test-lease-link]:eq(0)`); + }; + + skip('it renders the show page', function(assert) { + createSecret(this); + navToDetail(this); assert.equal( currentRouteName(), 'vault.cluster.access.leases.show', @@ -61,13 +62,11 @@ skip('it renders the show page', function(assert) { .dom('[data-test-lease-renew-picker]') .doesNotExist('non-renewable lease does not render a renew picker'); }); -}); -// skip for now until we find an easy way to generate a renewable lease -skip('it renders the show page with a picker', function(assert) { - createSecret(this, true); - navToDetail(this); - andThen(() => { + // skip for now until we find an easy way to generate a renewable lease + skip('it renders the show page with a picker', function(assert) { + createSecret(this, true); + navToDetail(this); assert.equal( currentRouteName(), 'vault.cluster.access.leases.show', @@ -77,35 +76,29 @@ skip('it renders the show page with a picker', function(assert) { .dom('[data-test-lease-renew-picker]') .exists({ count: 1 }, 'renewable lease renders a renew picker'); }); -}); -skip('it removes leases upon revocation', function(assert) { - createSecret(this); - navToDetail(this); - click('[data-test-lease-revoke] button'); - click('[data-test-confirm-button]'); - andThen(() => { + skip('it removes leases upon revocation', async function(assert) { + createSecret(this); + navToDetail(this); + await click('[data-test-lease-revoke] button'); + await click('[data-test-confirm-button]'); assert.equal( currentRouteName(), 'vault.cluster.access.leases.list-root', 'it navigates back to the leases root on revocation' ); - }); - click(`[data-test-lease-link="${this.enginePath}/"]`); - click('[data-test-lease-link="data/"]'); - andThen(() => { + await click(`[data-test-lease-link="${this.enginePath}/"]`); + await click('[data-test-lease-link="data/"]'); assert .dom(`[data-test-lease-link="${this.enginePath}/data/${this.name}/"]`) .doesNotExist('link to the lease was removed with revocation'); }); -}); -skip('it removes branches when a prefix is revoked', function(assert) { - createSecret(this); - visit(`/vault/access/leases/list/${this.enginePath}`); - click('[data-test-lease-revoke-prefix] button'); - click('[data-test-confirm-button]'); - andThen(() => { + skip('it removes branches when a prefix is revoked', async function(assert) { + createSecret(this); + await visit(`/vault/access/leases/list/${this.enginePath}`); + await click('[data-test-lease-revoke-prefix] button'); + await click('[data-test-confirm-button]'); assert.equal( currentRouteName(), 'vault.cluster.access.leases.list-root', @@ -115,11 +108,9 @@ skip('it removes branches when a prefix is revoked', function(assert) { .dom(`[data-test-lease-link="${this.enginePath}/"]`) .doesNotExist('link to the prefix was removed with revocation'); }); -}); -skip('lease not found', function(assert) { - visit('/vault/access/leases/show/not-found'); - andThen(() => { + skip('lease not found', async function(assert) { + await visit('/vault/access/leases/show/not-found'); assert .dom('[data-test-lease-error]') .hasText('not-found is not a valid lease ID', 'it shows an error when the lease is not found'); diff --git a/ui/tests/acceptance/not-found-test.js b/ui/tests/acceptance/not-found-test.js index ec19b2845..2d8b60b05 100644 --- a/ui/tests/acceptance/not-found-test.js +++ b/ui/tests/acceptance/not-found-test.js @@ -1,52 +1,53 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { findAll, visit } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import authPage from 'vault/tests/pages/auth'; +import logout from 'vault/tests/pages/logout'; import Ember from 'ember'; let adapterException; let loggerError; -moduleForAcceptance('Acceptance | not-found', { - beforeEach() { +module('Acceptance | not-found', function(hooks) { + setupApplicationTest(hooks); + + hooks.beforeEach(function() { loggerError = Ember.Logger.error; adapterException = Ember.Test.adapter.exception; Ember.Test.adapter.exception = () => {}; Ember.Logger.error = () => {}; - return authLogin(); - }, - afterEach() { + return authPage.login(); + }); + + hooks.afterEach(function() { Ember.Test.adapter.exception = adapterException; Ember.Logger.error = loggerError; - return authLogout(); - }, -}); - -test('top-level not-found', function(assert) { - visit('/404'); - andThen(() => { - assert.ok(find('[data-test-not-found]').length, 'renders the not found component'); - assert.ok(find('[data-test-header-without-nav]').length, 'renders the not found component with a header'); + return logout.visit(); }); -}); -test('vault route not-found', function(assert) { - visit('/vault/404'); - andThen(() => { + test('top-level not-found', async function(assert) { + await visit('/404'); + assert.ok(findAll('[data-test-not-found]').length, 'renders the not found component'); + assert.ok( + findAll('[data-test-header-without-nav]').length, + 'renders the not found component with a header' + ); + }); + + test('vault route not-found', async function(assert) { + await visit('/vault/404'); assert.dom('[data-test-not-found]').exists('renders the not found component'); - assert.ok(find('[data-test-header-with-nav]').length, 'renders header with nav'); + assert.ok(findAll('[data-test-header-with-nav]').length, 'renders header with nav'); }); -}); -test('cluster route not-found', function(assert) { - visit('/vault/secrets/secret/404/show'); - andThen(() => { + test('cluster route not-found', async function(assert) { + await visit('/vault/secrets/secret/404/show'); assert.dom('[data-test-not-found]').exists('renders the not found component'); - assert.ok(find('[data-test-header-with-nav]').length, 'renders header with nav'); + assert.ok(findAll('[data-test-header-with-nav]').length, 'renders header with nav'); }); -}); -test('secret not-found', function(assert) { - visit('/vault/secrets/secret/show/404'); - andThen(() => { + test('secret not-found', async function(assert) { + await visit('/vault/secrets/secret/show/404'); assert.dom('[data-test-secret-not-found]').exists('renders the message about the secret not being found'); }); }); diff --git a/ui/tests/acceptance/policies-acl-old-test.js b/ui/tests/acceptance/policies-acl-old-test.js index 65195689c..db7f670d3 100644 --- a/ui/tests/acceptance/policies-acl-old-test.js +++ b/ui/tests/acceptance/policies-acl-old-test.js @@ -1,41 +1,30 @@ -import Ember from 'ember'; -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { click, fillIn, findAll, currentURL } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/policies/index'; +import authPage from 'vault/tests/pages/auth'; -let adapterException; -let loggerError; -moduleForAcceptance('Acceptance | policies (old)', { - beforeEach() { - loggerError = Ember.Logger.error; - adapterException = Ember.Test.adapter.exception; - Ember.Test.adapter.exception = () => {}; - Ember.Logger.error = () => {}; - return authLogin(); - }, - afterEach() { - Ember.Test.adapter.exception = adapterException; - Ember.Logger.error = loggerError; - }, -}); +module('Acceptance | policies (old)', function(hooks) { + setupApplicationTest(hooks); -test('policies', function(assert) { - const now = new Date().getTime(); - const policyString = 'path "*" { capabilities = ["update"]}'; - const policyName = `Policy test ${now}`; - const policyLower = policyName.toLowerCase(); - - page.visit({ type: 'acl' }); - // new policy creation - click('[data-test-policy-create-link]'); - fillIn('[data-test-policy-input="name"]', policyName); - click('[data-test-policy-save]'); - andThen(function() { - assert.dom('[data-test-error]').exists({ count: 1 }, 'renders error messages on save'); - find('.CodeMirror').get(0).CodeMirror.setValue(policyString); + hooks.beforeEach(function() { + return authPage.login(); }); - click('[data-test-policy-save]'); - andThen(function() { + + test('policies', async function(assert) { + const now = new Date().getTime(); + const policyString = 'path "*" { capabilities = ["update"]}'; + const policyName = `Policy test ${now}`; + const policyLower = policyName.toLowerCase(); + + await page.visit({ type: 'acl' }); + // new policy creation + await click('[data-test-policy-create-link]'); + await fillIn('[data-test-policy-input="name"]', policyName); + await click('[data-test-policy-save]'); + assert.dom('[data-test-error]').exists({ count: 1 }, 'renders error messages on save'); + findAll('.CodeMirror')[0].CodeMirror.setValue(policyString); + await click('[data-test-policy-save]'); assert.equal( currentURL(), `/vault/policy/acl/${encodeURIComponent(policyLower)}`, @@ -43,42 +32,34 @@ test('policies', function(assert) { ); assert.dom('[data-test-policy-name]').hasText(policyLower, 'displays the policy name on the show page'); assert.dom('[data-test-flash-message].is-info').doesNotExist('no flash message is displayed on save'); - }); - click('[data-test-policy-list-link]'); - andThen(function() { + await click('[data-test-policy-list-link]'); assert .dom(`[data-test-policy-link="${policyLower}"]`) .exists({ count: 1 }, 'new policy shown in the list'); - }); - // policy deletion - click(`[data-test-policy-link="${policyLower}"]`); - click('[data-test-policy-edit-toggle]'); - click('[data-test-policy-delete] button'); - click('[data-test-confirm-button]'); - andThen(function() { + // policy deletion + await click(`[data-test-policy-link="${policyLower}"]`); + await click('[data-test-policy-edit-toggle]'); + await click('[data-test-policy-delete] button'); + await click('[data-test-confirm-button]'); assert.equal(currentURL(), `/vault/policies/acl`, 'navigates to policy list on successful deletion'); assert .dom(`[data-test-policy-item="${policyLower}"]`) .doesNotExist('deleted policy is not shown in the list'); }); -}); -// https://github.com/hashicorp/vault/issues/4395 -test('it properly fetches policies when the name ends in a ,', function(assert) { - const now = new Date().getTime(); - const policyString = 'path "*" { capabilities = ["update"]}'; - const policyName = `${now}-symbol,.`; + // https://github.com/hashicorp/vault/issues/4395 + test('it properly fetches policies when the name ends in a ,', async function(assert) { + const now = new Date().getTime(); + const policyString = 'path "*" { capabilities = ["update"]}'; + const policyName = `${now}-symbol,.`; - page.visit({ type: 'acl' }); - // new policy creation - click('[data-test-policy-create-link]'); - fillIn('[data-test-policy-input="name"]', policyName); - andThen(function() { - find('.CodeMirror').get(0).CodeMirror.setValue(policyString); - }); - click('[data-test-policy-save]'); - andThen(function() { + await page.visit({ type: 'acl' }); + // new policy creation + await click('[data-test-policy-create-link]'); + await fillIn('[data-test-policy-input="name"]', policyName); + findAll('.CodeMirror')[0].CodeMirror.setValue(policyString); + await click('[data-test-policy-save]'); assert.equal( currentURL(), `/vault/policy/acl/${policyName}`, diff --git a/ui/tests/acceptance/policies-test.js b/ui/tests/acceptance/policies-test.js index 01e8c2c6c..a26a63920 100644 --- a/ui/tests/acceptance/policies-test.js +++ b/ui/tests/acceptance/policies-test.js @@ -1,29 +1,27 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentURL, currentRouteName, visit } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | policies', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | policies', function(hooks) { + setupApplicationTest(hooks); -test('it redirects to acls on unknown policy type', function(assert) { - visit('/vault/policy/foo/default'); - andThen(() => { + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it redirects to acls on unknown policy type', async function(assert) { + await visit('/vault/policy/foo/default'); + assert.equal(currentRouteName(), 'vault.cluster.policies.index'); + assert.equal(currentURL(), '/vault/policies/acl'); + + await visit('/vault/policy/foo/default/edit'); assert.equal(currentRouteName(), 'vault.cluster.policies.index'); assert.equal(currentURL(), '/vault/policies/acl'); }); - visit('/vault/policy/foo/default/edit'); - andThen(() => { - assert.equal(currentRouteName(), 'vault.cluster.policies.index'); - assert.equal(currentURL(), '/vault/policies/acl'); - }); -}); - -test('it redirects to acls on index navigation', function(assert) { - visit('/vault/policy/acl'); - andThen(() => { + test('it redirects to acls on index navigation', async function(assert) { + await visit('/vault/policy/acl'); assert.equal(currentRouteName(), 'vault.cluster.policies.index'); assert.equal(currentURL(), '/vault/policies/acl'); }); diff --git a/ui/tests/acceptance/policies/index-test.js b/ui/tests/acceptance/policies/index-test.js index e2109eef5..5b7ee05aa 100644 --- a/ui/tests/acceptance/policies/index-test.js +++ b/ui/tests/acceptance/policies/index-test.js @@ -1,30 +1,26 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentURL, currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/policies/index'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | policies/acl', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | policies/acl', function(hooks) { + setupApplicationTest(hooks); -test('it lists default and root acls', function(assert) { - page.visit({ type: 'acl' }); - andThen(() => { - let policies = page.policies(); + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it lists default and root acls', async function(assert) { + await page.visit({ type: 'acl' }); assert.equal(currentURL(), '/vault/policies/acl'); - assert.ok(policies.findByName('root'), 'root policy shown in the list'); - assert.ok(policies.findByName('default'), 'default policy shown in the list'); - }); -}); - -test('it navigates to show when clicking on the link', function(assert) { - page.visit({ type: 'acl' }); - andThen(() => { - page.policies().findByName('default').click(); + assert.ok(page.findPolicyByName('root'), 'root policy shown in the list'); + assert.ok(page.findPolicyByName('default'), 'default policy shown in the list'); }); - andThen(() => { + test('it navigates to show when clicking on the link', async function(assert) { + await page.visit({ type: 'acl' }); + await page.findPolicyByName('default').click(); assert.equal(currentRouteName(), 'vault.cluster.policy.show'); assert.equal(currentURL(), '/vault/policy/acl/default'); }); diff --git a/ui/tests/acceptance/policy-test.js b/ui/tests/acceptance/policy-test.js index a2cac7347..64787311a 100644 --- a/ui/tests/acceptance/policy-test.js +++ b/ui/tests/acceptance/policy-test.js @@ -1,18 +1,22 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentURL, currentRouteName, visit } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import authPage from 'vault/tests/pages/auth'; +import logout from 'vault/tests/pages/logout'; -moduleForAcceptance('Acceptance | policies', { - beforeEach() { - return authLogin(); - }, - afterEach() { - return authLogout(); - }, -}); +module('Acceptance | policies', function(hooks) { + setupApplicationTest(hooks); -test('it redirects to acls with unknown policy type', function(assert) { - visit('/vault/policies/foo'); - andThen(() => { + hooks.beforeEach(function() { + return authPage.login(); + }); + + hooks.afterEach(function() { + return logout.visit(); + }); + + test('it redirects to acls with unknown policy type', async function(assert) { + await visit('/vault/policies/foo'); assert.equal(currentRouteName(), 'vault.cluster.policies.index'); assert.equal(currentURL(), '/vault/policies/acl'); }); diff --git a/ui/tests/acceptance/policy/edit-test.js b/ui/tests/acceptance/policy/edit-test.js index c09f8835a..8ec6044ef 100644 --- a/ui/tests/acceptance/policy/edit-test.js +++ b/ui/tests/acceptance/policy/edit-test.js @@ -1,30 +1,28 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentURL } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/policy/edit'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | policy/acl/:name/edit', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | policy/acl/:name/edit', function(hooks) { + setupApplicationTest(hooks); -test('it redirects to list if navigating to root', function(assert) { - page.visit({ type: 'acl', name: 'root' }); - andThen(function() { + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it redirects to list if navigating to root', async function(assert) { + await page.visit({ type: 'acl', name: 'root' }); assert.equal(currentURL(), '/vault/policies/acl', 'navigation to root show redirects you to policy list'); }); -}); -test('it does not show delete for default policy', function(assert) { - page.visit({ type: 'acl', name: 'default' }); - andThen(function() { + test('it does not show delete for default policy', async function(assert) { + await page.visit({ type: 'acl', name: 'default' }); assert.notOk(page.deleteIsPresent, 'there is no delete button'); }); -}); -test('it navigates to show when the toggle is clicked', function(assert) { - page.visit({ type: 'acl', name: 'default' }).toggleEdit(); - andThen(() => { + test('it navigates to show when the toggle is clicked', async function(assert) { + await page.visit({ type: 'acl', name: 'default' }).toggleEdit(); assert.equal(currentURL(), '/vault/policy/acl/default', 'toggle navigates from edit to show'); }); }); diff --git a/ui/tests/acceptance/policy/show-test.js b/ui/tests/acceptance/policy/show-test.js index 15af7eaa5..1373cb20f 100644 --- a/ui/tests/acceptance/policy/show-test.js +++ b/ui/tests/acceptance/policy/show-test.js @@ -1,23 +1,23 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentURL } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/policy/show'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | policy/acl/:name', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | policy/acl/:name', function(hooks) { + setupApplicationTest(hooks); -test('it redirects to list if navigating to root', function(assert) { - page.visit({ type: 'acl', name: 'root' }); - andThen(function() { + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it redirects to list if navigating to root', async function(assert) { + await page.visit({ type: 'acl', name: 'root' }); assert.equal(currentURL(), '/vault/policies/acl', 'navigation to root show redirects you to policy list'); }); -}); -test('it navigates to edit when the toggle is clicked', function(assert) { - page.visit({ type: 'acl', name: 'default' }).toggleEdit(); - andThen(() => { + test('it navigates to edit when the toggle is clicked', async function(assert) { + await page.visit({ type: 'acl', name: 'default' }).toggleEdit(); assert.equal(currentURL(), '/vault/policy/acl/default/edit', 'toggle navigates to edit page'); }); }); diff --git a/ui/tests/acceptance/secrets/backend/cubbyhole/secret-test.js b/ui/tests/acceptance/secrets/backend/cubbyhole/secret-test.js index c9af92d77..b15ce4dc6 100644 --- a/ui/tests/acceptance/secrets/backend/cubbyhole/secret-test.js +++ b/ui/tests/acceptance/secrets/backend/cubbyhole/secret-test.js @@ -1,30 +1,31 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import editPage from 'vault/tests/pages/secrets/backend/kv/edit-secret'; import showPage from 'vault/tests/pages/secrets/backend/kv/show'; import listPage from 'vault/tests/pages/secrets/backend/list'; import apiStub from 'vault/tests/helpers/noop-all-api-requests'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | secrets/cubbyhole/create', { - beforeEach() { +module('Acceptance | secrets/cubbyhole/create', function(hooks) { + setupApplicationTest(hooks); + + hooks.beforeEach(function() { this.server = apiStub({ usePassthrough: true }); - return authLogin(); - }, - afterEach() { - this.server.shutdown(); - }, -}); - -test('it creates and can view a secret with the cubbyhole backend', function(assert) { - const kvPath = `cubbyhole-kv-${new Date().getTime()}`; - listPage.visitRoot({ backend: 'cubbyhole' }); - andThen(() => { - assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.list-root', 'navigates to the list page'); + return authPage.login(); }); - listPage.create(); - editPage.createSecret(kvPath, 'foo', 'bar'); - andThen(() => { + hooks.afterEach(function() { + this.server.shutdown(); + }); + + test('it creates and can view a secret with the cubbyhole backend', async function(assert) { + const kvPath = `cubbyhole-kv-${new Date().getTime()}`; + await listPage.visitRoot({ backend: 'cubbyhole' }); + assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.list-root', 'navigates to the list page'); + + await listPage.create(); + await editPage.createSecret(kvPath, 'foo', 'bar'); let capabilitiesReq = this.server.passthroughRequests.findBy('url', '/v1/sys/capabilities-self'); assert.equal( JSON.parse(capabilitiesReq.requestBody).paths, diff --git a/ui/tests/acceptance/secrets/backend/generic/secret-test.js b/ui/tests/acceptance/secrets/backend/generic/secret-test.js index 86906542e..57b9780f0 100644 --- a/ui/tests/acceptance/secrets/backend/generic/secret-test.js +++ b/ui/tests/acceptance/secrets/backend/generic/secret-test.js @@ -1,9 +1,11 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import editPage from 'vault/tests/pages/secrets/backend/kv/edit-secret'; import showPage from 'vault/tests/pages/secrets/backend/kv/show'; import listPage from 'vault/tests/pages/secrets/backend/list'; import consolePanel from 'vault/tests/pages/components/console/ui-panel'; +import authPage from 'vault/tests/pages/auth'; import { create } from 'ember-cli-page-object'; @@ -11,32 +13,31 @@ import apiStub from 'vault/tests/helpers/noop-all-api-requests'; const cli = create(consolePanel); -moduleForAcceptance('Acceptance | secrets/generic/create', { - beforeEach() { - this.server = apiStub({ usePassthrough: true }); - return authLogin(); - }, - afterEach() { - this.server.shutdown(); - }, -}); +module('Acceptance | secrets/generic/create', function(hooks) { + setupApplicationTest(hooks); -test('it creates and can view a secret with the generic backend', function(assert) { - const path = `generic-${new Date().getTime()}`; - const kvPath = `generic-kv-${new Date().getTime()}`; - cli.consoleInput(`write sys/mounts/${path} type=generic`); - cli.enter(); - cli.consoleInput(`write ${path}/foo bar=baz`); - cli.enter(); - listPage.visitRoot({ backend: path }); - andThen(() => { - assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.list-root', 'navigates to the list page'); - assert.equal(listPage.secrets.length, 1, 'lists one secret in the backend'); + hooks.beforeEach(function() { + this.server = apiStub({ usePassthrough: true }); + return authPage.login(); }); - listPage.create(); - editPage.createSecret(kvPath, 'foo', 'bar'); - andThen(() => { + hooks.afterEach(function() { + this.server.shutdown(); + }); + + test('it creates and can view a secret with the generic backend', async function(assert) { + const path = `generic-${new Date().getTime()}`; + const kvPath = `generic-kv-${new Date().getTime()}`; + cli.consoleInput(`write sys/mounts/${path} type=generic`); + cli.enter(); + cli.consoleInput(`write ${path}/foo bar=baz`); + cli.enter(); + await listPage.visitRoot({ backend: path }); + assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.list-root', 'navigates to the list page'); + assert.equal(listPage.secrets.length, 1, 'lists one secret in the backend'); + + await listPage.create(); + await editPage.createSecret(kvPath, 'foo', 'bar'); let capabilitiesReq = this.server.passthroughRequests.findBy('url', '/v1/sys/capabilities-self'); assert.equal( JSON.parse(capabilitiesReq.requestBody).paths, @@ -46,38 +47,30 @@ test('it creates and can view a secret with the generic backend', function(asser assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'redirects to the show page'); assert.ok(showPage.editIsPresent, 'shows the edit button'); }); -}); -test('upgrading generic to version 2 lists all existing secrets, and CRUD continues to work', function( - assert -) { - const path = `generic-${new Date().getTime()}`; - const kvPath = `generic-kv-${new Date().getTime()}`; - cli.consoleInput(`write sys/mounts/${path} type=generic`); - cli.enter(); - cli.consoleInput(`write ${path}/foo bar=baz`); - cli.enter(); - // upgrade to version 2 generic mount - cli.consoleInput(`write sys/mounts/${path}/tune options=version=2`); - cli.enter(); - listPage.visitRoot({ backend: path }); - andThen(() => { + test('upgrading generic to version 2 lists all existing secrets, and CRUD continues to work', async function(assert) { + const path = `generic-${new Date().getTime()}`; + const kvPath = `generic-kv-${new Date().getTime()}`; + cli.consoleInput(`write sys/mounts/${path} type=generic`); + cli.enter(); + cli.consoleInput(`write ${path}/foo bar=baz`); + cli.enter(); + // upgrade to version 2 generic mount + cli.consoleInput(`write sys/mounts/${path}/tune options=version=2`); + cli.enter(); + await listPage.visitRoot({ backend: path }); assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.list-root', 'navigates to the list page'); assert.equal(listPage.secrets.length, 1, 'lists the old secret in the backend'); - }); - listPage.create(); - editPage.createSecret(kvPath, 'foo', 'bar'); - andThen(() => { + await listPage.create(); + await editPage.createSecret(kvPath, 'foo', 'bar'); let capabilitiesReq = this.server.passthroughRequests.findBy('url', '/v1/sys/capabilities-self'); assert.equal( JSON.parse(capabilitiesReq.requestBody).paths, `${path}/data/${kvPath}`, 'calls capabilites with the correct path' ); - }); - listPage.visitRoot({ backend: path }); - andThen(() => { + await listPage.visitRoot({ backend: path }); assert.equal(listPage.secrets.length, 2, 'lists two secrets in the backend'); }); }); diff --git a/ui/tests/acceptance/secrets/backend/kv/secret-test.js b/ui/tests/acceptance/secrets/backend/kv/secret-test.js index 6e9370633..483282204 100644 --- a/ui/tests/acceptance/secrets/backend/kv/secret-test.js +++ b/ui/tests/acceptance/secrets/backend/kv/secret-test.js @@ -1,32 +1,34 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentURL, currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import editPage from 'vault/tests/pages/secrets/backend/kv/edit-secret'; import showPage from 'vault/tests/pages/secrets/backend/kv/show'; import listPage from 'vault/tests/pages/secrets/backend/list'; import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend'; import apiStub from 'vault/tests/helpers/noop-all-api-requests'; +import authPage from 'vault/tests/pages/auth'; +import withFlash from 'vault/tests/helpers/with-flash'; -moduleForAcceptance('Acceptance | secrets/secret/create', { - beforeEach() { +module('Acceptance | secrets/secret/create', function(hooks) { + setupApplicationTest(hooks); + + hooks.beforeEach(function() { this.server = apiStub({ usePassthrough: true }); - return authLogin(); - }, - afterEach() { - this.server.shutdown(); - }, -}); - -test('it creates a secret and redirects', function(assert) { - const path = `kv-path-${new Date().getTime()}`; - listPage.visitRoot({ backend: 'secret' }); - andThen(() => { - assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.list-root', 'navigates to the list page'); + return authPage.login(); }); - listPage.create(); - editPage.createSecret(path, 'foo', 'bar'); - andThen(() => { + hooks.afterEach(function() { + this.server.shutdown(); + }); + + test('it creates a secret and redirects', async function(assert) { + const path = `kv-path-${new Date().getTime()}`; + await listPage.visitRoot({ backend: 'secret' }); + assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.list-root', 'navigates to the list page'); + + await listPage.create(); + await editPage.createSecret(path, 'foo', 'bar'); let capabilitiesReq = this.server.passthroughRequests.findBy('url', '/v1/sys/capabilities-self'); assert.equal( JSON.parse(capabilitiesReq.requestBody).paths, @@ -36,20 +38,23 @@ test('it creates a secret and redirects', function(assert) { assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'redirects to the show page'); assert.ok(showPage.editIsPresent, 'shows the edit button'); }); -}); -test('version 1 performs the correct capabilities lookup', function(assert) { - let enginePath = `kv-${new Date().getTime()}`; - let secretPath = 'foo/bar'; - // mount version 1 engine - mountSecrets.visit(); - andThen(() => { - mountSecrets.selectType('kv').next().path(enginePath).version(1).submit(); - }); + test('version 1 performs the correct capabilities lookup', async function(assert) { + let enginePath = `kv-${new Date().getTime()}`; + let secretPath = 'foo/bar'; + // mount version 1 engine + await mountSecrets.visit(); + await mountSecrets.selectType('kv'); + await withFlash( + mountSecrets + .next() + .path(enginePath) + .version(1) + .submit() + ); - listPage.create(); - editPage.createSecret(secretPath, 'foo', 'bar'); - andThen(() => { + await listPage.create(); + await editPage.createSecret(secretPath, 'foo', 'bar'); let capabilitiesReq = this.server.passthroughRequests.findBy('url', '/v1/sys/capabilities-self'); assert.equal( JSON.parse(capabilitiesReq.requestBody).paths, @@ -57,15 +62,13 @@ test('version 1 performs the correct capabilities lookup', function(assert) { 'calls capabilites with the correct path' ); }); -}); -test('it redirects to the path ending in / for list pages', function(assert) { - const path = `foo/bar/kv-path-${new Date().getTime()}`; - listPage.visitRoot({ backend: 'secret' }); - listPage.create(); - editPage.createSecret(path, 'foo', 'bar'); - listPage.visit({ backend: 'secret', id: 'foo/bar' }); - andThen(() => { + test('it redirects to the path ending in / for list pages', async function(assert) { + const path = `foo/bar/kv-path-${new Date().getTime()}`; + await listPage.visitRoot({ backend: 'secret' }); + await listPage.create(); + await editPage.createSecret(path, 'foo', 'bar'); + await listPage.visit({ backend: 'secret', id: 'foo/bar' }); assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.list'); assert.ok(currentURL().endsWith('/'), 'redirects to the path ending in a slash'); }); diff --git a/ui/tests/acceptance/secrets/backend/pki/cert-test.js b/ui/tests/acceptance/secrets/backend/pki/cert-test.js index 8bd4664b9..cb437044f 100644 --- a/ui/tests/acceptance/secrets/backend/pki/cert-test.js +++ b/ui/tests/acceptance/secrets/backend/pki/cert-test.js @@ -1,18 +1,23 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import editPage from 'vault/tests/pages/secrets/backend/pki/edit-role'; import listPage from 'vault/tests/pages/secrets/backend/list'; import generatePage from 'vault/tests/pages/secrets/backend/pki/generate-cert'; import showPage from 'vault/tests/pages/secrets/backend/pki/show'; import configPage from 'vault/tests/pages/settings/configure-secret-backends/pki/section-cert'; +import enablePage from 'vault/tests/pages/settings/mount-secret-backend'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | secrets/pki/list?tab=certs', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | secrets/pki/list?tab=certs', function(hooks) { + setupApplicationTest(hooks); -const CSR = `-----BEGIN CERTIFICATE REQUEST----- + hooks.beforeEach(function() { + return authPage.login(); + }); + // important for this comment to stay here otherwise the formatting mangles the CSR + // prettier-ignore + const CSR = `-----BEGIN CERTIFICATE REQUEST----- MIICdDCCAVwCAQAwDjEMMAoGA1UEAxMDbG9sMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEA4Dz2b/nAP/M6bqyk5mctqqYAAcoME//xPBy0wREHuZ776Pu4 l45kDL3dPXiY8U2P9pn8WIr2KpLK6oWUfSsiG2P082bpWDL20UymkWqDhhrA4unf @@ -29,50 +34,41 @@ XA2ZOCA7s34/szr2FczXtIoKiYmv3UzPyO9/4mc0Q2+/nR4CG8NU9WW/XJCne9ID elRplAzrMF4= -----END CERTIFICATE REQUEST-----`; -// mount, generate CA, nav to create role page -const setup = (assert, action = 'issue') => { - const path = `pki-${new Date().getTime()}`; - const roleName = 'role'; - mountSupportedSecretBackend(assert, 'pki', path); - configPage.visit({ backend: path }).form.generateCA(); - editPage.visitRoot({ backend: path }); - editPage.createRole('role', 'example.com'); - generatePage.visit({ backend: path, id: roleName, action }); - return path; -}; + // mount, generate CA, nav to create role page + const setup = async (assert, action = 'issue') => { + const path = `pki-${new Date().getTime()}`; + const roleName = 'role'; + await enablePage.enable('pki', path); + await configPage.visit({ backend: path }).form.generateCA(); + await editPage.visitRoot({ backend: path }); + await editPage.createRole('role', 'example.com'); + await generatePage.visit({ backend: path, id: roleName, action }); + return path; + }; -test('it issues a cert', function(assert) { - setup(assert); + test('it issues a cert', async function(assert) { + await setup(assert); - generatePage.issueCert('foo'); - andThen(() => { + await generatePage.issueCert('foo'); assert.ok(generatePage.hasCert, 'displays the cert'); - }); - generatePage.back(); - andThen(() => { + await generatePage.back(); assert.notOk(generatePage.commonNameValue, 'the form is cleared'); }); -}); -test('it signs a csr', function(assert) { - setup(assert, 'sign'); - generatePage.sign('common', CSR); - andThen(() => { + test('it signs a csr', async function(assert) { + await setup(assert, 'sign'); + await generatePage.sign('common', CSR); assert.ok(generatePage.hasCert, 'displays the cert'); }); -}); -test('it views a cert', function(assert) { - const path = setup(assert); - generatePage.issueCert('foo'); - listPage.visitRoot({ backend: path, tab: 'certs' }); - andThen(() => { + test('it views a cert', async function(assert) { + const path = await setup(assert); + await generatePage.issueCert('foo'); + await listPage.visitRoot({ backend: path, tab: 'certs' }); assert.ok(listPage.secrets.length > 0, 'lists certs'); - }); - listPage.secrets.objectAt(0).click(); - andThen(() => { + await listPage.secrets.objectAt(0).click(); assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'navigates to the show page'); assert.ok(showPage.hasCert, 'shows the cert'); }); diff --git a/ui/tests/acceptance/secrets/backend/pki/list-test.js b/ui/tests/acceptance/secrets/backend/pki/list-test.js index 4b27e8d82..875f22bca 100644 --- a/ui/tests/acceptance/secrets/backend/pki/list-test.js +++ b/ui/tests/acceptance/secrets/backend/pki/list-test.js @@ -1,42 +1,42 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName, settled } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/secrets/backend/list'; +import authPage from 'vault/tests/pages/auth'; +import enablePage from 'vault/tests/pages/settings/mount-secret-backend'; -moduleForAcceptance('Acceptance | secrets/pki/list', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | secrets/pki/list', function(hooks) { + setupApplicationTest(hooks); -const mountAndNav = assert => { - const path = `pki-${new Date().getTime()}`; - mountSupportedSecretBackend(assert, 'pki', path); - page.visitRoot({ backend: path }); -}; + hooks.beforeEach(function() { + return authPage.login(); + }); -test('it renders an empty list', function(assert) { - mountAndNav(assert); - andThen(() => { + const mountAndNav = async () => { + const path = `pki-${new Date().getTime()}`; + await enablePage.enable('pki', path); + await page.visitRoot({ backend: path }); + }; + + test('it renders an empty list', async function(assert) { + await mountAndNav(assert); assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.list-root', 'redirects from the index'); assert.ok(page.createIsPresent, 'create button is present'); assert.ok(page.configureIsPresent, 'configure button is present'); assert.equal(page.tabs.length, 2, 'shows 2 tabs'); assert.ok(page.backendIsEmpty); }); -}); -test('it navigates to the create page', function(assert) { - mountAndNav(assert); - page.create(); - andThen(() => { + test('it navigates to the create page', async function(assert) { + await mountAndNav(assert); + await page.create(); assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.create-root', 'links to the create page'); }); -}); -test('it navigates to the configure page', function(assert) { - mountAndNav(assert); - page.configure(); - andThen(() => { + test('it navigates to the configure page', async function(assert) { + await mountAndNav(assert); + await page.configure(); + await settled(); assert.equal( currentRouteName(), 'vault.cluster.settings.configure-secret-backend.section', diff --git a/ui/tests/acceptance/secrets/backend/pki/role-test.js b/ui/tests/acceptance/secrets/backend/pki/role-test.js index 76c9c3bb8..d9b9a1cb5 100644 --- a/ui/tests/acceptance/secrets/backend/pki/role-test.js +++ b/ui/tests/acceptance/secrets/backend/pki/role-test.js @@ -1,68 +1,61 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import editPage from 'vault/tests/pages/secrets/backend/pki/edit-role'; import showPage from 'vault/tests/pages/secrets/backend/pki/show'; import listPage from 'vault/tests/pages/secrets/backend/list'; +import enablePage from 'vault/tests/pages/settings/mount-secret-backend'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | secrets/pki/create', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | secrets/pki/create', function(hooks) { + setupApplicationTest(hooks); -const mountAndNav = assert => { - const path = `pki-${new Date().getTime()}`; - mountSupportedSecretBackend(assert, 'pki', path); - editPage.visitRoot({ backend: path }); - return path; -}; + hooks.beforeEach(function() { + return authPage.login(); + }); -test('it creates a role and redirects', function(assert) { - const path = mountAndNav(assert); - editPage.createRole('role', 'example.com'); - andThen(() => { + const mountAndNav = async () => { + const path = `pki-${new Date().getTime()}`; + await enablePage.enable('pki', path); + await editPage.visitRoot({ backend: path }); + return path; + }; + + test('it creates a role and redirects', async function(assert) { + const path = await mountAndNav(assert); + await editPage.createRole('role', 'example.com'); assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'redirects to the show page'); assert.ok(showPage.editIsPresent, 'shows the edit button'); assert.ok(showPage.generateCertIsPresent, 'shows the generate button'); assert.ok(showPage.signCertIsPresent, 'shows the sign button'); - }); - showPage.visit({ backend: path, id: 'role' }); - showPage.generateCert(); - andThen(() => { + await showPage.visit({ backend: path, id: 'role' }); + await showPage.generateCert(); assert.equal( currentRouteName(), 'vault.cluster.secrets.backend.credentials', 'navs to the credentials page' ); - }); - showPage.visit({ backend: path, id: 'role' }); - showPage.signCert(); - andThen(() => { + await showPage.visit({ backend: path, id: 'role' }); + await showPage.signCert(); assert.equal( currentRouteName(), 'vault.cluster.secrets.backend.credentials', 'navs to the credentials page' ); - }); - listPage.visitRoot({ backend: path }); - andThen(() => { + await listPage.visitRoot({ backend: path }); assert.equal(listPage.secrets.length, 1, 'shows role in the list'); }); -}); -test('it deletes a role', function(assert) { - mountAndNav(assert); - editPage.createRole('role', 'example.com'); - showPage.edit(); - andThen(() => { + test('it deletes a role', async function(assert) { + await mountAndNav(assert); + await editPage.createRole('role', 'example.com'); + await showPage.edit(); assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.edit', 'navs to the edit page'); - }); - editPage.deleteRole(); - andThen(() => { + await editPage.deleteRole(); assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.list-root', 'redirects to list page'); assert.ok(listPage.backendIsEmpty, 'no roles listed'); }); diff --git a/ui/tests/acceptance/settings-test.js b/ui/tests/acceptance/settings-test.js index 5f95af32a..25f6d8f24 100644 --- a/ui/tests/acceptance/settings-test.js +++ b/ui/tests/acceptance/settings-test.js @@ -1,52 +1,52 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentURL, find, visit } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import backendListPage from 'vault/tests/pages/secrets/backends'; import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend'; +import authPage from 'vault/tests/pages/auth'; +import logout from 'vault/tests/pages/logout'; +import withFlash from 'vault/tests/helpers/with-flash'; -moduleForAcceptance('Acceptance | settings', { - beforeEach() { - return authLogin(); - }, - afterEach() { - return authLogout(); - }, -}); +module('Acceptance | settings', function(hooks) { + setupApplicationTest(hooks); -test('settings', function(assert) { - const now = new Date().getTime(); - const type = 'consul'; - const path = `path-${now}`; + hooks.beforeEach(function() { + return authPage.login(); + }); - // mount unsupported backend - visit('/vault/settings/mount-secret-backend'); - andThen(function() { + hooks.afterEach(function() { + return logout.visit(); + }); + + test('settings', async function(assert) { + const now = new Date().getTime(); + const type = 'consul'; + const path = `path-${now}`; + + // mount unsupported backend + await visit('/vault/settings/mount-secret-backend'); assert.equal(currentURL(), '/vault/settings/mount-secret-backend'); - mountSecrets - .selectType(type) - .next() - .path(path) - .toggleOptions() - .defaultTTLVal(100) - .defaultTTLUnit('s') - .submit(); - }); - - andThen(() => { - assert.equal(currentURL(), `/vault/secrets`, 'redirects to secrets page'); - assert.ok( - find('[data-test-flash-message]').text().trim(), - `Successfully mounted '${type}' at '${path}'!` + await mountSecrets.selectType(type); + await withFlash( + mountSecrets + .next() + .path(path) + .toggleOptions() + .defaultTTLVal(100) + .defaultTTLUnit('s') + .submit(), + () => { + assert.ok( + find('[data-test-flash-message]').textContent.trim(), + `Successfully mounted '${type}' at '${path}'!` + ); + } ); - let row = backendListPage.rows().findByPath(path); - row.menu(); - }); - - andThen(() => { - backendListPage.configLink(); - }); - - andThen(() => { + assert.equal(currentURL(), `/vault/secrets`, 'redirects to secrets page'); + let row = backendListPage.rows.filterBy('path', path + '/')[0]; + await row.menu(); + await backendListPage.configLink(); assert.ok(currentURL(), '/vault/secrets/${path}/configuration', 'navigates to the config page'); }); }); diff --git a/ui/tests/acceptance/settings/auth/configure/index-test.js b/ui/tests/acceptance/settings/auth/configure/index-test.js index f8310e51f..f1ef1d756 100644 --- a/ui/tests/acceptance/settings/auth/configure/index-test.js +++ b/ui/tests/acceptance/settings/auth/configure/index-test.js @@ -1,37 +1,31 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentURL, currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import enablePage from 'vault/tests/pages/settings/auth/enable'; import page from 'vault/tests/pages/settings/auth/configure/index'; +import authPage from 'vault/tests/pages/auth'; -moduleForAcceptance('Acceptance | settings/auth/configure', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | settings/auth/configure', function(hooks) { + setupApplicationTest(hooks); -test('it redirects to section options when there are no other sections', function(assert) { - const path = `approle-${new Date().getTime()}`; - const type = 'approle'; - enablePage.visit(); - andThen(() => { - enablePage.form.mount(type, path); + hooks.beforeEach(function() { + return authPage.login(); }); - page.visit({ path }); - andThen(() => { + + test('it redirects to section options when there are no other sections', async function(assert) { + const path = `approle-${new Date().getTime()}`; + const type = 'approle'; + await enablePage.enable(type, path); + await page.visit({ path }); assert.equal(currentRouteName(), 'vault.cluster.settings.auth.configure.section'); assert.equal(currentURL(), `/vault/settings/auth/configure/${path}/options`, 'loads the options route'); }); -}); -test('it redirects to the first section', function(assert) { - const path = `aws-${new Date().getTime()}`; - const type = 'aws'; - enablePage.visit(); - andThen(() => { - enablePage.form.mount(type, path); - }); - page.visit({ path }); - andThen(() => { + test('it redirects to the first section', async function(assert) { + const path = `aws-${new Date().getTime()}`; + const type = 'aws'; + await enablePage.enable(type, path); + await page.visit({ path }); assert.equal(currentRouteName(), 'vault.cluster.settings.auth.configure.section'); assert.equal( currentURL(), diff --git a/ui/tests/acceptance/settings/auth/configure/section-test.js b/ui/tests/acceptance/settings/auth/configure/section-test.js index f2ac4ae42..0216a21b5 100644 --- a/ui/tests/acceptance/settings/auth/configure/section-test.js +++ b/ui/tests/acceptance/settings/auth/configure/section-test.js @@ -1,61 +1,57 @@ -import { test } from 'qunit'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import { create } from 'ember-cli-page-object'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; import enablePage from 'vault/tests/pages/settings/auth/enable'; import page from 'vault/tests/pages/settings/auth/configure/section'; import indexPage from 'vault/tests/pages/settings/auth/configure/index'; import apiStub from 'vault/tests/helpers/noop-all-api-requests'; import consolePanel from 'vault/tests/pages/components/console/ui-panel'; +import authPage from 'vault/tests/pages/auth'; +import withFlash from 'vault/tests/helpers/with-flash'; const cli = create(consolePanel); -moduleForAcceptance('Acceptance | settings/auth/configure/section', { - beforeEach() { - this.server = apiStub({ usePassthrough: true }); - return authLogin(); - }, - afterEach() { - this.server.shutdown(); - }, -}); +module('Acceptance | settings/auth/configure/section', function(hooks) { + setupApplicationTest(hooks); -test('it can save options', function(assert) { - const path = `approle-${new Date().getTime()}`; - const type = 'approle'; - const section = 'options'; - enablePage.visit(); - andThen(() => { - enablePage.form.mount(type, path); + hooks.beforeEach(function() { + this.server = apiStub({ usePassthrough: true }); + return authPage.login(); }); - page.visit({ path, section }); - andThen(() => { - page.fields().findByName('description').textarea('This is AppRole!'); - page.save(); + + hooks.afterEach(function() { + this.server.shutdown(); }); - andThen(() => { + + test('it can save options', async function(assert) { + const path = `approle-${new Date().getTime()}`; + const type = 'approle'; + const section = 'options'; + await enablePage.enable(type, path); + await page.visit({ path, section }); + await page.fillInTextarea('description', 'This is AppRole!'); + await withFlash(page.save(), () => { + assert.equal( + page.flash.latestMessage, + `The configuration options were saved successfully.`, + 'success flash shows' + ); + }); let tuneRequest = this.server.passthroughRequests.filterBy('url', `/v1/sys/mounts/auth/${path}/tune`)[0]; let keys = Object.keys(JSON.parse(tuneRequest.requestBody)); assert.ok(keys.includes('default_lease_ttl'), 'passes default_lease_ttl on tune'); assert.ok(keys.includes('max_lease_ttl'), 'passes max_lease_ttl on tune'); - - assert.equal( - page.flash.latestMessage, - `The configuration options were saved successfully.`, - 'success flash shows' - ); }); -}); -['aws', 'azure', 'gcp', 'github', 'kubernetes', 'ldap', 'okta', 'radius'].forEach(function(type) { - test(`it shows tabs for auth method: ${type}`, assert => { - let path = `${type}-${Date.now()}`; - cli.consoleInput(`write sys/auth/${path} type=${type}`); - cli.enter(); - indexPage.visit({ path }); - andThen(() => { + for (let type of ['aws', 'azure', 'gcp', 'github', 'kubernetes', 'ldap', 'okta', 'radius']) { + test(`it shows tabs for auth method: ${type}`, async assert => { + let path = `${type}-${Date.now()}`; + await cli.consoleInput(`write sys/auth/${path} type=${type}`); + await cli.enter(); + await indexPage.visit({ path }); // aws has 4 tabs, the others will have 'Configuration' and 'Method Options' tabs let numTabs = type === 'aws' ? 4 : 2; assert.equal(page.tabs.length, numTabs, 'shows correct number of tabs'); }); - }); + } }); diff --git a/ui/tests/acceptance/settings/auth/enable-test.js b/ui/tests/acceptance/settings/auth/enable-test.js index 869312108..bba0c6f37 100644 --- a/ui/tests/acceptance/settings/auth/enable-test.js +++ b/ui/tests/acceptance/settings/auth/enable-test.js @@ -1,34 +1,36 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/settings/auth/enable'; import listPage from 'vault/tests/pages/access/methods'; +import authPage from 'vault/tests/pages/auth'; +import withFlash from 'vault/tests/helpers/with-flash'; -moduleForAcceptance('Acceptance | settings/auth/enable', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | settings/auth/enable', function(hooks) { + setupApplicationTest(hooks); -test('it mounts and redirects', function(assert) { - // always force the new mount to the top of the list - const path = `approle-${new Date().getTime()}`; - const type = 'approle'; - page.visit(); - andThen(() => { - assert.equal(currentRouteName(), 'vault.cluster.settings.auth.enable'); - page.form.mount(type, path); + hooks.beforeEach(function() { + return authPage.login(); }); - andThen(() => { - assert.equal( - page.flash.latestMessage, - `Successfully mounted ${type} auth method at ${path}.`, - 'success flash shows' - ); + + test('it mounts and redirects', async function(assert) { + // always force the new mount to the top of the list + const path = `approle-${new Date().getTime()}`; + const type = 'approle'; + await page.visit(); + assert.equal(currentRouteName(), 'vault.cluster.settings.auth.enable'); + await withFlash(page.enable(type, path), () => { + assert.equal( + page.flash.latestMessage, + `Successfully mounted ${type} auth method at ${path}.`, + 'success flash shows' + ); + }); assert.equal( currentRouteName(), 'vault.cluster.access.methods', 'redirects to the auth backend list page' ); - assert.ok(listPage.backendLinks().findById(path), 'mount is present in the list'); + assert.ok(listPage.findLinkById(path), 'mount is present in the list'); }); }); diff --git a/ui/tests/acceptance/settings/configure-secret-backends/pki/index-test.js b/ui/tests/acceptance/settings/configure-secret-backends/pki/index-test.js index dcf7ba0dd..052f6fd0a 100644 --- a/ui/tests/acceptance/settings/configure-secret-backends/pki/index-test.js +++ b/ui/tests/acceptance/settings/configure-secret-backends/pki/index-test.js @@ -1,18 +1,21 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/settings/configure-secret-backends/pki/index'; +import authPage from 'vault/tests/pages/auth'; +import enablePage from 'vault/tests/pages/settings/mount-secret-backend'; -moduleForAcceptance('Acceptance | settings/configure/secrets/pki', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | settings/configure/secrets/pki', function(hooks) { + setupApplicationTest(hooks); -test('it redirects to the cert section', function(assert) { - const path = `pki-${new Date().getTime()}`; - mountSupportedSecretBackend(assert, 'pki', path); - page.visit({ backend: path }); - andThen(() => { + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it redirects to the cert section', async function(assert) { + const path = `pki-${new Date().getTime()}`; + await enablePage.enable('pki', path); + await page.visit({ backend: path }); assert.equal( currentRouteName(), 'vault.cluster.settings.configure-secret-backend.section', diff --git a/ui/tests/acceptance/settings/configure-secret-backends/pki/section-cert-test.js b/ui/tests/acceptance/settings/configure-secret-backends/pki/section-cert-test.js index 864fe0e63..8ceff914f 100644 --- a/ui/tests/acceptance/settings/configure-secret-backends/pki/section-cert-test.js +++ b/ui/tests/acceptance/settings/configure-secret-backends/pki/section-cert-test.js @@ -1,14 +1,20 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName, settled } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/settings/configure-secret-backends/pki/section-cert'; +import authPage from 'vault/tests/pages/auth'; +import enablePage from 'vault/tests/pages/settings/mount-secret-backend'; +import withFlash from 'vault/tests/helpers/with-flash'; -moduleForAcceptance('Acceptance | settings/configure/secrets/pki/cert', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | settings/configure/secrets/pki/cert', function(hooks) { + setupApplicationTest(hooks); -const PEM_BUNDLE = `-----BEGIN CERTIFICATE----- + hooks.beforeEach(function() { + return authPage.login(); + }); + + //prettier-ignore + const PEM_BUNDLE = `-----BEGIN CERTIFICATE----- MIIDGjCCAgKgAwIBAgIUFvnhb2nQ8+KNS3SzjlfYDMHGIRgwDQYJKoZIhvcNAQEL BQAwDTELMAkGA1UEAxMCZmEwHhcNMTgwMTEwMTg1NDI5WhcNMTgwMjExMTg1NDU5 WjANMQswCQYDVQQDEwJmYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB @@ -55,82 +61,63 @@ ZzkXwRCdcJARkaKulTfjby7+oGpQydP8iZr+CNKFxwf838UbhhsXHnN6rc62qzYD BXUV2Uwtxf+QCphnlht9muX2fsLIzDJea0JipWj1uf2H8OZsjE8= -----END RSA PRIVATE KEY-----`; -const mountAndNav = (assert, prefix) => { - const path = `${prefix}pki-${new Date().getTime()}`; - mountSupportedSecretBackend(assert, 'pki', path); - page.visit({ backend: path }); - return path; -}; + const mountAndNav = async (assert, prefix) => { + const path = `${prefix}pki-${new Date().getTime()}`; + await enablePage.enable('pki', path); + await page.visit({ backend: path }); + return path; + }; -test('cert config: generate', function(assert) { - mountAndNav(assert); - andThen(() => { + test('cert config: generate', async function(assert) { + await mountAndNav(assert); assert.equal(currentRouteName(), 'vault.cluster.settings.configure-secret-backend.section'); - }); - page.form.generateCA(); - andThen(() => { - assert.ok(page.form.rows().count > 0, 'shows all of the rows'); + await page.form.generateCA(); + assert.ok(page.form.rows.length > 0, 'shows all of the rows'); assert.ok(page.form.certificateIsPresent, 'the certificate is included'); + + await page.form.back(); + await withFlash(page.form.generateCA(), () => { + assert.ok( + page.flash.latestMessage.includes('You tried to generate a new root CA'), + 'shows warning message' + ); + }); }); - page.form.back(); - page.form.generateCA(); - andThen(() => { - assert.ok( - page.flash.latestMessage.includes('You tried to generate a new root CA'), - 'shows warning message' - ); - }); -}); + test('cert config: upload', async function(assert) { + await mountAndNav(assert); + assert.equal(page.form.downloadLinks.length, 0, 'there are no download links'); -test('cert config: upload', function(assert) { - mountAndNav(assert); - andThen(() => { - assert.equal(page.form.downloadLinks().count, 0, 'there are no download links'); + await withFlash(page.form.uploadCA(PEM_BUNDLE), () => { + assert.ok( + page.flash.latestMessage.startsWith('The certificate for this backend has been updated'), + 'flash message displays properly' + ); + }); }); - page.form.uploadCA(PEM_BUNDLE); - andThen(() => { - assert.ok( - page.flash.latestMessage.startsWith('The certificate for this backend has been updated'), - 'flash message displays properly' - ); - }); -}); + test('cert config: sign intermediate and set signed intermediate', async function(assert) { + let csrVal, intermediateCert; + const rootPath = await mountAndNav(assert, 'root-'); + await page.form.generateCA(); -test('cert config: sign intermediate and set signed intermediate', function(assert) { - let csrVal, intermediateCert; - const rootPath = mountAndNav(assert, 'root-'); - page.form.generateCA(); - - const intermediatePath = mountAndNav(assert, 'intermediate-'); - page.form.generateCA('Intermediate CA', 'intermediate'); - andThen(() => { + const intermediatePath = await mountAndNav(assert, 'intermediate-'); + await page.form.generateCA('Intermediate CA', 'intermediate'); // cache csr csrVal = page.form.csr; - }); - page.form.back(); + await page.form.back(); - page.visit({ backend: rootPath }); - page.form.signIntermediate('Intermediate CA'); - andThen(() => { - page.form.csrField(csrVal).submit(); - }); - andThen(() => { + await page.visit({ backend: rootPath }); + await page.form.signIntermediate('Intermediate CA'); + await page.form.csrField(csrVal).submit(); intermediateCert = page.form.certificate; - }); - page.form.back(); - page.visit({ backend: intermediatePath }); + await page.form.back(); + await page.visit({ backend: intermediatePath }); + await page.form.setSignedIntermediateBtn().signedIntermediate(intermediateCert); - andThen(() => { - page.form.setSignedIntermediateBtn().signedIntermediate(intermediateCert).submit(); - }); - andThen(() => { - assert.ok( - page.flash.latestMessage.startsWith('The certificate for this backend has been updated'), - 'flash message displays properly' - ); - assert.equal(page.form.downloadLinks().count, 3, 'includes the caChain download link'); + await page.form.submit(); + await settled(); + assert.equal(page.form.downloadLinks.length, 3, 'includes the caChain download link'); }); }); diff --git a/ui/tests/acceptance/settings/configure-secret-backends/pki/section-crl-test.js b/ui/tests/acceptance/settings/configure-secret-backends/pki/section-crl-test.js index a196fc522..381198620 100644 --- a/ui/tests/acceptance/settings/configure-secret-backends/pki/section-crl-test.js +++ b/ui/tests/acceptance/settings/configure-secret-backends/pki/section-crl-test.js @@ -1,26 +1,28 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/settings/configure-secret-backends/pki/section'; +import authPage from 'vault/tests/pages/auth'; +import enablePage from 'vault/tests/pages/settings/mount-secret-backend'; +import withFlash from 'vault/tests/helpers/with-flash'; -moduleForAcceptance('Acceptance | settings/configure/secrets/pki/crl', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | settings/configure/secrets/pki/crl', function(hooks) { + setupApplicationTest(hooks); -test('it saves crl config', function(assert) { - const path = `pki-${new Date().getTime()}`; - mountSupportedSecretBackend(assert, 'pki', path); - page.visit({ backend: path, section: 'crl' }); - andThen(() => { + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it saves crl config', async function(assert) { + const path = `pki-${new Date().getTime()}`; + await enablePage.enable('pki', path); + await page.visit({ backend: path, section: 'crl' }); assert.equal(currentRouteName(), 'vault.cluster.settings.configure-secret-backend.section'); - }); - page.form.fillInField('time', 3); - page.form.fillInField('unit', 'h'); - page.form.submit(); - - andThen(() => { - assert.equal(page.lastMessage, 'The crl config for this backend has been updated.'); + await page.form.fillInField('time', 3); + await page.form.fillInField('unit', 'h'); + await withFlash(page.form.submit(), () => { + assert.equal(page.lastMessage, 'The crl config for this backend has been updated.'); + }); }); }); diff --git a/ui/tests/acceptance/settings/configure-secret-backends/pki/section-tidy-test.js b/ui/tests/acceptance/settings/configure-secret-backends/pki/section-tidy-test.js index 40c66e544..a1fc65579 100644 --- a/ui/tests/acceptance/settings/configure-secret-backends/pki/section-tidy-test.js +++ b/ui/tests/acceptance/settings/configure-secret-backends/pki/section-tidy-test.js @@ -1,26 +1,27 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/settings/configure-secret-backends/pki/section'; +import authPage from 'vault/tests/pages/auth'; +import enablePage from 'vault/tests/pages/settings/mount-secret-backend'; +import withFlash from 'vault/tests/helpers/with-flash'; -moduleForAcceptance('Acceptance | settings/configure/secrets/pki/tidy', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | settings/configure/secrets/pki/tidy', function(hooks) { + setupApplicationTest(hooks); -test('it saves tidy config', function(assert) { - const path = `pki-${new Date().getTime()}`; - mountSupportedSecretBackend(assert, 'pki', path); - page.visit({ backend: path, section: 'tidy' }); - andThen(() => { + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it saves tidy config', async function(assert) { + const path = `pki-${new Date().getTime()}`; + await enablePage.enable('pki', path); + await page.visit({ backend: path, section: 'tidy' }); assert.equal(currentRouteName(), 'vault.cluster.settings.configure-secret-backend.section'); - page.form.fields(); - }); + await page.form.fields.objectAt(0).clickLabel(); - page.form.fields(0).clickLabel(); - page.form.submit(); - - andThen(() => { - assert.equal(page.lastMessage, 'The tidy config for this backend has been updated.'); + await withFlash(page.form.submit(), () => { + assert.equal(page.lastMessage, 'The tidy config for this backend has been updated.'); + }); }); }); diff --git a/ui/tests/acceptance/settings/configure-secret-backends/pki/section-urls-test.js b/ui/tests/acceptance/settings/configure-secret-backends/pki/section-urls-test.js index 92b270b88..dbbc6714a 100644 --- a/ui/tests/acceptance/settings/configure-secret-backends/pki/section-urls-test.js +++ b/ui/tests/acceptance/settings/configure-secret-backends/pki/section-urls-test.js @@ -1,38 +1,38 @@ -import Ember from 'ember'; -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/settings/configure-secret-backends/pki/section'; -let adapterException; -moduleForAcceptance('Acceptance | settings/configure/secrets/pki/urls', { - beforeEach() { - adapterException = Ember.Test.adapter.exception; - Ember.Test.adapter.exception = () => null; - return authLogin(); - }, - afterEach() { - Ember.Test.adapter.exception = adapterException; - }, -}); +import authPage from 'vault/tests/pages/auth'; +import enablePage from 'vault/tests/pages/settings/mount-secret-backend'; +import withFlash from 'vault/tests/helpers/with-flash'; -test('it saves urls config', function(assert) { - const path = `pki-${new Date().getTime()}`; - mountSupportedSecretBackend(assert, 'pki', path); - page.visit({ backend: path, section: 'urls' }); - andThen(() => { +module('Acceptance | settings/configure/secrets/pki/urls', function(hooks) { + setupApplicationTest(hooks); + + hooks.beforeEach(function() { + return authPage.login(); + }); + + test('it saves urls config', async function(assert) { + const path = `pki-${new Date().getTime()}`; + await enablePage.enable('pki', path); + await page.visit({ backend: path, section: 'urls' }); assert.equal(currentRouteName(), 'vault.cluster.settings.configure-secret-backend.section'); - }); - page.form.fields(0).input('foo').change(); - page.form.submit(); + await page.form.fields + .objectAt(0) + .input('foo') + .change(); + await page.form.submit(); - andThen(() => { assert.ok(page.form.hasError, 'shows error on invalid input'); - }); - page.form.fields(0).input('foo.example.com').change(); - page.form.submit(); - - andThen(() => { - assert.equal(page.lastMessage, 'The urls config for this backend has been updated.'); + await page.form.fields + .objectAt(0) + .input('foo.example.com') + .change(); + await withFlash(page.form.submit(), () => { + assert.equal(page.lastMessage, 'The urls config for this backend has been updated.'); + }); }); }); diff --git a/ui/tests/acceptance/settings/mount-secret-backend-test.js b/ui/tests/acceptance/settings/mount-secret-backend-test.js index 04af15223..46083c53c 100644 --- a/ui/tests/acceptance/settings/mount-secret-backend-test.js +++ b/ui/tests/acceptance/settings/mount-secret-backend-test.js @@ -1,40 +1,41 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { currentRouteName } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import page from 'vault/tests/pages/settings/mount-secret-backend'; import configPage from 'vault/tests/pages/secrets/backend/configuration'; +import authPage from 'vault/tests/pages/auth'; +import withFlash from 'vault/tests/helpers/with-flash'; -moduleForAcceptance('Acceptance | settings/mount-secret-backend', { - beforeEach() { - return authLogin(); - }, -}); +module('Acceptance | settings/mount-secret-backend', function(hooks) { + setupApplicationTest(hooks); -test('it sets the ttl corrects when mounting', function(assert) { - // always force the new mount to the top of the list - const path = `kv-${new Date().getTime()}`; - const defaultTTLHours = 100; - const maxTTLHours = 300; - const defaultTTLSeconds = defaultTTLHours * 60 * 60; - const maxTTLSeconds = maxTTLHours * 60 * 60; + hooks.beforeEach(function() { + return authPage.login(); + }); - page.visit(); - andThen(() => { + test('it sets the ttl corrects when mounting', async function(assert) { + // always force the new mount to the top of the list + const path = `kv-${new Date().getTime()}`; + const defaultTTLHours = 100; + const maxTTLHours = 300; + const defaultTTLSeconds = defaultTTLHours * 60 * 60; + const maxTTLSeconds = maxTTLHours * 60 * 60; + + await page.visit(); assert.equal(currentRouteName(), 'vault.cluster.settings.mount-secret-backend'); - page - .selectType('kv') - .next() - .path(path) - .toggleOptions() - .defaultTTLVal(defaultTTLHours) - .defaultTTLUnit('h') - .maxTTLVal(maxTTLHours) - .maxTTLUnit('h') - .submit(); - }); - andThen(() => { - configPage.visit({ backend: path }); - }); - andThen(() => { + await page.selectType('kv'); + await withFlash( + page + .next() + .path(path) + .toggleOptions() + .defaultTTLVal(defaultTTLHours) + .defaultTTLUnit('h') + .maxTTLVal(maxTTLHours) + .maxTTLUnit('h') + .submit() + ); + await configPage.visit({ backend: path }); assert.equal(configPage.defaultTTL, defaultTTLSeconds, 'shows the proper TTL'); assert.equal(configPage.maxTTL, maxTTLSeconds, 'shows the proper max TTL'); }); diff --git a/ui/tests/acceptance/ssh-test.js b/ui/tests/acceptance/ssh-test.js index 9abee52b4..572b231f1 100644 --- a/ui/tests/acceptance/ssh-test.js +++ b/ui/tests/acceptance/ssh-test.js @@ -1,151 +1,135 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { click, fillIn, findAll, currentURL, find, settled } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import authPage from 'vault/tests/pages/auth'; +import enablePage from 'vault/tests/pages/settings/mount-secret-backend'; -moduleForAcceptance('Acceptance | ssh secret backend', { - beforeEach() { - return authLogin(); - }, - afterEach() { - return authLogout(); - }, -}); +module('Acceptance | ssh secret backend', function(hooks) { + setupApplicationTest(hooks); -const PUB_KEY = `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCn9p5dHNr4aU4R2W7ln+efzO5N2Cdv/SXk6zbCcvhWcblWMjkXf802B0PbKvf6cJIzM/Xalb3qz1cK+UUjCSEAQWefk6YmfzbOikfc5EHaSKUqDdE+HlsGPvl42rjCr28qYfuYh031YfwEQGEAIEypo7OyAj+38NLbHAQxDxuaReee1YCOV5rqWGtEgl2VtP5kG+QEBza4ZfeglS85f/GGTvZC4Jq1GX+wgmFxIPnd6/mUXa4ecoR0QMfOAzzvPm4ajcNCQORfHLQKAcmiBYMiyQJoU+fYpi9CJGT1jWTmR99yBkrSg6yitI2qqXyrpwAbhNGrM0Fw0WpWxh66N9Xp meirish@Macintosh-3.local`; + hooks.beforeEach(function() { + return authPage.login(); + }); -const ROLES = [ - { - type: 'ca', - name: 'carole', - fillInCreate() { - click('[data-test-input="allowUserCertificates"]'); - }, - fillInGenerate() { - fillIn('[data-test-input="publicKey"]', PUB_KEY); - }, - assertAfterGenerate(assert, sshPath) { - assert.equal(currentURL(), `/vault/secrets/${sshPath}/sign/${this.name}`, 'ca sign url is correct'); - assert.dom('[data-test-row-label="Signed key"]').exists({ count: 1 }, 'renders the signed key'); - assert.dom('[data-test-row-value="Signed key"]').exists({ count: 1 }, "renders the signed key's value"); - assert.dom('[data-test-row-label="Serial number"]').exists({ count: 1 }, 'renders the serial'); - assert.dom('[data-test-row-value="Serial number"]').exists({ count: 1 }, 'renders the serial value'); - }, - }, - { - type: 'otp', - name: 'otprole', - fillInCreate() { - fillIn('[data-test-input="defaultUser"]', 'admin'); - click('[data-test-toggle-more]'); - fillIn('[data-test-input="cidrList"]', '1.2.3.4/32'); - }, - fillInGenerate() { - fillIn('[data-test-input="username"]', 'admin'); - fillIn('[data-test-input="ip"]', '1.2.3.4'); - }, - assertAfterGenerate(assert, sshPath) { - assert.equal( - currentURL(), - `/vault/secrets/${sshPath}/credentials/${this.name}`, - 'otp credential url is correct' - ); - assert.dom('[data-test-row-label="Key"]').exists({ count: 1 }, 'renders the key'); - assert.dom('[data-test-row-value="Key"]').exists({ count: 1 }, "renders the key's value"); - assert.dom('[data-test-row-label="Port"]').exists({ count: 1 }, 'renders the port'); - assert.dom('[data-test-row-value="Port"]').exists({ count: 1 }, "renders the port's value"); - }, - }, -]; -test('ssh backend', function(assert) { - const now = new Date().getTime(); - const sshPath = `ssh-${now}`; + const PUB_KEY = `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCn9p5dHNr4aU4R2W7ln+efzO5N2Cdv/SXk6zbCcvhWcblWMjkXf802B0PbKvf6cJIzM/Xalb3qz1cK+UUjCSEAQWefk6YmfzbOikfc5EHaSKUqDdE+HlsGPvl42rjCr28qYfuYh031YfwEQGEAIEypo7OyAj+38NLbHAQxDxuaReee1YCOV5rqWGtEgl2VtP5kG+QEBza4ZfeglS85f/GGTvZC4Jq1GX+wgmFxIPnd6/mUXa4ecoR0QMfOAzzvPm4ajcNCQORfHLQKAcmiBYMiyQJoU+fYpi9CJGT1jWTmR99yBkrSg6yitI2qqXyrpwAbhNGrM0Fw0WpWxh66N9Xp meirish@Macintosh-3.local`; - mountSupportedSecretBackend(assert, 'ssh', sshPath); - click('[data-test-secret-backend-configure]'); - andThen(() => { + const ROLES = [ + { + type: 'ca', + name: 'carole', + async fillInCreate() { + await click('[data-test-input="allowUserCertificates"]'); + }, + async fillInGenerate() { + await fillIn('[data-test-input="publicKey"]', PUB_KEY); + }, + assertAfterGenerate(assert, sshPath) { + assert.equal(currentURL(), `/vault/secrets/${sshPath}/sign/${this.name}`, 'ca sign url is correct'); + assert.dom('[data-test-row-label="Signed key"]').exists({ count: 1 }, 'renders the signed key'); + assert + .dom('[data-test-row-value="Signed key"]') + .exists({ count: 1 }, "renders the signed key's value"); + assert.dom('[data-test-row-label="Serial number"]').exists({ count: 1 }, 'renders the serial'); + assert.dom('[data-test-row-value="Serial number"]').exists({ count: 1 }, 'renders the serial value'); + }, + }, + { + type: 'otp', + name: 'otprole', + async fillInCreate() { + await fillIn('[data-test-input="defaultUser"]', 'admin'); + await click('[data-test-toggle-more]'); + await fillIn('[data-test-input="cidrList"]', '1.2.3.4/32'); + }, + async fillInGenerate() { + await fillIn('[data-test-input="username"]', 'admin'); + await fillIn('[data-test-input="ip"]', '1.2.3.4'); + }, + assertAfterGenerate(assert, sshPath) { + assert.equal( + currentURL(), + `/vault/secrets/${sshPath}/credentials/${this.name}`, + 'otp credential url is correct' + ); + assert.dom('[data-test-row-label="Key"]').exists({ count: 1 }, 'renders the key'); + assert.dom('[data-test-row-value="Key"]').exists({ count: 1 }, "renders the key's value"); + assert.dom('[data-test-row-label="Port"]').exists({ count: 1 }, 'renders the port'); + assert.dom('[data-test-row-value="Port"]').exists({ count: 1 }, "renders the port's value"); + }, + }, + ]; + test('ssh backend', async function(assert) { + const now = new Date().getTime(); + const sshPath = `ssh-${now}`; + + await enablePage.enable('ssh', sshPath); + await click('[data-test-secret-backend-configure]'); assert.equal(currentURL(), `/vault/settings/secrets/configure/${sshPath}`); - assert.ok(find('[data-test-ssh-configure-form]').length, 'renders the empty configuration form'); - }); + assert.ok(findAll('[data-test-ssh-configure-form]').length, 'renders the empty configuration form'); - // default has generate CA checked so we just submit the form - click('[data-test-ssh-input="configure-submit"]'); - andThen(() => { - assert.ok(find('[data-test-ssh-input="public-key"]').length, 'a public key is fetched'); - }); - click('[data-test-backend-view-link]'); + // default has generate CA checked so we just submit the form + await click('[data-test-ssh-input="configure-submit"]'); + + assert.ok(findAll('[data-test-ssh-input="public-key"]').length, 'a public key is fetched'); + await click('[data-test-backend-view-link]'); - //back at the roles list - andThen(() => { assert.equal(currentURL(), `/vault/secrets/${sshPath}/list`, `redirects to ssh index`); - }); - ROLES.forEach(role => { - // create a role - click('[ data-test-secret-create]'); - andThen(() => { + for (let role of ROLES) { + // create a role + await click('[ data-test-secret-create]'); assert.ok( - find('[data-test-secret-header]').text().includes('SSH Role'), + find('[data-test-secret-header]').textContent.includes('SSH Role'), `${role.type}: renders the create page` ); - }); - fillIn('[data-test-input="name"]', role.name); - fillIn('[data-test-input="keyType"]', role.type); - role.fillInCreate(); + await fillIn('[data-test-input="name"]', role.name); + await fillIn('[data-test-input="keyType"]', role.type); + await role.fillInCreate(); - // save the role - click('[data-test-role-ssh-create]'); - andThen(() => { + // save the role + await click('[data-test-role-ssh-create]'); assert.equal( currentURL(), `/vault/secrets/${sshPath}/show/${role.name}`, `${role.type}: navigates to the show page on creation` ); - }); - // sign a key with this role - click('[data-test-backend-credentials]'); - role.fillInGenerate(); + // sign a key with this role + await click('[data-test-backend-credentials]'); + await role.fillInGenerate(); - // generate creds - click('[data-test-secret-generate]'); - andThen(() => { + // generate creds + await click('[data-test-secret-generate]'); role.assertAfterGenerate(assert, sshPath); - }); - // click the "Back" button - click('[data-test-secret-generate-back]'); - andThen(() => { + // click the "Back" button + await click('[data-test-secret-generate-back]'); assert.ok( - find('[data-test-secret-generate-form]').length, + findAll('[data-test-secret-generate-form]').length, `${role.type}: back takes you back to the form` ); - }); - click('[data-test-secret-generate-cancel]'); - //back at the roles list - andThen(() => { + await click('[data-test-secret-generate-cancel]'); assert.equal( currentURL(), `/vault/secrets/${sshPath}/list`, `${role.type}: cancel takes you to ssh index` ); assert.ok( - find(`[data-test-secret-link="${role.name}"]`).length, + findAll(`[data-test-secret-link="${role.name}"]`).length, `${role.type}: role shows in the list` ); - }); - //and delete - click(`[data-test-secret-link="${role.name}"] [data-test-popup-menu-trigger]`); - andThen(() => { - click(`[data-test-ssh-role-delete="${role.name}"] button`); - }); - click(`[data-test-confirm-button]`); + //and delete + await click(`[data-test-secret-link="${role.name}"] [data-test-popup-menu-trigger]`); + await click(`[data-test-ssh-role-delete="${role.name}"] button`); + await click(`[data-test-confirm-button]`); - andThen(() => { + await settled(); assert .dom(`[data-test-secret-link="${role.name}"]`) .doesNotExist(`${role.type}: role is no longer in the list`); - }); + } }); }); diff --git a/ui/tests/acceptance/tools-test.js b/ui/tests/acceptance/tools-test.js index efd48c510..29c43589c 100644 --- a/ui/tests/acceptance/tools-test.js +++ b/ui/tests/acceptance/tools-test.js @@ -1,169 +1,146 @@ +import { click, fillIn, find, findAll, currentURL, visit } from '@ember/test-helpers'; import Pretender from 'pretender'; -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import { toolsActions } from 'vault/helpers/tools-actions'; +import authPage from 'vault/tests/pages/auth'; +import logout from 'vault/tests/pages/logout'; -moduleForAcceptance('Acceptance | tools', { - beforeEach() { - return authLogin(); - }, - afterEach() { - return authLogout(); - } -}); +module('Acceptance | tools', function(hooks) { + setupApplicationTest(hooks); -const DATA_TO_WRAP = JSON.stringify({ tools: 'tests' }); -const TOOLS_ACTIONS = toolsActions(); + hooks.beforeEach(function() { + return authPage.login(); + }); -/* -data-test-tools-input="wrapping-token" -data-test-tools-input="rewrapped-token" -data-test-tools="token-lookup-row" -data-test-tools-action-link=supportedAction -*/ + hooks.afterEach(function() { + return logout.visit(); + }); -var createTokenStore = () => { - let token; - return { - set(val) { - token = val; - }, - get() { - return token; - }, + const DATA_TO_WRAP = JSON.stringify({ tools: 'tests' }); + const TOOLS_ACTIONS = toolsActions(); + + /* + data-test-tools-input="wrapping-token" + data-test-tools-input="rewrapped-token" + data-test-tools="token-lookup-row" + data-test-tools-action-link=supportedAction + */ + + var createTokenStore = () => { + let token; + return { + set(val) { + token = val; + }, + get() { + return token; + }, + }; }; -}; -test('tools functionality', function(assert) { - var tokenStore = createTokenStore(); - visit('/vault/tools'); - andThen(function() { + test('tools functionality', async function(assert) { + var tokenStore = createTokenStore(); + await visit('/vault/tools'); assert.equal(currentURL(), '/vault/tools/wrap', 'forwards to the first action'); TOOLS_ACTIONS.forEach(action => { - assert.ok(findWithAssert(`[data-test-tools-action-link="${action}"]`), `${action} link renders`); + assert.ok(find(`[data-test-tools-action-link="${action}"]`), `${action} link renders`); }); - find('.CodeMirror').get(0).CodeMirror.setValue(DATA_TO_WRAP); - }); + findAll('.CodeMirror')[0].CodeMirror.setValue(DATA_TO_WRAP); - // wrap - click('[data-test-tools-submit]'); - andThen(function() { - tokenStore.set(find('[data-test-tools-input="wrapping-token"]').val()); - assert.ok(find('[data-test-tools-input="wrapping-token"]').val(), 'has a wrapping token'); - }); + // wrap + await click('[data-test-tools-submit]'); + tokenStore.set(find('[data-test-tools-input="wrapping-token"]').value); + assert.ok(find('[data-test-tools-input="wrapping-token"]').value, 'has a wrapping token'); - //lookup - click('[data-test-tools-action-link="lookup"]'); - // have to wrap this in andThen because tokenStore is sync, but fillIn is async - andThen(() => { - fillIn('[data-test-tools-input="wrapping-token"]', tokenStore.get()); - }); - click('[data-test-tools-submit]'); - andThen(() => { + //lookup + await click('[data-test-tools-action-link="lookup"]'); + await fillIn('[data-test-tools-input="wrapping-token"]', tokenStore.get()); + await click('[data-test-tools-submit]'); let rows = document.querySelectorAll('[data-test-tools="token-lookup-row"]'); assert.dom(rows[0]).hasText(/Creation path/, 'show creation path row'); assert.dom(rows[1]).hasText(/Creation time/, 'show creation time row'); assert.dom(rows[2]).hasText(/Creation TTL/, 'show creation ttl row'); - }); - //rewrap - click('[data-test-tools-action-link="rewrap"]'); - andThen(() => { - fillIn('[data-test-tools-input="wrapping-token"]', tokenStore.get()); - }); - click('[data-test-tools-submit]'); - andThen(() => { - assert.ok(find('[data-test-tools-input="rewrapped-token"]').val(), 'has a new re-wrapped token'); + //rewrap + await click('[data-test-tools-action-link="rewrap"]'); + await fillIn('[data-test-tools-input="wrapping-token"]', tokenStore.get()); + await click('[data-test-tools-submit]'); + assert.ok(find('[data-test-tools-input="rewrapped-token"]').value, 'has a new re-wrapped token'); assert.notEqual( - find('[data-test-tools-input="rewrapped-token"]').val(), + find('[data-test-tools-input="rewrapped-token"]').value, tokenStore.get(), 're-wrapped token is not the wrapped token' ); - tokenStore.set(find('[data-test-tools-input="rewrapped-token"]').val()); - }); + tokenStore.set(find('[data-test-tools-input="rewrapped-token"]').value); - //unwrap - click('[data-test-tools-action-link="unwrap"]'); - andThen(() => { - fillIn('[data-test-tools-input="wrapping-token"]', tokenStore.get()); - }); - click('[data-test-tools-submit]'); - andThen(() => { + //unwrap + await click('[data-test-tools-action-link="unwrap"]'); + await fillIn('[data-test-tools-input="wrapping-token"]', tokenStore.get()); + await click('[data-test-tools-submit]'); assert.deepEqual( - JSON.parse(find('.CodeMirror').get(0).CodeMirror.getValue()), + JSON.parse(findAll('.CodeMirror')[0].CodeMirror.getValue()), JSON.parse(DATA_TO_WRAP), 'unwrapped data equals input data' ); - }); - //random - click('[data-test-tools-action-link="random"]'); - andThen(() => { + //random + await click('[data-test-tools-action-link="random"]'); assert.dom('[data-test-tools-input="bytes"]').hasValue('32', 'defaults to 32 bytes'); - }); - click('[data-test-tools-submit]'); - andThen(() => { + await click('[data-test-tools-submit]'); assert.ok( - find('[data-test-tools-input="random-bytes"]').val(), + find('[data-test-tools-input="random-bytes"]').value, 'shows the returned value of random bytes' ); - }); - //hash - click('[data-test-tools-action-link="hash"]'); - fillIn('[data-test-tools-input="hash-input"]', 'foo'); - click('[data-test-tools-b64-toggle="input"]'); - click('[data-test-tools-submit]'); - andThen(() => { + //hash + await click('[data-test-tools-action-link="hash"]'); + await fillIn('[data-test-tools-input="hash-input"]', 'foo'); + await click('[data-test-tools-b64-toggle="input"]'); + await click('[data-test-tools-submit]'); assert .dom('[data-test-tools-input="sum"]') .hasValue('LCa0a2j/xo/5m0U8HTBBNBNCLXBkg7+g+YpeiGJm564=', 'hashes the data, encodes input'); - }); - click('[data-test-tools-back]'); - fillIn('[data-test-tools-input="hash-input"]', 'e2RhdGE6ImZvbyJ9'); + await click('[data-test-tools-back]'); + await fillIn('[data-test-tools-input="hash-input"]', 'e2RhdGE6ImZvbyJ9'); - click('[data-test-tools-submit]'); - andThen(() => { + await click('[data-test-tools-submit]'); assert .dom('[data-test-tools-input="sum"]') .hasValue('JmSi2Hhbgu2WYOrcOyTqqMdym7KT3sohCwAwaMonVrc=', 'hashes the data, passes b64 input through'); }); -}); -const AUTH_RESPONSE = { - request_id: '39802bc4-235c-2f0b-87f3-ccf38503ac3e', - lease_id: '', - renewable: false, - lease_duration: 0, - data: null, - wrap_info: null, - warnings: null, - auth: { - client_token: 'ecfc2758-588e-981d-50f4-a25883bbf03c', - accessor: '6299780b-f2b2-1a3f-7b83-9d3d67629249', - policies: ['root'], - metadata: null, - lease_duration: 0, + const AUTH_RESPONSE = { + request_id: '39802bc4-235c-2f0b-87f3-ccf38503ac3e', + lease_id: '', renewable: false, - entity_id: '', - }, -}; + lease_duration: 0, + data: null, + wrap_info: null, + warnings: null, + auth: { + client_token: 'ecfc2758-588e-981d-50f4-a25883bbf03c', + accessor: '6299780b-f2b2-1a3f-7b83-9d3d67629249', + policies: ['root'], + metadata: null, + lease_duration: 0, + renewable: false, + entity_id: '', + }, + }; -test('ensure unwrap with auth block works properly', function(assert) { - this.server = new Pretender(function() { - this.post('/v1/sys/wrapping/unwrap', response => { - return [response, { 'Content-Type': 'application/json' }, JSON.stringify(AUTH_RESPONSE)]; + test('ensure unwrap with auth block works properly', async function(assert) { + this.server = new Pretender(function() { + this.post('/v1/sys/wrapping/unwrap', response => { + return [response, { 'Content-Type': 'application/json' }, JSON.stringify(AUTH_RESPONSE)]; + }); }); - }); - visit('/vault/tools'); - //unwrap - click('[data-test-tools-action-link="unwrap"]'); - andThen(() => { - fillIn('[data-test-tools-input="wrapping-token"]', 'sometoken'); - }); - click('[data-test-tools-submit]'); - andThen(() => { + await visit('/vault/tools'); + //unwrap + await click('[data-test-tools-action-link="unwrap"]'); + await fillIn('[data-test-tools-input="wrapping-token"]', 'sometoken'); + await click('[data-test-tools-submit]'); assert.deepEqual( - JSON.parse(find('.CodeMirror').get(0).CodeMirror.getValue()), + JSON.parse(findAll('.CodeMirror')[0].CodeMirror.getValue()), AUTH_RESPONSE.auth, 'unwrapped data equals input data' ); diff --git a/ui/tests/acceptance/transit-test.js b/ui/tests/acceptance/transit-test.js index dd3cdad3f..0393e6cf1 100644 --- a/ui/tests/acceptance/transit-test.js +++ b/ui/tests/acceptance/transit-test.js @@ -1,17 +1,11 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { click, fillIn, find, currentURL, settled, visit } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import { encodeString } from 'vault/utils/b64'; +import authPage from 'vault/tests/pages/auth'; +import enablePage from 'vault/tests/pages/settings/mount-secret-backend'; -moduleForAcceptance('Acceptance | transit', { - beforeEach() { - return authLogin(); - }, - afterEach() { - return authLogout(); - }, -}); - -let generateTransitKeys = () => { +let generateTransitKeys = async () => { const ts = new Date().getTime(); const keys = [ { @@ -64,28 +58,29 @@ let generateTransitKeys = () => { }, ]; - keys.forEach(key => { - click('[data-test-secret-create]'); - fillIn('[data-test-transit-key-name]', key.name); - fillIn('[data-test-transit-key-type]', key.type); + for (let key of keys) { + await click('[data-test-secret-create]'); + await fillIn('[data-test-transit-key-name]', key.name); + await fillIn('[data-test-transit-key-type]', key.type); if (key.exportable) { - click('[data-test-transit-key-exportable]'); + await click('[data-test-transit-key-exportable]'); } if (key.derived) { - click('[data-test-transit-key-derived]'); + await click('[data-test-transit-key-derived]'); } if (key.convergent) { - click('[data-test-transit-key-convergent-encryption]'); + await click('[data-test-transit-key-convergent-encryption]'); } - click('[data-test-transit-key-create]'); + await click('[data-test-transit-key-create]'); // link back to the list - click('[data-test-secret-root-link]'); - }); + await click('[data-test-secret-root-link]'); + } + await settled(); return keys; }; -const testEncryption = (assert, keyName) => { +const testEncryption = async (assert, keyName) => { const tests = [ // raw bytes for plaintext and context { @@ -96,7 +91,7 @@ const testEncryption = (assert, keyName) => { decodeAfterDecrypt: false, assertAfterEncrypt: key => { assert.ok( - /vault:/.test(find('[data-test-transit-input="ciphertext"]').val()), + /vault:/.test(find('[data-test-transit-input="ciphertext"]').value), `${key}: ciphertext shows a vault-prefixed ciphertext` ); }, @@ -127,7 +122,7 @@ const testEncryption = (assert, keyName) => { decodeAfterDecrypt: false, assertAfterEncrypt: key => { assert.ok( - /vault:/.test(find('[data-test-transit-input="ciphertext"]').val()), + /vault:/.test(find('[data-test-transit-input="ciphertext"]').value), `${key}: ciphertext shows a vault-prefixed ciphertext` ); }, @@ -154,7 +149,7 @@ const testEncryption = (assert, keyName) => { decodeAfterDecrypt: true, assertAfterEncrypt: key => { assert.ok( - /vault:/.test(find('[data-test-transit-input="ciphertext"]').val()), + /vault:/.test(find('[data-test-transit-input="ciphertext"]').value), `${key}: ciphertext shows a vault-prefixed ciphertext` ); }, @@ -178,9 +173,9 @@ const testEncryption = (assert, keyName) => { encodeContext: true, decodeAfterDecrypt: true, assertAfterEncrypt: key => { - assert.ok(findWithAssert('[data-test-transit-input="ciphertext"]'), `${key}: ciphertext box shows`); + assert.ok(find('[data-test-transit-input="ciphertext"]'), `${key}: ciphertext box shows`); assert.ok( - /vault:/.test(find('[data-test-transit-input="ciphertext"]').val()), + /vault:/.test(find('[data-test-transit-input="ciphertext"]').value), `${key}: ciphertext shows a vault-prefixed ciphertext` ); }, @@ -190,7 +185,7 @@ const testEncryption = (assert, keyName) => { .hasValue(encodeString('secret 2'), `${key}: the ui shows the encoded context`); }, assertAfterDecrypt: key => { - assert.ok(findWithAssert('[data-test-transit-input="plaintext"]'), `${key}: plaintext box shows`); + assert.ok(find('[data-test-transit-input="plaintext"]'), `${key}: plaintext box shows`); assert .dom('[data-test-transit-input="plaintext"]') .hasValue('There are many secrets 🤐', `${key}: the ui decodes plaintext`); @@ -198,80 +193,78 @@ const testEncryption = (assert, keyName) => { }, ]; - tests.forEach(testCase => { - click('[data-test-transit-action-link="encrypt"]'); - fillIn('[data-test-transit-input="plaintext"]', testCase.plaintext); - fillIn('[data-test-transit-input="context"]', testCase.context); + for (let testCase of tests) { + await click('[data-test-transit-action-link="encrypt"]'); + await fillIn('[data-test-transit-input="plaintext"]', testCase.plaintext); + await fillIn('[data-test-transit-input="context"]', testCase.context); if (testCase.encodePlaintext) { - click('[data-test-transit-b64-toggle="plaintext"]'); + await click('[data-test-transit-b64-toggle="plaintext"]'); } if (testCase.encodeContext) { - click('[data-test-transit-b64-toggle="context"]'); + await click('[data-test-transit-b64-toggle="context"]'); } - click('button:contains(Encrypt)'); + await click('[data-test-button-encrypt]'); if (testCase.assertAfterEncrypt) { - andThen(() => testCase.assertAfterEncrypt(keyName)); + testCase.assertAfterEncrypt(keyName); } - click('[data-test-transit-action-link="decrypt"]'); + await click('[data-test-transit-action-link="decrypt"]'); if (testCase.assertBeforeDecrypt) { - andThen(() => testCase.assertBeforeDecrypt(keyName)); + testCase.assertBeforeDecrypt(keyName); } - click('button:contains(Decrypt)'); + await click('[data-test-button-decrypt]'); if (testCase.assertAfterDecrypt) { - andThen(() => { - if (testCase.decodeAfterDecrypt) { - click('[data-test-transit-b64-toggle="plaintext"]'); - andThen(() => testCase.assertAfterDecrypt(keyName)); - } else { - testCase.assertAfterDecrypt(keyName); - } - }); + if (testCase.decodeAfterDecrypt) { + await click('[data-test-transit-b64-toggle="plaintext"]'); + testCase.assertAfterDecrypt(keyName); + } else { + testCase.assertAfterDecrypt(keyName); + } } - }); + } }; -test('transit backend', function(assert) { - assert.expect(49); - const now = new Date().getTime(); - const transitPath = `transit-${now}`; +module('Acceptance | transit', function(hooks) { + setupApplicationTest(hooks); - mountSupportedSecretBackend(assert, 'transit', transitPath); + hooks.beforeEach(async function() { + await authPage.login(); + const now = new Date().getTime(); + hooks.transitPath = `transit-${now}`; - // create a bunch of different kinds of keys - const transitKeys = generateTransitKeys(); + await enablePage.enable('transit', hooks.transitPath); + // create a bunch of different kinds of keys + hooks.transitKeys = await generateTransitKeys(); + }); - transitKeys.forEach((key, index) => { - click(`[data-test-secret-link="${key.name}"]`); - if (index === 0) { - click('[data-test-transit-link="versions"]'); - andThen(() => { + test('transit backend', async function(assert) { + assert.expect(47); + for (let [index, key] of hooks.transitKeys.entries()) { + await visit(`vault/secrets/${hooks.transitPath}/show/${key.name}`); + if (index === 0) { + await click('[data-test-transit-link="versions"]'); assert .dom('[data-test-transit-key-version-row]') .exists({ count: 1 }, `${key.name}: only one key version`); - }); - click('[data-test-transit-key-rotate] button'); - click('[data-test-confirm-button]'); - andThen(() => { + await click('[data-test-transit-key-rotate] button'); + await click('[data-test-confirm-button]'); assert .dom('[data-test-transit-key-version-row]') .exists({ count: 2 }, `${key.name}: two key versions after rotate`); - }); - } - click('[data-test-transit-key-actions-link]'); - andThen(() => { + } + await click('[data-test-transit-key-actions-link]'); assert.ok( - currentURL().startsWith(`/vault/secrets/${transitPath}/actions/${key.name}`), + currentURL().startsWith(`/vault/secrets/${hooks.transitPath}/actions/${key.name}`), `${key.name}: navigates to tranist actions` ); if (index === 0) { assert.ok( - findWithAssert('[data-test-transit-key-version-select]'), + find('[data-test-transit-key-version-select]'), `${key.name}: the rotated key allows you to select versions` ); } if (key.exportable) { assert.ok( - findWithAssert('[data-test-transit-action-link="export"]'), + find('[data-test-transit-action-link="export"]'), `${key.name}: exportable key has a link to export action` ); } else { @@ -280,9 +273,8 @@ test('transit backend', function(assert) { .doesNotExist(`${key.name}: non-exportable key does not link to export action`); } if (key.convergent && key.supportsEncryption) { - testEncryption(assert, key.name); + await testEncryption(assert, key.name); } - }); - click('[data-test-secret-root-link]'); + } }); }); diff --git a/ui/tests/acceptance/unseal-test.js b/ui/tests/acceptance/unseal-test.js index b009764d4..4df5dc11a 100644 --- a/ui/tests/acceptance/unseal-test.js +++ b/ui/tests/acceptance/unseal-test.js @@ -1,42 +1,39 @@ -import { test } from 'qunit'; -import moduleForAcceptance from 'vault/tests/helpers/module-for-acceptance'; +import { click, fillIn, findAll, currentURL, visit } from '@ember/test-helpers'; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; import VAULT_KEYS from 'vault/tests/helpers/vault-keys'; +import authPage from 'vault/tests/pages/auth'; +import logout from 'vault/tests/pages/logout'; +import { pollCluster } from 'vault/tests/helpers/poll-cluster'; const { unseal } = VAULT_KEYS; -moduleForAcceptance('Acceptance | unseal', { - beforeEach() { - return authLogin(); - }, - afterEach() { - return authLogout(); - }, -}); +module('Acceptance | unseal', function(hooks) { + setupApplicationTest(hooks); -test('seal then unseal', function(assert) { - visit('/vault/settings/seal'); - andThen(function() { + hooks.beforeEach(function() { + return authPage.login(); + }); + + hooks.afterEach(function() { + return logout.visit(); + }); + + test('seal then unseal', async function(assert) { + await visit('/vault/settings/seal'); assert.equal(currentURL(), '/vault/settings/seal'); - }); - // seal - click('[data-test-seal] button'); - click('[data-test-confirm-button]'); - andThen(() => { - pollCluster(); - }); - andThen(function() { + // seal + await click('[data-test-seal] button'); + await click('[data-test-confirm-button]'); + await pollCluster(this.owner); assert.equal(currentURL(), '/vault/unseal', 'vault is on the unseal page'); - }); - // unseal - fillIn('[data-test-shamir-input]', unseal); - click('button[type="submit"]'); - andThen(() => { - pollCluster(); - }); - andThen(() => { - assert.equal(find('[data-test-cluster-status]').length, 0, 'ui does not show sealed warning'); + // unseal + await fillIn('[data-test-shamir-input]', unseal); + await click('button[type="submit"]'); + await pollCluster(this.owner); + assert.equal(findAll('[data-test-cluster-status]').length, 0, 'ui does not show sealed warning'); assert.ok(currentURL().match(/\/vault\/auth/), 'vault is ready to authenticate'); }); }); diff --git a/ui/tests/helpers/.gitkeep b/ui/tests/helpers/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/ui/tests/helpers/auth-login.js b/ui/tests/helpers/auth-login.js deleted file mode 100644 index b35cb10d9..000000000 --- a/ui/tests/helpers/auth-login.js +++ /dev/null @@ -1,11 +0,0 @@ -import Ember from 'ember'; - -export default Ember.Test.registerAsyncHelper('authLogin', function(app, token) { - visit('/vault/auth?with=token'); - fillIn('[data-test-token]', token || 'root'); - click('[data-test-auth-submit]'); - // get rid of the root warning flash - if (find('[data-test-flash-message-body]').length) { - click('[data-test-flash-message-body]'); - } -}); diff --git a/ui/tests/helpers/auth-logout.js b/ui/tests/helpers/auth-logout.js deleted file mode 100644 index b44b7b450..000000000 --- a/ui/tests/helpers/auth-logout.js +++ /dev/null @@ -1,5 +0,0 @@ -import Ember from 'ember'; - -export default Ember.Test.registerAsyncHelper('authLogout', function() { - visit('/vault/logout'); -}); diff --git a/ui/tests/helpers/destroy-app.js b/ui/tests/helpers/destroy-app.js deleted file mode 100644 index 2541c6182..000000000 --- a/ui/tests/helpers/destroy-app.js +++ /dev/null @@ -1,6 +0,0 @@ -import Ember from 'ember'; - -export default function destroyApp(application) { - Ember.run(application, 'destroy'); - //server.shutdown(); -} diff --git a/ui/tests/helpers/module-for-acceptance.js b/ui/tests/helpers/module-for-acceptance.js deleted file mode 100644 index 135329425..000000000 --- a/ui/tests/helpers/module-for-acceptance.js +++ /dev/null @@ -1,23 +0,0 @@ -import { module } from 'qunit'; -import Ember from 'ember'; -import startApp from '../helpers/start-app'; -import destroyApp from '../helpers/destroy-app'; - -const { RSVP: { resolve } } = Ember; - -export default function(name, options = {}) { - module(name, { - beforeEach() { - this.application = startApp(); - - if (options.beforeEach) { - return options.beforeEach.apply(this, arguments); - } - }, - - afterEach() { - let afterEach = options.afterEach && options.afterEach.apply(this, arguments); - return resolve(afterEach).then(() => destroyApp(this.application)); - }, - }); -} diff --git a/ui/tests/helpers/mount-secret-backend.js b/ui/tests/helpers/mount-secret-backend.js deleted file mode 100644 index 47593466a..000000000 --- a/ui/tests/helpers/mount-secret-backend.js +++ /dev/null @@ -1,17 +0,0 @@ -import Ember from 'ember'; -import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend'; - -export default Ember.Test.registerAsyncHelper('mountSupportedSecretBackend', function(_, assert, type, path) { - mountSecrets.visit(); - andThen(() => { - return mountSecrets.mount(type, path); - }); - return andThen(() => { - assert.equal(currentURL(), `/vault/secrets/${path}/list`, `redirects to ${path} index`); - assert.ok( - find('[data-test-flash-message]').text().trim(), - `Successfully mounted '${type}' at '${path}'!` - ); - click('[data-test-flash-message]'); - }); -}); diff --git a/ui/tests/helpers/poll-cluster.js b/ui/tests/helpers/poll-cluster.js index 6d38ef4bf..bbe82da88 100644 --- a/ui/tests/helpers/poll-cluster.js +++ b/ui/tests/helpers/poll-cluster.js @@ -1,8 +1,13 @@ -import Ember from 'ember'; +import { run } from '@ember/runloop'; +import { registerAsyncHelper } from '@ember/test'; -export default Ember.Test.registerAsyncHelper('pollCluster', function(app) { - const clusterRoute = app.__container__.cache['route:vault/cluster']; - return Ember.run(() => { +export function pollCluster(owner) { + const clusterRoute = owner.lookup('route:vault/cluster'); + return run(() => { return clusterRoute.controller.model.reload(); }); +} + +registerAsyncHelper('pollCluster', function(app) { + pollCluster(app.__container__); }); diff --git a/ui/tests/helpers/resolver.js b/ui/tests/helpers/resolver.js deleted file mode 100644 index 319b45fc1..000000000 --- a/ui/tests/helpers/resolver.js +++ /dev/null @@ -1,11 +0,0 @@ -import Resolver from '../../resolver'; -import config from '../../config/environment'; - -const resolver = Resolver.create(); - -resolver.namespace = { - modulePrefix: config.modulePrefix, - podModulePrefix: config.podModulePrefix, -}; - -export default resolver; diff --git a/ui/tests/helpers/start-app.js b/ui/tests/helpers/start-app.js deleted file mode 100644 index c64e9b273..000000000 --- a/ui/tests/helpers/start-app.js +++ /dev/null @@ -1,23 +0,0 @@ -import Ember from 'ember'; -import Application from '../../app'; -import config from '../../config/environment'; - -import './auth-login'; -import './auth-logout'; -import './mount-secret-backend'; -import './poll-cluster'; - -import registerClipboardHelpers from '../helpers/ember-cli-clipboard'; -registerClipboardHelpers(); - -export default function startApp(attrs) { - let attributes = Ember.merge({}, config.APP); - attributes = Ember.merge(attributes, attrs); // use defaults, but you can override; - - return Ember.run(() => { - let application = Application.create(attributes); - application.setupForTesting(); - application.injectTestHelpers(); - return application; - }); -} diff --git a/ui/tests/helpers/wait-for-error.js b/ui/tests/helpers/wait-for-error.js new file mode 100644 index 000000000..f7af5a519 --- /dev/null +++ b/ui/tests/helpers/wait-for-error.js @@ -0,0 +1,15 @@ +import { waitUntil } from '@ember/test-helpers'; +import Ember from 'ember'; + +export default function waitForError(opts) { + const orig = Ember.onerror; + + let error = null; + Ember.onerror = err => { + error = err; + }; + + return waitUntil(() => error, opts).finally(() => { + Ember.onerror = orig; + }); +} diff --git a/ui/tests/helpers/with-flash.js b/ui/tests/helpers/with-flash.js new file mode 100644 index 000000000..0d12c1c8b --- /dev/null +++ b/ui/tests/helpers/with-flash.js @@ -0,0 +1,13 @@ +import { create } from 'ember-cli-page-object'; +import flashMessage from 'vault/tests/pages/components/flash-message'; + +const flash = create(flashMessage); + +export default async function withFlash(promise, assertion) { + await flash.waitForFlash(); + if (assertion) { + assertion(); + } + await flash.clickAll(); + await promise; +} diff --git a/ui/tests/integration/components/auth-config-form/options-test.js b/ui/tests/integration/components/auth-config-form/options-test.js index f3428720e..77459e98f 100644 --- a/ui/tests/integration/components/auth-config-form/options-test.js +++ b/ui/tests/integration/components/auth-config-form/options-test.js @@ -1,6 +1,8 @@ -import { moduleForComponent, test } from 'ember-qunit'; -import Ember from 'ember'; -import wait from 'ember-test-helpers/wait'; +import { resolve } from 'rsvp'; +import EmberObject from '@ember/object'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, settled } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import sinon from 'sinon'; @@ -9,34 +11,35 @@ import authConfigForm from 'vault/tests/pages/components/auth-config-form/option const component = create(authConfigForm); -moduleForComponent('auth-config-form/options', 'Integration | Component | auth-config-form options', { - integration: true, - beforeEach() { - Ember.getOwner(this).lookup('service:flash-messages').registerTypes(['success']); +module('Integration | Component | auth-config-form options', function(hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function() { + this.owner.lookup('service:flash-messages').registerTypes(['success']); component.setContext(this); - }, + }); - afterEach() { + hooks.afterEach(function() { component.removeContext(); - }, -}); + }); -test('it submits data correctly', function(assert) { - let model = Ember.Object.create({ - tune() { - return Ember.RSVP.resolve(); - }, - config: { - serialize() { - return {}; + test('it submits data correctly', async function(assert) { + let model = EmberObject.create({ + tune() { + return resolve(); }, - }, - }); - sinon.spy(model.config, 'serialize'); - this.set('model', model); - this.render(hbs`{{auth-config-form/options model=model}}`); - component.save(); - wait().then(() => { - assert.ok(model.config.serialize.calledOnce); + config: { + serialize() { + return {}; + }, + }, + }); + sinon.spy(model.config, 'serialize'); + this.set('model', model); + await render(hbs`{{auth-config-form/options model=model}}`); + component.save(); + return settled().then(() => { + assert.ok(model.config.serialize.calledOnce); + }); }); }); diff --git a/ui/tests/integration/components/auth-form-test.js b/ui/tests/integration/components/auth-form-test.js index 834ac1176..f863722ff 100644 --- a/ui/tests/integration/components/auth-form-test.js +++ b/ui/tests/integration/components/auth-form-test.js @@ -1,7 +1,12 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { later, run } from '@ember/runloop'; +import EmberObject from '@ember/object'; +import { resolve } from 'rsvp'; +import $ from 'jquery'; +import Service from '@ember/service'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, settled } from '@ember/test-helpers'; import { supportedAuthBackends } from 'vault/helpers/supported-auth-backends'; -import Ember from 'ember'; -import wait from 'ember-test-helpers/wait'; import hbs from 'htmlbars-inline-precompile'; import sinon from 'sinon'; import Pretender from 'pretender'; @@ -11,207 +16,207 @@ import authForm from '../../pages/components/auth-form'; const component = create(authForm); const BACKENDS = supportedAuthBackends(); -const authService = Ember.Service.extend({ +const authService = Service.extend({ authenticate() { - return Ember.$.getJSON('http://localhost:2000'); + return $.getJSON('http://localhost:2000'); }, setLastFetch() {}, }); -const workingAuthService = Ember.Service.extend({ +const workingAuthService = Service.extend({ authenticate() { - return Ember.RSVP.resolve({}); + return resolve({}); }, setLastFetch() {}, }); -const routerService = Ember.Service.extend({ +const routerService = Service.extend({ transitionTo() { - return Ember.RSVP.resolve(); + return resolve(); }, replaceWith() { - return Ember.RSVP.resolve(); + return resolve(); }, }); -moduleForComponent('auth-form', 'Integration | Component | auth form', { - integration: true, - beforeEach() { - Ember.getOwner(this).lookup('service:csp-event').attach(); + +module('Integration | Component | auth form', function(hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function() { + this.owner.lookup('service:csp-event').attach(); component.setContext(this); - this.register('service:router', routerService); - this.inject.service('router'); - }, + this.owner.register('service:router', routerService); + this.router = this.owner.lookup('service:router'); + }); - afterEach() { - Ember.getOwner(this).lookup('service:csp-event').remove(); + hooks.afterEach(function() { + this.owner.lookup('service:csp-event').remove(); component.removeContext(); - }, -}); - -const CSP_ERR_TEXT = `Error This is a standby Vault node but can't communicate with the active node via request forwarding. Sign in at the active node to use the Vault UI.`; -test('it renders error on CSP violation', function(assert) { - this.register('service:auth', authService); - this.inject.service('auth'); - this.set('cluster', Ember.Object.create({ standby: true })); - this.set('selectedAuth', 'token'); - this.render(hbs`{{auth-form cluster=cluster selectedAuth=selectedAuth}}`); - assert.equal(component.errorText, ''); - component.login(); - // because this is an ember-concurrency backed service, - // we have to manually force settling the run queue - Ember.run.later(() => Ember.run.cancelTimers(), 50); - return wait().then(() => { - assert.equal(component.errorText, CSP_ERR_TEXT); }); -}); -test('it renders with vault style errors', function(assert) { - let server = new Pretender(function() { - this.get('/v1/auth/**', () => { - return [ - 400, - { 'Content-Type': 'application/json' }, - JSON.stringify({ - errors: ['Not allowed'], - }), - ]; + const CSP_ERR_TEXT = `Error This is a standby Vault node but can't communicate with the active node via request forwarding. Sign in at the active node to use the Vault UI.`; + test('it renders error on CSP violation', async function(assert) { + this.owner.register('service:auth', authService); + this.auth = this.owner.lookup('service:auth'); + this.set('cluster', EmberObject.create({ standby: true })); + this.set('selectedAuth', 'token'); + await render(hbs`{{auth-form cluster=cluster selectedAuth=selectedAuth}}`); + assert.equal(component.errorText, ''); + component.login(); + // because this is an ember-concurrency backed service, + // we have to manually force settling the run queue + later(() => run.cancelTimers(), 50); + return settled().then(() => { + assert.equal(component.errorText, CSP_ERR_TEXT); }); }); - this.set('cluster', Ember.Object.create({})); - this.set('selectedAuth', 'token'); - this.render(hbs`{{auth-form cluster=cluster selectedAuth=selectedAuth}}`); - return component.login().then(() => { - assert.equal(component.errorText, 'Error Authentication failed: Not allowed'); - server.shutdown(); - }); -}); + test('it renders with vault style errors', async function(assert) { + let server = new Pretender(function() { + this.get('/v1/auth/**', () => { + return [ + 400, + { 'Content-Type': 'application/json' }, + JSON.stringify({ + errors: ['Not allowed'], + }), + ]; + }); + }); -test('it renders AdapterError style errors', function(assert) { - let server = new Pretender(function() { - this.get('/v1/auth/**', () => { - return [400, { 'Content-Type': 'application/json' }]; + this.set('cluster', EmberObject.create({})); + this.set('selectedAuth', 'token'); + await render(hbs`{{auth-form cluster=cluster selectedAuth=selectedAuth}}`); + return component.login().then(() => { + assert.equal(component.errorText, 'Error Authentication failed: Not allowed'); + server.shutdown(); }); }); - this.set('cluster', Ember.Object.create({})); - this.set('selectedAuth', 'token'); - this.render(hbs`{{auth-form cluster=cluster selectedAuth=selectedAuth}}`); - return component.login().then(() => { - assert.equal(component.errorText, 'Error Authentication failed: Bad Request'); - server.shutdown(); + test('it renders AdapterError style errors', async function(assert) { + let server = new Pretender(function() { + this.get('/v1/auth/**', () => { + return [400, { 'Content-Type': 'application/json' }]; + }); + }); + + this.set('cluster', EmberObject.create({})); + this.set('selectedAuth', 'token'); + await render(hbs`{{auth-form cluster=cluster selectedAuth=selectedAuth}}`); + return component.login().then(() => { + assert.equal(component.errorText, 'Error Authentication failed: Bad Request'); + server.shutdown(); + }); }); -}); -test('it renders all the supported tabs when no methods are passed', function(assert) { - let replaceSpy = sinon.spy(this.get('router'), 'replaceWith'); - this.render(hbs`{{auth-form cluster=cluster}}`); + test('it renders all the supported tabs when no methods are passed', async function(assert) { + let methods = { + 'approle/': { + type: 'approle', + }, + }; + let server = new Pretender(function() { + this.get('/v1/sys/internal/ui/mounts', () => { + return [200, { 'Content-Type': 'application/json' }, JSON.stringify({ data: { auth: methods } })]; + }); + }); + await render(hbs`{{auth-form cluster=cluster}}`); - return wait().then(() => { + await settled(); assert.equal(component.tabs.length, BACKENDS.length, 'renders a tab for every backend'); - assert.equal( - replaceSpy.getCall(0).args[0].queryParams.with, - 'token', - 'calls router replaceWith properly' - ); + server.shutdown(); }); -}); -test('it renders all the supported methods and Other tab when methods are present', function(assert) { - let replaceSpy = sinon.spy(this.get('router'), 'replaceWith'); - let methods = { - 'foo/': { - type: 'userpass', - }, - 'approle/': { - type: 'approle', - }, - }; - let server = new Pretender(function() { - this.get('/v1/sys/internal/ui/mounts', () => { - return [200, { 'Content-Type': 'application/json' }, JSON.stringify({ data: { auth: methods } })]; + test('it renders all the supported methods and Other tab when methods are present', async function(assert) { + let methods = { + 'foo/': { + type: 'userpass', + }, + 'approle/': { + type: 'approle', + }, + }; + let server = new Pretender(function() { + this.get('/v1/sys/internal/ui/mounts', () => { + return [200, { 'Content-Type': 'application/json' }, JSON.stringify({ data: { auth: methods } })]; + }); }); - }); - this.render(hbs`{{auth-form cluster=cluster }}`); - return wait().then(() => { + await render(hbs`{{auth-form cluster=cluster }}`); + await settled(); assert.equal(component.tabs.length, 2, 'renders a tab for userpass and Other'); assert.equal(component.tabs.objectAt(0).name, 'foo', 'uses the path in the label'); assert.equal(component.tabs.objectAt(1).name, 'Other', 'second tab is the Other tab'); - assert.equal(replaceSpy.getCall(0).args[0].queryParams.with, 'foo/', 'calls router replaceWith properly'); server.shutdown(); - replaceSpy.restore(); }); -}); -test('it calls authorize with the correct path', function(assert) { - this.register('service:auth', workingAuthService); - this.inject.service('auth'); - let authSpy = sinon.spy(this.get('auth'), 'authenticate'); - let methods = { - 'foo/': { - type: 'userpass', - }, - }; - let server = new Pretender(function() { - this.get('/v1/sys/internal/ui/mounts', () => { - return [200, { 'Content-Type': 'application/json' }, JSON.stringify({ data: { auth: methods } })]; + test('it calls authorize with the correct path', async function(assert) { + this.owner.register('service:auth', workingAuthService); + this.auth = this.owner.lookup('service:auth'); + let authSpy = sinon.spy(this.get('auth'), 'authenticate'); + let methods = { + 'foo/': { + type: 'userpass', + }, + }; + let server = new Pretender(function() { + this.get('/v1/sys/internal/ui/mounts', () => { + return [200, { 'Content-Type': 'application/json' }, JSON.stringify({ data: { auth: methods } })]; + }); }); - }); - this.set('selectedAuth', 'foo/'); - this.render(hbs`{{auth-form cluster=cluster selectedAuth=selectedAuth}}`); - wait().then(() => { - return component.login(); - }); + this.set('selectedAuth', 'foo/'); + await render(hbs`{{auth-form cluster=cluster selectedAuth=selectedAuth}}`); + await component.login(); - return wait().then(() => { + await settled(); assert.ok(authSpy.calledOnce, 'a call to authenticate was made'); let { data } = authSpy.getCall(0).args[0]; assert.equal(data.path, 'foo', 'uses the id for the path'); authSpy.restore(); server.shutdown(); }); -}); -test('it renders all the supported methods when no supported methods are present in passed methods', function( - assert -) { - let methods = [ - { - type: 'approle', - id: 'approle', - path: 'approle/', - }, - ]; - this.set('methods', methods); - this.render(hbs`{{auth-form cluster=cluster methods=methods}}`); - assert.equal(component.tabs.length, BACKENDS.length, 'renders a tab for every backend'); -}); - -test('it makes a request to unwrap if passed a wrappedToken and logs in', function(assert) { - this.register('service:auth', workingAuthService); - this.inject.service('auth'); - let authSpy = sinon.spy(this.get('auth'), 'authenticate'); - let server = new Pretender(function() { - this.post('/v1/sys/wrapping/unwrap', () => { - return [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify({ - auth: { - client_token: '12345', - }, - }), - ]; + test('it renders all the supported methods when no supported methods are present in passed methods', async function(assert) { + let methods = { + 'approle/': { + type: 'approle', + }, + }; + let server = new Pretender(function() { + this.get('/v1/sys/internal/ui/mounts', () => { + return [200, { 'Content-Type': 'application/json' }, JSON.stringify({ data: { auth: methods } })]; + }); }); + await render(hbs`{{auth-form cluster=cluster}}`); + await settled(); + server.shutdown(); + assert.equal(component.tabs.length, BACKENDS.length, 'renders a tab for every backend'); }); - let wrappedToken = '54321'; - this.set('wrappedToken', wrappedToken); - this.render(hbs`{{auth-form cluster=cluster wrappedToken=wrappedToken}}`); - Ember.run.later(() => Ember.run.cancelTimers(), 50); - return wait().then(() => { + test('it makes a request to unwrap if passed a wrappedToken and logs in', async function(assert) { + this.owner.register('service:auth', workingAuthService); + this.auth = this.owner.lookup('service:auth'); + let authSpy = sinon.spy(this.get('auth'), 'authenticate'); + let server = new Pretender(function() { + this.post('/v1/sys/wrapping/unwrap', () => { + return [ + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({ + auth: { + client_token: '12345', + }, + }), + ]; + }); + }); + + let wrappedToken = '54321'; + this.set('wrappedToken', wrappedToken); + await render(hbs`{{auth-form cluster=cluster wrappedToken=wrappedToken}}`); + later(() => run.cancelTimers(), 50); + await settled(); assert.equal(server.handledRequests[0].url, '/v1/sys/wrapping/unwrap', 'makes call to unwrap the token'); assert.equal( server.handledRequests[0].requestHeaders['X-Vault-Token'], @@ -222,26 +227,25 @@ test('it makes a request to unwrap if passed a wrappedToken and logs in', functi server.shutdown(); authSpy.restore(); }); -}); -test('it shows an error if unwrap errors', function(assert) { - let server = new Pretender(function() { - this.post('/v1/sys/wrapping/unwrap', () => { - return [ - 400, - { 'Content-Type': 'application/json' }, - JSON.stringify({ - errors: ['There was an error unwrapping!'], - }), - ]; + test('it shows an error if unwrap errors', async function(assert) { + let server = new Pretender(function() { + this.post('/v1/sys/wrapping/unwrap', () => { + return [ + 400, + { 'Content-Type': 'application/json' }, + JSON.stringify({ + errors: ['There was an error unwrapping!'], + }), + ]; + }); }); - }); - this.set('wrappedToken', '54321'); - this.render(hbs`{{auth-form cluster=cluster wrappedToken=wrappedToken}}`); - Ember.run.later(() => Ember.run.cancelTimers(), 50); + this.set('wrappedToken', '54321'); + await render(hbs`{{auth-form cluster=cluster wrappedToken=wrappedToken}}`); + later(() => run.cancelTimers(), 50); - return wait().then(() => { + await settled(); assert.equal( component.errorText, 'Error Token unwrap failed: There was an error unwrapping!', diff --git a/ui/tests/integration/components/b64-toggle-test.js b/ui/tests/integration/components/b64-toggle-test.js index 32defe1da..656fec8b7 100644 --- a/ui/tests/integration/components/b64-toggle-test.js +++ b/ui/tests/integration/components/b64-toggle-test.js @@ -1,45 +1,50 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click, findAll, find } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('b64-toggle', 'Integration | Component | b64 toggle', { - integration: true, -}); +module('Integration | Component | b64 toggle', function(hooks) { + setupRenderingTest(hooks); -test('it renders', function(assert) { - this.render(hbs`{{b64-toggle}}`); - assert.equal(this.$('button').length, 1); -}); + test('it renders', async function(assert) { + await render(hbs`{{b64-toggle}}`); + assert.equal(findAll('button').length, 1); + }); -test('it toggles encoding on the passed string', function(assert) { - this.set('value', 'value'); - this.render(hbs`{{b64-toggle value=value}}`); - this.$('button').click(); - assert.equal(this.get('value'), btoa('value'), 'encodes to base64'); - this.$('button').click(); - assert.equal(this.get('value'), 'value', 'decodes from base64'); -}); + test('it toggles encoding on the passed string', async function(assert) { + this.set('value', 'value'); + await render(hbs`{{b64-toggle value=value}}`); + await click('button'); + assert.equal(this.get('value'), btoa('value'), 'encodes to base64'); + await click('button'); + assert.equal(this.get('value'), 'value', 'decodes from base64'); + }); -test('it toggles encoding starting with base64', function(assert) { - this.set('value', btoa('value')); - this.render(hbs`{{b64-toggle value=value initialEncoding='base64'}}`); - assert.ok(this.$('button').text().includes('Decode'), 'renders as on when in b64 mode'); - this.$('button').click(); - assert.equal(this.get('value'), 'value', 'decodes from base64'); -}); + test('it toggles encoding starting with base64', async function(assert) { + this.set('value', btoa('value')); + await render(hbs`{{b64-toggle value=value initialEncoding='base64'}}`); + assert.ok(find('button').textContent.includes('Decode'), 'renders as on when in b64 mode'); + await click('button'); + assert.equal(this.get('value'), 'value', 'decodes from base64'); + }); -test('it detects changes to value after encoding', function(assert) { - this.set('value', btoa('value')); - this.render(hbs`{{b64-toggle value=value initialEncoding='base64'}}`); - assert.ok(this.$('button').text().includes('Decode'), 'renders as on when in b64 mode'); - this.set('value', btoa('value') + '='); - assert.ok(this.$('button').text().includes('Encode'), 'toggles off since value has changed'); - this.set('value', btoa('value')); - assert.ok(this.$('button').text().includes('Decode'), 'toggles on since value is equal to the original'); -}); + test('it detects changes to value after encoding', async function(assert) { + this.set('value', btoa('value')); + await render(hbs`{{b64-toggle value=value initialEncoding='base64'}}`); + assert.ok(find('button').textContent.includes('Decode'), 'renders as on when in b64 mode'); + this.set('value', btoa('value') + '='); + assert.ok(find('button').textContent.includes('Encode'), 'toggles off since value has changed'); + this.set('value', btoa('value')); + assert.ok( + find('button').textContent.includes('Decode'), + 'toggles on since value is equal to the original' + ); + }); -test('it does not toggle when the value is empty', function(assert) { - this.set('value', ''); - this.render(hbs`{{b64-toggle value=value}}`); - this.$('button').click(); - assert.ok(this.$('button').text().includes('Encode')); + test('it does not toggle when the value is empty', async function(assert) { + this.set('value', ''); + await render(hbs`{{b64-toggle value=value}}`); + await click('button'); + assert.ok(find('button').textContent.includes('Encode')); + }); }); diff --git a/ui/tests/integration/components/config-pki-ca-test.js b/ui/tests/integration/components/config-pki-ca-test.js index a4b6b46fe..8ca3bf5af 100644 --- a/ui/tests/integration/components/config-pki-ca-test.js +++ b/ui/tests/integration/components/config-pki-ca-test.js @@ -1,16 +1,21 @@ -import Ember from 'ember'; -import { moduleForComponent, test } from 'ember-qunit'; +import { resolve } from 'rsvp'; +import EmberObject from '@ember/object'; +import Service from '@ember/service'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import { create } from 'ember-cli-page-object'; import configPki from '../../pages/components/config-pki-ca'; +import apiStub from 'vault/tests/helpers/noop-all-api-requests'; const component = create(configPki); -const storeStub = Ember.Service.extend({ +const storeStub = Service.extend({ createRecord(type, args) { - return Ember.Object.create(args, { + return EmberObject.create(args, { save() { - return Ember.RSVP.resolve(this); + return resolve(this); }, destroyRecord() {}, send() {}, @@ -19,57 +24,59 @@ const storeStub = Ember.Service.extend({ }, }); -moduleForComponent('config-pki-ca', 'Integration | Component | config pki ca', { - integration: true, - beforeEach() { +module('Integration | Component | config pki ca', function(hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function() { + this.server = apiStub(); component.setContext(this); - Ember.getOwner(this).lookup('service:flash-messages').registerTypes(['success']); - this.register('service:store', storeStub); - this.inject.service('store', { as: 'storeService' }); - }, - - afterEach() { - component.removeContext(); - }, -}); - -const config = function(pem) { - return Ember.Object.create({ - pem: pem, - backend: 'pki', - caChain: 'caChain', - der: new File(['der'], { type: 'text/plain' }), + this.owner.lookup('service:flash-messages').registerTypes(['success']); + this.owner.register('service:store', storeStub); + this.storeService = this.owner.lookup('service:store'); }); -}; -const setupAndRender = function(context, onRefresh) { - const refreshFn = onRefresh || function() {}; - context.set('config', config()); - context.set('onRefresh', refreshFn); - context.render(hbs`{{config-pki-ca onRefresh=onRefresh config=config}}`); -}; + hooks.afterEach(function() { + this.server.shutdown(); + component.removeContext(); + }); -test('it renders, no pem', function(assert) { - setupAndRender(this); + const config = function(pem) { + return EmberObject.create({ + pem: pem, + backend: 'pki', + caChain: 'caChain', + der: new File(['der'], { type: 'text/plain' }), + }); + }; - assert.notOk(component.hasTitle, 'no title in the default state'); - assert.equal(component.replaceCAText, 'Configure CA'); - assert.equal(component.downloadLinks().count, 0, 'there are no download links'); + const setupAndRender = async function(context, onRefresh) { + const refreshFn = onRefresh || function() {}; + context.set('config', config()); + context.set('onRefresh', refreshFn); + await context.render(hbs`{{config-pki-ca onRefresh=onRefresh config=config}}`); + }; - component.replaceCA(); - assert.equal(component.title, 'Configure CA Certificate'); - component.back(); + test('it renders, no pem', async function(assert) { + await setupAndRender(this); - component.setSignedIntermediateBtn(); - assert.equal(component.title, 'Set signed intermediate'); - component.back(); -}); - -test('it renders, with pem', function(assert) { - const c = config('pem'); - this.set('config', c); - this.render(hbs`{{config-pki-ca config=config}}`); - assert.notOk(component.hasTitle, 'no title in the default state'); - assert.equal(component.replaceCAText, 'Replace CA'); - assert.equal(component.downloadLinks().count, 3, 'shows download links'); + assert.notOk(component.hasTitle, 'no title in the default state'); + assert.equal(component.replaceCAText, 'Configure CA'); + assert.equal(component.downloadLinks.length, 0, 'there are no download links'); + + await component.replaceCA(); + assert.equal(component.title, 'Configure CA Certificate'); + await component.back(); + + await component.setSignedIntermediateBtn(); + assert.equal(component.title, 'Set signed intermediate'); + }); + + test('it renders, with pem', async function(assert) { + const c = config('pem'); + this.set('config', c); + await render(hbs`{{config-pki-ca config=config}}`); + assert.notOk(component.hasTitle, 'no title in the default state'); + assert.equal(component.replaceCAText, 'Replace CA'); + assert.equal(component.downloadLinks.length, 3, 'shows download links'); + }); }); diff --git a/ui/tests/integration/components/config-pki-test.js b/ui/tests/integration/components/config-pki-test.js index 5aaff453c..47794d2c7 100644 --- a/ui/tests/integration/components/config-pki-test.js +++ b/ui/tests/integration/components/config-pki-test.js @@ -1,103 +1,106 @@ -import Ember from 'ember'; -import { moduleForComponent, test } from 'ember-qunit'; +import { resolve } from 'rsvp'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import { create } from 'ember-cli-page-object'; import configPki from '../../pages/components/config-pki'; const component = create(configPki); -moduleForComponent('config-pki', 'Integration | Component | config pki', { - integration: true, - beforeEach() { +module('Integration | Component | config pki', function(hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function() { component.setContext(this); - Ember.getOwner(this).lookup('service:flash-messages').registerTypes(['success']); - }, - - afterEach() { - component.removeContext(); - }, -}); - -const config = function(saveFn) { - return { - save: saveFn, - rollbackAttributes: () => {}, - tidyAttrs: [ - { - type: 'boolean', - name: 'tidyCertStore', - }, - { - type: 'string', - name: 'anotherAttr', - }, - ], - crlAttrs: [ - { - type: 'string', - name: 'crl', - }, - ], - urlsAttrs: [ - { - type: 'string', - name: 'urls', - }, - ], - }; -}; - -const setupAndRender = function(context, section = 'tidy') { - context.set('config', config()); - context.set('section', section); - context.render(hbs`{{config-pki section=section config=config}}`); -}; - -test('it renders tidy section', function(assert) { - setupAndRender(this); - assert.ok(component.text.startsWith('You can tidy up the backend')); - assert.notOk(component.hasTitle, 'No title for tidy section'); - assert.equal(component.fields().count, 2); - assert.ok(component.fields(0).labelText, 'Tidy cert store'); - assert.ok(component.fields(1).labelText, 'Another attr'); -}); - -test('it renders crl section', function(assert) { - setupAndRender(this, 'crl'); - assert.ok(component.hasTitle, 'renders the title'); - assert.equal(component.title, 'Certificate Revocation List (CRL) Config'); - assert.ok(component.text.startsWith('Set the duration for which the generated CRL')); - assert.equal(component.fields().count, 1); - assert.ok(component.fields(0).labelText, 'Crl'); -}); - -test('it renders urls section', function(assert) { - setupAndRender(this, 'urls'); - assert.notOk(component.hasTitle, 'No title for urls section'); - assert.equal(component.fields().count, 1); - assert.ok(component.fields(0).labelText, 'urls'); -}); - -test('it calls save with the correct arguments', function(assert) { - assert.expect(3); - const section = 'tidy'; - this.set('onRefresh', () => { - assert.ok(true, 'refresh called'); + this.owner.lookup('service:flash-messages').registerTypes(['success']); }); - this.set( - 'config', - config(options => { - assert.equal(options.adapterOptions.method, section, 'method passed to save'); - assert.deepEqual( - options.adapterOptions.fields, - ['tidyCertStore', 'anotherAttr'], - 'fields passed to save' - ); - return Ember.RSVP.resolve(); - }) - ); - this.set('section', section); - this.render(hbs`{{config-pki section=section config=config onRefresh=onRefresh}}`); - component.submit(); + hooks.afterEach(function() { + component.removeContext(); + }); + + const config = function(saveFn) { + return { + save: saveFn, + rollbackAttributes: () => {}, + tidyAttrs: [ + { + type: 'boolean', + name: 'tidyCertStore', + }, + { + type: 'string', + name: 'anotherAttr', + }, + ], + crlAttrs: [ + { + type: 'string', + name: 'crl', + }, + ], + urlsAttrs: [ + { + type: 'string', + name: 'urls', + }, + ], + }; + }; + + const setupAndRender = async function(context, section = 'tidy') { + context.set('config', config()); + context.set('section', section); + await context.render(hbs`{{config-pki section=section config=config}}`); + }; + + test('it renders tidy section', async function(assert) { + await setupAndRender(this); + assert.ok(component.text.startsWith('You can tidy up the backend')); + assert.notOk(component.hasTitle, 'No title for tidy section'); + assert.equal(component.fields.length, 2); + assert.ok(component.fields.objectAt(0).labelText, 'Tidy cert store'); + assert.ok(component.fields.objectAt(1).labelText, 'Another attr'); + }); + + test('it renders crl section', async function(assert) { + await setupAndRender(this, 'crl'); + assert.ok(component.hasTitle, 'renders the title'); + assert.equal(component.title, 'Certificate Revocation List (CRL) Config'); + assert.ok(component.text.startsWith('Set the duration for which the generated CRL')); + assert.equal(component.fields.length, 1); + assert.ok(component.fields.objectAt(0).labelText, 'Crl'); + }); + + test('it renders urls section', async function(assert) { + await setupAndRender(this, 'urls'); + assert.notOk(component.hasTitle, 'No title for urls section'); + assert.equal(component.fields.length, 1); + assert.ok(component.fields.objectAt(0).labelText, 'urls'); + }); + + test('it calls save with the correct arguments', async function(assert) { + assert.expect(3); + const section = 'tidy'; + this.set('onRefresh', () => { + assert.ok(true, 'refresh called'); + }); + this.set( + 'config', + config(options => { + assert.equal(options.adapterOptions.method, section, 'method passed to save'); + assert.deepEqual( + options.adapterOptions.fields, + ['tidyCertStore', 'anotherAttr'], + 'fields passed to save' + ); + return resolve(); + }) + ); + this.set('section', section); + await render(hbs`{{config-pki section=section config=config onRefresh=onRefresh}}`); + + component.submit(); + }); }); diff --git a/ui/tests/integration/components/console/log-command-test.js b/ui/tests/integration/components/console/log-command-test.js index 72a9514ac..af913d837 100644 --- a/ui/tests/integration/components/console/log-command-test.js +++ b/ui/tests/integration/components/console/log-command-test.js @@ -1,15 +1,17 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('console/log-command', 'Integration | Component | console/log command', { - integration: true, -}); - -test('it renders', function(assert) { - const commandText = 'list this/path'; - this.set('content', commandText); - - this.render(hbs`{{console/log-command content=content}}`); - - assert.dom('pre').includesText(commandText); +module('Integration | Component | console/log command', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + const commandText = 'list this/path'; + this.set('content', commandText); + + await render(hbs`{{console/log-command content=content}}`); + + assert.dom('pre').includesText(commandText); + }); }); diff --git a/ui/tests/integration/components/console/log-error-test.js b/ui/tests/integration/components/console/log-error-test.js index f32c2dad9..3bc174995 100644 --- a/ui/tests/integration/components/console/log-error-test.js +++ b/ui/tests/integration/components/console/log-error-test.js @@ -1,13 +1,15 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('console/log-error', 'Integration | Component | console/log error', { - integration: true, -}); +module('Integration | Component | console/log error', function(hooks) { + setupRenderingTest(hooks); -test('it renders', function(assert) { - const errorText = 'Error deleting at: sys/foo.\nURL: v1/sys/foo\nCode: 404'; - this.set('content', errorText); - this.render(hbs`{{console/log-error content=content}}`); - assert.dom('pre').includesText(errorText); + test('it renders', async function(assert) { + const errorText = 'Error deleting at: sys/foo.\nURL: v1/sys/foo\nCode: 404'; + this.set('content', errorText); + await render(hbs`{{console/log-error content=content}}`); + assert.dom('pre').includesText(errorText); + }); }); diff --git a/ui/tests/integration/components/console/log-json-test.js b/ui/tests/integration/components/console/log-json-test.js index 353835df0..a5b10407e 100644 --- a/ui/tests/integration/components/console/log-json-test.js +++ b/ui/tests/integration/components/console/log-json-test.js @@ -1,24 +1,26 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, find } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('console/log-json', 'Integration | Component | console/log json', { - integration: true, +module('Integration | Component | console/log json', function(hooks) { + setupRenderingTest(hooks); - beforeEach() { - this.inject.service('code-mirror', { as: 'codeMirror' }); - }, -}); - -test('it renders', function(assert) { - // Set any properties with this.set('myProperty', 'value'); - // Handle any actions with this.on('myAction', function(val) { ... }); - const objectContent = { one: 'two', three: 'four', seven: { five: 'six' }, eight: [5, 6] }; - const expectedText = JSON.stringify(objectContent, null, 2); - - this.set('content', objectContent); - - this.render(hbs`{{console/log-json content=content}}`); - const instance = this.codeMirror.instanceFor(this.$('[data-test-component=json-editor]').attr('id')); - - assert.equal(instance.getValue(), expectedText); + hooks.beforeEach(function() { + this.codeMirror = this.owner.lookup('service:code-mirror'); + }); + + test('it renders', async function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + const objectContent = { one: 'two', three: 'four', seven: { five: 'six' }, eight: [5, 6] }; + const expectedText = JSON.stringify(objectContent, null, 2); + + this.set('content', objectContent); + + await render(hbs`{{console/log-json content=content}}`); + const instance = this.codeMirror.instanceFor(find('[data-test-component=json-editor]').id); + + assert.equal(instance.getValue(), expectedText); + }); }); diff --git a/ui/tests/integration/components/console/log-list-test.js b/ui/tests/integration/components/console/log-list-test.js index 625787b54..1220ca4c7 100644 --- a/ui/tests/integration/components/console/log-list-test.js +++ b/ui/tests/integration/components/console/log-list-test.js @@ -1,19 +1,21 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('console/log-list', 'Integration | Component | console/log list', { - integration: true, -}); - -test('it renders', function(assert) { - // Set any properties with this.set('myProperty', 'value'); - // Handle any actions with this.on('myAction', function(val) { ... }); - const listContent = { keys: ['one', 'two'] }; - const expectedText = 'Keys\none\ntwo'; - - this.set('content', listContent); - - this.render(hbs`{{console/log-list content=content}}`); - - assert.dom('pre').includesText(`${expectedText}`); +module('Integration | Component | console/log list', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + const listContent = { keys: ['one', 'two'] }; + const expectedText = 'Keys\none\ntwo'; + + this.set('content', listContent); + + await render(hbs`{{console/log-list content=content}}`); + + assert.dom('pre').includesText(`${expectedText}`); + }); }); diff --git a/ui/tests/integration/components/console/log-object-test.js b/ui/tests/integration/components/console/log-object-test.js index 1b5347004..31a079123 100644 --- a/ui/tests/integration/components/console/log-object-test.js +++ b/ui/tests/integration/components/console/log-object-test.js @@ -1,27 +1,29 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import columnify from 'columnify'; import { capitalize } from 'vault/helpers/capitalize'; import { stringifyObjectValues } from 'vault/components/console/log-object'; -moduleForComponent('console/log-object', 'Integration | Component | console/log object', { - integration: true, -}); +module('Integration | Component | console/log object', function(hooks) { + setupRenderingTest(hooks); -test('it renders', function(assert) { - const objectContent = { one: 'two', three: 'four', seven: { five: 'six' }, eight: [5, 6] }; - const data = { one: 'two', three: 'four', seven: { five: 'six' }, eight: [5, 6] }; - stringifyObjectValues(data); - const expectedText = columnify(data, { - preserveNewLines: true, - headingTransform: function(heading) { - return capitalize([heading]); - }, + test('it renders', async function(assert) { + const objectContent = { one: 'two', three: 'four', seven: { five: 'six' }, eight: [5, 6] }; + const data = { one: 'two', three: 'four', seven: { five: 'six' }, eight: [5, 6] }; + stringifyObjectValues(data); + const expectedText = columnify(data, { + preserveNewLines: true, + headingTransform: function(heading) { + return capitalize([heading]); + }, + }); + + this.set('content', objectContent); + + await render(hbs`{{console/log-object content=content}}`); + + assert.dom('pre').includesText(`${expectedText}`); }); - - this.set('content', objectContent); - - this.render(hbs`{{console/log-object content=content}}`); - - assert.dom('pre').includesText(`${expectedText}`); }); diff --git a/ui/tests/integration/components/console/log-text-test.js b/ui/tests/integration/components/console/log-text-test.js index 357c99cc8..18baa7ab9 100644 --- a/ui/tests/integration/components/console/log-text-test.js +++ b/ui/tests/integration/components/console/log-text-test.js @@ -1,17 +1,19 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('console/log-text', 'Integration | Component | console/log text', { - integration: true, -}); - -test('it renders', function(assert) { - // Set any properties with this.set('myProperty', 'value'); - // Handle any actions with this.on('myAction', function(val) { ... }); - const text = 'Success! You did a thing!'; - this.set('content', text); - - this.render(hbs`{{console/log-text content=content}}`); - - assert.dom('pre').includesText(text); +module('Integration | Component | console/log text', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + const text = 'Success! You did a thing!'; + this.set('content', text); + + await render(hbs`{{console/log-text content=content}}`); + + assert.dom('pre').includesText(text); + }); }); diff --git a/ui/tests/integration/components/console/ui-panel-test.js b/ui/tests/integration/components/console/ui-panel-test.js index e9919c309..18fa928a2 100644 --- a/ui/tests/integration/components/console/ui-panel-test.js +++ b/ui/tests/integration/components/console/ui-panel-test.js @@ -1,48 +1,41 @@ -import { moduleForComponent, test, skip } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import { create } from 'ember-cli-page-object'; -import wait from 'ember-test-helpers/wait'; import uiPanel from 'vault/tests/pages/components/console/ui-panel'; import hbs from 'htmlbars-inline-precompile'; const component = create(uiPanel); -moduleForComponent('console/ui-panel', 'Integration | Component | console/ui panel', { - integration: true, +module('Integration | Component | console/ui panel', function(hooks) { + setupRenderingTest(hooks); - beforeEach() { + hooks.beforeEach(function() { component.setContext(this); - }, + }); - afterEach() { + hooks.afterEach(function() { component.removeContext(); - }, -}); + }); -test('it renders', function(assert) { - this.render(hbs`{{console/ui-panel}}`); - assert.ok(component.hasInput); -}); + test('it renders', async function(assert) { + await render(hbs`{{console/ui-panel}}`); + assert.ok(component.hasInput); + }); -test('it clears console input on enter', function(assert) { - this.render(hbs`{{console/ui-panel}}`); - component.consoleInput('list this/thing/here').enter(); - return wait().then(() => { + test('it clears console input on enter', async function(assert) { + await render(hbs`{{console/ui-panel}}`); + await component.runCommands('list this/thing/here'); assert.equal(component.consoleInputValue, '', 'empties input field on enter'); }); -}); -test('it clears the log when using clear command', function(assert) { - this.render(hbs`{{console/ui-panel}}`); - component.consoleInput('list this/thing/here').enter(); - component.consoleInput('list this/other/thing').enter(); - component.consoleInput('read another/thing').enter(); - wait().then(() => { + test('it clears the log when using clear command', async function(assert) { + await render(hbs`{{console/ui-panel}}`); + await component.runCommands(['list this/thing/here', 'list this/other/thing', 'read another/thing']); assert.notEqual(component.logOutput, '', 'there is output in the log'); - component.consoleInput('clear').enter(); - }); - wait().then(() => component.up()); - return wait().then(() => { + await component.runCommands('clear'); + await component.up(); assert.equal(component.logOutput, '', 'clears the output log'); assert.equal( component.consoleInputValue, @@ -50,65 +43,48 @@ test('it clears the log when using clear command', function(assert) { 'populates console input with previous command on up after enter' ); }); -}); -test('it adds command to history on enter', function(assert) { - this.render(hbs`{{console/ui-panel}}`); - component.consoleInput('list this/thing/here').enter(); - wait().then(() => component.up()); - wait().then(() => { + test('it adds command to history on enter', async function(assert) { + await render(hbs`{{console/ui-panel}}`); + await component.runCommands('list this/thing/here'); + await component.up(); assert.equal( component.consoleInputValue, 'list this/thing/here', 'populates console input with previous command on up after enter' ); - }); - wait().then(() => component.down()); - return wait().then(() => { + await component.down(); assert.equal(component.consoleInputValue, '', 'populates console input with next command on down'); }); -}); -skip('it cycles through history with more than one command', function(assert) { - this.render(hbs`{{console/ui-panel}}`); - component.consoleInput('list this/thing/here').enter(); - wait().then(() => component.consoleInput('read that/thing/there').enter()); - wait().then(() => component.consoleInput('qwerty').enter()); - - wait().then(() => component.up()); - wait().then(() => { + test('it cycles through history with more than one command', async function(assert) { + await render(hbs`{{console/ui-panel}}`); + await component.runCommands(['list this/thing/here', 'read that/thing/there', 'qwerty']); + await component.up(); assert.equal( component.consoleInputValue, 'qwerty', 'populates console input with previous command on up after enter' ); - }); - wait().then(() => component.up()); - wait().then(() => { + await component.up(); assert.equal( component.consoleInputValue, 'read that/thing/there', 'populates console input with previous command on up' ); - }); - wait().then(() => component.up()); - wait().then(() => { + await component.up(); assert.equal( component.consoleInputValue, 'list this/thing/here', 'populates console input with previous command on up' ); - }); - wait().then(() => component.up()); - wait().then(() => { + await component.up(); assert.equal( component.consoleInputValue, 'qwerty', 'populates console input with initial command if cycled through all previous commands' ); - }); - wait().then(() => component.down()); - return wait().then(() => { + await component.down(); assert.equal( component.consoleInputValue, '', diff --git a/ui/tests/integration/components/control-group-success-test.js b/ui/tests/integration/components/control-group-success-test.js index 8fd67d2b7..3c3ee97c3 100644 --- a/ui/tests/integration/components/control-group-success-test.js +++ b/ui/tests/integration/components/control-group-success-test.js @@ -1,6 +1,9 @@ -import { moduleForComponent, test } from 'ember-qunit'; -import Ember from 'ember'; -import wait from 'ember-test-helpers/wait'; +import { later, run } from '@ember/runloop'; +import { resolve } from 'rsvp'; +import Service from '@ember/service'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, settled } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import sinon from 'sinon'; import { create } from 'ember-cli-page-object'; @@ -8,75 +11,77 @@ import controlGroupSuccess from '../../pages/components/control-group-success'; const component = create(controlGroupSuccess); -const controlGroupService = Ember.Service.extend({ +const controlGroupService = Service.extend({ deleteControlGroupToken: sinon.stub(), markTokenForUnwrap: sinon.stub(), }); -const routerService = Ember.Service.extend({ - transitionTo: sinon.stub().returns(Ember.RSVP.resolve()), +const routerService = Service.extend({ + transitionTo: sinon.stub().returns(resolve()), }); -const storeService = Ember.Service.extend({ +const storeService = Service.extend({ adapterFor() { return { toolAction() { - return Ember.RSVP.resolve({ data: { foo: 'bar' } }); + return resolve({ data: { foo: 'bar' } }); }, }; }, }); -moduleForComponent('control-group-success', 'Integration | Component | control group success', { - integration: true, - beforeEach() { - component.setContext(this); - this.register('service:control-group', controlGroupService); - this.inject.service('controlGroup'); - this.register('service:router', routerService); - this.inject.service('router'); - this.register('service:store', storeService); - this.inject.service('store'); - }, +module('Integration | Component | control group success', function(hooks) { + setupRenderingTest(hooks); - afterEach() { + hooks.beforeEach(function() { + run(() => { + this.owner.unregister('service:store'); + this.owner.register('service:control-group', controlGroupService); + this.controlGroup = this.owner.lookup('service:control-group'); + this.owner.register('service:router', routerService); + this.owner.register('service:store', storeService); + this.router = this.owner.lookup('service:router'); + component.setContext(this); + }); + }); + + hooks.afterEach(function() { component.removeContext(); - }, -}); + }); -const MODEL = { - approved: false, - requestPath: 'foo/bar', - id: 'accessor', - requestEntity: { id: 'requestor', name: 'entity8509' }, - reload: sinon.stub(), -}; -test('render with saved token', function(assert) { - let response = { - uiParams: { url: '/foo' }, - token: 'token', + const MODEL = { + approved: false, + requestPath: 'foo/bar', + id: 'accessor', + requestEntity: { id: 'requestor', name: 'entity8509' }, + reload: sinon.stub(), }; - this.set('model', MODEL); - this.set('response', response); - this.render(hbs`{{control-group-success model=model controlGroupResponse=response }}`); - assert.ok(component.showsNavigateMessage, 'shows unwrap message'); - component.navigate(); - Ember.run.later(() => Ember.run.cancelTimers(), 50); - return wait().then(() => { - assert.ok(this.get('controlGroup').markTokenForUnwrap.calledOnce, 'marks token for unwrap'); - assert.ok(this.get('router').transitionTo.calledOnce, 'calls router transition'); - }); -}); - -test('render without token', function(assert) { - this.set('model', MODEL); - this.render(hbs`{{control-group-success model=model}}`); - assert.ok(component.showsUnwrapForm, 'shows unwrap form'); - component.token('token'); - component.unwrap(); - - Ember.run.later(() => Ember.run.cancelTimers(), 50); - return wait().then(() => { - assert.ok(component.showsJsonViewer, 'shows unwrapped data'); + test('render with saved token', async function(assert) { + let response = { + uiParams: { url: '/foo' }, + token: 'token', + }; + this.set('model', MODEL); + this.set('response', response); + await render(hbs`{{control-group-success model=model controlGroupResponse=response }}`); + assert.ok(component.showsNavigateMessage, 'shows unwrap message'); + await component.navigate(); + later(() => run.cancelTimers(), 50); + return settled().then(() => { + assert.ok(this.controlGroup.markTokenForUnwrap.calledOnce, 'marks token for unwrap'); + assert.ok(this.router.transitionTo.calledOnce, 'calls router transition'); + }); + }); + + test('render without token', async function(assert) { + this.set('model', MODEL); + await render(hbs`{{control-group-success model=model}}`); + assert.ok(component.showsUnwrapForm, 'shows unwrap form'); + await component.token('token'); + component.unwrap(); + later(() => run.cancelTimers(), 50); + return settled().then(() => { + assert.ok(component.showsJsonViewer, 'shows unwrapped data'); + }); }); }); diff --git a/ui/tests/integration/components/control-group-test.js b/ui/tests/integration/components/control-group-test.js index 1e970c28b..d9832fbc3 100644 --- a/ui/tests/integration/components/control-group-test.js +++ b/ui/tests/integration/components/control-group-test.js @@ -1,5 +1,7 @@ -import { moduleForComponent, test } from 'ember-qunit'; -import Ember from 'ember'; +import Service from '@ember/service'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import sinon from 'sinon'; import { create } from 'ember-cli-page-object'; @@ -7,8 +9,9 @@ import controlGroup from '../../pages/components/control-group'; const component = create(controlGroup); -const controlGroupService = Ember.Service.extend({ +const controlGroupService = Service.extend({ init() { + this._super(...arguments); this.set('wrapInfo', null); }, wrapInfoForAccessor() { @@ -16,165 +19,166 @@ const controlGroupService = Ember.Service.extend({ }, }); -const authService = Ember.Service.extend(); +const authService = Service.extend(); -moduleForComponent('control-group', 'Integration | Component | control group', { - integration: true, - beforeEach() { +module('Integration | Component | control group', function(hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function() { component.setContext(this); - this.register('service:auth', authService); - this.register('service:control-group', controlGroupService); - this.inject.service('controlGroup'); - this.inject.service('auth'); - }, + this.owner.register('service:auth', authService); + this.owner.register('service:control-group', controlGroupService); + this.controlGroup = this.owner.lookup('service:controlGroup'); + this.auth = this.owner.lookup('service:auth'); + }); - afterEach() { + hooks.afterEach(function() { component.removeContext(); - }, -}); + }); -const setup = (modelData = {}, authData = {}) => { - let modelDefaults = { - approved: false, - requestPath: 'foo/bar', - id: 'accessor', - requestEntity: { id: 'requestor', name: 'entity8509' }, - reload: sinon.stub(), + const setup = (modelData = {}, authData = {}) => { + let modelDefaults = { + approved: false, + requestPath: 'foo/bar', + id: 'accessor', + requestEntity: { id: 'requestor', name: 'entity8509' }, + reload: sinon.stub(), + }; + let authDataDefaults = { entity_id: 'requestor' }; + + return { + model: { + ...modelDefaults, + ...modelData, + }, + authData: { + ...authDataDefaults, + ...authData, + }, + }; }; - let authDataDefaults = { entity_id: 'requestor' }; - return { - model: { - ...modelDefaults, - ...modelData, - }, - authData: { - ...authDataDefaults, - ...authData, - }, - }; -}; + test('requestor rendering', async function(assert) { + let { model, authData } = setup(); + this.set('model', model); + this.set('auth.authData', authData); + await render(hbs`{{control-group model=model}}`); + assert.ok(component.showsAccessorCallout, 'shows accessor callout'); + assert.equal(component.bannerPrefix, 'Locked'); + assert.equal(component.bannerText, 'The path you requested is locked by a control group'); + assert.equal(component.requestorText, `You are requesting access to ${model.requestPath}`); + assert.equal(component.showsTokenText, false, 'does not show token message when there is no token'); + assert.ok(component.showsRefresh, 'shows refresh button'); + assert.ok(component.authorizationText, 'Awaiting authorization.'); + }); -test('requestor rendering', function(assert) { - let { model, authData } = setup(); - this.set('model', model); - this.set('auth.authData', authData); - this.render(hbs`{{control-group model=model}}`); - assert.ok(component.showsAccessorCallout, 'shows accessor callout'); - assert.equal(component.bannerPrefix, 'Locked'); - assert.equal(component.bannerText, 'The path you requested is locked by a control group'); - assert.equal(component.requestorText, `You are requesting access to ${model.requestPath}`); - assert.equal(component.showsTokenText, false, 'does not show token message when there is no token'); - assert.ok(component.showsRefresh, 'shows refresh button'); - assert.ok(component.authorizationText, 'Awaiting authorization.'); -}); - -test('requestor rendering: with token', function(assert) { - let { model, authData } = setup(); - this.set('model', model); - this.set('auth.authData', authData); - this.set('controlGroup.wrapInfo', { token: 'token' }); - this.render(hbs`{{control-group model=model}}`); - assert.equal(component.showsTokenText, true, 'shows token message'); - assert.equal(component.token, 'token', 'shows token value'); -}); - -test('requestor rendering: some approvals', function(assert) { - let { model, authData } = setup({ authorizations: [{ name: 'manager 1' }, { name: 'manager 2' }] }); - this.set('model', model); - this.set('auth.authData', authData); - this.render(hbs`{{control-group model=model}}`); - assert.ok(component.authorizationText, 'Already approved by manager 1, manager 2'); -}); - -test('requestor rendering: approved with no token', function(assert) { - let { model, authData } = setup({ approved: true }); - this.set('model', model); - this.set('auth.authData', authData); - this.render(hbs`{{control-group model=model}}`); - - assert.equal(component.bannerPrefix, 'Success!'); - assert.equal(component.bannerText, 'You have been given authorization'); - assert.equal(component.showsTokenText, false, 'does not show token message when there is no token'); - assert.notOk(component.showsRefresh, 'does not shows refresh button'); - assert.ok(component.showsSuccessComponent, 'renders control group success'); -}); - -test('requestor rendering: approved with token', function(assert) { - let { model, authData } = setup({ approved: true }); - this.set('model', model); - this.set('auth.authData', authData); - this.set('controlGroup.wrapInfo', { token: 'token' }); - this.render(hbs`{{control-group model=model}}`); - assert.equal(component.showsTokenText, true, 'shows token'); - assert.notOk(component.showsRefresh, 'does not shows refresh button'); - assert.ok(component.showsSuccessComponent, 'renders control group success'); -}); - -test('authorizer rendering', function(assert) { - let { model, authData } = setup({ canAuthorize: true }, { entity_id: 'manager' }); - - this.set('model', model); - this.set('auth.authData', authData); - this.render(hbs`{{control-group model=model}}`); - - assert.equal(component.bannerPrefix, 'Locked'); - assert.equal(component.bannerText, 'Someone is requesting access to a path locked by a control group'); - assert.equal( - component.requestorText, - `${model.requestEntity.name} is requesting access to ${model.requestPath}` - ); - assert.equal(component.showsTokenText, false, 'does not show token message when there is no token'); - - assert.ok(component.showsAuthorize, 'shows authorize button'); -}); - -test('authorizer rendering:authorized', function(assert) { - let { model, authData } = setup( - { canAuthorize: true, authorizations: [{ id: 'manager', name: 'manager' }] }, - { entity_id: 'manager' } - ); - - this.set('model', model); - this.set('auth.authData', authData); - this.render(hbs`{{control-group model=model}}`); - - assert.equal(component.bannerPrefix, 'Thanks!'); - assert.equal(component.bannerText, 'You have given authorization'); - assert.ok(component.showsBackLink, 'back link is visible'); -}); - -test('authorizer rendering: authorized and success', function(assert) { - let { model, authData } = setup( - { approved: true, canAuthorize: true, authorizations: [{ id: 'manager', name: 'manager' }] }, - { entity_id: 'manager' } - ); - - this.set('model', model); - this.set('auth.authData', authData); - this.render(hbs`{{control-group model=model}}`); - - assert.equal(component.bannerPrefix, 'Thanks!'); - assert.equal(component.bannerText, 'You have given authorization'); - assert.ok(component.showsBackLink, 'back link is visible'); - assert.equal( - component.requestorText, - `${model.requestEntity.name} is authorized to access ${model.requestPath}` - ); - assert.notOk(component.showsSuccessComponent, 'does not render control group success'); -}); - -test('third-party: success', function(assert) { - let { model, authData } = setup( - { approved: true, canAuthorize: true, authorizations: [{ id: 'foo', name: 'foo' }] }, - { entity_id: 'manager' } - ); - - this.set('model', model); - this.set('auth.authData', authData); - this.render(hbs`{{control-group model=model}}`); - assert.equal(component.bannerPrefix, 'Success!'); - assert.equal(component.bannerText, 'This control group has been authorized'); - assert.ok(component.showsBackLink, 'back link is visible'); - assert.notOk(component.showsSuccessComponent, 'does not render control group success'); + test('requestor rendering: with token', async function(assert) { + let { model, authData } = setup(); + this.set('model', model); + this.set('auth.authData', authData); + this.set('controlGroup.wrapInfo', { token: 'token' }); + await render(hbs`{{control-group model=model}}`); + assert.equal(component.showsTokenText, true, 'shows token message'); + assert.equal(component.token, 'token', 'shows token value'); + }); + + test('requestor rendering: some approvals', async function(assert) { + let { model, authData } = setup({ authorizations: [{ name: 'manager 1' }, { name: 'manager 2' }] }); + this.set('model', model); + this.set('auth.authData', authData); + await render(hbs`{{control-group model=model}}`); + assert.ok(component.authorizationText, 'Already approved by manager 1, manager 2'); + }); + + test('requestor rendering: approved with no token', async function(assert) { + let { model, authData } = setup({ approved: true }); + this.set('model', model); + this.set('auth.authData', authData); + await render(hbs`{{control-group model=model}}`); + + assert.equal(component.bannerPrefix, 'Success!'); + assert.equal(component.bannerText, 'You have been given authorization'); + assert.equal(component.showsTokenText, false, 'does not show token message when there is no token'); + assert.notOk(component.showsRefresh, 'does not shows refresh button'); + assert.ok(component.showsSuccessComponent, 'renders control group success'); + }); + + test('requestor rendering: approved with token', async function(assert) { + let { model, authData } = setup({ approved: true }); + this.set('model', model); + this.set('auth.authData', authData); + this.set('controlGroup.wrapInfo', { token: 'token' }); + await render(hbs`{{control-group model=model}}`); + assert.equal(component.showsTokenText, true, 'shows token'); + assert.notOk(component.showsRefresh, 'does not shows refresh button'); + assert.ok(component.showsSuccessComponent, 'renders control group success'); + }); + + test('authorizer rendering', async function(assert) { + let { model, authData } = setup({ canAuthorize: true }, { entity_id: 'manager' }); + + this.set('model', model); + this.set('auth.authData', authData); + await render(hbs`{{control-group model=model}}`); + + assert.equal(component.bannerPrefix, 'Locked'); + assert.equal(component.bannerText, 'Someone is requesting access to a path locked by a control group'); + assert.equal( + component.requestorText, + `${model.requestEntity.name} is requesting access to ${model.requestPath}` + ); + assert.equal(component.showsTokenText, false, 'does not show token message when there is no token'); + + assert.ok(component.showsAuthorize, 'shows authorize button'); + }); + + test('authorizer rendering:authorized', async function(assert) { + let { model, authData } = setup( + { canAuthorize: true, authorizations: [{ id: 'manager', name: 'manager' }] }, + { entity_id: 'manager' } + ); + + this.set('model', model); + this.set('auth.authData', authData); + await render(hbs`{{control-group model=model}}`); + + assert.equal(component.bannerPrefix, 'Thanks!'); + assert.equal(component.bannerText, 'You have given authorization'); + assert.ok(component.showsBackLink, 'back link is visible'); + }); + + test('authorizer rendering: authorized and success', async function(assert) { + let { model, authData } = setup( + { approved: true, canAuthorize: true, authorizations: [{ id: 'manager', name: 'manager' }] }, + { entity_id: 'manager' } + ); + + this.set('model', model); + this.set('auth.authData', authData); + await render(hbs`{{control-group model=model}}`); + + assert.equal(component.bannerPrefix, 'Thanks!'); + assert.equal(component.bannerText, 'You have given authorization'); + assert.ok(component.showsBackLink, 'back link is visible'); + assert.equal( + component.requestorText, + `${model.requestEntity.name} is authorized to access ${model.requestPath}` + ); + assert.notOk(component.showsSuccessComponent, 'does not render control group success'); + }); + + test('third-party: success', async function(assert) { + let { model, authData } = setup( + { approved: true, canAuthorize: true, authorizations: [{ id: 'foo', name: 'foo' }] }, + { entity_id: 'manager' } + ); + + this.set('model', model); + this.set('auth.authData', authData); + await render(hbs`{{control-group model=model}}`); + assert.equal(component.bannerPrefix, 'Success!'); + assert.equal(component.bannerText, 'This control group has been authorized'); + assert.ok(component.showsBackLink, 'back link is visible'); + assert.notOk(component.showsSuccessComponent, 'does not render control group success'); + }); }); diff --git a/ui/tests/integration/components/edit-form-test.js b/ui/tests/integration/components/edit-form-test.js index 798f1df7c..813ac4dac 100644 --- a/ui/tests/integration/components/edit-form-test.js +++ b/ui/tests/integration/components/edit-form-test.js @@ -1,6 +1,10 @@ -import { moduleForComponent, test } from 'ember-qunit'; -import Ember from 'ember'; -import wait from 'ember-test-helpers/wait'; +import { later, run } from '@ember/runloop'; +import { resolve } from 'rsvp'; +import EmberObject from '@ember/object'; +import Service from '@ember/service'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, settled } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import sinon from 'sinon'; import { create } from 'ember-cli-page-object'; @@ -8,90 +12,97 @@ import editForm from 'vault/tests/pages/components/edit-form'; const component = create(editForm); -const flash = Ember.Service.extend({ +const flash = Service.extend({ success: sinon.stub(), }); const createModel = (canDelete = true) => { - return Ember.Object.create({ + return EmberObject.create({ fields: [{ name: 'one', type: 'string' }, { name: 'two', type: 'boolean' }], canDelete, destroyRecord() { - return Ember.RSVP.resolve(); + return resolve(); }, save() { - return Ember.RSVP.resolve(); + return resolve(); }, rollbackAttributes() {}, }); }; -moduleForComponent('edit-form', 'Integration | Component | edit form', { - integration: true, - beforeEach() { - this.register('service:flash-messages', flash); - this.inject.service('flashMessages'); - }, -}); +module('Integration | Component | edit form', function(hooks) { + setupRenderingTest(hooks); -test('it renders', function(assert) { - let model = createModel(); - this.set('model', model); - this.render(hbs`{{edit-form model=model}}`); - - assert.ok(component.fields.length, 2); - assert.ok(component.showsDelete); - assert.equal(component.deleteText, 'Delete'); -}); - -test('it renders: custom deleteButton', function(assert) { - let model = createModel(); - let delText = 'Exterminate'; - this.set('model', model); - this.set('deleteButtonText', delText); - this.render(hbs`{{edit-form model=model deleteButtonText=deleteButtonText}}`); - - assert.ok(component.showsDelete); - assert.equal(component.deleteText, delText); -}); - -test('it calls flash message fns on save', function(assert) { - let model = createModel(); - let onSave = () => { - return Ember.RSVP.resolve(); - }; - this.set('model', model); - this.set('onSave', onSave); - let saveSpy = sinon.spy(this, 'onSave'); - - this.render(hbs`{{edit-form model=model onSave=onSave}}`); - - component.submit(); - return wait().then(() => { - assert.ok(saveSpy.calledOnce, 'calls passed onSave'); - assert.equal(saveSpy.getCall(0).args[0].saveType, 'save'); - assert.deepEqual(saveSpy.getCall(0).args[0].model, model, 'passes model to onSave'); - assert.equal(this.flashMessages.success.callCount, 1, 'calls flash message success'); - }); -}); - -test('it calls flash message fns on delete', function(assert) { - let model = createModel(); - let onSave = () => { - return Ember.RSVP.resolve(); - }; - this.set('model', model); - this.set('onSave', onSave); - let saveSpy = sinon.spy(this, 'onSave'); - - this.render(hbs`{{edit-form model=model onSave=onSave}}`); - component.deleteButton(); - wait().then(() => { - Ember.run(() => component.deleteConfirm()); + hooks.beforeEach(function() { + run(() => { + this.owner.unregister('service:flash-messages'); + this.owner.register('service:flash-messages', flash); + component.setContext(this); + }); }); - return wait().then(() => { - return wait().then(() => { + hooks.afterEach(function() { + component.removeContext(); + }); + + test('it renders', async function(assert) { + let model = createModel(); + this.set('model', model); + await render(hbs`{{edit-form model=model}}`); + + assert.ok(component.fields.length, 2); + assert.ok(component.showsDelete); + assert.equal(component.deleteText, 'Delete'); + }); + + test('it renders: custom deleteButton', async function(assert) { + let model = createModel(); + let delText = 'Exterminate'; + this.set('model', model); + this.set('deleteButtonText', delText); + await render(hbs`{{edit-form model=model deleteButtonText=deleteButtonText}}`); + + assert.ok(component.showsDelete); + assert.equal(component.deleteText, delText); + }); + + test('it calls flash message fns on save', async function(assert) { + let model = createModel(); + let onSave = () => { + return resolve(); + }; + this.set('model', model); + this.set('onSave', onSave); + let saveSpy = sinon.spy(this, 'onSave'); + + await render(hbs`{{edit-form model=model onSave=onSave}}`); + + component.submit(); + later(() => run.cancelTimers(), 50); + return settled().then(() => { + assert.ok(saveSpy.calledOnce, 'calls passed onSave'); + assert.equal(saveSpy.getCall(0).args[0].saveType, 'save'); + assert.deepEqual(saveSpy.getCall(0).args[0].model, model, 'passes model to onSave'); + let flash = this.owner.lookup('service:flash-messages'); + assert.equal(flash.success.callCount, 1, 'calls flash message success'); + }); + }); + + test('it calls flash message fns on delete', async function(assert) { + let model = createModel(); + let onSave = () => { + return resolve(); + }; + this.set('model', model); + this.set('onSave', onSave); + let saveSpy = sinon.spy(this, 'onSave'); + + await render(hbs`{{edit-form model=model onSave=onSave}}`); + await component.deleteButton(); + await component.deleteConfirm(); + + later(() => run.cancelTimers(), 50); + return settled().then(() => { assert.ok(saveSpy.calledOnce, 'calls onSave'); assert.equal(saveSpy.getCall(0).args[0].saveType, 'destroyRecord'); assert.deepEqual(saveSpy.getCall(0).args[0].model, model, 'passes model to onSave'); diff --git a/ui/tests/integration/components/edition-badge-test.js b/ui/tests/integration/components/edition-badge-test.js index b01ec1729..a43414dd9 100644 --- a/ui/tests/integration/components/edition-badge-test.js +++ b/ui/tests/integration/components/edition-badge-test.js @@ -1,20 +1,22 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, find } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('edition-badge', 'Integration | Component | edition badge', { - integration: true, -}); - -test('it renders', function(assert) { - this.render(hbs` - {{edition-badge edition="Custom"}} - `); - - assert.equal(this.$('.edition-badge').text().trim(), 'Custom', 'contains edition'); - - this.render(hbs` - {{edition-badge edition="Enterprise"}} - `); - - assert.equal(this.$('.edition-badge').text().trim(), 'Enterprise', 'renders edition'); +module('Integration | Component | edition badge', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + await render(hbs` + {{edition-badge edition="Custom"}} + `); + + assert.equal(find('.edition-badge').textContent.trim(), 'Custom', 'contains edition'); + + await render(hbs` + {{edition-badge edition="Enterprise"}} + `); + + assert.equal(find('.edition-badge').textContent.trim(), 'Enterprise', 'renders edition'); + }); }); diff --git a/ui/tests/integration/components/form-field-test.js b/ui/tests/integration/components/form-field-test.js index 62e91227e..460069665 100644 --- a/ui/tests/integration/components/form-field-test.js +++ b/ui/tests/integration/components/form-field-test.js @@ -1,135 +1,138 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import EmberObject from '@ember/object'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import { create } from 'ember-cli-page-object'; -import Ember from 'ember'; import sinon from 'sinon'; import formFields from '../../pages/components/form-field'; const component = create(formFields); -moduleForComponent('form-field', 'Integration | Component | form field', { - integration: true, - beforeEach() { +module('Integration | Component | form field', function(hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function() { component.setContext(this); - }, + }); - afterEach() { + hooks.afterEach(function() { component.removeContext(); - }, -}); + }); -const createAttr = (name, type, options) => { - return { - name, - type, - options, + const createAttr = (name, type, options) => { + return { + name, + type, + options, + }; }; -}; -const setup = function(attr) { - let model = Ember.Object.create({}); - let spy = sinon.spy(); - this.set('onChange', spy); - this.set('model', model); - this.set('attr', attr); - this.render(hbs`{{form-field attr=attr model=model onChange=onChange}}`); - return [model, spy]; -}; + const setup = async function(attr) { + let model = EmberObject.create({}); + let spy = sinon.spy(); + this.set('onChange', spy); + this.set('model', model); + this.set('attr', attr); + await render(hbs`{{form-field attr=attr model=model onChange=onChange}}`); + return [model, spy]; + }; -test('it renders', function(assert) { - let model = Ember.Object.create({}); - this.set('attr', { name: 'foo' }); - this.set('model', model); - this.render(hbs`{{form-field attr=attr model=model}}`); + test('it renders', async function(assert) { + let model = EmberObject.create({}); + this.set('attr', { name: 'foo' }); + this.set('model', model); + await render(hbs`{{form-field attr=attr model=model}}`); - assert.equal(component.field.labelText, 'Foo', 'renders a label'); - assert.notOk(component.hasInput, 'renders only the label'); -}); - -test('it renders: string', function(assert) { - let [model, spy] = setup.call(this, createAttr('foo', 'string', { defaultValue: 'default' })); - assert.equal(component.field.labelText, 'Foo', 'renders a label'); - assert.equal(component.field.inputValue, 'default', 'renders default value'); - assert.ok(component.hasInput, 'renders input for string'); - component.field.input('bar').change(); - - assert.equal(model.get('foo'), 'bar'); - assert.ok(spy.calledWith('foo', 'bar'), 'onChange called with correct args'); -}); - -test('it renders: boolean', function(assert) { - let [model, spy] = setup.call(this, createAttr('foo', 'boolean', { defaultValue: false })); - assert.equal(component.field.labelText, 'Foo', 'renders a label'); - assert.notOk(component.field.inputChecked, 'renders default value'); - assert.ok(component.hasCheckbox, 'renders a checkbox for boolean'); - component.field.clickLabel(); - - assert.equal(model.get('foo'), true); - assert.ok(spy.calledWith('foo', true), 'onChange called with correct args'); -}); - -test('it renders: number', function(assert) { - let [model, spy] = setup.call(this, createAttr('foo', 'number', { defaultValue: 5 })); - assert.equal(component.field.labelText, 'Foo', 'renders a label'); - assert.equal(component.field.inputValue, 5, 'renders default value'); - assert.ok(component.hasInput, 'renders input for number'); - component.field.input(8).change(); - - assert.equal(model.get('foo'), 8); - assert.ok(spy.calledWith('foo', '8'), 'onChange called with correct args'); -}); - -test('it renders: object', function(assert) { - setup.call(this, createAttr('foo', 'object')); - assert.equal(component.field.labelText, 'Foo', 'renders a label'); - assert.ok(component.hasJSONEditor, 'renders the json editor'); -}); - -test('it renders: editType textarea', function(assert) { - let [model, spy] = setup.call( - this, - createAttr('foo', 'string', { defaultValue: 'goodbye', editType: 'textarea' }) - ); - assert.equal(component.field.labelText, 'Foo', 'renders a label'); - assert.ok(component.hasTextarea, 'renders a textarea'); - assert.equal(component.field.textareaValue, 'goodbye', 'renders default value'); - component.field.textarea('hello'); - - assert.equal(model.get('foo'), 'hello'); - assert.ok(spy.calledWith('foo', 'hello'), 'onChange called with correct args'); -}); - -test('it renders: editType file', function(assert) { - setup.call(this, createAttr('foo', 'string', { editType: 'file' })); - assert.ok(component.hasTextFile, 'renders the text-file component'); -}); - -test('it renders: editType ttl', function(assert) { - let [model, spy] = setup.call(this, createAttr('foo', null, { editType: 'ttl' })); - assert.ok(component.hasTTLPicker, 'renders the ttl-picker component'); - component.field.input('3'); - component.field.select('h').change(); - - assert.equal(model.get('foo'), '3h'); - assert.ok(spy.calledWith('foo', '3h'), 'onChange called with correct args'); -}); - -test('it renders: editType stringArray', function(assert) { - let [model, spy] = setup.call(this, createAttr('foo', 'string', { editType: 'stringArray' })); - assert.ok(component.hasStringList, 'renders the string-list component'); - - component.field.input('array').change(); - assert.deepEqual(model.get('foo'), ['array'], 'sets the value on the model'); - assert.deepEqual(spy.args[0], ['foo', ['array']], 'onChange called with correct args'); -}); - -test('it uses a passed label', function(assert) { - setup.call(this, createAttr('foo', 'string', { label: 'Not Foo' })); - assert.equal(component.field.labelText, 'Not Foo', 'renders the label from options'); -}); - -test('it renders a help tooltip', function(assert) { - setup.call(this, createAttr('foo', 'string', { helpText: 'Here is some help text' })); - assert.ok(component.hasTooltip, 'renders the tooltip component'); - component.tooltipTrigger(); + assert.equal(component.fields[0].labelText, 'Foo', 'renders a label'); + assert.notOk(component.hasInput, 'renders only the label'); + }); + + test('it renders: string', async function(assert) { + let [model, spy] = await setup.call(this, createAttr('foo', 'string', { defaultValue: 'default' })); + assert.equal(component.fields[0].labelText, 'Foo', 'renders a label'); + assert.equal(component.fields[0].inputValue, 'default', 'renders default value'); + assert.ok(component.hasInput, 'renders input for string'); + await component.fields[0].input('bar').change(); + + assert.equal(model.get('foo'), 'bar'); + assert.ok(spy.calledWith('foo', 'bar'), 'onChange called with correct args'); + }); + + test('it renders: boolean', async function(assert) { + let [model, spy] = await setup.call(this, createAttr('foo', 'boolean', { defaultValue: false })); + assert.equal(component.fields[0].labelText, 'Foo', 'renders a label'); + assert.notOk(component.fields[0].inputChecked, 'renders default value'); + assert.ok(component.hasCheckbox, 'renders a checkbox for boolean'); + await component.fields[0].clickLabel(); + + assert.equal(model.get('foo'), true); + assert.ok(spy.calledWith('foo', true), 'onChange called with correct args'); + }); + + test('it renders: number', async function(assert) { + let [model, spy] = await setup.call(this, createAttr('foo', 'number', { defaultValue: 5 })); + assert.equal(component.fields[0].labelText, 'Foo', 'renders a label'); + assert.equal(component.fields[0].inputValue, 5, 'renders default value'); + assert.ok(component.hasInput, 'renders input for number'); + await component.fields[0].input(8).change(); + + assert.equal(model.get('foo'), 8); + assert.ok(spy.calledWith('foo', '8'), 'onChange called with correct args'); + }); + + test('it renders: object', async function(assert) { + await setup.call(this, createAttr('foo', 'object')); + assert.equal(component.fields[0].labelText, 'Foo', 'renders a label'); + assert.ok(component.hasJSONEditor, 'renders the json editor'); + }); + + test('it renders: editType textarea', async function(assert) { + let [model, spy] = await setup.call( + this, + createAttr('foo', 'string', { defaultValue: 'goodbye', editType: 'textarea' }) + ); + assert.equal(component.fields[0].labelText, 'Foo', 'renders a label'); + assert.ok(component.hasTextarea, 'renders a textarea'); + assert.equal(component.fields[0].textareaValue, 'goodbye', 'renders default value'); + await component.fields[0].textarea('hello'); + + assert.equal(model.get('foo'), 'hello'); + assert.ok(spy.calledWith('foo', 'hello'), 'onChange called with correct args'); + }); + + test('it renders: editType file', async function(assert) { + await setup.call(this, createAttr('foo', 'string', { editType: 'file' })); + assert.ok(component.hasTextFile, 'renders the text-file component'); + }); + + test('it renders: editType ttl', async function(assert) { + let [model, spy] = await setup.call(this, createAttr('foo', null, { editType: 'ttl' })); + assert.ok(component.hasTTLPicker, 'renders the ttl-picker component'); + await component.fields[0].input('3'); + await component.fields[0].select('h').change(); + + assert.equal(model.get('foo'), '3h'); + assert.ok(spy.calledWith('foo', '3h'), 'onChange called with correct args'); + }); + + test('it renders: editType stringArray', async function(assert) { + let [model, spy] = await setup.call(this, createAttr('foo', 'string', { editType: 'stringArray' })); + assert.ok(component.hasStringList, 'renders the string-list component'); + + await component.fields[0].input('array').change(); + assert.deepEqual(model.get('foo'), ['array'], 'sets the value on the model'); + assert.deepEqual(spy.args[0], ['foo', ['array']], 'onChange called with correct args'); + }); + + test('it uses a passed label', async function(assert) { + await setup.call(this, createAttr('foo', 'string', { label: 'Not Foo' })); + assert.equal(component.fields[0].labelText, 'Not Foo', 'renders the label from options'); + }); + + test('it renders a help tooltip', async function(assert) { + await setup.call(this, createAttr('foo', 'string', { helpText: 'Here is some help text' })); + await component.tooltipTrigger(); + assert.ok(component.hasTooltip, 'renders the tooltip component'); + }); }); diff --git a/ui/tests/integration/components/hover-copy-button-test.js b/ui/tests/integration/components/hover-copy-button-test.js index 9f114a255..4875a3142 100644 --- a/ui/tests/integration/components/hover-copy-button-test.js +++ b/ui/tests/integration/components/hover-copy-button-test.js @@ -1,39 +1,43 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test, skip } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import { create } from 'ember-cli-page-object'; import hbs from 'htmlbars-inline-precompile'; import copyButton from 'vault/tests/pages/components/hover-copy-button'; -import { triggerSuccess } from '../../helpers/ember-cli-clipboard'; const component = create(copyButton); -moduleForComponent('hover-copy-button', 'Integration | Component | hover copy button', { - integration: true, +module('Integration | Component | hover copy button', function(hooks) { + setupRenderingTest(hooks); - beforeEach() { + hooks.beforeEach(function() { component.setContext(this); - }, + }); - afterEach() { + hooks.afterEach(function() { component.removeContext(); - }, -}); + }); -test('it shows success message in tooltip', function(assert) { - this.set('copyValue', 'foo'); - this.render( - hbs`
    {{hover-copy-button copyValue=copyValue}}
    ` - ); + // ember-cli-clipboard helpers don't like the new style + skip('it shows success message in tooltip', async function(assert) { + this.set('copyValue', 'foo'); + await render( + hbs`
    + +
    ` + ); - component.focusContainer(); - assert.ok(component.buttonIsVisible); - component.mouseEnter(); - assert.equal(component.tooltipText, 'Copy', 'shows copy'); - triggerSuccess(this, '[data-test-hover-copy-button]'); - assert.equal(component.tooltipText, 'Copied!', 'shows success message'); -}); + await component.focusContainer(); + assert.ok(component.buttonIsVisible); + await component.mouseEnter(); + assert.equal(component.tooltipText, 'Copy', 'shows copy'); + await component.click(); + assert.equal(component.tooltipText, 'Copied!', 'shows success message'); + }); -test('it has the correct class when alwaysShow is true', function(assert) { - this.set('copyValue', 'foo'); - this.render(hbs`{{hover-copy-button alwaysShow=true copyValue=copyValue}}`); - assert.ok(component.buttonIsVisible); - assert.ok(component.wrapperClass.includes('hover-copy-button-static')); + test('it has the correct class when alwaysShow is true', async function(assert) { + this.set('copyValue', 'foo'); + await render(hbs`{{hover-copy-button alwaysShow=true copyValue=copyValue}}`); + assert.ok(component.buttonIsVisible); + assert.ok(component.wrapperClass.includes('hover-copy-button-static')); + }); }); diff --git a/ui/tests/integration/components/identity/item-details-test.js b/ui/tests/integration/components/identity/item-details-test.js index 3e54efbdf..cd8153ea4 100644 --- a/ui/tests/integration/components/identity/item-details-test.js +++ b/ui/tests/integration/components/identity/item-details-test.js @@ -1,56 +1,60 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { resolve } from 'rsvp'; +import EmberObject from '@ember/object'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import sinon from 'sinon'; import { create } from 'ember-cli-page-object'; import itemDetails from 'vault/tests/pages/components/identity/item-details'; -import Ember from 'ember'; const component = create(itemDetails); -const { getOwner } = Ember; -moduleForComponent('identity/item-details', 'Integration | Component | identity/item details', { - integration: true, - beforeEach() { +module('Integration | Component | identity/item details', function(hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function() { component.setContext(this); - getOwner(this).lookup('service:flash-messages').registerTypes(['success']); - }, - afterEach() { + this.owner.lookup('service:flash-messages').registerTypes(['success']); + }); + + hooks.afterEach(function() { component.removeContext(); - }, -}); - -test('it renders the disabled warning', function(assert) { - let model = Ember.Object.create({ - save() { - return Ember.RSVP.resolve(); - }, - disabled: true, - canEdit: true, - }); - sinon.spy(model, 'save'); - this.set('model', model); - this.render(hbs`{{identity/item-details model=model}}`); - assert.dom('[data-test-disabled-warning]').exists(); - component.enable(); - - assert.ok(model.save.calledOnce, 'clicking enable calls model save'); -}); - -test('it does not render the button if canEdit is false', function(assert) { - let model = Ember.Object.create({ - disabled: true, }); - this.set('model', model); - this.render(hbs`{{identity/item-details model=model}}`); - assert.dom('[data-test-disabled-warning]').exists('shows the warning banner'); - assert.dom('[data-test-enable]').doesNotExist('does not show the enable button'); -}); + test('it renders the disabled warning', async function(assert) { + let model = EmberObject.create({ + save() { + return resolve(); + }, + disabled: true, + canEdit: true, + }); + sinon.spy(model, 'save'); + this.set('model', model); + await render(hbs`{{identity/item-details model=model}}`); + assert.dom('[data-test-disabled-warning]').exists(); + await component.enable(); -test('it does not render the banner when item is enabled', function(assert) { - let model = Ember.Object.create(); - this.set('model', model); + assert.ok(model.save.calledOnce, 'clicking enable calls model save'); + }); - this.render(hbs`{{identity/item-details model=model}}`); - assert.dom('[data-test-disabled-warning]').doesNotExist('does not show the warning banner'); + test('it does not render the button if canEdit is false', async function(assert) { + let model = EmberObject.create({ + disabled: true, + }); + + this.set('model', model); + await render(hbs`{{identity/item-details model=model}}`); + assert.dom('[data-test-disabled-warning]').exists('shows the warning banner'); + assert.dom('[data-test-enable]').doesNotExist('does not show the enable button'); + }); + + test('it does not render the banner when item is enabled', async function(assert) { + let model = EmberObject.create(); + this.set('model', model); + + await render(hbs`{{identity/item-details model=model}}`); + assert.dom('[data-test-disabled-warning]').doesNotExist('does not show the warning banner'); + }); }); diff --git a/ui/tests/integration/components/kv-object-editor-test.js b/ui/tests/integration/components/kv-object-editor-test.js index 4340c1bcc..917dc0b2d 100644 --- a/ui/tests/integration/components/kv-object-editor-test.js +++ b/ui/tests/integration/components/kv-object-editor-test.js @@ -1,5 +1,6 @@ -import { moduleForComponent, test } from 'ember-qunit'; -import wait from 'ember-test-helpers/wait'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import { create } from 'ember-cli-page-object'; @@ -8,84 +9,79 @@ import kvObjectEditor from '../../pages/components/kv-object-editor'; import sinon from 'sinon'; const component = create(kvObjectEditor); -moduleForComponent('kv-object-editor', 'Integration | Component | kv object editor', { - integration: true, - beforeEach() { +module('Integration | Component | kv object editor', function(hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function() { component.setContext(this); - }, - - afterEach() { - component.removeContext(); - }, -}); - -test('it renders with no initial value', function(assert) { - let spy = sinon.spy(); - this.set('onChange', spy); - this.render(hbs`{{kv-object-editor onChange=onChange}}`); - assert.equal(component.rows().count, 1, 'renders a single row'); - component.addRow(); - return wait().then(() => { - assert.equal(component.rows().count, 1, 'will only render row with a blank key'); }); -}); -test('it calls onChange when the val changes', function(assert) { - let spy = sinon.spy(); - this.set('onChange', spy); - this.render(hbs`{{kv-object-editor onChange=onChange}}`); - component.rows(0).kvKey('foo').kvVal('bar'); - wait().then(() => { + hooks.afterEach(function() { + component.removeContext(); + }); + + test('it renders with no initial value', async function(assert) { + let spy = sinon.spy(); + this.set('onChange', spy); + await render(hbs`{{kv-object-editor onChange=onChange}}`); + assert.equal(component.rows.length, 1, 'renders a single row'); + await component.addRow(); + assert.equal(component.rows.length, 1, 'will only render row with a blank key'); + }); + + test('it calls onChange when the val changes', async function(assert) { + let spy = sinon.spy(); + this.set('onChange', spy); + await render(hbs`{{kv-object-editor onChange=onChange}}`); + await component.rows + .objectAt(0) + .kvKey('foo') + .kvVal('bar'); assert.equal(spy.callCount, 2, 'calls onChange each time change is triggered'); assert.deepEqual( spy.lastCall.args[0], { foo: 'bar' }, 'calls onChange with the JSON respresentation of the data' ); + await component.addRow(); + assert.equal(component.rows.length, 2, 'adds a row when there is no blank one'); }); - component.addRow(); - return wait().then(() => { - assert.equal(component.rows().count, 2, 'adds a row when there is no blank one'); + + test('it renders passed data', async function(assert) { + let metadata = { foo: 'bar', baz: 'bop' }; + this.set('value', metadata); + await render(hbs`{{kv-object-editor value=value}}`); + assert.equal( + component.rows.length, + Object.keys(metadata).length + 1, + 'renders both rows of the metadata, plus an empty one' + ); }); -}); -test('it renders passed data', function(assert) { - let metadata = { foo: 'bar', baz: 'bop' }; - this.set('value', metadata); - this.render(hbs`{{kv-object-editor value=value}}`); - assert.equal( - component.rows().count, - Object.keys(metadata).length + 1, - 'renders both rows of the metadata, plus an empty one' - ); -}); - -test('it deletes a row', function(assert) { - let spy = sinon.spy(); - this.set('onChange', spy); - this.render(hbs`{{kv-object-editor onChange=onChange}}`); - component.rows(0).kvKey('foo').kvVal('bar'); - component.addRow(); - wait().then(() => { - assert.equal(component.rows().count, 2); + test('it deletes a row', async function(assert) { + let spy = sinon.spy(); + this.set('onChange', spy); + await render(hbs`{{kv-object-editor onChange=onChange}}`); + await component.rows + .objectAt(0) + .kvKey('foo') + .kvVal('bar'); + await component.addRow(); + assert.equal(component.rows.length, 2); assert.equal(spy.callCount, 2, 'calls onChange for editing'); - component.rows(0).deleteRow(); - }); + await component.rows.objectAt(0).deleteRow(); - return wait().then(() => { - assert.equal(component.rows().count, 1, 'only the blank row left'); + assert.equal(component.rows.length, 1, 'only the blank row left'); assert.equal(spy.callCount, 3, 'calls onChange deleting row'); assert.deepEqual(spy.lastCall.args[0], {}, 'last call to onChange is an empty object'); }); -}); -test('it shows a warning if there are duplicate keys', function(assert) { - let metadata = { foo: 'bar', baz: 'bop' }; - this.set('value', metadata); - this.render(hbs`{{kv-object-editor value=value}}`); - component.rows(0).kvKey('foo'); + test('it shows a warning if there are duplicate keys', async function(assert) { + let metadata = { foo: 'bar', baz: 'bop' }; + this.set('value', metadata); + await render(hbs`{{kv-object-editor value=value}}`); + await component.rows.objectAt(0).kvKey('foo'); - return wait().then(() => { assert.ok(component.showsDuplicateError, 'duplicate keys are allowed but an error message is shown'); }); }); diff --git a/ui/tests/integration/components/masked-input-test.js b/ui/tests/integration/components/masked-input-test.js index 9dfddf1f1..50c9adf4b 100644 --- a/ui/tests/integration/components/masked-input-test.js +++ b/ui/tests/integration/components/masked-input-test.js @@ -1,95 +1,84 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import { create } from 'ember-cli-page-object'; import hbs from 'htmlbars-inline-precompile'; import maskedInput from 'vault/tests/pages/components/masked-input'; const component = create(maskedInput); -moduleForComponent('masked-input', 'Integration | Component | masked input', { - integration: true, +module('Integration | Component | masked input', function(hooks) { + setupRenderingTest(hooks); - beforeEach() { + hooks.beforeEach(function() { component.setContext(this); - }, + }); - afterEach() { + hooks.afterEach(function() { component.removeContext(); - }, + }); + + const hasClass = (classString = '', classToFind) => { + return classString.split(' ').includes(classToFind); + }; + + test('it renders', async function(assert) { + await render(hbs`{{masked-input}}`); + + assert.ok(hasClass(component.wrapperClass, 'masked')); + }); + + test('it renders a textarea', async function(assert) { + await render(hbs`{{masked-input}}`); + + assert.ok(component.textareaIsPresent); + }); + + test('it does not render a textarea when displayOnly is true', async function(assert) { + await render(hbs`{{masked-input displayOnly=true}}`); + + assert.notOk(component.textareaIsPresent); + }); + + test('it unmasks text on focus', async function(assert) { + this.set('value', 'value'); + await render(hbs`{{masked-input value=value}}`); + assert.ok(hasClass(component.wrapperClass, 'masked')); + + await component.focusField(); + assert.notOk(hasClass(component.wrapperClass, 'masked')); + }); + + test('it remasks text on blur', async function(assert) { + this.set('value', 'value'); + await render(hbs`{{masked-input value=value}}`); + + assert.ok(hasClass(component.wrapperClass, 'masked')); + + await component.focusField(); + await component.blurField(); + + assert.ok(hasClass(component.wrapperClass, 'masked')); + }); + + test('it unmasks text when button is clicked', async function(assert) { + this.set('value', 'value'); + await render(hbs`{{masked-input value=value}}`); + + assert.ok(hasClass(component.wrapperClass, 'masked')); + + await component.toggleMasked(); + + assert.notOk(hasClass(component.wrapperClass, 'masked')); + }); + + test('it remasks text when button is clicked', async function(assert) { + this.set('value', 'value'); + await render(hbs`{{masked-input value=value}}`); + + await component.toggleMasked(); + await component.toggleMasked(); + + assert.ok(hasClass(component.wrapperClass, 'masked')); + }); }); - -const hasClass = (classString = '', classToFind) => { - return classString.split(' ').contains(classToFind); -} - -test('it renders', function(assert) { - - this.render(hbs`{{masked-input}}`); - - assert.ok(hasClass(component.wrapperClass, 'masked')); -}); - - -test('it renders a textarea', function(assert) { - - this.render(hbs`{{masked-input}}`); - - assert.ok(component.textareaIsPresent); -}); - -test('it does not render a textarea when displayOnly is true', function(assert) { - - this.render(hbs`{{masked-input displayOnly=true}}`); - - assert.notOk(component.textareaIsPresent); -}); - - -test('it unmasks text on focus', function(assert) { - - this.set('value', 'value'); - this.render(hbs`{{masked-input value=value}}`); - - assert.ok(hasClass(component.wrapperClass, 'masked')); - - component.focus(); - assert.notOk(hasClass(component.wrapperClass, 'masked')); -}); - -test('it remasks text on blur', function(assert) { - - this.set('value', 'value'); - this.render(hbs`{{masked-input value=value}}`); - - assert.ok(hasClass(component.wrapperClass, 'masked')); - - component.focus(); - component.blur(); - - assert.ok(hasClass(component.wrapperClass, 'masked')); -}); - -test('it unmasks text when button is clicked', function(assert) { - - this.set('value', 'value'); - this.render(hbs`{{masked-input value=value}}`); - - assert.ok(hasClass(component.wrapperClass, 'masked')); - - component.toggleMasked(); - - assert.notOk(hasClass(component.wrapperClass, 'masked')); - -}); - -test('it remasks text when button is clicked', function(assert) { - - this.set('value', 'value'); - this.render(hbs`{{masked-input value=value}}`); - - component.toggleMasked(); - component.toggleMasked(); - - assert.ok(hasClass(component.wrapperClass, 'masked')); - -}); - diff --git a/ui/tests/integration/components/mount-backend-form-test.js b/ui/tests/integration/components/mount-backend-form-test.js index db790ac1e..28b878c75 100644 --- a/ui/tests/integration/components/mount-backend-form-test.js +++ b/ui/tests/integration/components/mount-backend-form-test.js @@ -1,6 +1,7 @@ -import Ember from 'ember'; -import { moduleForComponent, test } from 'ember-qunit'; -import wait from 'ember-test-helpers/wait'; +import { later, run } from '@ember/runloop'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, settled } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import { create } from 'ember-cli-page-object'; @@ -11,67 +12,73 @@ import sinon from 'sinon'; const component = create(mountBackendForm); -moduleForComponent('mount-backend-form', 'Integration | Component | mount backend form', { - integration: true, - beforeEach() { - component.setContext(this); - Ember.getOwner(this).lookup('service:flash-messages').registerTypes(['success', 'danger']); - this.server = startMirage(); - }, +module('Integration | Component | mount backend form', function(hooks) { + setupRenderingTest(hooks); - afterEach() { + hooks.beforeEach(function() { + component.setContext(this); + this.owner.lookup('service:flash-messages').registerTypes(['success', 'danger']); + this.server = startMirage(); + }); + + hooks.afterEach(function() { component.removeContext(); this.server.shutdown(); - }, -}); + }); -test('it renders', function(assert) { - this.render(hbs`{{mount-backend-form}}`); - assert.equal(component.header, 'Enable an authentication method', 'renders auth header in default state'); - assert.ok(component.types.length > 0, 'renders type picker'); -}); + test('it renders', async function(assert) { + await render(hbs`{{mount-backend-form}}`); + assert.equal(component.header, 'Enable an authentication method', 'renders auth header in default state'); + assert.ok(component.types.length > 0, 'renders type picker'); + }); -test('it changes path when type is changed', function(assert) { - this.render(hbs`{{mount-backend-form}}`); - component.selectType('aws').next(); - assert.equal(component.pathValue, 'aws', 'sets the value of the type'); - component.back().selectType('approle').next(); - assert.equal(component.pathValue, 'approle', 'updates the value of the type'); -}); + test('it changes path when type is changed', async function(assert) { + await render(hbs`{{mount-backend-form}}`); + await component.selectType('aws'); + await component.next(); + assert.equal(component.pathValue, 'aws', 'sets the value of the type'); + await component.back(); + await component.selectType('approle'); + await component.next(); + assert.equal(component.pathValue, 'approle', 'updates the value of the type'); + }); -test('it keeps path value if the user has changed it', function(assert) { - this.render(hbs`{{mount-backend-form}}`); - component.selectType('approle').next(); - assert.equal(component.pathValue, 'approle', 'defaults to approle (first in the list)'); - component.path('newpath'); - component.back().selectType('aws').next(); - assert.equal(component.pathValue, 'newpath', 'updates to the value of the type'); -}); + test('it keeps path value if the user has changed it', async function(assert) { + await render(hbs`{{mount-backend-form}}`); + await component.selectType('approle'); + await component.next(); + assert.equal(component.pathValue, 'approle', 'defaults to approle (first in the list)'); + await component.path('newpath'); + await component.back(); + await component.selectType('aws'); + await component.next(); + assert.equal(component.pathValue, 'newpath', 'updates to the value of the type'); + }); -test('it calls mount success', function(assert) { - const spy = sinon.spy(); - this.set('onMountSuccess', spy); - this.render(hbs`{{mount-backend-form onMountSuccess=onMountSuccess}}`); + test('it calls mount success', async function(assert) { + const spy = sinon.spy(); + this.set('onMountSuccess', spy); + await render(hbs`{{mount-backend-form onMountSuccess=onMountSuccess}}`); - component.mount('approle', 'foo').submit(); - return wait().then(() => { + await component.mount('approle', 'foo'); assert.equal(this.server.db.authMethods.length, 1, 'it enables an auth method'); assert.ok(spy.calledOnce, 'calls the passed success method'); }); -}); -test('it calls mount mount config error', function(assert) { - const spy = sinon.spy(); - const spy2 = sinon.spy(); - this.set('onMountSuccess', spy); - this.set('onConfigError', spy2); - this.render(hbs`{{mount-backend-form onMountSuccess=onMountSuccess onConfigError=onConfigError}}`); + test('it calls mount config error', async function(assert) { + const spy = sinon.spy(); + const spy2 = sinon.spy(); + this.set('onMountSuccess', spy); + this.set('onConfigError', spy2); + await render(hbs`{{mount-backend-form onMountSuccess=onMountSuccess onConfigError=onConfigError}}`); - component.selectType('kubernetes').next().path('bar'); - // kubernetes requires a host + a cert / pem, so only filling the host will error - component.fields().fillIn('kubernetesHost', 'host'); - component.submit(); - return wait().then(() => { + await component.selectType('kubernetes'); + await component.next().path('bar'); + // kubernetes requires a host + a cert / pem, so only filling the host will error + await component.fillIn('kubernetesHost', 'host'); + component.submit(); + later(() => run.cancelTimers(), 50); + await settled(); assert.equal(this.server.db.authMethods.length, 1, 'it still enables an auth method'); assert.equal(spy.callCount, 0, 'does not call the success method'); assert.ok(spy2.calledOnce, 'calls the passed error method'); diff --git a/ui/tests/integration/components/mount-filter-config-list-test.js b/ui/tests/integration/components/mount-filter-config-list-test.js index 0b48b10aa..1afd600de 100644 --- a/ui/tests/integration/components/mount-filter-config-list-test.js +++ b/ui/tests/integration/components/mount-filter-config-list-test.js @@ -1,33 +1,36 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click, findAll, fillIn, blur } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('mount-filter-config-list', 'Integration | Component | mount filter config list', { - integration: true, -}); - -test('it renders', function(assert) { - this.set('config', { mode: 'whitelist', paths: [] }); - this.set('mounts', [{ path: 'userpass/', type: 'userpass', accessor: 'userpass' }]); - this.render(hbs`{{mount-filter-config-list config=config mounts=mounts}}`); - - assert.equal(this.$('#filter-userpass').length, 1); -}); - -test('it sets config.paths', function(assert) { - this.set('config', { mode: 'whitelist', paths: [] }); - this.set('mounts', [{ path: 'userpass/', type: 'userpass', accessor: 'userpass' }]); - this.render(hbs`{{mount-filter-config-list config=config mounts=mounts}}`); - - this.$('#filter-userpass').click(); - assert.ok(this.get('config.paths').includes('userpass/'), 'adds to paths'); - - this.$('#filter-userpass').click(); - assert.equal(this.get('config.paths').length, 0, 'removes from paths'); -}); - -test('it sets config.mode', function(assert) { - this.set('config', { mode: 'whitelist', paths: [] }); - this.render(hbs`{{mount-filter-config-list config=config}}`); - this.$('#filter-mode').val('blacklist').change(); - assert.equal(this.get('config.mode'), 'blacklist'); +module('Integration | Component | mount filter config list', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + this.set('config', { mode: 'whitelist', paths: [] }); + this.set('mounts', [{ path: 'userpass/', type: 'userpass', accessor: 'userpass' }]); + await render(hbs`{{mount-filter-config-list config=config mounts=mounts}}`); + + assert.equal(findAll('#filter-userpass').length, 1); + }); + + test('it sets config.paths', async function(assert) { + this.set('config', { mode: 'whitelist', paths: [] }); + this.set('mounts', [{ path: 'userpass/', type: 'userpass', accessor: 'userpass' }]); + await render(hbs`{{mount-filter-config-list config=config mounts=mounts}}`); + + await click('#filter-userpass'); + assert.ok(this.get('config.paths').includes('userpass/'), 'adds to paths'); + + await click('#filter-userpass'); + assert.equal(this.get('config.paths').length, 0, 'removes from paths'); + }); + + test('it sets config.mode', async function(assert) { + this.set('config', { mode: 'whitelist', paths: [] }); + await render(hbs`{{mount-filter-config-list config=config}}`); + await fillIn('#filter-mode', 'blacklist'); + await blur('#filter-mode'); + assert.equal(this.get('config.mode'), 'blacklist'); + }); }); diff --git a/ui/tests/integration/components/nav-header-test.js b/ui/tests/integration/components/nav-header-test.js index e35e94b2d..bf33e6f72 100644 --- a/ui/tests/integration/components/nav-header-test.js +++ b/ui/tests/integration/components/nav-header-test.js @@ -1,39 +1,41 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import { create } from 'ember-cli-page-object'; import hbs from 'htmlbars-inline-precompile'; import navHeader from 'vault/tests/pages/components/nav-header'; const component = create(navHeader); -moduleForComponent('nav-header', 'Integration | Component | nav header', { - integration: true, +module('Integration | Component | nav header', function(hooks) { + setupRenderingTest(hooks); - beforeEach() { + hooks.beforeEach(function() { component.setContext(this); - }, + }); - afterEach() { + hooks.afterEach(function() { component.removeContext(); - }, -}); + }); -test('it renders', function(assert) { - this.render(hbs` - {{#nav-header as |h|}} - {{#h.home}} - Home! - {{/h.home}} - {{#h.items}} - Some Items - {{/h.items}} - {{#h.main}} - Main stuff here - {{/h.main}} - {{/nav-header}} - `); + test('it renders', async function(assert) { + await render(hbs` + {{#nav-header as |h|}} + {{#h.home}} + Home! + {{/h.home}} + {{#h.items}} + Some Items + {{/h.items}} + {{#h.main}} + Main stuff here + {{/h.main}} + {{/nav-header}} + `); - assert.ok(component.ele, 'renders the outer element'); - assert.equal(component.homeText.trim(), 'Home!', 'renders home content'); - assert.equal(component.itemsText.trim(), 'Some Items', 'renders items content'); - assert.equal(component.mainText.trim(), 'Main stuff here', 'renders items content'); + assert.ok(component.ele, 'renders the outer element'); + assert.equal(component.homeText.trim(), 'Home!', 'renders home content'); + assert.equal(component.itemsText.trim(), 'Some Items', 'renders items content'); + assert.equal(component.mainText.trim(), 'Main stuff here', 'renders items content'); + }); }); diff --git a/ui/tests/integration/components/pgp-file-test.js b/ui/tests/integration/components/pgp-file-test.js index cffb67eaa..4ca77d89e 100644 --- a/ui/tests/integration/components/pgp-file-test.js +++ b/ui/tests/integration/components/pgp-file-test.js @@ -1,101 +1,92 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click, fillIn, findAll, find, triggerEvent, waitUntil } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -import Ember from 'ember'; -import wait from 'ember-test-helpers/wait'; let file; const fileEvent = () => { const data = { some: 'content' }; file = new File([JSON.stringify(data, null, 2)], 'file.json', { type: 'application/json' }); - return Ember.$.Event('change', { - target: { - files: [file], - }, - }); + return ['change', [file]]; }; -moduleForComponent('pgp-file', 'Integration | Component | pgp file', { - integration: true, - beforeEach: function() { +module('Integration | Component | pgp file', function(hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function() { file = null; this.lastOnChangeCall = null; this.set('change', (index, key) => { this.lastOnChangeCall = [index, key]; this.set('key', key); }); - }, -}); + }); -test('it renders', function(assert) { - this.set('key', { value: '' }); - this.set('index', 0); + test('it renders', async function(assert) { + this.set('key', { value: '' }); + this.set('index', 0); - this.render(hbs`{{pgp-file index=index key=key onChange=(action change)}}`); + await render(hbs`{{pgp-file index=index key=key onChange=(action change)}}`); - assert.equal(this.$('[data-test-pgp-label]').text().trim(), 'PGP KEY 1'); - assert.equal(this.$('[data-test-pgp-file-input-label]').text().trim(), 'Choose a file…'); -}); + assert.equal(find('[data-test-pgp-label]').textContent.trim(), 'PGP KEY 1'); + assert.equal(find('[data-test-pgp-file-input-label]').textContent.trim(), 'Choose a file…'); + }); -test('it accepts files', function(assert) { - const key = { value: '' }; - const event = fileEvent(); - this.set('key', key); - this.set('index', 0); + test('it accepts files', async function(assert) { + const key = { value: '' }; + const event = fileEvent(); + this.set('key', key); + this.set('index', 0); - this.render(hbs`{{pgp-file index=index key=key onChange=(action change)}}`); - this.$('[data-test-pgp-file-input]').trigger(event); + await render(hbs`{{pgp-file index=index key=key onChange=(action change)}}`); + triggerEvent('[data-test-pgp-file-input]', ...event); - return wait().then(() => { // FileReader is async, but then we need extra run loop wait to re-render - Ember.run.next(() => { - assert.equal( - this.$('[data-test-pgp-file-input-label]').text().trim(), - file.name, - 'the file input shows the file name' - ); - assert.notDeepEqual(this.lastOnChangeCall[1].value, key.value, 'onChange was called with the new key'); - assert.equal(this.lastOnChangeCall[0], 0, 'onChange is called with the index value'); - this.$('[data-test-pgp-clear]').click(); + await waitUntil(() => { + return !!this.lastOnChangeCall; }); - return wait().then(() => { - assert.equal(this.lastOnChangeCall[1].value, key.value, 'the key gets reset when the input is cleared'); - }); - }); -}); - -test('it allows for text entry', function(assert) { - const key = { value: '' }; - const text = 'a really long pgp key'; - this.set('key', key); - this.set('index', 0); - - this.render(hbs`{{pgp-file index=index key=key onChange=(action change)}}`); - this.$('[data-test-text-toggle]').click(); - assert.equal(this.$('[data-test-pgp-file-textarea]').length, 1, 'renders the textarea on toggle'); - - this.$('[data-test-pgp-file-textarea]').text(text).trigger('input'); - assert.equal(this.lastOnChangeCall[1].value, text, 'the key value is passed to onChange'); -}); - -test('toggling back and forth', function(assert) { - const key = { value: '' }; - const event = fileEvent(); - this.set('key', key); - this.set('index', 0); - - this.render(hbs`{{pgp-file index=index key=key onChange=(action change)}}`); - this.$('[data-test-pgp-file-input]').trigger(event); - return wait().then(() => { - Ember.run.next(() => { - this.$('[data-test-text-toggle]').click(); - wait().then(() => { - assert.equal(this.$('[data-test-pgp-file-textarea]').length, 1, 'renders the textarea on toggle'); - assert.equal( - this.$('[data-test-pgp-file-textarea]').text().trim(), - this.lastOnChangeCall[1].value, - 'textarea shows the value of the base64d key' - ); - }); + assert.equal( + find('[data-test-pgp-file-input-label]').textContent.trim(), + file.name, + 'the file input shows the file name' + ); + assert.notDeepEqual(this.lastOnChangeCall[1].value, key.value, 'onChange was called with the new key'); + assert.equal(this.lastOnChangeCall[0], 0, 'onChange is called with the index value'); + await click('[data-test-pgp-clear]'); + assert.equal(this.lastOnChangeCall[1].value, key.value, 'the key gets reset when the input is cleared'); + }); + + test('it allows for text entry', async function(assert) { + const key = { value: '' }; + const text = 'a really long pgp key'; + this.set('key', key); + this.set('index', 0); + + await render(hbs`{{pgp-file index=index key=key onChange=(action change)}}`); + await click('[data-test-text-toggle]'); + assert.equal(findAll('[data-test-pgp-file-textarea]').length, 1, 'renders the textarea on toggle'); + + fillIn('[data-test-pgp-file-textarea]', text); + await waitUntil(() => { + return !!this.lastOnChangeCall; }); + assert.equal(this.lastOnChangeCall[1].value, text, 'the key value is passed to onChange'); + }); + + test('toggling back and forth', async function(assert) { + const key = { value: '' }; + const event = fileEvent(); + this.set('key', key); + this.set('index', 0); + + await render(hbs`{{pgp-file index=index key=key onChange=(action change)}}`); + await triggerEvent('[data-test-pgp-file-input]', ...event); + await click('[data-test-text-toggle]'); + assert.equal(findAll('[data-test-pgp-file-textarea]').length, 1, 'renders the textarea on toggle'); + assert.equal( + find('[data-test-pgp-file-textarea]').textContent.trim(), + this.lastOnChangeCall[1].value, + 'textarea shows the value of the base64d key' + ); }); }); diff --git a/ui/tests/integration/components/radial-progress-test.js b/ui/tests/integration/components/radial-progress-test.js index db7f43b44..c0c5881a1 100644 --- a/ui/tests/integration/components/radial-progress-test.js +++ b/ui/tests/integration/components/radial-progress-test.js @@ -1,33 +1,35 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import { create } from 'ember-cli-page-object'; import hbs from 'htmlbars-inline-precompile'; import radialProgress from 'vault/tests/pages/components/radial-progress'; const component = create(radialProgress); -moduleForComponent('radial-progress', 'Integration | Component | radial progress', { - integration: true, +module('Integration | Component | radial progress', function(hooks) { + setupRenderingTest(hooks); - beforeEach() { + hooks.beforeEach(function() { component.setContext(this); - }, + }); - afterEach() { + hooks.afterEach(function() { component.removeContext(); - }, -}); + }); -test('it renders', function(assert) { - let circumference = 19 / 2 * Math.PI * 2; - this.render(hbs`{{radial-progress progressDecimal=0.5}}`); + test('it renders', async function(assert) { + let circumference = (19 / 2) * Math.PI * 2; + await render(hbs`{{radial-progress progressDecimal=0.5}}`); - assert.equal(component.viewBox, '0 0 20 20'); - assert.equal(component.height, '20'); - assert.equal(component.width, '20'); - assert.equal(component.strokeWidth, '1'); - assert.equal(component.r, 19 / 2); - assert.equal(component.cx, 10); - assert.equal(component.cy, 10); - assert.equal(component.strokeDash, circumference); - assert.equal(component.strokeDashOffset, circumference * 0.5); + assert.equal(component.viewBox, '0 0 20 20'); + assert.equal(component.height, '20'); + assert.equal(component.width, '20'); + assert.equal(component.strokeWidth, '1'); + assert.equal(component.r, 19 / 2); + assert.equal(component.cx, 10); + assert.equal(component.cy, 10); + assert.equal(component.strokeDash, circumference); + assert.equal(component.strokeDashOffset, circumference * 0.5); + }); }); diff --git a/ui/tests/integration/components/replication-actions-test.js b/ui/tests/integration/components/replication-actions-test.js index 43c75aff0..e59883fa2 100644 --- a/ui/tests/integration/components/replication-actions-test.js +++ b/ui/tests/integration/components/replication-actions-test.js @@ -1,158 +1,130 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { run } from '@ember/runloop'; +import { resolve } from 'rsvp'; +import Service from '@ember/service'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { click, fillIn, blur, render, find } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -import Ember from 'ember'; +import sinon from 'sinon'; -const CapabilitiesStub = Ember.Object.extend({ - canUpdate: Ember.computed('capabilities', function() { - return (this.get('capabilities') || []).includes('root'); - }), -}); - -const storeStub = Ember.Service.extend({ +const storeStub = Service.extend({ callArgs: null, - capabilitiesReturnVal: null, - findRecord(_, path) { - const self = this; - self.set('callArgs', { path }); - const caps = CapabilitiesStub.create({ - path, - capabilities: self.get('capabilitiesReturnVal') || [], - }); - return Ember.RSVP.resolve(caps); + adapterFor() { + return { + replicationAction() { + return { + then(cb) { + cb(); + }, + }; + }, + }; }, }); -moduleForComponent('replication-actions', 'Integration | Component | replication actions', { - integration: true, - beforeEach: function() { - this.register('service:store', storeStub); - this.inject.service('store', { as: 'storeService' }); - }, +const routerService = Service.extend({ + transitionTo: sinon.stub().returns(resolve()), }); -function testAction( - assert, - replicationMode, - clusterMode, - action, - headerText, - capabilitiesPath, - fillInFn, - expectedOnSubmit -) { - const testKey = `${replicationMode}-${clusterMode}-${action}`; - if (replicationMode) { - this.set('model', { - replicationAttrs: { - modeForUrl: clusterMode, - }, - [replicationMode]: { - mode: clusterMode, - modeForUrl: clusterMode, - }, +module('Integration | Component | replication actions', function(hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function() { + run(() => { + this.owner.register('service:router', routerService); + this.owner.unregister('service:store'); + this.owner.register('service:store', storeStub); + this.storeService = this.owner.lookup('service:store'); }); - this.set('replicationMode', replicationMode); - } else { - this.set('model', { mode: clusterMode }); - } - this.set('selectedAction', action); - this.set('onSubmit', (...actual) => { - assert.deepEqual( - JSON.stringify(actual), - JSON.stringify(expectedOnSubmit), - `${testKey}: submitted values match expected` - ); - return Ember.RSVP.resolve(); }); - this.set('storeService.capabilitiesReturnVal', ['root']); - this.render( - hbs`{{replication-actions model=model replicationMode=replicationMode selectedAction=selectedAction onSubmit=(action onSubmit)}}` - ); - assert.equal( - this.$(`h4:contains(${headerText})`).length, - 1, - `${testKey}: renders the correct partial as default` - ); + let testCases = [ + ['dr', 'primary', 'disable', 'Disable replication', null, ['disable', 'primary']], + ['performance', 'primary', 'disable', 'Disable replication', null, ['disable', 'primary']], + ['dr', 'secondary', 'disable', 'Disable replication', null, ['disable', 'secondary']], + ['performance', 'secondary', 'disable', 'Disable replication', null, ['disable', 'secondary']], + ['dr', 'primary', 'recover', 'Recover', null, ['recover']], + ['performance', 'primary', 'recover', 'Recover', null, ['recover']], + ['performance', 'secondary', 'recover', 'Recover', null, ['recover']], - if (typeof fillInFn === 'function') { - fillInFn.call(this); + ['dr', 'primary', 'reindex', 'Reindex', null, ['reindex']], + ['performance', 'primary', 'reindex', 'Reindex', null, ['reindex']], + ['dr', 'secondary', 'reindex', 'Reindex', null, ['reindex']], + ['performance', 'secondary', 'reindex', 'Reindex', null, ['reindex']], + + ['dr', 'primary', 'demote', 'Demote cluster', null, ['demote', 'primary']], + ['performance', 'primary', 'demote', 'Demote cluster', null, ['demote', 'primary']], + // we don't do dr secondary promote in this component so just test perf + [ + 'performance', + 'secondary', + 'promote', + 'Promote cluster', + async function() { + await fillIn('[name="primary_cluster_addr"]', 'cluster addr'); + await blur('[name="primary_cluster_addr"]'); + }, + ['promote', 'secondary', { primary_cluster_addr: 'cluster addr' }], + ], + + // don't yet update-primary for dr + [ + 'performance', + 'secondary', + 'update-primary', + 'Update primary', + async function() { + await fillIn('#secondary-token', 'token'); + await blur('#secondary-token'); + await fillIn('#primary_api_addr', 'addr'); + await blur('#primary_api_addr'); + }, + ['update-primary', 'secondary', { token: 'token', primary_api_addr: 'addr' }], + ], + ]; + + for (let [replicationMode, clusterMode, action, headerText, fillInFn, expectedOnSubmit] of testCases) { + test(`replication mode ${replicationMode}, cluster mode: ${clusterMode}, action: ${action}`, async function(assert) { + const testKey = `${replicationMode}-${clusterMode}-${action}`; + this.set('model', { + replicationAttrs: { + modeForUrl: clusterMode, + }, + [replicationMode]: { + mode: clusterMode, + modeForUrl: clusterMode, + }, + reload() { + return resolve(); + }, + rollbackAttributes() {}, + }); + this.set('replicationMode', replicationMode); + this.set('selectedAction', action); + this.set('onSubmit', (...actual) => { + assert.deepEqual( + JSON.stringify(actual), + JSON.stringify(expectedOnSubmit), + `${testKey}: submitted values match expected` + ); + return resolve(); + }); + this.set('storeService.capabilitiesReturnVal', ['root']); + await render( + hbs`{{replication-actions model=model replicationMode=replicationMode selectedAction=selectedAction onSubmit=(action onSubmit)}}` + ); + + assert.equal( + find('h4').textContent.trim(), + headerText, + `${testKey}: renders the correct partial as default` + ); + + if (typeof fillInFn === 'function') { + await fillInFn.call(this); + } + await click('[data-test-confirm-action-trigger]'); + await click('[data-test-confirm-button]'); + }); } - this.$('button').click(); - this.$('button.red').click(); -} - -function callTest(context, assert) { - return function() { - testAction.call(context, assert, ...arguments); - }; -} - -test('actions', function(assert) { - const t = callTest(this, assert); - //TODO move to table test so we don't share the same store - //t('dr', 'primary', 'disable', 'Disable dr replication', 'sys/replication/dr/primary/disable', null, ['disable', 'primary']); - //t('performance', 'primary', 'disable', 'Disable performance replication', 'sys/replication/performance/primary/disable', null, ['disable', 'primary']); - t('dr', 'secondary', 'disable', 'Disable replication', 'sys/replication/dr/secondary/disable', null, [ - 'disable', - 'secondary', - ]); - t( - 'performance', - 'secondary', - 'disable', - 'Disable replication', - 'sys/replication/performance/secondary/disable', - null, - ['disable', 'secondary'] - ); - - t('dr', 'primary', 'recover', 'Recover', 'sys/replication/recover', null, ['recover']); - t('performance', 'primary', 'recover', 'Recover', 'sys/replication/recover', null, ['recover']); - t('performance', 'secondary', 'recover', 'Recover', 'sys/replication/recover', null, ['recover']); - - t('dr', 'primary', 'reindex', 'Reindex', 'sys/replication/reindex', null, ['reindex']); - t('performance', 'primary', 'reindex', 'Reindex', 'sys/replication/reindex', null, ['reindex']); - t('dr', 'secondary', 'reindex', 'Reindex', 'sys/replication/reindex', null, ['reindex']); - t('performance', 'secondary', 'reindex', 'Reindex', 'sys/replication/reindex', null, ['reindex']); - - t('dr', 'primary', 'demote', 'Demote cluster', 'sys/replication/dr/primary/demote', null, [ - 'demote', - 'primary', - ]); - t( - 'performance', - 'primary', - 'demote', - 'Demote cluster', - 'sys/replication/performance/primary/demote', - null, - ['demote', 'primary'] - ); - // we don't do dr secondary promote in this component so just test perf - t( - 'performance', - 'secondary', - 'promote', - 'Promote cluster', - 'sys/replication/performance/secondary/promote', - function() { - this.$('[name="primary_cluster_addr"]').val('cluster addr').change(); - }, - ['promote', 'secondary', { primary_cluster_addr: 'cluster addr' }] - ); - - // don't yet update-primary for dr - t( - 'performance', - 'secondary', - 'update-primary', - 'Update primary', - 'sys/replication/performance/secondary/update-primary', - function() { - this.$('#secondary-token').val('token').change(); - this.$('#primary_api_addr').val('addr').change(); - }, - ['update-primary', 'secondary', { token: 'token', primary_api_addr: 'addr' }] - ); }); diff --git a/ui/tests/integration/components/secret-edit-test.js b/ui/tests/integration/components/secret-edit-test.js index 445916203..3637c6357 100644 --- a/ui/tests/integration/components/secret-edit-test.js +++ b/ui/tests/integration/components/secret-edit-test.js @@ -1,72 +1,77 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, find, settled } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('secret-edit', 'Integration | Component | secret edit', { - integration: true, - beforeEach() { - this.inject.service('code-mirror', { as: 'codeMirror' }); - }, -}); +module('Integration | Component | secret edit', function(hooks) { + setupRenderingTest(hooks); -test('it disables JSON toggle in show mode when is an advanced format', function(assert) { - this.set('mode', 'show'); - this.set('key', { - secretData: { - int: 2, - null: null, - float: 1.234, - }, + hooks.beforeEach(function() { + this.codeMirror = this.owner.lookup('service:code-mirror'); }); - this.render(hbs`{{secret-edit mode=mode key=key }}`); - assert.dom('[data-test-secret-json-toggle]').isDisabled(); -}); + test('it disables JSON toggle in show mode when is an advanced format', async function(assert) { + this.set('mode', 'show'); + this.set('key', { + secretData: { + int: 2, + null: null, + float: 1.234, + }, + }); -test('it does JSON toggle in show mode when showing string data', function(assert) { - this.set('mode', 'show'); - this.set('key', { - secretData: { - int: '2', - null: 'null', - float: '1.234', - }, + await render(hbs`{{secret-edit mode=mode key=key }}`); + assert.dom('[data-test-secret-json-toggle]').isDisabled(); }); - this.render(hbs`{{secret-edit mode=mode key=key }}`); - assert.dom('[data-test-secret-json-toggle]').isNotDisabled(); -}); + test('it does JSON toggle in show mode when showing string data', async function(assert) { + this.set('mode', 'show'); + this.set('key', { + secretData: { + int: '2', + null: 'null', + float: '1.234', + }, + }); -test('it shows an error when creating and data is not an object', function(assert) { - this.set('mode', 'create'); - this.set('key', { - secretData: { - int: '2', - null: 'null', - float: '1.234', - }, + await render(hbs`{{secret-edit mode=mode key=key }}`); + assert.dom('[data-test-secret-json-toggle]').isNotDisabled(); }); - this.render(hbs`{{secret-edit mode=mode key=key preferAdvancedEdit=true }}`); - let instance = this.codeMirror.instanceFor(this.$('[data-test-component=json-editor]').attr('id')); - instance.setValue(JSON.stringify([{ foo: 'bar' }])); - assert.dom('[data-test-error]').includesText('Vault expects data to be formatted as an JSON object'); -}); + test('it shows an error when creating and data is not an object', async function(assert) { + this.set('mode', 'create'); + this.set('key', { + secretData: { + int: '2', + null: 'null', + float: '1.234', + }, + }); -test('it shows an error when editing and the data is not an object', function(assert) { - this.set('mode', 'edit'); - this.set('capabilities', { - canUpdate: true, - }); - this.set('key', { - secretData: { - int: '2', - null: 'null', - float: '1.234', - }, + await render(hbs`{{secret-edit mode=mode key=key preferAdvancedEdit=true }}`); + let instance = this.codeMirror.instanceFor(find('[data-test-component=json-editor]').id); + instance.setValue(JSON.stringify([{ foo: 'bar' }])); + await settled(); + assert.dom('[data-test-error]').includesText('Vault expects data to be formatted as an JSON object'); }); - this.render(hbs`{{secret-edit capabilities=capabilities mode=mode key=key preferAdvancedEdit=true }}`); - let instance = this.codeMirror.instanceFor(this.$('[data-test-component=json-editor]').attr('id')); - instance.setValue(JSON.stringify([{ foo: 'bar' }])); - assert.dom('[data-test-error]').includesText('Vault expects data to be formatted as an JSON object'); + test('it shows an error when editing and the data is not an object', async function(assert) { + this.set('mode', 'edit'); + this.set('capabilities', { + canUpdate: true, + }); + this.set('key', { + secretData: { + int: '2', + null: 'null', + float: '1.234', + }, + }); + + await render(hbs`{{secret-edit capabilities=capabilities mode=mode key=key preferAdvancedEdit=true }}`); + let instance = this.codeMirror.instanceFor(find('[data-test-component=json-editor]').id); + instance.setValue(JSON.stringify([{ foo: 'bar' }])); + await settled(); + assert.dom('[data-test-error]').includesText('Vault expects data to be formatted as an JSON object'); + }); }); diff --git a/ui/tests/integration/components/shamir-flow-test.js b/ui/tests/integration/components/shamir-flow-test.js index 54dd2acfa..d23f9ad4b 100644 --- a/ui/tests/integration/components/shamir-flow-test.js +++ b/ui/tests/integration/components/shamir-flow-test.js @@ -1,6 +1,10 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { run } from '@ember/runloop'; +import Service from '@ember/service'; +import { resolve } from 'rsvp'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click, findAll, find } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -import Ember from 'ember'; let response = { progress: 1, @@ -10,87 +14,98 @@ let response = { let adapter = { foo() { - return Ember.RSVP.resolve(response); + return resolve(response); }, }; -const storeStub = Ember.Service.extend({ +const storeStub = Service.extend({ adapterFor() { return adapter; }, }); -moduleForComponent('shamir-flow', 'Integration | Component | shamir flow', { - integration: true, - beforeEach: function() { - this.register('service:store', storeStub); - this.inject.service('store', { as: 'storeService' }); - }, -}); +module('Integration | Component | shamir flow', function(hooks) { + setupRenderingTest(hooks); -test('it renders', function(assert) { - this.render(hbs`{{shamir-flow formText="like whoa"}}`); - - assert.equal(this.$('form p').text().trim(), 'like whoa', 'renders formText inline'); - - this.render(hbs` - {{#shamir-flow formText="like whoa"}} -

    whoa again

    - {{/shamir-flow}} - `); - - assert.equal(this.$('.shamir-progress').length, 0, 'renders no progress bar for no progress'); - assert.equal(this.$('form p').text().trim(), 'whoa again', 'renders the block, not formText'); - - this.render(hbs` - {{shamir-flow progress=1 threshold=5}} - `); - - assert.ok(this.$('.shamir-progress').text().includes('1/5 keys provided'), 'displays textual progress'); - - this.set('errors', ['first error', 'this is fine']); - this.render(hbs` - {{shamir-flow errors=errors}} - `); - assert.equal(this.$('.message.is-danger').length, 2, 'renders errors'); -}); - -test('it sends data to the passed action', function(assert) { - this.set('key', 'foo'); - this.render(hbs` - {{shamir-flow key=key action='foo' thresholdPath='required'}} - `); - this.$('[data-test-shamir-submit]').click(); - assert.ok( - this.$('.shamir-progress').text().includes(`${response.progress}/${response.required} keys provided`), - 'displays the correct progress' - ); -}); - -test('it checks onComplete to call onShamirSuccess', function(assert) { - this.set('key', 'foo'); - this.set('onSuccess', function() { - assert.ok(true, 'onShamirSuccess called'); + hooks.beforeEach(function() { + run(() => { + this.owner.unregister('service:store'); + this.owner.register('service:store', storeStub); + this.storeService = this.owner.lookup('service:store'); + }); }); - this.set('checkComplete', function() { - assert.ok(true, 'onComplete called'); - // return true so we trigger success call - return true; + test('it renders', async function(assert) { + await render(hbs`{{shamir-flow formText="like whoa"}}`); + + assert.equal(find('form p').textContent.trim(), 'like whoa', 'renders formText inline'); + + await render(hbs` + {{#shamir-flow formText="like whoa"}} +

    whoa again

    + {{/shamir-flow}} + `); + + assert.equal(findAll('.shamir-progress').length, 0, 'renders no progress bar for no progress'); + assert.equal(find('form p').textContent.trim(), 'whoa again', 'renders the block, not formText'); + + await render(hbs` + {{shamir-flow progress=1 threshold=5}} + `); + + assert.ok( + find('.shamir-progress').textContent.includes('1/5 keys provided'), + 'displays textual progress' + ); + + this.set('errors', ['first error', 'this is fine']); + await render(hbs` + {{shamir-flow errors=errors}} + `); + assert.equal(findAll('.message.is-danger').length, 2, 'renders errors'); }); - this.render(hbs` - {{shamir-flow key=key action='foo' isComplete=(action checkComplete) onShamirSuccess=(action onSuccess)}} - `); - this.$('[data-test-shamir-submit]').click(); -}); + test('it sends data to the passed action', async function(assert) { + this.set('key', 'foo'); + await render(hbs` + {{shamir-flow key=key action='foo' thresholdPath='required'}} + `); + await click('[data-test-shamir-submit]'); + assert.ok( + find('.shamir-progress').textContent.includes( + `${response.progress}/${response.required} keys provided` + ), + 'displays the correct progress' + ); + }); -test('it fetches progress on init when fetchOnInit is true', function(assert) { - this.render(hbs` - {{shamir-flow action='foo' fetchOnInit=true}} - `); - assert.ok( - this.$('.shamir-progress').text().includes(`${response.progress}/${response.required} keys provided`), - 'displays the correct progress' - ); + test('it checks onComplete to call onShamirSuccess', async function(assert) { + this.set('key', 'foo'); + this.set('onSuccess', function() { + assert.ok(true, 'onShamirSuccess called'); + }); + + this.set('checkComplete', function() { + assert.ok(true, 'onComplete called'); + // return true so we trigger success call + return true; + }); + + await render(hbs` + {{shamir-flow key=key action='foo' isComplete=(action checkComplete) onShamirSuccess=(action onSuccess)}} + `); + await click('[data-test-shamir-submit]'); + }); + + test('it fetches progress on init when fetchOnInit is true', async function(assert) { + await render(hbs` + {{shamir-flow action='foo' fetchOnInit=true}} + `); + assert.ok( + find('.shamir-progress').textContent.includes( + `${response.progress}/${response.required} keys provided` + ), + 'displays the correct progress' + ); + }); }); diff --git a/ui/tests/integration/components/string-list-test.js b/ui/tests/integration/components/string-list-test.js index 283667a2b..4ec2649b5 100644 --- a/ui/tests/integration/components/string-list-test.js +++ b/ui/tests/integration/components/string-list-test.js @@ -1,118 +1,122 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click, find, findAll, fillIn, triggerKeyEvent } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('string-list', 'Integration | Component | string list', { - integration: true, -}); +module('Integration | Component | string list', function(hooks) { + setupRenderingTest(hooks); -const assertBlank = function(assert) { - assert.equal(this.$('[data-test-string-list-input]').length, 1, 'renders 1 input'); - assert.equal(this.$('[data-test-string-list-input]').val(), '', 'the input is blank'); -}; + const assertBlank = function(assert) { + assert.equal(findAll('[data-test-string-list-input]').length, 1, 'renders 1 input'); + assert.equal(find('[data-test-string-list-input]').value, '', 'the input is blank'); + }; -const assertFoo = function(assert) { - assert.equal(this.$('[data-test-string-list-input]').length, 2, 'renders 2 inputs'); - assert.equal(this.$('[data-test-string-list-input="0"]').val(), 'foo', 'first input has the inputValue'); - assert.equal(this.$('[data-test-string-list-input="1"]').val(), '', 'second input is blank'); -}; + const assertFoo = function(assert) { + assert.equal(findAll('[data-test-string-list-input]').length, 2, 'renders 2 inputs'); + assert.equal(find('[data-test-string-list-input="0"]').value, 'foo', 'first input has the inputValue'); + assert.equal(find('[data-test-string-list-input="1"]').value, '', 'second input is blank'); + }; -const assertFooBar = function(assert) { - assert.equal(this.$('[data-test-string-list-input]').length, 3, 'renders 3 inputs'); - assert.equal(this.$('[data-test-string-list-input="0"]').val(), 'foo'); - assert.equal(this.$('[data-test-string-list-input="1"]').val(), 'bar'); - assert.equal(this.$('[data-test-string-list-input="2"]').val(), '', 'last input is blank'); -}; + const assertFooBar = function(assert) { + assert.equal(findAll('[data-test-string-list-input]').length, 3, 'renders 3 inputs'); + assert.equal(find('[data-test-string-list-input="0"]').value, 'foo'); + assert.equal(find('[data-test-string-list-input="1"]').value, 'bar'); + assert.equal(find('[data-test-string-list-input="2"]').value, '', 'last input is blank'); + }; -test('it renders the label', function(assert) { - this.render(hbs`{{string-list label="foo"}}`); - assert.equal( - this.$('[data-test-string-list-label]').text().trim(), - 'foo', - 'renders the label when provided' - ); + test('it renders the label', async function(assert) { + await render(hbs`{{string-list label="foo"}}`); + assert.equal( + find('[data-test-string-list-label]').textContent.trim(), + 'foo', + 'renders the label when provided' + ); - this.render(hbs`{{string-list}}`); - assert.equal(this.$('[data-test-string-list-label]').length, 0, 'does not render the label'); - assertBlank.call(this, assert); -}); - -test('it renders inputValue from empty string', function(assert) { - this.render(hbs`{{string-list inputValue=""}}`); - assertBlank.call(this, assert); -}); - -test('it renders inputValue from string with one value', function(assert) { - this.render(hbs`{{string-list inputValue="foo"}}`); - assertFoo.call(this, assert); -}); - -test('it renders inputValue from comma-separated string', function(assert) { - this.render(hbs`{{string-list inputValue="foo,bar"}}`); - assertFooBar.call(this, assert); -}); - -test('it renders inputValue from a blank array', function(assert) { - this.set('inputValue', []); - this.render(hbs`{{string-list inputValue=inputValue}}`); - assertBlank.call(this, assert); -}); - -test('it renders inputValue array with a single item', function(assert) { - this.set('inputValue', ['foo']); - this.render(hbs`{{string-list inputValue=inputValue}}`); - assertFoo.call(this, assert); -}); - -test('it renders inputValue array with a multiple items', function(assert) { - this.set('inputValue', ['foo', 'bar']); - this.render(hbs`{{string-list inputValue=inputValue}}`); - assertFooBar.call(this, assert); -}); - -test('it adds a new row only when the last row is not blank', function(assert) { - this.render(hbs`{{string-list inputValue=""}}`); - this.$('[data-test-string-list-button="add"]').click(); - assertBlank.call(this, assert); - this.$('[data-test-string-list-input="0"]').val('foo').keyup(); - this.$('[data-test-string-list-button="add"]').click(); - assertFoo.call(this, assert); -}); - -test('it trims input values', function(assert) { - this.render(hbs`{{string-list inputValue=""}}`); - this.$('[data-test-string-list-input="0"]').val(' foo ').keyup(); - assert.equal(this.$('[data-test-string-list-input="0"]').val(), 'foo'); -}); - -test('it calls onChange with array when editing', function(assert) { - assert.expect(1); - this.set('inputValue', ['foo']); - this.set('onChange', function(val) { - assert.deepEqual(val, ['foo', 'bar'], 'calls onChange with expected value'); + await render(hbs`{{string-list}}`); + assert.equal(findAll('[data-test-string-list-label]').length, 0, 'does not render the label'); + assertBlank(assert); }); - this.render(hbs`{{string-list inputValue=inputValue onChange=(action onChange)}}`); - this.$('[data-test-string-list-input="1"]').val('bar').keyup(); -}); -test('it calls onChange with string when editing', function(assert) { - assert.expect(1); - this.set('inputValue', 'foo'); - this.set('onChange', function(val) { - assert.equal(val, 'foo,bar', 'calls onChange with expected value'); + test('it renders inputValue from empty string', async function(assert) { + await render(hbs`{{string-list inputValue=""}}`); + assertBlank(assert); }); - this.render(hbs`{{string-list inputValue=inputValue onChange=(action onChange)}}`); - this.$('[data-test-string-list-input="1"]').val('bar').keyup(); -}); -test('it removes a row', function(assert) { - this.set('inputValue', ['foo', 'bar']); - this.set('onChange', function(val) { - assert.equal(val, 'bar', 'calls onChange with expected value'); + test('it renders inputValue from string with one value', async function(assert) { + await render(hbs`{{string-list inputValue="foo"}}`); + assertFoo(assert); }); - this.render(hbs`{{string-list inputValue=inputValue onChange=(action onChange)}}`); - this.$('[data-test-string-list-row="0"] [data-test-string-list-button="delete"]').click(); - assert.equal(this.$('[data-test-string-list-input]').length, 2, 'renders 2 inputs'); - assert.equal(this.$('[data-test-string-list-input="0"]').val(), 'bar'); - assert.equal(this.$('[data-test-string-list-input="1"]').val(), ''); + test('it renders inputValue from comma-separated string', async function(assert) { + await render(hbs`{{string-list inputValue="foo,bar"}}`); + assertFooBar(assert); + }); + + test('it renders inputValue from a blank array', async function(assert) { + this.set('inputValue', []); + await render(hbs`{{string-list inputValue=inputValue}}`); + assertBlank(assert); + }); + + test('it renders inputValue array with a single item', async function(assert) { + this.set('inputValue', ['foo']); + await render(hbs`{{string-list inputValue=inputValue}}`); + assertFoo(assert); + }); + + test('it renders inputValue array with a multiple items', async function(assert) { + this.set('inputValue', ['foo', 'bar']); + await render(hbs`{{string-list inputValue=inputValue}}`); + assertFooBar(assert); + }); + + test('it adds a new row only when the last row is not blank', async function(assert) { + await render(hbs`{{string-list inputValue=""}}`); + await click('[data-test-string-list-button="add"]'); + assertBlank(assert); + await fillIn('[data-test-string-list-input="0"]', 'foo'); + await triggerKeyEvent('[data-test-string-list-input="0"]', 'keyup', 14); + await click('[data-test-string-list-button="add"]'); + assertFoo(assert); + }); + + test('it trims input values', async function(assert) { + await render(hbs`{{string-list inputValue=""}}`); + await fillIn('[data-test-string-list-input="0"]', 'foo'); + await triggerKeyEvent('[data-test-string-list-input="0"]', 'keyup', 14); + assert.equal(find('[data-test-string-list-input="0"]').value, 'foo'); + }); + + test('it calls onChange with array when editing', async function(assert) { + this.set('inputValue', ['foo']); + this.set('onChange', function(val) { + assert.deepEqual(val, ['foo', 'bar'], 'calls onChange with expected value'); + }); + await render(hbs`{{string-list inputValue=inputValue onChange=(action onChange)}}`); + await fillIn('[data-test-string-list-input="1"]', 'bar'); + await triggerKeyEvent('[data-test-string-list-input="1"]', 'keyup', 14); + }); + + test('it calls onChange with string when editing', async function(assert) { + this.set('inputValue', 'foo'); + this.set('onChange', function(val) { + assert.equal(val, 'foo,bar', 'calls onChange with expected value'); + }); + await render(hbs`{{string-list inputValue=inputValue onChange=(action onChange)}}`); + await fillIn('[data-test-string-list-input="1"]', 'bar'); + await triggerKeyEvent('[data-test-string-list-input="1"]', 'keyup', 14); + }); + + test('it removes a row', async function(assert) { + this.set('inputValue', ['foo', 'bar']); + this.set('onChange', function(val) { + assert.equal(val, 'bar', 'calls onChange with expected value'); + }); + await render(hbs`{{string-list inputValue=inputValue onChange=(action onChange)}}`); + + await click('[data-test-string-list-row="0"] [data-test-string-list-button="delete"]'); + assert.equal(findAll('[data-test-string-list-input]').length, 2, 'renders 2 inputs'); + assert.equal(find('[data-test-string-list-input="0"]').value, 'bar'); + assert.equal(find('[data-test-string-list-input="1"]').value, ''); + }); }); diff --git a/ui/tests/integration/components/toggle-button-test.js b/ui/tests/integration/components/toggle-button-test.js index f1ccfbb6b..c6408d1ab 100644 --- a/ui/tests/integration/components/toggle-button-test.js +++ b/ui/tests/integration/components/toggle-button-test.js @@ -1,30 +1,32 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click, find } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('toggle-button', 'Integration | Component | toggle button', { - integration: true, -}); - -test('toggle functionality', function(assert) { - this.set('toggleTarget', {}); - - this.render(hbs`{{toggle-button toggleTarget=toggleTarget toggleAttr="toggled"}}`); - - assert.equal(this.$('button').text().trim(), 'More options', 'renders default closedLabel'); - - this.$('button').click(); - assert.equal(this.get('toggleTarget.toggled'), true, 'it toggles the attr on the target'); - assert.equal(this.$('button').text().trim(), 'Hide options', 'renders default openLabel'); - this.$('button').click(); - assert.equal(this.get('toggleTarget.toggled'), false, 'it toggles the attr on the target'); - - this.set('closedLabel', 'Open the options!'); - this.set('openLabel', 'Close the options!'); - this.render( - hbs`{{toggle-button toggleTarget=toggleTarget toggleAttr="toggled" closedLabel=closedLabel openLabel=openLabel}}` - ); - - assert.equal(this.$('button').text().trim(), 'Open the options!', 'renders passed closedLabel'); - this.$('button').click(); - assert.equal(this.$('button').text().trim(), 'Close the options!', 'renders passed openLabel'); +module('Integration | Component | toggle button', function(hooks) { + setupRenderingTest(hooks); + + test('toggle functionality', async function(assert) { + this.set('toggleTarget', {}); + + await render(hbs`{{toggle-button toggleTarget=toggleTarget toggleAttr="toggled"}}`); + + assert.equal(find('button').textContent.trim(), 'More options', 'renders default closedLabel'); + + await click('button'); + assert.equal(this.get('toggleTarget.toggled'), true, 'it toggles the attr on the target'); + assert.equal(find('button').textContent.trim(), 'Hide options', 'renders default openLabel'); + await click('button'); + assert.equal(this.get('toggleTarget.toggled'), false, 'it toggles the attr on the target'); + + this.set('closedLabel', 'Open the options!'); + this.set('openLabel', 'Close the options!'); + await render( + hbs`{{toggle-button toggleTarget=toggleTarget toggleAttr="toggled" closedLabel=closedLabel openLabel=openLabel}}` + ); + + assert.equal(find('button').textContent.trim(), 'Open the options!', 'renders passed closedLabel'); + await click('button'); + assert.equal(find('button').textContent.trim(), 'Close the options!', 'renders passed openLabel'); + }); }); diff --git a/ui/tests/integration/components/transit-key-actions-test.js b/ui/tests/integration/components/transit-key-actions-test.js index a6e29f1d4..0bce4d07d 100644 --- a/ui/tests/integration/components/transit-key-actions-test.js +++ b/ui/tests/integration/components/transit-key-actions-test.js @@ -1,9 +1,15 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { run } from '@ember/runloop'; +import { resolve } from 'rsvp'; +import { assign } from '@ember/polyfills'; +import Service from '@ember/service'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click, find, findAll, fillIn, blur, triggerEvent } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -import Ember from 'ember'; import { encodeString } from 'vault/utils/b64'; +import waitForError from 'vault/tests/helpers/wait-for-error'; -const storeStub = Ember.Service.extend({ +const storeStub = Service.extend({ callArgs: null, keyActionReturnVal: null, rootKeyActionReturnVal: null, @@ -13,275 +19,282 @@ const storeStub = Ember.Service.extend({ keyAction(action, { backend, id, payload }, options) { self.set('callArgs', { action, backend, id, payload }); self.set('callArgsOptions', options); - const rootResp = Ember.assign({}, self.get('rootKeyActionReturnVal')); + const rootResp = assign({}, self.get('rootKeyActionReturnVal')); const resp = Object.keys(rootResp).length > 0 ? rootResp : { - data: Ember.assign({}, self.get('keyActionReturnVal')), + data: assign({}, self.get('keyActionReturnVal')), }; - return Ember.RSVP.resolve(resp); + return resolve(resp); }, }; }, }); -moduleForComponent('transit-key-actions', 'Integration | Component | transit key actions', { - integration: true, - beforeEach: function() { - this.register('service:store', storeStub); - this.inject.service('store', { as: 'storeService' }); - }, -}); +module('Integration | Component | transit key actions', function(hooks) { + setupRenderingTest(hooks); -test('it requires `key`', function(assert) { - assert.expectAssertion( - () => this.render(hbs`{{transit-key-actions}}`), - /`key` is required for/, - 'asserts without key' - ); -}); - -test('it renders', function(assert) { - this.set('key', { backend: 'transit', supportedActions: ['encrypt'] }); - this.render(hbs`{{transit-key-actions selectedAction="encrypt" key=key}}`); - assert.equal(this.$('[data-test-transit-action="encrypt"]').length, 1, 'renders encrypt'); - - this.set('key', { backend: 'transit', supportedActions: ['sign'] }); - this.render(hbs`{{transit-key-actions selectedAction="sign" key=key}}`); - assert.equal(this.$('[data-test-transit-action="sign"]').length, 1, 'renders sign'); -}); - -test('it renders: signature_algorithm field', function(assert) { - this.set('key', { backend: 'transit', supportsSigning: true, supportedActions: ['sign', 'verify'] }); - this.set('selectedAction', 'sign'); - this.render(hbs`{{transit-key-actions selectedAction=selectedAction key=key}}`); - assert.equal( - this.$('[data-test-signature-algorithm]').length, - 0, - 'does not render signature_algorithm field on sign' - ); - this.set('selectedAction', 'verify'); - assert.equal( - this.$('[data-test-signature-algorithm]').length, - 0, - 'does not render signature_algorithm field on verify' - ); - - this.set('selectedAction', 'sign'); - this.set('key', { - type: 'rsa-2048', - supportsSigning: true, - backend: 'transit', - supportedActions: ['sign', 'verify'], + hooks.beforeEach(function() { + run(() => { + this.owner.unregister('service:store'); + this.owner.register('service:store', storeStub); + this.storeService = this.owner.lookup('service:store'); + }); }); - assert.equal( - this.$('[data-test-signature-algorithm]').length, - 1, - 'renders signature_algorithm field on sign with rsa key' - ); - this.set('selectedAction', 'verify'); - assert.equal( - this.$('[data-test-signature-algorithm]').length, - 1, - 'renders signature_algorithm field on verify with rsa key' - ); -}); -test('it renders: rotate', function(assert) { - this.set('key', { backend: 'transit', id: 'akey', supportedActions: ['rotate'] }); - this.render(hbs`{{transit-key-actions selectedAction="rotate" key=key}}`); - - assert.equal(this.$().text().trim(), '', 'renders an empty div'); - - this.set('key.canRotate', true); - assert.equal( - this.$('button').text().trim(), - 'Rotate encryption key', - 'renders confirm-button when key.canRotate is true' - ); -}); - -function doEncrypt(assert, actions = [], keyattrs = {}) { - let keyDefaults = { backend: 'transit', id: 'akey', supportedActions: ['encrypt'].concat(actions) }; - - const key = Ember.assign({}, keyDefaults, keyattrs); - this.set('key', key); - this.set('selectedAction', 'encrypt'); - this.set('storeService.keyActionReturnVal', { ciphertext: 'secret' }); - this.render(hbs`{{transit-key-actions selectedAction=selectedAction key=key}}`); - - this.$('#plaintext').val('plaintext').trigger('input'); - this.$('[data-test-transit-b64-toggle="plaintext"]').click(); - this.$('button:submit').click(); - assert.deepEqual( - this.get('storeService.callArgs'), - { - action: 'encrypt', - backend: 'transit', - id: 'akey', - payload: { - plaintext: encodeString('plaintext'), - }, - }, - 'passes expected args to the adapter' - ); - - assert.equal(this.$('#ciphertext').val(), 'secret'); -} - -test('it encrypts', doEncrypt); - -test('it shows key version selection', function(assert) { - let keyDefaults = { backend: 'transit', id: 'akey', supportedActions: ['encrypt'].concat([]) }; - let keyattrs = { keysForEncryption: [3, 2, 1], latestVersion: 3 }; - const key = Ember.assign({}, keyDefaults, keyattrs); - this.set('key', key); - this.set('storeService.keyActionReturnVal', { ciphertext: 'secret' }); - this.render(hbs`{{transit-key-actions selectedAction="encrypt" key=key}}`); - - this.$('#plaintext').val('plaintext').trigger('input'); - this.$('[data-test-transit-b64-toggle="plaintext"]').click(); - assert.equal(this.$('#key_version').length, 1, 'it renders the key version selector'); - - this.$('#key_version').trigger('change'); - this.$('button:submit').click(); - assert.deepEqual( - this.get('storeService.callArgs'), - { - action: 'encrypt', - backend: 'transit', - id: 'akey', - payload: { - plaintext: encodeString('plaintext'), - key_version: '0', - }, - }, - 'includes key_version in the payload' - ); -}); - -test('it hides key version selection', function(assert) { - let keyDefaults = { backend: 'transit', id: 'akey', supportedActions: ['encrypt'].concat([]) }; - let keyattrs = { keysForEncryption: [1] }; - const key = Ember.assign({}, keyDefaults, keyattrs); - this.set('key', key); - this.set('storeService.keyActionReturnVal', { ciphertext: 'secret' }); - this.render(hbs`{{transit-key-actions selectedAction="encrypt" key=key}}`); - - this.$('#plaintext').val('plaintext').trigger('input'); - this.$('[data-test-transit-b64-toggle="plaintext"]').click(); - - assert.equal( - this.$('#key_version').length, - 0, - 'it does not render the selector when there is only one key' - ); -}); - -test('it carries ciphertext value over to decrypt', function(assert) { - const plaintext = 'not so secret'; - doEncrypt.call(this, assert, ['decrypt']); - - this.set('storeService.keyActionReturnVal', { plaintext }); - this.set('selectedAction', 'decrypt'); - assert.equal(this.$('#ciphertext').val(), 'secret', 'keeps ciphertext value'); - - this.$('button:submit').click(); - assert.equal(this.$('#plaintext').val(), plaintext, 'renders decrypted value'); -}); - -const setupExport = function() { - this.set('key', { - backend: 'transit', - id: 'akey', - supportedActions: ['export'], - exportKeyTypes: ['encryption'], - validKeyVersions: [1], + test('it requires `key`', async function(assert) { + let promise = waitForError(); + render(hbs`{{transit-key-actions}}`); + let err = await promise; + assert.ok(err.message.includes('`key` is required for'), 'asserts without key'); }); - this.render(hbs`{{transit-key-actions key=key}}`); -}; -test('it can export a key:default behavior', function(assert) { - this.set('storeService.rootKeyActionReturnVal', { wrap_info: { token: 'wrapped-token' } }); - setupExport.call(this); - this.$('button:submit').click(); + test('it renders', async function(assert) { + this.set('key', { backend: 'transit', supportedActions: ['encrypt'] }); + await render(hbs`{{transit-key-actions selectedAction="encrypt" key=key}}`); + assert.equal(findAll('[data-test-transit-action="encrypt"]').length, 1, 'renders encrypt'); - assert.deepEqual( - this.get('storeService.callArgs'), - { - action: 'export', - backend: 'transit', - id: 'akey', - payload: { - param: ['encryption'], - }, - }, - 'passes expected args to the adapter' - ); - assert.equal(this.get('storeService.callArgsOptions.wrapTTL'), '30m', 'passes value for wrapTTL'); - assert.equal(this.$('#export').val(), 'wrapped-token', 'wraps by default'); -}); - -test('it can export a key:unwrapped behavior', function(assert) { - const response = { keys: { a: 'key' } }; - this.set('storeService.keyActionReturnVal', response); - setupExport.call(this); - this.$('#wrap-response').click().change(); - this.$('button:submit').click(); - assert.deepEqual( - JSON.parse(this.$('.CodeMirror').get(0).CodeMirror.getValue()), - response, - 'prints json response' - ); -}); - -test('it can export a key: unwrapped, single version', function(assert) { - const response = { keys: { a: 'key' } }; - this.set('storeService.keyActionReturnVal', response); - setupExport.call(this); - this.$('#wrap-response').click().change(); - this.$('#exportVersion').click().change(); - this.$('button:submit').click(); - assert.deepEqual( - JSON.parse(this.$('.CodeMirror').get(0).CodeMirror.getValue()), - response, - 'prints json response' - ); - assert.deepEqual( - this.get('storeService.callArgs'), - { - action: 'export', - backend: 'transit', - id: 'akey', - payload: { - param: ['encryption', 1], - }, - }, - 'passes expected args to the adapter' - ); -}); - -test('it includes algorithm param for HMAC', function(assert) { - this.set('key', { - backend: 'transit', - id: 'akey', - supportedActions: ['hmac'], - validKeyVersions: [1], + this.set('key', { backend: 'transit', supportedActions: ['sign'] }); + await render(hbs`{{transit-key-actions selectedAction="sign" key=key}}`); + assert.equal(findAll('[data-test-transit-action="sign"]').length, 1, 'renders sign'); }); - this.render(hbs`{{transit-key-actions key=key}}`); - this.$('#algorithm').val('sha2-384').change(); - this.$('button:submit').click(); - assert.deepEqual( - this.get('storeService.callArgs'), - { - action: 'hmac', + + test('it renders: signature_algorithm field', async function(assert) { + this.set('key', { backend: 'transit', supportsSigning: true, supportedActions: ['sign', 'verify'] }); + this.set('selectedAction', 'sign'); + await render(hbs`{{transit-key-actions selectedAction=selectedAction key=key}}`); + assert.equal( + findAll('[data-test-signature-algorithm]').length, + 0, + 'does not render signature_algorithm field on sign' + ); + this.set('selectedAction', 'verify'); + assert.equal( + findAll('[data-test-signature-algorithm]').length, + 0, + 'does not render signature_algorithm field on verify' + ); + + this.set('selectedAction', 'sign'); + this.set('key', { + type: 'rsa-2048', + supportsSigning: true, + backend: 'transit', + supportedActions: ['sign', 'verify'], + }); + assert.equal( + findAll('[data-test-signature-algorithm]').length, + 1, + 'renders signature_algorithm field on sign with rsa key' + ); + this.set('selectedAction', 'verify'); + assert.equal( + findAll('[data-test-signature-algorithm]').length, + 1, + 'renders signature_algorithm field on verify with rsa key' + ); + }); + + test('it renders: rotate', async function(assert) { + this.set('key', { backend: 'transit', id: 'akey', supportedActions: ['rotate'] }); + await render(hbs`{{transit-key-actions selectedAction="rotate" key=key}}`); + + assert.equal(find('*').textContent.trim(), '', 'renders an empty div'); + + this.set('key.canRotate', true); + assert.equal( + find('button').textContent.trim(), + 'Rotate encryption key', + 'renders confirm-button when key.canRotate is true' + ); + }); + + async function doEncrypt(assert, actions = [], keyattrs = {}) { + let keyDefaults = { backend: 'transit', id: 'akey', supportedActions: ['encrypt'].concat(actions) }; + + const key = assign({}, keyDefaults, keyattrs); + this.set('key', key); + this.set('selectedAction', 'encrypt'); + this.set('storeService.keyActionReturnVal', { ciphertext: 'secret' }); + await render(hbs`{{transit-key-actions selectedAction=selectedAction key=key}}`); + + await fillIn('#plaintext', 'plaintext'); + await click('[data-test-transit-b64-toggle="plaintext"]'); + await click('button[type="submit"]'); + assert.deepEqual( + this.get('storeService.callArgs'), + { + action: 'encrypt', + backend: 'transit', + id: 'akey', + payload: { + plaintext: encodeString('plaintext'), + }, + }, + 'passes expected args to the adapter' + ); + + assert.equal(find('#ciphertext').value, 'secret'); + } + + test('it encrypts', doEncrypt); + + test('it shows key version selection', async function(assert) { + let keyDefaults = { backend: 'transit', id: 'akey', supportedActions: ['encrypt'].concat([]) }; + let keyattrs = { keysForEncryption: [3, 2, 1], latestVersion: 3 }; + const key = assign({}, keyDefaults, keyattrs); + this.set('key', key); + this.set('storeService.keyActionReturnVal', { ciphertext: 'secret' }); + await render(hbs`{{transit-key-actions selectedAction="encrypt" key=key}}`); + + await fillIn('#plaintext', 'plaintext'); + await click('[data-test-transit-b64-toggle="plaintext"]'); + assert.equal(findAll('#key_version').length, 1, 'it renders the key version selector'); + + await triggerEvent('#key_version', 'change'); + await click('button[type="submit"]'); + assert.deepEqual( + this.get('storeService.callArgs'), + { + action: 'encrypt', + backend: 'transit', + id: 'akey', + payload: { + plaintext: encodeString('plaintext'), + key_version: '0', + }, + }, + 'includes key_version in the payload' + ); + }); + + test('it hides key version selection', async function(assert) { + let keyDefaults = { backend: 'transit', id: 'akey', supportedActions: ['encrypt'].concat([]) }; + let keyattrs = { keysForEncryption: [1] }; + const key = assign({}, keyDefaults, keyattrs); + this.set('key', key); + this.set('storeService.keyActionReturnVal', { ciphertext: 'secret' }); + await render(hbs`{{transit-key-actions selectedAction="encrypt" key=key}}`); + + await fillIn('#plaintext', 'plaintext'); + await click('[data-test-transit-b64-toggle="plaintext"]'); + + assert.equal( + findAll('#key_version').length, + 0, + 'it does not render the selector when there is only one key' + ); + }); + + test('it carries ciphertext value over to decrypt', async function(assert) { + const plaintext = 'not so secret'; + await doEncrypt.call(this, assert, ['decrypt']); + + this.set('storeService.keyActionReturnVal', { plaintext }); + this.set('selectedAction', 'decrypt'); + assert.equal(find('#ciphertext').value, 'secret', 'keeps ciphertext value'); + + await click('button[type="submit"]'); + assert.equal(find('#plaintext').value, plaintext, 'renders decrypted value'); + }); + + const setupExport = async function() { + this.set('key', { backend: 'transit', id: 'akey', - payload: { - algorithm: 'sha2-384', + supportedActions: ['export'], + exportKeyTypes: ['encryption'], + validKeyVersions: [1], + }); + await render(hbs`{{transit-key-actions key=key}}`); + }; + + test('it can export a key:default behavior', async function(assert) { + this.set('storeService.rootKeyActionReturnVal', { wrap_info: { token: 'wrapped-token' } }); + await setupExport.call(this); + await click('button[type="submit"]'); + + assert.deepEqual( + this.get('storeService.callArgs'), + { + action: 'export', + backend: 'transit', + id: 'akey', + payload: { + param: ['encryption'], + }, }, - }, - 'passes expected args to the adapter' - ); + 'passes expected args to the adapter' + ); + assert.equal(this.get('storeService.callArgsOptions.wrapTTL'), '30m', 'passes value for wrapTTL'); + assert.equal(find('#export').value, 'wrapped-token', 'wraps by default'); + }); + + test('it can export a key:unwrapped behavior', async function(assert) { + const response = { keys: { a: 'key' } }; + this.set('storeService.keyActionReturnVal', response); + await setupExport.call(this); + await click('#wrap-response'); + await triggerEvent('#wrap-response', 'change'); + await click('button[type="submit"]'); + assert.deepEqual( + JSON.parse(findAll('.CodeMirror')[0].CodeMirror.getValue()), + response, + 'prints json response' + ); + }); + + test('it can export a key: unwrapped, single version', async function(assert) { + const response = { keys: { a: 'key' } }; + this.set('storeService.keyActionReturnVal', response); + await setupExport.call(this); + await click('#wrap-response'); + await triggerEvent('#wrap-response', 'change'); + await click('#exportVersion'); + await triggerEvent('#exportVersion', 'change'); + await click('button[type="submit"]'); + assert.deepEqual( + JSON.parse(findAll('.CodeMirror')[0].CodeMirror.getValue()), + response, + 'prints json response' + ); + assert.deepEqual( + this.get('storeService.callArgs'), + { + action: 'export', + backend: 'transit', + id: 'akey', + payload: { + param: ['encryption', 1], + }, + }, + 'passes expected args to the adapter' + ); + }); + + test('it includes algorithm param for HMAC', async function(assert) { + this.set('key', { + backend: 'transit', + id: 'akey', + supportedActions: ['hmac'], + validKeyVersions: [1], + }); + await render(hbs`{{transit-key-actions key=key}}`); + await fillIn('#algorithm', 'sha2-384'); + await blur('#algorithm'); + await click('button[type="submit"]'); + assert.deepEqual( + this.get('storeService.callArgs'), + { + action: 'hmac', + backend: 'transit', + id: 'akey', + payload: { + algorithm: 'sha2-384', + }, + }, + 'passes expected args to the adapter' + ); + }); }); diff --git a/ui/tests/integration/components/upgrade-link-test.js b/ui/tests/integration/components/upgrade-link-test.js index 7d44328cd..59eaddd7c 100644 --- a/ui/tests/integration/components/upgrade-link-test.js +++ b/ui/tests/integration/components/upgrade-link-test.js @@ -1,42 +1,48 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, find, findAll } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('upgrade-link', 'Integration | Component | upgrade link', { - integration: true, -}); - -test('it renders with overlay', function(assert) { - this.render(hbs` - - - `); - - assert.equal(this.$('.upgrade-link-container button').text().trim(), 'upgrade', 'renders link content'); - assert.equal( - this.$('#modal-wormhole .upgrade-overlay-title').text().trim(), - 'Try Vault Enterprise Free for 30 Days', - 'contains overlay content' - ); - assert.equal( - this.$('#modal-wormhole a[href^="https://hashicorp.com/products/vault/trial?source=vaultui"]').length, - 1, - 'contains info link' - ); -}); - -test('it adds custom classes', function(assert) { - this.render(hbs` - - - `); - - assert.equal( - this.$('.upgrade-link-container button').attr('class'), - 'link button upgrade-button', - 'adds classes to link' - ); +module('Integration | Component | upgrade link', function(hooks) { + setupRenderingTest(hooks); + + test('it renders with overlay', async function(assert) { + await render(hbs` + + + `); + + assert.equal( + find('.upgrade-link-container button').textContent.trim(), + 'upgrade', + 'renders link content' + ); + assert.equal( + find('#modal-wormhole .upgrade-overlay-title').textContent.trim(), + 'Try Vault Enterprise Free for 30 Days', + 'contains overlay content' + ); + assert.equal( + findAll('#modal-wormhole a[href^="https://hashicorp.com/products/vault/trial?source=vaultui"]').length, + 1, + 'contains info link' + ); + }); + + test('it adds custom classes', async function(assert) { + await render(hbs` + + + `); + + assert.equal( + find('.upgrade-link-container button').getAttribute('class'), + 'link button upgrade-button', + 'adds classes to link' + ); + }); }); diff --git a/ui/tests/integration/components/upgrade-page-test.js b/ui/tests/integration/components/upgrade-page-test.js index 43372a7a4..a7787cfc2 100644 --- a/ui/tests/integration/components/upgrade-page-test.js +++ b/ui/tests/integration/components/upgrade-page-test.js @@ -1,35 +1,41 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, findAll, find } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('upgrade-page', 'Integration | Component | upgrade page', { - integration: true, -}); - -test('it renders with defaults', function(assert) { - this.render(hbs` - {{upgrade-page}} - - `); - - assert.equal(this.$('.page-header .title').text().trim(), 'Vault Enterprise', 'renders default title'); - assert.equal( - this.$('[data-test-upgrade-feature-description]').text().trim(), - 'This is a Vault Enterprise feature.', - 'renders default description' - ); - assert.equal(this.$('[data-test-upgrade-link]').length, 1, 'renders upgrade link'); -}); - -test('it renders with custom attributes', function(assert) { - this.render(hbs` - {{upgrade-page title="Test Feature Title" featureName="Specific Feature Name" minimumEdition="Premium"}} - - `); - - assert.equal(this.$('.page-header .title').text().trim(), 'Test Feature Title', 'renders default title'); - assert.equal( - this.$('[data-test-upgrade-feature-description]').text().trim(), - 'Specific Feature Name is a Premium feature.', - 'renders default description' - ); +module('Integration | Component | upgrade page', function(hooks) { + setupRenderingTest(hooks); + + test('it renders with defaults', async function(assert) { + await render(hbs` + {{upgrade-page}} + + `); + + assert.equal(find('.page-header .title').textContent.trim(), 'Vault Enterprise', 'renders default title'); + assert.equal( + find('[data-test-upgrade-feature-description]').textContent.trim(), + 'This is a Vault Enterprise feature.', + 'renders default description' + ); + assert.equal(findAll('[data-test-upgrade-link]').length, 1, 'renders upgrade link'); + }); + + test('it renders with custom attributes', async function(assert) { + await render(hbs` + {{upgrade-page title="Test Feature Title" featureName="Specific Feature Name" minimumEdition="Premium"}} + + `); + + assert.equal( + find('.page-header .title').textContent.trim(), + 'Test Feature Title', + 'renders default title' + ); + assert.equal( + find('[data-test-upgrade-feature-description]').textContent.trim(), + 'Specific Feature Name is a Premium feature.', + 'renders default description' + ); + }); }); diff --git a/ui/tests/integration/components/wrap-ttl-test.js b/ui/tests/integration/components/wrap-ttl-test.js index 3d43dddc6..8b2bc2b4f 100644 --- a/ui/tests/integration/components/wrap-ttl-test.js +++ b/ui/tests/integration/components/wrap-ttl-test.js @@ -1,45 +1,51 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click, fillIn, blur, find, triggerEvent } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; +import waitForError from 'vault/tests/helpers/wait-for-error'; -moduleForComponent('wrap-ttl', 'Integration | Component | wrap ttl', { - integration: true, - beforeEach() { +module('Integration | Component | wrap ttl', function(hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function() { this.lastOnChangeCall = null; this.set('onChange', val => { this.lastOnChangeCall = val; }); - }, -}); - -test('it requires `onChange`', function(assert) { - assert.expectAssertion( - () => this.render(hbs`{{wrap-ttl}}`), - /`onChange` handler is a required attr in/, - 'asserts without onChange' - ); -}); - -test('it renders', function(assert) { - this.render(hbs`{{wrap-ttl onChange=(action onChange)}}`); - assert.equal(this.lastOnChangeCall, '30m', 'calls onChange with 30m default on first render'); - assert.equal(this.$('label[for=wrap-response]').text().trim(), 'Wrap response'); -}); - -test('it nulls out value when you uncheck wrapResponse', function(assert) { - this.render(hbs`{{wrap-ttl onChange=(action onChange)}}`); - this.$('#wrap-response').click().change(); - assert.equal(this.lastOnChangeCall, null, 'calls onChange with null'); -}); - -test('it sends value changes to onChange handler', function(assert) { - this.render(hbs`{{wrap-ttl onChange=(action onChange)}}`); - - this.$('[data-test-wrap-ttl-picker] input').val('20').trigger('input'); - assert.equal(this.lastOnChangeCall, '20m', 'calls onChange correctly on time input'); - - this.$('#unit').val('h').change(); - assert.equal(this.lastOnChangeCall, '20h', 'calls onChange correctly on unit change'); - - this.$('#unit').val('d').change(); - assert.equal(this.lastOnChangeCall, '480h', 'converts days to hours correctly'); + }); + + test('it requires `onChange`', async function(assert) { + let promise = waitForError(); + render(hbs`{{wrap-ttl}}`); + let err = await promise; + assert.ok(err.message.includes('`onChange` handler is a required attr in'), 'asserts without onChange'); + }); + + test('it renders', async function(assert) { + await render(hbs`{{wrap-ttl onChange=(action onChange)}}`); + assert.equal(this.lastOnChangeCall, '30m', 'calls onChange with 30m default on first render'); + assert.equal(find('label[for=wrap-response]').textContent.trim(), 'Wrap response'); + }); + + test('it nulls out value when you uncheck wrapResponse', async function(assert) { + await render(hbs`{{wrap-ttl onChange=(action onChange)}}`); + await click('#wrap-response'); + await triggerEvent('#wrap-response', 'change'); + assert.equal(this.lastOnChangeCall, null, 'calls onChange with null'); + }); + + test('it sends value changes to onChange handler', async function(assert) { + await render(hbs`{{wrap-ttl onChange=(action onChange)}}`); + + await fillIn('[data-test-wrap-ttl-picker] input', '20'); + assert.equal(this.lastOnChangeCall, '20m', 'calls onChange correctly on time input'); + + await fillIn('#unit', 'h'); + await blur('#unit'); + assert.equal(this.lastOnChangeCall, '20h', 'calls onChange correctly on unit change'); + + await fillIn('#unit', 'd'); + await blur('#unit'); + assert.equal(this.lastOnChangeCall, '480h', 'converts days to hours correctly'); + }); }); diff --git a/ui/tests/integration/helpers/has-feature-test.js b/ui/tests/integration/helpers/has-feature-test.js index 3a831c0ca..0bae4f961 100644 --- a/ui/tests/integration/helpers/has-feature-test.js +++ b/ui/tests/integration/helpers/has-feature-test.js @@ -1,33 +1,41 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import Service from '@ember/service'; +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -import Ember from 'ember'; +import waitForError from 'vault/tests/helpers/wait-for-error'; -const versionStub = Ember.Service.extend({ +const versionStub = Service.extend({ features: null, }); -moduleForComponent('has-feature', 'helper:has-feature', { - integration: true, - beforeEach: function() { - this.register('service:version', versionStub); - this.inject.service('version', { as: 'versionService' }); - }, -}); +module('helper:has-feature', function(hooks) { + setupRenderingTest(hooks); -test('it asserts on unknown features', function(assert) { - assert.expectAssertion(() => { - this.render(hbs`{{has-feature 'New Feature'}}`); - }, 'New Feature is not one of the available values for Vault Enterprise features.'); -}); + hooks.beforeEach(function() { + this.owner.register('service:version', versionStub); + this.versionService = this.owner.lookup('service:version'); + }); -test('it is true with existing features', function(assert) { - this.set('versionService.features', ['HSM']); - this.render(hbs`{{if (has-feature 'HSM') 'It works' null}}`); - assert.dom(this._element).hasText('It works', 'present features evaluate to true'); -}); + test('it asserts on unknown features', async function(assert) { + let promise = waitForError(); + render(hbs`{{has-feature 'New Feature'}}`); + let err = await promise; + assert.ok( + err.message.includes('New Feature is not one of the available values for Vault Enterprise features.'), + 'asserts when an unknown feature is passed as an arg' + ); + }); -test('it is false with missing features', function(assert) { - this.set('versionService.features', ['MFA']); - this.render(hbs`{{if (has-feature 'HSM') 'It works' null}}`); - assert.dom(this._element).hasText('', 'missing features evaluate to false'); + test('it is true with existing features', async function(assert) { + this.set('versionService.features', ['HSM']); + await render(hbs`{{if (has-feature 'HSM') 'It works' null}}`); + assert.dom(this.element).hasText('It works', 'present features evaluate to true'); + }); + + test('it is false with missing features', async function(assert) { + this.set('versionService.features', ['MFA']); + await render(hbs`{{if (has-feature 'HSM') 'It works' null}}`); + assert.dom(this.element).hasText('', 'missing features evaluate to false'); + }); }); diff --git a/ui/tests/integration/utils/field-to-attrs-test.js b/ui/tests/integration/utils/field-to-attrs-test.js index be5d9e9c7..59847025c 100644 --- a/ui/tests/integration/utils/field-to-attrs-test.js +++ b/ui/tests/integration/utils/field-to-attrs-test.js @@ -1,145 +1,149 @@ -import Ember from 'ember'; -import { moduleForModel, test } from 'ember-qunit'; +import { run } from '@ember/runloop'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import fieldToAttrs, { expandAttributeMeta } from 'vault/utils/field-to-attrs'; -moduleForModel('test-form-model', 'Integration | Util | field to attrs', { - needs: ['model:auth-config', 'model:mount-config'], -}); +module('Integration | Util | field to attrs', function(hooks) { + setupTest(hooks); -const PATH_ATTR = { type: 'string', name: 'path', options: {} }; -const DESCRIPTION_ATTR = { type: 'string', name: 'description', options: { editType: 'textarea' } }; -const DEFAULT_LEASE_ATTR = { - type: undefined, - name: 'config.defaultLeaseTtl', - options: { label: 'Default Lease TTL', editType: 'ttl' }, -}; + const PATH_ATTR = { type: 'string', name: 'path', options: {} }; + const DESCRIPTION_ATTR = { type: 'string', name: 'description', options: { editType: 'textarea' } }; + const DEFAULT_LEASE_ATTR = { + type: undefined, + name: 'config.defaultLeaseTtl', + options: { label: 'Default Lease TTL', editType: 'ttl' }, + }; -const OTHER_DEFAULT_LEASE_ATTR = { - type: undefined, - name: 'otherConfig.defaultLeaseTtl', - options: { label: 'Default Lease TTL', editType: 'ttl' }, -}; -const MAX_LEASE_ATTR = { - type: undefined, - name: 'config.maxLeaseTtl', - options: { label: 'Max Lease TTL', editType: 'ttl' }, -}; -const OTHER_MAX_LEASE_ATTR = { - type: undefined, - name: 'otherConfig.maxLeaseTtl', - options: { label: 'Max Lease TTL', editType: 'ttl' }, -}; + const OTHER_DEFAULT_LEASE_ATTR = { + type: undefined, + name: 'otherConfig.defaultLeaseTtl', + options: { label: 'Default Lease TTL', editType: 'ttl' }, + }; + const MAX_LEASE_ATTR = { + type: undefined, + name: 'config.maxLeaseTtl', + options: { label: 'Max Lease TTL', editType: 'ttl' }, + }; + const OTHER_MAX_LEASE_ATTR = { + type: undefined, + name: 'otherConfig.maxLeaseTtl', + options: { label: 'Max Lease TTL', editType: 'ttl' }, + }; -test('it extracts attrs', function(assert) { - const model = this.subject(); - Ember.run(() => { - const [attr] = expandAttributeMeta(model, ['path']); - assert.deepEqual(attr, PATH_ATTR, 'returns attribute meta'); - }); -}); - -test('it extracts more than one attr', function(assert) { - const model = this.subject(); - Ember.run(() => { - const [path, desc] = expandAttributeMeta(model, ['path', 'description']); - assert.deepEqual(path, PATH_ATTR, 'returns attribute meta'); - assert.deepEqual(desc, DESCRIPTION_ATTR, 'returns attribute meta'); - }); -}); - -test('it extracts fieldGroups', function(assert) { - const model = this.subject(); - Ember.run(() => { - const groups = fieldToAttrs(model, [{ default: ['path'] }, { Options: ['description'] }]); - const expected = [{ default: [PATH_ATTR] }, { Options: [DESCRIPTION_ATTR] }]; - assert.deepEqual(groups, expected, 'expands all given groups'); - }); -}); - -test('it extracts arrays as fieldGroups', function(assert) { - const model = this.subject(); - Ember.run(() => { - const groups = fieldToAttrs(model, [{ default: ['path', 'description'] }, { Options: ['description'] }]); - const expected = [{ default: [PATH_ATTR, DESCRIPTION_ATTR] }, { Options: [DESCRIPTION_ATTR] }]; - assert.deepEqual(groups, expected, 'expands all given groups'); - }); -}); - -test('it extracts model-fragment attributes with brace expansion', function(assert) { - const model = this.subject(); - Ember.run(() => { - const [attr] = expandAttributeMeta(model, ['config.{defaultLeaseTtl}']); - assert.deepEqual(attr, DEFAULT_LEASE_ATTR, 'properly extracts model fragment attr'); - }); - - Ember.run(() => { - const [defaultLease, maxLease] = expandAttributeMeta(model, ['config.{defaultLeaseTtl,maxLeaseTtl}']); - assert.deepEqual(defaultLease, DEFAULT_LEASE_ATTR, 'properly extracts default lease'); - assert.deepEqual(maxLease, MAX_LEASE_ATTR, 'properly extracts max lease'); - }); -}); - -test('it extracts model-fragment attributes with double brace expansion', function(assert) { - const model = this.subject(); - Ember.run(() => { - const [configDefault, configMax, otherConfigDefault, otherConfigMax] = expandAttributeMeta(model, [ - '{config,otherConfig}.{defaultLeaseTtl,maxLeaseTtl}', - ]); - assert.deepEqual(configDefault, DEFAULT_LEASE_ATTR, 'properly extracts config.defaultLeaseTTL'); - assert.deepEqual( - otherConfigDefault, - OTHER_DEFAULT_LEASE_ATTR, - 'properly extracts otherConfig.defaultLeaseTTL' - ); - - assert.deepEqual(configMax, MAX_LEASE_ATTR, 'properly extracts config.maxLeaseTTL'); - assert.deepEqual(otherConfigMax, OTHER_MAX_LEASE_ATTR, 'properly extracts otherConfig.maxLeaseTTL'); - }); -}); - -test('it extracts model-fragment attributes with dot notation', function(assert) { - const model = this.subject(); - Ember.run(() => { - const [attr] = expandAttributeMeta(model, ['config.defaultLeaseTtl']); - assert.deepEqual(attr, DEFAULT_LEASE_ATTR, 'properly extracts model fragment attr'); - }); - - Ember.run(() => { - const [defaultLease, maxLease] = expandAttributeMeta(model, [ - 'config.defaultLeaseTtl', - 'config.maxLeaseTtl', - ]); - assert.deepEqual(defaultLease, DEFAULT_LEASE_ATTR, 'properly extracts model fragment attr'); - assert.deepEqual(maxLease, MAX_LEASE_ATTR, 'properly extracts model fragment attr'); - }); -}); - -test('it extracts fieldGroups from model-fragment attributes with brace expansion', function(assert) { - const model = this.subject(); - const expected = [ - { default: [PATH_ATTR, DEFAULT_LEASE_ATTR, MAX_LEASE_ATTR] }, - { Options: [DESCRIPTION_ATTR] }, - ]; - Ember.run(() => { - const groups = fieldToAttrs(model, [ - { default: ['path', 'config.{defaultLeaseTtl,maxLeaseTtl}'] }, - { Options: ['description'] }, - ]); - assert.deepEqual(groups, expected, 'properly extracts fieldGroups with brace expansion'); - }); -}); - -test('it extracts fieldGroups from model-fragment attributes with dot notation', function(assert) { - const model = this.subject(); - const expected = [ - { default: [DEFAULT_LEASE_ATTR, PATH_ATTR, MAX_LEASE_ATTR] }, - { Options: [DESCRIPTION_ATTR] }, - ]; - Ember.run(() => { - const groups = fieldToAttrs(model, [ - { default: ['config.defaultLeaseTtl', 'path', 'config.maxLeaseTtl'] }, - { Options: ['description'] }, - ]); - assert.deepEqual(groups, expected, 'properly extracts fieldGroups with dot notation'); + test('it extracts attrs', function(assert) { + const model = run(() => this.owner.lookup('service:store').createRecord('test-form-model')); + run(() => { + const [attr] = expandAttributeMeta(model, ['path']); + assert.deepEqual(attr, PATH_ATTR, 'returns attribute meta'); + }); + }); + + test('it extracts more than one attr', function(assert) { + const model = run(() => this.owner.lookup('service:store').createRecord('test-form-model')); + run(() => { + const [path, desc] = expandAttributeMeta(model, ['path', 'description']); + assert.deepEqual(path, PATH_ATTR, 'returns attribute meta'); + assert.deepEqual(desc, DESCRIPTION_ATTR, 'returns attribute meta'); + }); + }); + + test('it extracts fieldGroups', function(assert) { + const model = run(() => this.owner.lookup('service:store').createRecord('test-form-model')); + run(() => { + const groups = fieldToAttrs(model, [{ default: ['path'] }, { Options: ['description'] }]); + const expected = [{ default: [PATH_ATTR] }, { Options: [DESCRIPTION_ATTR] }]; + assert.deepEqual(groups, expected, 'expands all given groups'); + }); + }); + + test('it extracts arrays as fieldGroups', function(assert) { + const model = run(() => this.owner.lookup('service:store').createRecord('test-form-model')); + run(() => { + const groups = fieldToAttrs(model, [ + { default: ['path', 'description'] }, + { Options: ['description'] }, + ]); + const expected = [{ default: [PATH_ATTR, DESCRIPTION_ATTR] }, { Options: [DESCRIPTION_ATTR] }]; + assert.deepEqual(groups, expected, 'expands all given groups'); + }); + }); + + test('it extracts model-fragment attributes with brace expansion', function(assert) { + const model = run(() => this.owner.lookup('service:store').createRecord('test-form-model')); + run(() => { + const [attr] = expandAttributeMeta(model, ['config.{defaultLeaseTtl}']); + assert.deepEqual(attr, DEFAULT_LEASE_ATTR, 'properly extracts model fragment attr'); + }); + + run(() => { + const [defaultLease, maxLease] = expandAttributeMeta(model, ['config.{defaultLeaseTtl,maxLeaseTtl}']); + assert.deepEqual(defaultLease, DEFAULT_LEASE_ATTR, 'properly extracts default lease'); + assert.deepEqual(maxLease, MAX_LEASE_ATTR, 'properly extracts max lease'); + }); + }); + + test('it extracts model-fragment attributes with double brace expansion', function(assert) { + const model = run(() => this.owner.lookup('service:store').createRecord('test-form-model')); + run(() => { + const [configDefault, configMax, otherConfigDefault, otherConfigMax] = expandAttributeMeta(model, [ + '{config,otherConfig}.{defaultLeaseTtl,maxLeaseTtl}', + ]); + assert.deepEqual(configDefault, DEFAULT_LEASE_ATTR, 'properly extracts config.defaultLeaseTTL'); + assert.deepEqual( + otherConfigDefault, + OTHER_DEFAULT_LEASE_ATTR, + 'properly extracts otherConfig.defaultLeaseTTL' + ); + + assert.deepEqual(configMax, MAX_LEASE_ATTR, 'properly extracts config.maxLeaseTTL'); + assert.deepEqual(otherConfigMax, OTHER_MAX_LEASE_ATTR, 'properly extracts otherConfig.maxLeaseTTL'); + }); + }); + + test('it extracts model-fragment attributes with dot notation', function(assert) { + const model = run(() => this.owner.lookup('service:store').createRecord('test-form-model')); + run(() => { + const [attr] = expandAttributeMeta(model, ['config.defaultLeaseTtl']); + assert.deepEqual(attr, DEFAULT_LEASE_ATTR, 'properly extracts model fragment attr'); + }); + + run(() => { + const [defaultLease, maxLease] = expandAttributeMeta(model, [ + 'config.defaultLeaseTtl', + 'config.maxLeaseTtl', + ]); + assert.deepEqual(defaultLease, DEFAULT_LEASE_ATTR, 'properly extracts model fragment attr'); + assert.deepEqual(maxLease, MAX_LEASE_ATTR, 'properly extracts model fragment attr'); + }); + }); + + test('it extracts fieldGroups from model-fragment attributes with brace expansion', function(assert) { + const model = run(() => this.owner.lookup('service:store').createRecord('test-form-model')); + const expected = [ + { default: [PATH_ATTR, DEFAULT_LEASE_ATTR, MAX_LEASE_ATTR] }, + { Options: [DESCRIPTION_ATTR] }, + ]; + run(() => { + const groups = fieldToAttrs(model, [ + { default: ['path', 'config.{defaultLeaseTtl,maxLeaseTtl}'] }, + { Options: ['description'] }, + ]); + assert.deepEqual(groups, expected, 'properly extracts fieldGroups with brace expansion'); + }); + }); + + test('it extracts fieldGroups from model-fragment attributes with dot notation', function(assert) { + const model = run(() => this.owner.lookup('service:store').createRecord('test-form-model')); + const expected = [ + { default: [DEFAULT_LEASE_ATTR, PATH_ATTR, MAX_LEASE_ATTR] }, + { Options: [DESCRIPTION_ATTR] }, + ]; + run(() => { + const groups = fieldToAttrs(model, [ + { default: ['config.defaultLeaseTtl', 'path', 'config.maxLeaseTtl'] }, + { Options: ['description'] }, + ]); + assert.deepEqual(groups, expected, 'properly extracts fieldGroups with dot notation'); + }); }); }); diff --git a/ui/tests/pages/access/identity/aliases/add.js b/ui/tests/pages/access/identity/aliases/add.js index 4be991f37..674bd46c1 100644 --- a/ui/tests/pages/access/identity/aliases/add.js +++ b/ui/tests/pages/access/identity/aliases/add.js @@ -1,7 +1,7 @@ -import { create, visitable } from 'ember-cli-page-object'; -import editForm from 'vault/tests/pages/components/identity/edit-form'; - -export default create({ - visit: visitable('/vault/access/identity/:item_type/aliases/add/:id'), - editForm, -}); +import { create, visitable } from 'ember-cli-page-object'; +import editForm from 'vault/tests/pages/components/identity/edit-form'; + +export default create({ + visit: visitable('/vault/access/identity/:item_type/aliases/add/:id'), + editForm, +}); diff --git a/ui/tests/pages/access/identity/aliases/index.js b/ui/tests/pages/access/identity/aliases/index.js index 9a67c169e..dfdab4f2f 100644 --- a/ui/tests/pages/access/identity/aliases/index.js +++ b/ui/tests/pages/access/identity/aliases/index.js @@ -8,6 +8,12 @@ export default create({ menu: clickable('[data-test-popup-menu-trigger]'), name: text('[data-test-identity-link]'), }), - delete: clickable('[data-test-item-delete] [data-test-confirm-action-trigger]'), - confirmDelete: clickable('[data-test-item-delete] [data-test-confirm-button]'), + delete: clickable('[data-test-confirm-action-trigger]', { + scope: '[data-test-item-delete]', + testContainer: '#ember-testing', + }), + confirmDelete: clickable('[data-test-confirm-button]', { + scope: '[data-test-item-delete]', + testContainer: '#ember-testing', + }), }); diff --git a/ui/tests/pages/access/identity/create.js b/ui/tests/pages/access/identity/create.js index 2fa8092a8..4015a84ae 100644 --- a/ui/tests/pages/access/identity/create.js +++ b/ui/tests/pages/access/identity/create.js @@ -1,13 +1,15 @@ -import { create, visitable } from 'ember-cli-page-object'; -import editForm from 'vault/tests/pages/components/identity/edit-form'; - -export default create({ - visit: visitable('/vault/access/identity/:item_type/create'), - editForm, - createItem(item_type, type) { - if (type) { - return this.visit({ item_type }).editForm.type(type).submit(); - } - return this.visit({ item_type }).editForm.submit(); - }, -}); +import { create, visitable } from 'ember-cli-page-object'; +import editForm from 'vault/tests/pages/components/identity/edit-form'; + +export default create({ + visit: visitable('/vault/access/identity/:item_type/create'), + editForm, + createItem(item_type, type) { + if (type) { + return this.visit({ item_type }) + .editForm.type(type) + .submit(); + } + return this.visit({ item_type }).editForm.submit(); + }, +}); diff --git a/ui/tests/pages/access/identity/index.js b/ui/tests/pages/access/identity/index.js index 7a24086b9..16fe15f0d 100644 --- a/ui/tests/pages/access/identity/index.js +++ b/ui/tests/pages/access/identity/index.js @@ -8,6 +8,13 @@ export default create({ menu: clickable('[data-test-popup-menu-trigger]'), name: text('[data-test-identity-link]'), }), - delete: clickable('[data-test-item-delete] [data-test-confirm-action-trigger]'), - confirmDelete: clickable('[data-test-item-delete] [data-test-confirm-button]'), + + delete: clickable('[data-test-confirm-action-trigger]', { + scope: '[data-test-item-delete]', + testContainer: '#ember-testing', + }), + confirmDelete: clickable('[data-test-confirm-button]', { + scope: '[data-test-item-delete]', + testContainer: '#ember-testing', + }), }); diff --git a/ui/tests/pages/access/methods.js b/ui/tests/pages/access/methods.js index 39af2890b..81d4465cf 100644 --- a/ui/tests/pages/access/methods.js +++ b/ui/tests/pages/access/methods.js @@ -2,23 +2,18 @@ import { create, attribute, visitable, collection, hasClass, text } from 'ember- export default create({ visit: visitable('/vault/access/'), - navLinks: collection({ + navLinks: collection('[data-test-link]', { + isActive: hasClass('is-active'), + text: text(), scope: '[data-test-sidebar]', - itemScope: '[data-test-link]', - item: { - isActive: hasClass('is-active'), - text: text(), - }, }), - backendLinks: collection({ - itemScope: '[data-test-auth-backend-link]', - item: { - path: text('[data-test-path]'), - id: attribute('data-test-id', '[data-test-path]'), - }, - findById(id) { - return this.toArray().findBy('id', id); - }, + backendLinks: collection('[data-test-auth-backend-link]', { + path: text('[data-test-path]'), + id: attribute('data-test-id', '[data-test-path]'), }), + + findLinkById(id) { + return this.backendLinks.filterBy('id', id)[0]; + }, }); diff --git a/ui/tests/pages/auth.js b/ui/tests/pages/auth.js new file mode 100644 index 000000000..27219d98a --- /dev/null +++ b/ui/tests/pages/auth.js @@ -0,0 +1,16 @@ +import { create, visitable, fillable, clickable } from 'ember-cli-page-object'; +import withFlash from 'vault/tests/helpers/with-flash'; + +export default create({ + visit: visitable('/vault/auth'), + submit: clickable('[data-test-auth-submit]'), + tokenInput: fillable('[data-test-token]'), + login: async function(token) { + await this.visit({ with: 'token' }); + if (token) { + return this.tokenInput(token).submit(); + } + + return withFlash(this.tokenInput('root').submit()); + }, +}); diff --git a/ui/tests/pages/components/config-pki-ca.js b/ui/tests/pages/components/config-pki-ca.js index e37c18fd4..4b8e34cd2 100644 --- a/ui/tests/pages/components/config-pki-ca.js +++ b/ui/tests/pages/components/config-pki-ca.js @@ -21,13 +21,9 @@ export default { back: clickable('[data-test-back-button]'), signedIntermediate: fillable('[data-test-signed-intermediate]'), - downloadLinks: collection({ itemScope: '[data-test-ca-download-link]' }), - rows: collection({ - itemScope: '[data-test-table-row]', - }), - rowValues: collection({ - itemScope: '[data-test-row-value]', - }), + downloadLinks: collection('[data-test-ca-download-link]'), + rows: collection('[data-test-table-row]'), + rowValues: collection('[data-test-row-value]'), csr: text('[data-test-row-value="CSR"]', { normalize: false }), csrField: fillable('[data-test-input="csr"]'), certificate: text('[data-test-row-value="Certificate"]', { normalize: false }), @@ -37,18 +33,27 @@ export default { pemBundle: fillable('[data-test-text-file-textarea="true"]'), commonName: fillable('[data-test-input="commonName"]'), - generateCA(commonName = 'PKI CA', type = 'root') { + async generateCA(commonName = 'PKI CA', type = 'root') { if (type === 'intermediate') { - return this.replaceCA().commonName(commonName).caType('intermediate').submit(); + return this.replaceCA() + .commonName(commonName) + .caType('intermediate') + .submit(); } - return this.replaceCA().commonName(commonName).submit(); + return this.replaceCA() + .commonName(commonName) + .submit(); }, - uploadCA(pem) { - return this.replaceCA().uploadCert().enterCertAsText().pemBundle(pem).submit(); + async uploadCA(pem) { + return this.replaceCA() + .uploadCert() + .enterCertAsText() + .pemBundle(pem) + .submit(); }, - signIntermediate(commonName) { + async signIntermediate(commonName) { return this.signIntermediateBtn().commonName(commonName); }, }; diff --git a/ui/tests/pages/components/console/ui-panel.js b/ui/tests/pages/components/console/ui-panel.js index a1b294598..394b960c9 100644 --- a/ui/tests/pages/components/console/ui-panel.js +++ b/ui/tests/pages/components/console/ui-panel.js @@ -39,11 +39,11 @@ export default { eventProperties: { keyCode: keys.ENTER }, }), hasInput: isPresent('[data-test-component="console/command-input"] input'), - runCommands(commands) { + runCommands: async function(commands) { let toExecute = Array.isArray(commands) ? commands : [commands]; - return toExecute.forEach(command => { - this.consoleInput(command); - this.enter(); - }); + for (let command of toExecute) { + await this.consoleInput(command); + await this.enter(); + } }, }; diff --git a/ui/tests/pages/components/flash-message.js b/ui/tests/pages/components/flash-message.js index c4f98e2da..1752f14b0 100644 --- a/ui/tests/pages/components/flash-message.js +++ b/ui/tests/pages/components/flash-message.js @@ -1,12 +1,29 @@ -import { collection } from 'ember-cli-page-object'; +import { waitFor, settled } from '@ember/test-helpers'; +import { collection, text, clickable } from 'ember-cli-page-object'; import { getter } from 'ember-cli-page-object/macros'; export default { latestMessage: getter(function() { - const count = this.messages().count; - return this.messages(count - 1).text; + return this.latestItem.text; }), - messages: collection({ - itemScope: '[data-test-flash-message-body]', + latestItem: getter(function() { + const count = this.messages.length; + return this.messages.objectAt(count - 1); }), + messages: collection('[data-test-flash-message-body]', { + click: clickable(), + text: text(), + }), + waitForFlash() { + return waitFor('[data-test-flash-message-body]'); + }, + clickLast() { + return this.latestItem.click(); + }, + async clickAll() { + for (let message of this.messages) { + message.click(); + } + await settled(); + }, }; diff --git a/ui/tests/pages/components/form-field.js b/ui/tests/pages/components/form-field.js index 4f5c2779c..094838d83 100644 --- a/ui/tests/pages/components/form-field.js +++ b/ui/tests/pages/components/form-field.js @@ -9,7 +9,6 @@ import { text, triggerable, } from 'ember-cli-page-object'; -import { getter } from 'ember-cli-page-object/macros'; export default { hasStringList: isPresent('[data-test-component=string-list]'), @@ -24,32 +23,31 @@ export default { tooltipTrigger: focusable('[data-test-tool-tip-trigger]'), tooltipContent: text('[data-test-help-text]'), - fields: collection({ - itemScope: '[data-test-field]', - item: { - clickLabel: clickable('label'), - for: attribute('for', 'label'), - labelText: text('label', { multiple: true }), - input: fillable('input'), - select: fillable('select'), - textarea: fillable('textarea'), - change: triggerable('keyup', 'input'), - inputValue: value('input'), - textareaValue: value('textarea'), - inputChecked: attribute('checked', 'input[type=checkbox]'), - selectValue: value('select'), - }, - findByName(name) { - // we use name in the label `for` attribute - // this is consistent across all types of fields - //(otherwise we'd have to use name on select or input or textarea) - return this.toArray().findBy('for', name); - }, - fillIn(name, value) { - return this.findByName(name).input(value); - }, - }), - field: getter(function() { - return this.fields(0); + fields: collection('[data-test-field]', { + clickLabel: clickable('label'), + for: attribute('for', 'label', { multiple: true }), + labelText: text('label', { multiple: true }), + input: fillable('input'), + select: fillable('select'), + textarea: fillable('textarea'), + change: triggerable('keyup', 'input'), + inputValue: value('input'), + textareaValue: value('textarea'), + inputChecked: attribute('checked', 'input[type=checkbox]'), + selectValue: value('select'), }), + fillInTextarea: async function(name, value) { + return this.fields + .filter(field => { + return field.for.includes(name); + })[0] + .textarea(value); + }, + fillIn: async function(name, value) { + return this.fields + .filter(field => { + return field.for.includes(name); + })[0] + .input(value); + }, }; diff --git a/ui/tests/pages/components/hover-copy-button.js b/ui/tests/pages/components/hover-copy-button.js index 360e93be8..aec760d64 100644 --- a/ui/tests/pages/components/hover-copy-button.js +++ b/ui/tests/pages/components/hover-copy-button.js @@ -1,9 +1,19 @@ -import { attribute, isVisible, triggerable, focusable, text } from 'ember-cli-page-object'; +import { attribute, clickable, isVisible, focusable, text } from 'ember-cli-page-object'; +import { triggerEvent, focus } from '@ember/test-helpers'; export default { - focusContainer: focusable('.has-copy-button'), - mouseEnter: triggerable('mouseenter', '[data-test-tooltip-trigger]'), - tooltipText: text('[data-test-hover-copy-tooltip-text]'), + async focusContainer() { + await focus('.has-copy-button'); + }, + tooltipText: text('[data-test-hover-copy-tooltip-text]', { + testContainer: '#ember-testing', + }), wrapperClass: attribute('class', '[data-test-hover-copy]'), buttonIsVisible: isVisible('[data-test-hover-copy-button]'), + click: clickable('[data-test-hover-copy-button]'), + focus: focusable('[data-test-hover-copy-button]'), + + async mouseEnter() { + await triggerEvent('[data-test-tooltip-trigger]', 'mouseenter'); + }, }; diff --git a/ui/tests/pages/components/identity/edit-form.js b/ui/tests/pages/components/identity/edit-form.js index a77daa8b7..74e72e01e 100644 --- a/ui/tests/pages/components/identity/edit-form.js +++ b/ui/tests/pages/components/identity/edit-form.js @@ -1,14 +1,14 @@ -import { clickable, fillable, attribute } from 'ember-cli-page-object'; -import fields from '../form-field'; - -export default { - ...fields, - cancelLinkHref: attribute('href', '[data-test-cancel-link]'), - cancelLink: clickable('[data-test-cancel-link]'), - name: fillable('[data-test-input="name"]'), - disabled: clickable('[data-test-input="disabled"]'), - type: fillable('[data-test-input="type"]'), - submit: clickable('[data-test-identity-submit]'), - delete: clickable('[data-test-confirm-action-trigger]'), - confirmDelete: clickable('[data-test-confirm-button]'), -}; +import { clickable, fillable, attribute } from 'ember-cli-page-object'; +import fields from '../form-field'; + +export default { + ...fields, + cancelLinkHref: attribute('href', '[data-test-cancel-link]'), + cancelLink: clickable('[data-test-cancel-link]'), + name: fillable('[data-test-input="name"]'), + disabled: clickable('[data-test-input="disabled"]'), + type: fillable('[data-test-input="type"]'), + submit: clickable('[data-test-identity-submit]'), + delete: clickable('[data-test-confirm-action-trigger]'), + confirmDelete: clickable('[data-test-confirm-button]'), +}; diff --git a/ui/tests/pages/components/kv-object-editor.js b/ui/tests/pages/components/kv-object-editor.js index cc120d4eb..88ad66cde 100644 --- a/ui/tests/pages/components/kv-object-editor.js +++ b/ui/tests/pages/components/kv-object-editor.js @@ -3,12 +3,9 @@ import { clickable, collection, fillable, isPresent } from 'ember-cli-page-objec export default { showsDuplicateError: isPresent('[data-test-duplicate-error-warnings]'), addRow: clickable('[data-test-kv-add-row]'), - rows: collection({ - itemScope: '[data-test-kv-row]', - item: { - kvKey: fillable('[data-test-kv-key]'), - kvVal: fillable('[data-test-kv-value]'), - deleteRow: clickable('[data-test-kv-delete-row]'), - }, + rows: collection('[data-test-kv-row]', { + kvKey: fillable('[data-test-kv-key]'), + kvVal: fillable('[data-test-kv-value]'), + deleteRow: clickable('[data-test-kv-delete-row]'), }), }; diff --git a/ui/tests/pages/components/masked-input.js b/ui/tests/pages/components/masked-input.js index f5d0361f6..81b526c85 100644 --- a/ui/tests/pages/components/masked-input.js +++ b/ui/tests/pages/components/masked-input.js @@ -1,10 +1,15 @@ -import { attribute, clickable, fillable, focusable, blurrable, isPresent } from 'ember-cli-page-object'; +import { attribute, clickable, fillable, isPresent } from 'ember-cli-page-object'; +import { focus, blur } from '@ember/test-helpers'; export default { - wrapperClass: attribute('class','[data-test-masked-input]'), + wrapperClass: attribute('class', '[data-test-masked-input]'), enterText: fillable('[data-test-textarea]'), textareaIsPresent: isPresent('[data-test-textarea]'), toggleMasked: clickable('[data-test-button]'), - focus: focusable('[data-test-textarea]'), - blur: blurrable('[data-test-textarea]') + async focusField() { + return focus('[data-test-textarea]'); + }, + async blurField() { + return blur('[data-test-textarea]'); + }, }; diff --git a/ui/tests/pages/components/mount-backend-form.js b/ui/tests/pages/components/mount-backend-form.js index 5482b9495..05035335c 100644 --- a/ui/tests/pages/components/mount-backend-form.js +++ b/ui/tests/pages/components/mount-backend-form.js @@ -17,16 +17,16 @@ export default { mountType: value(), }), type: fillable('[name="mount-type"]'), - selectType(type) { - let types = this.types; - let thing = types.filterBy('mountType', type)[0]; - thing.select(); - return this; + async selectType(type) { + return this.types.filterBy('mountType', type)[0].select(); }, - mount(type, path) { + async mount(type, path) { + await this.selectType(type); if (path) { - return this.selectType(type).next().path(path).submit(); + return this.next() + .path(path) + .submit(); } - return this.selectType(type).next().submit(); + return this.next().submit(); }, }; diff --git a/ui/tests/pages/logout.js b/ui/tests/pages/logout.js new file mode 100644 index 000000000..c250cdc9d --- /dev/null +++ b/ui/tests/pages/logout.js @@ -0,0 +1,5 @@ +import { create, visitable } from 'ember-cli-page-object'; + +export default create({ + visit: visitable('/vault/logout'), +}); diff --git a/ui/tests/pages/policies/index.js b/ui/tests/pages/policies/index.js index f058be660..9292792e9 100644 --- a/ui/tests/pages/policies/index.js +++ b/ui/tests/pages/policies/index.js @@ -1,13 +1,10 @@ import { text, create, collection, visitable } from 'ember-cli-page-object'; export default create({ visit: visitable('/vault/policies/:type'), - policies: collection({ - itemScope: '[data-test-policy-item]', - item: { - name: text('[data-test-policy-name]'), - }, - findByName(name) { - return this.toArray().findBy('name', name); - }, + policies: collection('[data-test-policy-item]', { + name: text('[data-test-policy-name]'), }), + findPolicyByName(name) { + return this.policies.filterBy('name', name)[0]; + }, }); diff --git a/ui/tests/pages/secrets/backend/kv/edit-secret.js b/ui/tests/pages/secrets/backend/kv/edit-secret.js index 1686eede2..d5080737b 100644 --- a/ui/tests/pages/secrets/backend/kv/edit-secret.js +++ b/ui/tests/pages/secrets/backend/kv/edit-secret.js @@ -5,7 +5,7 @@ export default create({ ...Base, path: fillable('[data-test-secret-path]'), secretKey: fillable('[data-test-secret-key]'), - secretValue: fillable('[data-test-secret-value]'), + secretValue: fillable('[data-test-secret-value] textarea'), save: clickable('[data-test-secret-save]'), deleteBtn: clickable('[data-test-secret-delete] button'), confirmBtn: clickable('[data-test-confirm-button]'), @@ -15,7 +15,10 @@ export default create({ return this.deleteBtn().confirmBtn(); }, - createSecret(path, key, value) { - return this.path(path).secretKey(key).secretValue(value).save(); + createSecret: async function(path, key, value) { + return this.path(path) + .secretKey(key) + .secretValue(value) + .save(); }, }); diff --git a/ui/tests/pages/secrets/backend/kv/show.js b/ui/tests/pages/secrets/backend/kv/show.js index 468fa8fe1..91da5a25b 100644 --- a/ui/tests/pages/secrets/backend/kv/show.js +++ b/ui/tests/pages/secrets/backend/kv/show.js @@ -3,9 +3,7 @@ import { create, clickable, collection, isPresent } from 'ember-cli-page-object' export default create({ ...Base, - rows: collection({ - scope: 'data-test-row-label', - }), + rows: collection('data-test-row-label'), edit: clickable('[data-test-secret-json-toggle]'), editIsPresent: isPresent('[data-test-secret-json-toggle]'), }); diff --git a/ui/tests/pages/secrets/backend/pki/generate-cert.js b/ui/tests/pages/secrets/backend/pki/generate-cert.js index 717a51fde..38c22e0ff 100644 --- a/ui/tests/pages/secrets/backend/pki/generate-cert.js +++ b/ui/tests/pages/secrets/backend/pki/generate-cert.js @@ -13,11 +13,18 @@ export default create({ toggleOptions: clickable('[data-test-toggle-group]'), hasCert: isPresent('[data-test-row-value="Certificate"]'), fillInField: fillable('[data-test-field]'), - issueCert(commonName) { - return this.commonName(commonName).toggleOptions().fillInField('unit', 'h').submit(); + issueCert: async function(commonName) { + await this.commonName(commonName) + .toggleOptions() + .fillInField('unit', 'h') + .submit(); }, - sign(commonName, csr) { - return this.csr(csr).commonName(commonName).toggleOptions().fillInField('unit', 'h').submit(); + sign: async function(commonName, csr) { + return this.csr(csr) + .commonName(commonName) + .toggleOptions() + .fillInField('unit', 'h') + .submit(); }, }); diff --git a/ui/tests/pages/secrets/backend/pki/show.js b/ui/tests/pages/secrets/backend/pki/show.js index 0eec10171..f1b75fcdd 100644 --- a/ui/tests/pages/secrets/backend/pki/show.js +++ b/ui/tests/pages/secrets/backend/pki/show.js @@ -3,9 +3,7 @@ import { create, clickable, collection, text, isPresent } from 'ember-cli-page-o export default create({ ...Base, - rows: collection({ - scope: 'data-test-row-label', - }), + rows: collection('data-test-row-label'), certificate: text('[data-test-row-value="Certificate"]'), hasCert: isPresent('[data-test-row-value="Certificate"]'), edit: clickable('[data-test-edit-link]'), diff --git a/ui/tests/pages/secrets/backends.js b/ui/tests/pages/secrets/backends.js index 8e4433c9e..776cc301d 100644 --- a/ui/tests/pages/secrets/backends.js +++ b/ui/tests/pages/secrets/backends.js @@ -5,15 +5,11 @@ export default create({ console: uiPanel, consoleToggle: clickable('[data-test-console-toggle]'), visit: visitable('/vault/secrets'), - rows: collection({ - itemScope: '[data-test-secret-backend-row]', - item: { - path: text('[data-test-secret-path]'), - menu: clickable('[data-test-popup-menu-trigger]'), - }, - findByPath(path) { - return this.toArray().findBy('path', path + '/'); - }, + rows: collection('[data-test-secret-backend-row]', { + path: text('[data-test-secret-path]'), + menu: clickable('[data-test-popup-menu-trigger]'), + }), + configLink: clickable('[data-test-engine-config]', { + testContainer: '#ember-testing', }), - configLink: clickable('[data-test-engine-config]'), }); diff --git a/ui/tests/pages/settings/auth/enable.js b/ui/tests/pages/settings/auth/enable.js index 2a744b545..4508d9b65 100644 --- a/ui/tests/pages/settings/auth/enable.js +++ b/ui/tests/pages/settings/auth/enable.js @@ -1,9 +1,14 @@ import { create, visitable } from 'ember-cli-page-object'; import backendForm from '../../components/mount-backend-form'; import flashMessages from '../../components/flash-message'; +import withFlash from 'vault/tests/helpers/with-flash'; export default create({ visit: visitable('/vault/settings/auth/enable'), - form: backendForm, + ...backendForm, flash: flashMessages, + enable: async function(type, path) { + await this.visit(); + return withFlash(this.mount(type, path)); + }, }); diff --git a/ui/tests/pages/settings/configure-secret-backends/pki/section.js b/ui/tests/pages/settings/configure-secret-backends/pki/section.js index cfb2d66b1..599310b2b 100644 --- a/ui/tests/pages/settings/configure-secret-backends/pki/section.js +++ b/ui/tests/pages/settings/configure-secret-backends/pki/section.js @@ -7,10 +7,8 @@ export default create({ visit: visitable('/vault/settings/secrets/configure/:backend/:section'), form: ConfigPKI, lastMessage: getter(function() { - const count = this.flashMessages().count; - return this.flashMessages(count - 1).text; - }), - flashMessages: collection({ - itemScope: '[data-test-flash-message-body]', + const count = this.flashMessages.length; + return this.flashMessages.objectAt(count - 1).text; }), + flashMessages: collection('[data-test-flash-message-body]'), }); diff --git a/ui/tests/pages/settings/mount-secret-backend.js b/ui/tests/pages/settings/mount-secret-backend.js index b5bd14200..38ed7564d 100644 --- a/ui/tests/pages/settings/mount-secret-backend.js +++ b/ui/tests/pages/settings/mount-secret-backend.js @@ -1,5 +1,6 @@ import { create, visitable, fillable } from 'ember-cli-page-object'; import mountForm from 'vault/tests/pages/components/mount-backend-form'; +import withFlash from 'vault/tests/helpers/with-flash'; export default create({ visit: visitable('/vault/settings/mount-secret-backend'), @@ -9,4 +10,8 @@ export default create({ maxTTLUnit: fillable('[data-test-input="config.maxLeaseTtl"] [data-test-ttl-unit]'), defaultTTLVal: fillable('[data-test-input="config.defaultLeaseTtl"] [data-test-ttl-value]'), defaultTTLUnit: fillable('[data-test-input="config.defaultLeaseTtl"] [data-test-ttl-unit]'), + enable: async function(type, path) { + await this.visit(); + return withFlash(this.mount(type, path)); + }, }); diff --git a/ui/tests/test-helper.js b/ui/tests/test-helper.js index 32bb2857f..0382a848d 100644 --- a/ui/tests/test-helper.js +++ b/ui/tests/test-helper.js @@ -1,10 +1,8 @@ -import resolver from './helpers/resolver'; -import './helpers/flash-message'; +import Application from '../app'; +import config from '../config/environment'; +import { setApplication } from '@ember/test-helpers'; +import { start } from 'ember-qunit'; -import { setResolver } from 'ember-qunit'; -import { start } from 'ember-cli-qunit'; -import { useNativeEvents } from 'ember-cli-page-object/extend'; +setApplication(Application.create(config.APP)); -useNativeEvents(); -setResolver(resolver); start(); diff --git a/ui/tests/unit/adapters/_adapter-needs.js b/ui/tests/unit/adapters/_adapter-needs.js deleted file mode 100644 index 1c11baf09..000000000 --- a/ui/tests/unit/adapters/_adapter-needs.js +++ /dev/null @@ -1,9 +0,0 @@ -const needs = [ - 'service:auth', - 'service:flash-messages', - 'service:control-group', - 'service:version', - 'service:namespace', - 'service:media', -]; -export default needs; diff --git a/ui/tests/unit/adapters/capabilities-test.js b/ui/tests/unit/adapters/capabilities-test.js index c881033c1..59d082004 100644 --- a/ui/tests/unit/adapters/capabilities-test.js +++ b/ui/tests/unit/adapters/capabilities-test.js @@ -1,22 +1,22 @@ -import { moduleFor, test } from 'ember-qunit'; -import Ember from 'ember'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; +import { resolve } from 'rsvp'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -moduleFor('adapter:capabilities', 'Unit | Adapter | capabilities', { - needs, -}); +module('Unit | Adapter | capabilities', function(hooks) { + setupTest(hooks); -test('calls the correct url', function(assert) { - let url, method, options; - let adapter = this.subject({ - ajax: (...args) => { - [url, method, options] = args; - return Ember.RSVP.resolve(); - }, + test('calls the correct url', function(assert) { + let url, method, options; + let adapter = this.owner.factoryFor('adapter:capabilities').create({ + ajax: (...args) => { + [url, method, options] = args; + return resolve(); + }, + }); + + adapter.findRecord(null, 'capabilities', 'foo'); + assert.equal('/v1/sys/capabilities-self', url, 'calls the correct URL'); + assert.deepEqual({ paths: ['foo'] }, options.data, 'data params OK'); + assert.equal('POST', method, 'method OK'); }); - - adapter.findRecord(null, 'capabilities', 'foo'); - assert.equal('/v1/sys/capabilities-self', url, 'calls the correct URL'); - assert.deepEqual({ paths: ['foo'] }, options.data, 'data params OK'); - assert.equal('POST', method, 'method OK'); }); diff --git a/ui/tests/unit/adapters/cluster-test.js b/ui/tests/unit/adapters/cluster-test.js index a4e8e2fc8..503b572cd 100644 --- a/ui/tests/unit/adapters/cluster-test.js +++ b/ui/tests/unit/adapters/cluster-test.js @@ -1,197 +1,197 @@ -import { moduleFor, test } from 'ember-qunit'; -import Ember from 'ember'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; +import { resolve } from 'rsvp'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -moduleFor('adapter:cluster', 'Unit | Adapter | cluster', { - needs, -}); +module('Unit | Adapter | cluster', function(hooks) { + setupTest(hooks); -test('cluster api urls', function(assert) { - let url, method, options; - let adapter = this.subject({ - ajax: (...args) => { - [url, method, options] = args; - return Ember.RSVP.resolve(); - }, - }); - adapter.health(); - assert.equal('/v1/sys/health', url, 'health url OK'); - assert.deepEqual( - { standbycode: 200, sealedcode: 200, uninitcode: 200, drsecondarycode: 200 }, - options.data, - 'health data params OK' - ); - assert.equal('GET', method, 'health method OK'); + test('cluster api urls', function(assert) { + let url, method, options; + let adapter = this.owner.factoryFor('adapter:cluster').create({ + ajax: (...args) => { + [url, method, options] = args; + return resolve(); + }, + }); + adapter.health(); + assert.equal('/v1/sys/health', url, 'health url OK'); + assert.deepEqual( + { standbycode: 200, sealedcode: 200, uninitcode: 200, drsecondarycode: 200 }, + options.data, + 'health data params OK' + ); + assert.equal('GET', method, 'health method OK'); - adapter.sealStatus(); - assert.equal('/v1/sys/seal-status', url, 'health url OK'); - assert.equal('GET', method, 'seal-status method OK'); + adapter.sealStatus(); + assert.equal('/v1/sys/seal-status', url, 'health url OK'); + assert.equal('GET', method, 'seal-status method OK'); - let data = { someData: 1 }; - adapter.unseal(data); - assert.equal('/v1/sys/unseal', url, 'unseal url OK'); - assert.equal('PUT', method, 'unseal method OK'); - assert.deepEqual({ data, unauthenticated: true }, options, 'unseal options OK'); + let data = { someData: 1 }; + adapter.unseal(data); + assert.equal('/v1/sys/unseal', url, 'unseal url OK'); + assert.equal('PUT', method, 'unseal method OK'); + assert.deepEqual({ data, unauthenticated: true }, options, 'unseal options OK'); - adapter.initCluster(data); - assert.equal('/v1/sys/init', url, 'init url OK'); - assert.equal('PUT', method, 'init method OK'); - assert.deepEqual({ data, unauthenticated: true }, options, 'init options OK'); + adapter.initCluster(data); + assert.equal('/v1/sys/init', url, 'init url OK'); + assert.equal('PUT', method, 'init method OK'); + assert.deepEqual({ data, unauthenticated: true }, options, 'init options OK'); - data = { token: 'token', password: 'password', username: 'username' }; + data = { token: 'token', password: 'password', username: 'username' }; - adapter.authenticate({ backend: 'token', data }); - assert.equal('/v1/auth/token/lookup-self', url, 'auth:token url OK'); - assert.equal('GET', method, 'auth:token method OK'); - assert.deepEqual( - { headers: { 'X-Vault-Token': 'token' }, unauthenticated: true }, - options, - 'auth:token options OK' - ); + adapter.authenticate({ backend: 'token', data }); + assert.equal('/v1/auth/token/lookup-self', url, 'auth:token url OK'); + assert.equal('GET', method, 'auth:token method OK'); + assert.deepEqual( + { headers: { 'X-Vault-Token': 'token' }, unauthenticated: true }, + options, + 'auth:token options OK' + ); - adapter.authenticate({ backend: 'github', data }); - assert.equal('/v1/auth/github/login', url, 'auth:github url OK'); - assert.equal('POST', method, 'auth:github method OK'); - assert.deepEqual( - { data: { password: 'password', token: 'token' }, unauthenticated: true }, - options, - 'auth:github options OK' - ); + adapter.authenticate({ backend: 'github', data }); + assert.equal('/v1/auth/github/login', url, 'auth:github url OK'); + assert.equal('POST', method, 'auth:github method OK'); + assert.deepEqual( + { data: { password: 'password', token: 'token' }, unauthenticated: true }, + options, + 'auth:github options OK' + ); - data = { token: 'token', password: 'password', username: 'username', path: 'path' }; + data = { token: 'token', password: 'password', username: 'username', path: 'path' }; - adapter.authenticate({ backend: 'token', data }); - assert.equal('/v1/auth/token/lookup-self', url, 'auth:token url with path OK'); + adapter.authenticate({ backend: 'token', data }); + assert.equal('/v1/auth/token/lookup-self', url, 'auth:token url with path OK'); - adapter.authenticate({ backend: 'github', data }); - assert.equal('/v1/auth/path/login', url, 'auth:github with path url OK'); + adapter.authenticate({ backend: 'github', data }); + assert.equal('/v1/auth/path/login', url, 'auth:github with path url OK'); - data = { password: 'password', username: 'username' }; + data = { password: 'password', username: 'username' }; - adapter.authenticate({ backend: 'userpass', data }); - assert.equal('/v1/auth/userpass/login/username', url, 'auth:userpass url OK'); - assert.equal('POST', method, 'auth:userpass method OK'); - assert.deepEqual( - { data: { password: 'password' }, unauthenticated: true }, - options, - 'auth:userpass options OK' - ); + adapter.authenticate({ backend: 'userpass', data }); + assert.equal('/v1/auth/userpass/login/username', url, 'auth:userpass url OK'); + assert.equal('POST', method, 'auth:userpass method OK'); + assert.deepEqual( + { data: { password: 'password' }, unauthenticated: true }, + options, + 'auth:userpass options OK' + ); - adapter.authenticate({ backend: 'LDAP', data }); - assert.equal('/v1/auth/ldap/login/username', url, 'ldap:userpass url OK'); - assert.equal('POST', method, 'ldap:userpass method OK'); - assert.deepEqual( - { data: { password: 'password' }, unauthenticated: true }, - options, - 'ldap:userpass options OK' - ); + adapter.authenticate({ backend: 'LDAP', data }); + assert.equal('/v1/auth/ldap/login/username', url, 'ldap:userpass url OK'); + assert.equal('POST', method, 'ldap:userpass method OK'); + assert.deepEqual( + { data: { password: 'password' }, unauthenticated: true }, + options, + 'ldap:userpass options OK' + ); - adapter.authenticate({ backend: 'okta', data }); - assert.equal('/v1/auth/okta/login/username', url, 'okta:userpass url OK'); - assert.equal('POST', method, 'ldap:userpass method OK'); - assert.deepEqual( - { data: { password: 'password' }, unauthenticated: true }, - options, - 'okta:userpass options OK' - ); + adapter.authenticate({ backend: 'okta', data }); + assert.equal('/v1/auth/okta/login/username', url, 'okta:userpass url OK'); + assert.equal('POST', method, 'ldap:userpass method OK'); + assert.deepEqual( + { data: { password: 'password' }, unauthenticated: true }, + options, + 'okta:userpass options OK' + ); - // use a custom mount path - data = { password: 'password', username: 'username', path: 'path' }; + // use a custom mount path + data = { password: 'password', username: 'username', path: 'path' }; - adapter.authenticate({ backend: 'userpass', data }); - assert.equal('/v1/auth/path/login/username', url, 'auth:userpass with path url OK'); + adapter.authenticate({ backend: 'userpass', data }); + assert.equal('/v1/auth/path/login/username', url, 'auth:userpass with path url OK'); - adapter.authenticate({ backend: 'LDAP', data }); - assert.equal('/v1/auth/path/login/username', url, 'auth:LDAP with path url OK'); + adapter.authenticate({ backend: 'LDAP', data }); + assert.equal('/v1/auth/path/login/username', url, 'auth:LDAP with path url OK'); - adapter.authenticate({ backend: 'Okta', data }); - assert.equal('/v1/auth/path/login/username', url, 'auth:Okta with path url OK'); -}); - -test('cluster replication api urls', function(assert) { - let url, method, options; - let adapter = this.subject({ - ajax: (...args) => { - [url, method, options] = args; - return Ember.RSVP.resolve(); - }, + adapter.authenticate({ backend: 'Okta', data }); + assert.equal('/v1/auth/path/login/username', url, 'auth:Okta with path url OK'); }); - adapter.replicationStatus(); - assert.equal('/v1/sys/replication/status', url, 'replication:status url OK'); - assert.equal('GET', method, 'replication:status method OK'); - assert.deepEqual({ unauthenticated: true }, options, 'replication:status options OK'); + test('cluster replication api urls', function(assert) { + let url, method, options; + let adapter = this.owner.factoryFor('adapter:cluster').create({ + ajax: (...args) => { + [url, method, options] = args; + return resolve(); + }, + }); - adapter.replicationAction('recover', 'dr'); - assert.equal('/v1/sys/replication/recover', url, 'replication: recover url OK'); - assert.equal('POST', method, 'replication:recover method OK'); + adapter.replicationStatus(); + assert.equal('/v1/sys/replication/status', url, 'replication:status url OK'); + assert.equal('GET', method, 'replication:status method OK'); + assert.deepEqual({ unauthenticated: true }, options, 'replication:status options OK'); - adapter.replicationAction('reindex', 'dr'); - assert.equal('/v1/sys/replication/reindex', url, 'replication: reindex url OK'); - assert.equal('POST', method, 'replication:reindex method OK'); + adapter.replicationAction('recover', 'dr'); + assert.equal('/v1/sys/replication/recover', url, 'replication: recover url OK'); + assert.equal('POST', method, 'replication:recover method OK'); - adapter.replicationAction('enable', 'dr', 'primary'); - assert.equal('/v1/sys/replication/dr/primary/enable', url, 'replication:dr primary:enable url OK'); - assert.equal('POST', method, 'replication:primary:enable method OK'); - adapter.replicationAction('enable', 'performance', 'primary'); - assert.equal( - '/v1/sys/replication/performance/primary/enable', - url, - 'replication:performance primary:enable url OK' - ); + adapter.replicationAction('reindex', 'dr'); + assert.equal('/v1/sys/replication/reindex', url, 'replication: reindex url OK'); + assert.equal('POST', method, 'replication:reindex method OK'); - adapter.replicationAction('enable', 'dr', 'secondary'); - assert.equal('/v1/sys/replication/dr/secondary/enable', url, 'replication:dr secondary:enable url OK'); - assert.equal('POST', method, 'replication:secondary:enable method OK'); - adapter.replicationAction('enable', 'performance', 'secondary'); - assert.equal( - '/v1/sys/replication/performance/secondary/enable', - url, - 'replication:performance secondary:enable url OK' - ); + adapter.replicationAction('enable', 'dr', 'primary'); + assert.equal('/v1/sys/replication/dr/primary/enable', url, 'replication:dr primary:enable url OK'); + assert.equal('POST', method, 'replication:primary:enable method OK'); + adapter.replicationAction('enable', 'performance', 'primary'); + assert.equal( + '/v1/sys/replication/performance/primary/enable', + url, + 'replication:performance primary:enable url OK' + ); - adapter.replicationAction('disable', 'dr', 'primary'); - assert.equal('/v1/sys/replication/dr/primary/disable', url, 'replication:dr primary:disable url OK'); - assert.equal('POST', method, 'replication:primary:disable method OK'); - adapter.replicationAction('disable', 'performance', 'primary'); - assert.equal( - '/v1/sys/replication/performance/primary/disable', - url, - 'replication:performance primary:disable url OK' - ); + adapter.replicationAction('enable', 'dr', 'secondary'); + assert.equal('/v1/sys/replication/dr/secondary/enable', url, 'replication:dr secondary:enable url OK'); + assert.equal('POST', method, 'replication:secondary:enable method OK'); + adapter.replicationAction('enable', 'performance', 'secondary'); + assert.equal( + '/v1/sys/replication/performance/secondary/enable', + url, + 'replication:performance secondary:enable url OK' + ); - adapter.replicationAction('disable', 'dr', 'secondary'); - assert.equal('/v1/sys/replication/dr/secondary/disable', url, 'replication: drsecondary:disable url OK'); - assert.equal('POST', method, 'replication:secondary:disable method OK'); - adapter.replicationAction('disable', 'performance', 'secondary'); - assert.equal( - '/v1/sys/replication/performance/secondary/disable', - url, - 'replication: performance:disable url OK' - ); + adapter.replicationAction('disable', 'dr', 'primary'); + assert.equal('/v1/sys/replication/dr/primary/disable', url, 'replication:dr primary:disable url OK'); + assert.equal('POST', method, 'replication:primary:disable method OK'); + adapter.replicationAction('disable', 'performance', 'primary'); + assert.equal( + '/v1/sys/replication/performance/primary/disable', + url, + 'replication:performance primary:disable url OK' + ); - adapter.replicationAction('demote', 'dr', 'primary'); - assert.equal('/v1/sys/replication/dr/primary/demote', url, 'replication: dr primary:demote url OK'); - assert.equal('POST', method, 'replication:primary:demote method OK'); - adapter.replicationAction('demote', 'performance', 'primary'); - assert.equal( - '/v1/sys/replication/performance/primary/demote', - url, - 'replication: performance primary:demote url OK' - ); + adapter.replicationAction('disable', 'dr', 'secondary'); + assert.equal('/v1/sys/replication/dr/secondary/disable', url, 'replication: drsecondary:disable url OK'); + assert.equal('POST', method, 'replication:secondary:disable method OK'); + adapter.replicationAction('disable', 'performance', 'secondary'); + assert.equal( + '/v1/sys/replication/performance/secondary/disable', + url, + 'replication: performance:disable url OK' + ); - adapter.replicationAction('promote', 'performance', 'secondary'); - assert.equal('POST', method, 'replication:secondary:promote method OK'); - assert.equal( - '/v1/sys/replication/performance/secondary/promote', - url, - 'replication:performance secondary:promote url OK' - ); + adapter.replicationAction('demote', 'dr', 'primary'); + assert.equal('/v1/sys/replication/dr/primary/demote', url, 'replication: dr primary:demote url OK'); + assert.equal('POST', method, 'replication:primary:demote method OK'); + adapter.replicationAction('demote', 'performance', 'primary'); + assert.equal( + '/v1/sys/replication/performance/primary/demote', + url, + 'replication: performance primary:demote url OK' + ); - adapter.replicationDrPromote(); - assert.equal('/v1/sys/replication/dr/secondary/promote', url, 'replication:dr secondary:promote url OK'); - assert.equal('PUT', method, 'replication:dr secondary:promote method OK'); - adapter.replicationDrPromote({}, { checkStatus: true }); - assert.equal('/v1/sys/replication/dr/secondary/promote', url, 'replication:dr secondary:promote url OK'); - assert.equal('GET', method, 'replication:dr secondary:promote method OK'); + adapter.replicationAction('promote', 'performance', 'secondary'); + assert.equal('POST', method, 'replication:secondary:promote method OK'); + assert.equal( + '/v1/sys/replication/performance/secondary/promote', + url, + 'replication:performance secondary:promote url OK' + ); + + adapter.replicationDrPromote(); + assert.equal('/v1/sys/replication/dr/secondary/promote', url, 'replication:dr secondary:promote url OK'); + assert.equal('PUT', method, 'replication:dr secondary:promote method OK'); + adapter.replicationDrPromote({}, { checkStatus: true }); + assert.equal('/v1/sys/replication/dr/secondary/promote', url, 'replication:dr secondary:promote url OK'); + assert.equal('GET', method, 'replication:dr secondary:promote method OK'); + }); }); diff --git a/ui/tests/unit/adapters/console-test.js b/ui/tests/unit/adapters/console-test.js index 60c7b900d..1607d5a69 100644 --- a/ui/tests/unit/adapters/console-test.js +++ b/ui/tests/unit/adapters/console-test.js @@ -1,14 +1,14 @@ -import { moduleFor, test } from 'ember-qunit'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -moduleFor('adapter:console', 'Unit | Adapter | console', { - needs, -}); +module('Unit | Adapter | console', function(hooks) { + setupTest(hooks); -test('it builds the correct URL', function(assert) { - let adapter = this.subject(); - let sysPath = 'sys/health'; - let awsPath = 'aws/roles/my-other-role'; - assert.equal(adapter.buildURL(sysPath), '/v1/sys/health'); - assert.equal(adapter.buildURL(awsPath), '/v1/aws/roles/my-other-role'); + test('it builds the correct URL', function(assert) { + let adapter = this.owner.lookup('adapter:console'); + let sysPath = 'sys/health'; + let awsPath = 'aws/roles/my-other-role'; + assert.equal(adapter.buildURL(sysPath), '/v1/sys/health'); + assert.equal(adapter.buildURL(awsPath), '/v1/aws/roles/my-other-role'); + }); }); diff --git a/ui/tests/unit/adapters/identity/entity-alias-test.js b/ui/tests/unit/adapters/identity/entity-alias-test.js index 7450123e0..87f65f907 100644 --- a/ui/tests/unit/adapters/identity/entity-alias-test.js +++ b/ui/tests/unit/adapters/identity/entity-alias-test.js @@ -1,31 +1,33 @@ -import { moduleFor, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import testCases from './_test-cases'; import apiStub from 'vault/tests/helpers/noop-all-api-requests'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; -moduleFor('adapter:identity/entity-alias', 'Unit | Adapter | identity/entity-alias', { - needs, - beforeEach() { +module('Unit | Adapter | identity/entity-alias', function(hooks) { + setupTest(hooks); + + hooks.beforeEach(function() { this.server = apiStub(); - }, - afterEach() { + }); + + hooks.afterEach(function() { this.server.shutdown(); - }, -}); + }); -const cases = testCases('identit/entity-alias'); + const cases = testCases('identit/entity-alias'); -cases.forEach(testCase => { - test(`entity-alias#${testCase.adapterMethod}`, function(assert) { - assert.expect(2); - let adapter = this.subject(); - adapter[testCase.adapterMethod](...testCase.args); - let { url, method } = this.server.handledRequests[0]; - assert.equal(url, testCase.url, `${testCase.adapterMethod} calls the correct url: ${testCase.url}`); - assert.equal( - method, - testCase.method, - `${testCase.adapterMethod} uses the correct http verb: ${testCase.method}` - ); + cases.forEach(testCase => { + test(`entity-alias#${testCase.adapterMethod}`, function(assert) { + assert.expect(2); + let adapter = this.owner.lookup('adapter:identity/entity-alias'); + adapter[testCase.adapterMethod](...testCase.args); + let { url, method } = this.server.handledRequests[0]; + assert.equal(url, testCase.url, `${testCase.adapterMethod} calls the correct url: ${testCase.url}`); + assert.equal( + method, + testCase.method, + `${testCase.adapterMethod} uses the correct http verb: ${testCase.method}` + ); + }); }); }); diff --git a/ui/tests/unit/adapters/identity/entity-merge-test.js b/ui/tests/unit/adapters/identity/entity-merge-test.js index e6c6829ab..309ae1fcd 100644 --- a/ui/tests/unit/adapters/identity/entity-merge-test.js +++ b/ui/tests/unit/adapters/identity/entity-merge-test.js @@ -1,27 +1,29 @@ import Pretender from 'pretender'; -import { moduleFor, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import { storeMVP } from './_test-cases'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; -moduleFor('adapter:identity/entity-merge', 'Unit | Adapter | identity/entity-merge', { - needs, - beforeEach() { +module('Unit | Adapter | identity/entity-merge', function(hooks) { + setupTest(hooks); + + hooks.beforeEach(function() { this.server = new Pretender(function() { this.post('/v1/**', response => { return [response, { 'Content-Type': 'application/json' }, JSON.stringify({})]; }); }); - }, - afterEach() { - this.server.shutdown(); - }, -}); + }); -test(`entity-merge#createRecord`, function(assert) { - assert.expect(2); - let adapter = this.subject(); - adapter.createRecord(storeMVP, { modelName: 'identity/entity-merge' }, { attr: x => x }); - let { url, method } = this.server.handledRequests[0]; - assert.equal(url, `/v1/identity/entity/merge`, ` calls the correct url`); - assert.equal(method, 'POST', `uses the correct http verb: POST`); + hooks.afterEach(function() { + this.server.shutdown(); + }); + + test(`entity-merge#createRecord`, function(assert) { + assert.expect(2); + let adapter = this.owner.lookup('adapter:identity/entity-merge'); + adapter.createRecord(storeMVP, { modelName: 'identity/entity-merge' }, { attr: x => x }); + let { url, method } = this.server.handledRequests[0]; + assert.equal(url, `/v1/identity/entity/merge`, ` calls the correct url`); + assert.equal(method, 'POST', `uses the correct http verb: POST`); + }); }); diff --git a/ui/tests/unit/adapters/identity/entity-test.js b/ui/tests/unit/adapters/identity/entity-test.js index 726ed2701..953be8f62 100644 --- a/ui/tests/unit/adapters/identity/entity-test.js +++ b/ui/tests/unit/adapters/identity/entity-test.js @@ -1,31 +1,33 @@ -import { moduleFor, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import testCases from './_test-cases'; import apiStub from 'vault/tests/helpers/noop-all-api-requests'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; -moduleFor('adapter:identity/entity', 'Unit | Adapter | identity/entity', { - needs, - beforeEach() { +module('Unit | Adapter | identity/entity', function(hooks) { + setupTest(hooks); + + hooks.beforeEach(function() { this.server = apiStub(); - }, - afterEach() { + }); + + hooks.afterEach(function() { this.server.shutdown(); - }, -}); + }); -const cases = testCases('identit/entity'); + const cases = testCases('identit/entity'); -cases.forEach(testCase => { - test(`entity#${testCase.adapterMethod}`, function(assert) { - assert.expect(2); - let adapter = this.subject(); - adapter[testCase.adapterMethod](...testCase.args); - let { url, method } = this.server.handledRequests[0]; - assert.equal(url, testCase.url, `${testCase.adapterMethod} calls the correct url: ${testCase.url}`); - assert.equal( - method, - testCase.method, - `${testCase.adapterMethod} uses the correct http verb: ${testCase.method}` - ); + cases.forEach(testCase => { + test(`entity#${testCase.adapterMethod}`, function(assert) { + assert.expect(2); + let adapter = this.owner.lookup('adapter:identity/entity'); + adapter[testCase.adapterMethod](...testCase.args); + let { url, method } = this.server.handledRequests[0]; + assert.equal(url, testCase.url, `${testCase.adapterMethod} calls the correct url: ${testCase.url}`); + assert.equal( + method, + testCase.method, + `${testCase.adapterMethod} uses the correct http verb: ${testCase.method}` + ); + }); }); }); diff --git a/ui/tests/unit/adapters/identity/group-alias-test.js b/ui/tests/unit/adapters/identity/group-alias-test.js index 15a9c6ab3..7c6ebd615 100644 --- a/ui/tests/unit/adapters/identity/group-alias-test.js +++ b/ui/tests/unit/adapters/identity/group-alias-test.js @@ -1,31 +1,33 @@ -import { moduleFor, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import testCases from './_test-cases'; import apiStub from 'vault/tests/helpers/noop-all-api-requests'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; -moduleFor('adapter:identity/group-alias', 'Unit | Adapter | identity/group-alias', { - needs, - beforeEach() { +module('Unit | Adapter | identity/group-alias', function(hooks) { + setupTest(hooks); + + hooks.beforeEach(function() { this.server = apiStub(); - }, - afterEach() { + }); + + hooks.afterEach(function() { this.server.shutdown(); - }, -}); + }); -const cases = testCases('identity/group-alias'); + const cases = testCases('identity/group-alias'); -cases.forEach(testCase => { - test(`group-alias#${testCase.adapterMethod}`, function(assert) { - assert.expect(2); - let adapter = this.subject(); - adapter[testCase.adapterMethod](...testCase.args); - let { url, method } = this.server.handledRequests[0]; - assert.equal(url, testCase.url, `${testCase.adapterMethod} calls the correct url: ${testCase.url}`); - assert.equal( - method, - testCase.method, - `${testCase.adapterMethod} uses the correct http verb: ${testCase.method}` - ); + cases.forEach(testCase => { + test(`group-alias#${testCase.adapterMethod}`, function(assert) { + assert.expect(2); + let adapter = this.owner.lookup('adapter:identity/group-alias'); + adapter[testCase.adapterMethod](...testCase.args); + let { url, method } = this.server.handledRequests[0]; + assert.equal(url, testCase.url, `${testCase.adapterMethod} calls the correct url: ${testCase.url}`); + assert.equal( + method, + testCase.method, + `${testCase.adapterMethod} uses the correct http verb: ${testCase.method}` + ); + }); }); }); diff --git a/ui/tests/unit/adapters/identity/group-test.js b/ui/tests/unit/adapters/identity/group-test.js index 41234a118..f27194954 100644 --- a/ui/tests/unit/adapters/identity/group-test.js +++ b/ui/tests/unit/adapters/identity/group-test.js @@ -1,31 +1,33 @@ -import { moduleFor, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import testCases from './_test-cases'; import apiStub from 'vault/tests/helpers/noop-all-api-requests'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; -moduleFor('adapter:identity/group', 'Unit | Adapter | identity/group', { - needs, - beforeEach() { +module('Unit | Adapter | identity/group', function(hooks) { + setupTest(hooks); + + hooks.beforeEach(function() { this.server = apiStub(); - }, - afterEach() { + }); + + hooks.afterEach(function() { this.server.shutdown(); - }, -}); + }); -const cases = testCases('identit/entity'); + const cases = testCases('identit/entity'); -cases.forEach(testCase => { - test(`group#${testCase.adapterMethod}`, function(assert) { - assert.expect(2); - let adapter = this.subject(); - adapter[testCase.adapterMethod](...testCase.args); - let { url, method } = this.server.handledRequests[0]; - assert.equal(url, testCase.url, `${testCase.adapterMethod} calls the correct url: ${testCase.url}`); - assert.equal( - method, - testCase.method, - `${testCase.adapterMethod} uses the correct http verb: ${testCase.method}` - ); + cases.forEach(testCase => { + test(`group#${testCase.adapterMethod}`, function(assert) { + assert.expect(2); + let adapter = this.owner.lookup('adapter:identity/group'); + adapter[testCase.adapterMethod](...testCase.args); + let { url, method } = this.server.handledRequests[0]; + assert.equal(url, testCase.url, `${testCase.adapterMethod} calls the correct url: ${testCase.url}`); + assert.equal( + method, + testCase.method, + `${testCase.adapterMethod} uses the correct http verb: ${testCase.method}` + ); + }); }); }); diff --git a/ui/tests/unit/adapters/secret-engine-test.js b/ui/tests/unit/adapters/secret-engine-test.js index 733bae237..028d295da 100644 --- a/ui/tests/unit/adapters/secret-engine-test.js +++ b/ui/tests/unit/adapters/secret-engine-test.js @@ -1,63 +1,65 @@ -import { moduleFor, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import apiStub from 'vault/tests/helpers/noop-all-api-requests'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; -moduleFor('adapter:secret-engine', 'Unit | Adapter | secret engine', { - needs, - beforeEach() { +module('Unit | Adapter | secret engine', function(hooks) { + setupTest(hooks); + + hooks.beforeEach(function() { this.server = apiStub(); - }, - afterEach() { + }); + + hooks.afterEach(function() { this.server.shutdown(); - }, -}); + }); -const storeStub = { - serializerFor() { - return { - serializeIntoHash() {}, - }; - }, -}; -const type = { - modelName: 'secret-engine', -}; + const storeStub = { + serializerFor() { + return { + serializeIntoHash() {}, + }; + }, + }; + const type = { + modelName: 'secret-engine', + }; -const cases = [ - { - description: 'Empty query', - adapterMethod: 'query', - args: [storeStub, type, {}], - url: '/v1/sys/internal/ui/mounts', - method: 'GET', - }, - { - description: 'Query with a path', - adapterMethod: 'query', - args: [storeStub, type, { path: 'foo' }], - url: '/v1/sys/internal/ui/mounts/foo', - method: 'GET', - }, + const cases = [ + { + description: 'Empty query', + adapterMethod: 'query', + args: [storeStub, type, {}], + url: '/v1/sys/internal/ui/mounts', + method: 'GET', + }, + { + description: 'Query with a path', + adapterMethod: 'query', + args: [storeStub, type, { path: 'foo' }], + url: '/v1/sys/internal/ui/mounts/foo', + method: 'GET', + }, - { - description: 'Query with nested path', - adapterMethod: 'query', - args: [storeStub, type, { path: 'foo/bar/baz' }], - url: '/v1/sys/internal/ui/mounts/foo/bar/baz', - method: 'GET', - }, -]; -cases.forEach(testCase => { - test(`secret-engine: ${testCase.description}`, function(assert) { - assert.expect(2); - let adapter = this.subject(); - adapter[testCase.adapterMethod](...testCase.args); - let { url, method } = this.server.handledRequests[0]; - assert.equal(url, testCase.url, `${testCase.adapterMethod} calls the correct url: ${testCase.url}`); - assert.equal( - method, - testCase.method, - `${testCase.adapterMethod} uses the correct http verb: ${testCase.method}` - ); + { + description: 'Query with nested path', + adapterMethod: 'query', + args: [storeStub, type, { path: 'foo/bar/baz' }], + url: '/v1/sys/internal/ui/mounts/foo/bar/baz', + method: 'GET', + }, + ]; + cases.forEach(testCase => { + test(`secret-engine: ${testCase.description}`, function(assert) { + assert.expect(2); + let adapter = this.owner.lookup('adapter:secret-engine'); + adapter[testCase.adapterMethod](...testCase.args); + let { url, method } = this.server.handledRequests[0]; + assert.equal(url, testCase.url, `${testCase.adapterMethod} calls the correct url: ${testCase.url}`); + assert.equal( + method, + testCase.method, + `${testCase.adapterMethod} uses the correct http verb: ${testCase.method}` + ); + }); }); }); diff --git a/ui/tests/unit/adapters/secret-test.js b/ui/tests/unit/adapters/secret-test.js index 8ee4d9da8..c0ece51cf 100644 --- a/ui/tests/unit/adapters/secret-test.js +++ b/ui/tests/unit/adapters/secret-test.js @@ -1,26 +1,26 @@ -import { moduleFor, test } from 'ember-qunit'; -import Ember from 'ember'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; +import { resolve } from 'rsvp'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -moduleFor('adapter:secret', 'Unit | Adapter | secret', { - needs, -}); +module('Unit | Adapter | secret', function(hooks) { + setupTest(hooks); -test('secret api urls', function(assert) { - let url, method, options; - let adapter = this.subject({ - ajax: (...args) => { - [url, method, options] = args; - return Ember.RSVP.resolve({}); - }, + test('secret api urls', function(assert) { + let url, method, options; + let adapter = this.owner.factoryFor('adapter:secret').create({ + ajax: (...args) => { + [url, method, options] = args; + return resolve({}); + }, + }); + + adapter.query({}, 'secret', { id: '', backend: 'secret' }); + assert.equal(url, '/v1/secret/', 'query generic url OK'); + assert.equal('GET', method, 'query generic method OK'); + assert.deepEqual(options, { data: { list: true } }, 'query generic url OK'); + + adapter.queryRecord({}, 'secret', { id: 'foo', backend: 'secret' }); + assert.equal(url, '/v1/secret/foo', 'queryRecord generic url OK'); + assert.equal('GET', method, 'queryRecord generic method OK'); }); - - adapter.query({}, 'secret', { id: '', backend: 'secret' }); - assert.equal(url, '/v1/secret/', 'query generic url OK'); - assert.equal('GET', method, 'query generic method OK'); - assert.deepEqual(options, { data: { list: true } }, 'query generic url OK'); - - adapter.queryRecord({}, 'secret', { id: 'foo', backend: 'secret' }); - assert.equal(url, '/v1/secret/foo', 'queryRecord generic url OK'); - assert.equal('GET', method, 'queryRecord generic method OK'); }); diff --git a/ui/tests/unit/adapters/secret-v2-test.js b/ui/tests/unit/adapters/secret-v2-test.js index bc3fe5557..3ddd45c23 100644 --- a/ui/tests/unit/adapters/secret-v2-test.js +++ b/ui/tests/unit/adapters/secret-v2-test.js @@ -1,26 +1,26 @@ -import { moduleFor, test } from 'ember-qunit'; -import Ember from 'ember'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; +import { resolve } from 'rsvp'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -moduleFor('adapter:secret-v2', 'Unit | Adapter | secret-v2', { - needs, -}); +module('Unit | Adapter | secret-v2', function(hooks) { + setupTest(hooks); -test('secret api urls', function(assert) { - let url, method, options; - let adapter = this.subject({ - ajax: (...args) => { - [url, method, options] = args; - return Ember.RSVP.resolve({}); - }, + test('secret api urls', function(assert) { + let url, method, options; + let adapter = this.owner.factoryFor('adapter:secret-v2').create({ + ajax: (...args) => { + [url, method, options] = args; + return resolve({}); + }, + }); + + adapter.query({}, 'secret', { id: '', backend: 'secret' }); + assert.equal(url, '/v1/secret/metadata/', 'query generic url OK'); + assert.equal('GET', method, 'query generic method OK'); + assert.deepEqual(options, { data: { list: true } }, 'query generic url OK'); + + adapter.queryRecord({}, 'secret', { id: 'foo', backend: 'secret' }); + assert.equal(url, '/v1/secret/data/foo', 'queryRecord generic url OK'); + assert.equal('GET', method, 'queryRecord generic method OK'); }); - - adapter.query({}, 'secret', { id: '', backend: 'secret' }); - assert.equal(url, '/v1/secret/metadata/', 'query generic url OK'); - assert.equal('GET', method, 'query generic method OK'); - assert.deepEqual(options, { data: { list: true } }, 'query generic url OK'); - - adapter.queryRecord({}, 'secret', { id: 'foo', backend: 'secret' }); - assert.equal(url, '/v1/secret/data/foo', 'queryRecord generic url OK'); - assert.equal('GET', method, 'queryRecord generic method OK'); }); diff --git a/ui/tests/unit/adapters/tools-test.js b/ui/tests/unit/adapters/tools-test.js index c4fc24897..05381dd9f 100644 --- a/ui/tests/unit/adapters/tools-test.js +++ b/ui/tests/unit/adapters/tools-test.js @@ -1,58 +1,58 @@ -import { moduleFor, test } from 'ember-qunit'; -import Ember from 'ember'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; +import { resolve } from 'rsvp'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -moduleFor('adapter:tools', 'Unit | Adapter | tools', { - needs, -}); +module('Unit | Adapter | tools', function(hooks) { + setupTest(hooks); -test('wrapping api urls', function(assert) { - let url, method, options; - let adapter = this.subject({ - ajax: (...args) => { - [url, method, options] = args; - return Ember.RSVP.resolve(); - }, + test('wrapping api urls', function(assert) { + let url, method, options; + let adapter = this.owner.factoryFor('adapter:tools').create({ + ajax: (...args) => { + [url, method, options] = args; + return resolve(); + }, + }); + + let clientToken; + let data = { foo: 'bar' }; + adapter.toolAction('wrap', data, { wrapTTL: '30m' }); + assert.equal('/v1/sys/wrapping/wrap', url, 'wrapping:wrap url OK'); + assert.equal('POST', method, 'wrapping:wrap method OK'); + assert.deepEqual({ data: data, wrapTTL: '30m', clientToken }, options, 'wrapping:wrap options OK'); + + data = { token: 'token' }; + adapter.toolAction('lookup', data); + assert.equal('/v1/sys/wrapping/lookup', url, 'wrapping:lookup url OK'); + assert.equal('POST', method, 'wrapping:lookup method OK'); + assert.deepEqual({ data, clientToken }, options, 'wrapping:lookup options OK'); + + adapter.toolAction('unwrap', data); + assert.equal('/v1/sys/wrapping/unwrap', url, 'wrapping:unwrap url OK'); + assert.equal('POST', method, 'wrapping:unwrap method OK'); + assert.deepEqual({ data, clientToken }, options, 'wrapping:unwrap options OK'); + + adapter.toolAction('rewrap', data); + assert.equal('/v1/sys/wrapping/rewrap', url, 'wrapping:rewrap url OK'); + assert.equal('POST', method, 'wrapping:rewrap method OK'); + assert.deepEqual({ data, clientToken }, options, 'wrapping:rewrap options OK'); }); - let clientToken; - let data = { foo: 'bar' }; - adapter.toolAction('wrap', data, { wrapTTL: '30m' }); - assert.equal('/v1/sys/wrapping/wrap', url, 'wrapping:wrap url OK'); - assert.equal('POST', method, 'wrapping:wrap method OK'); - assert.deepEqual({ data: data, wrapTTL: '30m', clientToken }, options, 'wrapping:wrap options OK'); + test('tools api urls', function(assert) { + let url, method; + let adapter = this.owner.factoryFor('adapter:tools').create({ + ajax: (...args) => { + [url, method] = args; + return resolve(); + }, + }); - data = { token: 'token' }; - adapter.toolAction('lookup', data); - assert.equal('/v1/sys/wrapping/lookup', url, 'wrapping:lookup url OK'); - assert.equal('POST', method, 'wrapping:lookup method OK'); - assert.deepEqual({ data, clientToken }, options, 'wrapping:lookup options OK'); + adapter.toolAction('hash', { input: 'someBase64' }); + assert.equal(url, '/v1/sys/tools/hash', 'sys tools hash: url OK'); + assert.equal('POST', method, 'sys tools hash: method OK'); - adapter.toolAction('unwrap', data); - assert.equal('/v1/sys/wrapping/unwrap', url, 'wrapping:unwrap url OK'); - assert.equal('POST', method, 'wrapping:unwrap method OK'); - assert.deepEqual({ data, clientToken }, options, 'wrapping:unwrap options OK'); - - adapter.toolAction('rewrap', data); - assert.equal('/v1/sys/wrapping/rewrap', url, 'wrapping:rewrap url OK'); - assert.equal('POST', method, 'wrapping:rewrap method OK'); - assert.deepEqual({ data, clientToken }, options, 'wrapping:rewrap options OK'); -}); - -test('tools api urls', function(assert) { - let url, method; - let adapter = this.subject({ - ajax: (...args) => { - [url, method] = args; - return Ember.RSVP.resolve(); - }, + adapter.toolAction('random', { bytes: '32' }); + assert.equal(url, '/v1/sys/tools/random', 'sys tools random: url OK'); + assert.equal('POST', method, 'sys tools random: method OK'); }); - - adapter.toolAction('hash', { input: 'someBase64' }); - assert.equal(url, '/v1/sys/tools/hash', 'sys tools hash: url OK'); - assert.equal('POST', method, 'sys tools hash: method OK'); - - adapter.toolAction('random', { bytes: '32' }); - assert.equal(url, '/v1/sys/tools/random', 'sys tools random: url OK'); - assert.equal('POST', method, 'sys tools random: method OK'); }); diff --git a/ui/tests/unit/adapters/transit-key-test.js b/ui/tests/unit/adapters/transit-key-test.js index 2da57085e..c52958242 100644 --- a/ui/tests/unit/adapters/transit-key-test.js +++ b/ui/tests/unit/adapters/transit-key-test.js @@ -1,41 +1,41 @@ -import { moduleFor, test } from 'ember-qunit'; -import Ember from 'ember'; -import needs from 'vault/tests/unit/adapters/_adapter-needs'; +import { resolve } from 'rsvp'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -moduleFor('adapter:transit-key', 'Unit | Adapter | transit key', { - needs, -}); +module('Unit | Adapter | transit key', function(hooks) { + setupTest(hooks); -test('transit api urls', function(assert) { - let url, method, options; - let adapter = this.subject({ - ajax: (...args) => { - [url, method, options] = args; - return Ember.RSVP.resolve({}); - }, + test('transit api urls', function(assert) { + let url, method, options; + let adapter = this.owner.factoryFor('adapter:transit-key').create({ + ajax: (...args) => { + [url, method, options] = args; + return resolve({}); + }, + }); + + adapter.query({}, 'transit-key', { id: '', backend: 'transit' }); + assert.equal(url, '/v1/transit/keys/', 'query list url OK'); + assert.equal('GET', method, 'query list method OK'); + assert.deepEqual(options, { data: { list: true } }, 'query generic url OK'); + + adapter.queryRecord({}, 'transit-key', { id: 'foo', backend: 'transit' }); + assert.equal(url, '/v1/transit/keys/foo', 'queryRecord generic url OK'); + assert.equal('GET', method, 'queryRecord generic method OK'); + + adapter.keyAction('rotate', { backend: 'transit', id: 'foo', payload: {} }); + assert.equal(url, '/v1/transit/keys/foo/rotate', 'keyAction:rotate url OK'); + + adapter.keyAction('encrypt', { backend: 'transit', id: 'foo', payload: {} }); + assert.equal(url, '/v1/transit/encrypt/foo', 'keyAction:encrypt url OK'); + + adapter.keyAction('datakey', { backend: 'transit', id: 'foo', payload: { param: 'plaintext' } }); + assert.equal(url, '/v1/transit/datakey/plaintext/foo', 'keyAction:datakey url OK'); + + adapter.keyAction('export', { backend: 'transit', id: 'foo', payload: { param: ['hmac'] } }); + assert.equal(url, '/v1/transit/export/hmac-key/foo', 'transitAction:export, no version url OK'); + + adapter.keyAction('export', { backend: 'transit', id: 'foo', payload: { param: ['hmac', 10] } }); + assert.equal(url, '/v1/transit/export/hmac-key/foo/10', 'transitAction:export, with version url OK'); }); - - adapter.query({}, 'transit-key', { id: '', backend: 'transit' }); - assert.equal(url, '/v1/transit/keys/', 'query list url OK'); - assert.equal('GET', method, 'query list method OK'); - assert.deepEqual(options, { data: { list: true } }, 'query generic url OK'); - - adapter.queryRecord({}, 'transit-key', { id: 'foo', backend: 'transit' }); - assert.equal(url, '/v1/transit/keys/foo', 'queryRecord generic url OK'); - assert.equal('GET', method, 'queryRecord generic method OK'); - - adapter.keyAction('rotate', { backend: 'transit', id: 'foo', payload: {} }); - assert.equal(url, '/v1/transit/keys/foo/rotate', 'keyAction:rotate url OK'); - - adapter.keyAction('encrypt', { backend: 'transit', id: 'foo', payload: {} }); - assert.equal(url, '/v1/transit/encrypt/foo', 'keyAction:encrypt url OK'); - - adapter.keyAction('datakey', { backend: 'transit', id: 'foo', payload: { param: 'plaintext' } }); - assert.equal(url, '/v1/transit/datakey/plaintext/foo', 'keyAction:datakey url OK'); - - adapter.keyAction('export', { backend: 'transit', id: 'foo', payload: { param: ['hmac'] } }); - assert.equal(url, '/v1/transit/export/hmac-key/foo', 'transitAction:export, no version url OK'); - - adapter.keyAction('export', { backend: 'transit', id: 'foo', payload: { param: ['hmac', 10] } }); - assert.equal(url, '/v1/transit/export/hmac-key/foo/10', 'transitAction:export, with version url OK'); }); diff --git a/ui/tests/unit/components/identity/edit-form-test.js b/ui/tests/unit/components/identity/edit-form-test.js index 3006c1b9c..a56769255 100644 --- a/ui/tests/unit/components/identity/edit-form-test.js +++ b/ui/tests/unit/components/identity/edit-form-test.js @@ -1,69 +1,69 @@ -import { moduleForComponent, test } from 'ember-qunit'; +import EmberObject from '@ember/object'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import sinon from 'sinon'; -import Ember from 'ember'; -moduleForComponent('identity/edit-form', 'Unit | Component | identity/edit-form', { - unit: true, - needs: ['service:auth', 'service:flash-messages'], -}); +module('Unit | Component | identity/edit-form', function(hooks) { + setupTest(hooks); -let testCases = [ - { - identityType: 'entity', - mode: 'create', - expected: 'vault.cluster.access.identity', - }, - { - identityType: 'entity', - mode: 'edit', - expected: 'vault.cluster.access.identity.show', - }, - { - identityType: 'entity-merge', - mode: 'merge', - expected: 'vault.cluster.access.identity', - }, - { - identityType: 'entity-alias', - mode: 'create', - expected: 'vault.cluster.access.identity.aliases', - }, - { - identityType: 'entity-alias', - mode: 'edit', - expected: 'vault.cluster.access.identity.aliases.show', - }, - { - identityType: 'group', - mode: 'create', - expected: 'vault.cluster.access.identity', - }, - { - identityType: 'group', - mode: 'edit', - expected: 'vault.cluster.access.identity.show', - }, - { - identityType: 'group-alias', - mode: 'create', - expected: 'vault.cluster.access.identity.aliases', - }, - { - identityType: 'group-alias', - mode: 'edit', - expected: 'vault.cluster.access.identity.aliases.show', - }, -]; -testCases.forEach(function(testCase) { - let model = Ember.Object.create({ - identityType: testCase.identityType, - rollbackAttributes: sinon.spy(), - }); - test(`it computes cancelLink properly: ${testCase.identityType} ${testCase.mode}`, function(assert) { - let component = this.subject(); + let testCases = [ + { + identityType: 'entity', + mode: 'create', + expected: 'vault.cluster.access.identity', + }, + { + identityType: 'entity', + mode: 'edit', + expected: 'vault.cluster.access.identity.show', + }, + { + identityType: 'entity-merge', + mode: 'merge', + expected: 'vault.cluster.access.identity', + }, + { + identityType: 'entity-alias', + mode: 'create', + expected: 'vault.cluster.access.identity.aliases', + }, + { + identityType: 'entity-alias', + mode: 'edit', + expected: 'vault.cluster.access.identity.aliases.show', + }, + { + identityType: 'group', + mode: 'create', + expected: 'vault.cluster.access.identity', + }, + { + identityType: 'group', + mode: 'edit', + expected: 'vault.cluster.access.identity.show', + }, + { + identityType: 'group-alias', + mode: 'create', + expected: 'vault.cluster.access.identity.aliases', + }, + { + identityType: 'group-alias', + mode: 'edit', + expected: 'vault.cluster.access.identity.aliases.show', + }, + ]; + testCases.forEach(function(testCase) { + let model = EmberObject.create({ + identityType: testCase.identityType, + rollbackAttributes: sinon.spy(), + }); + test(`it computes cancelLink properly: ${testCase.identityType} ${testCase.mode}`, function(assert) { + let component = this.owner.lookup('component:identity/edit-form'); - component.set('mode', testCase.mode); - component.set('model', model); - assert.equal(component.get('cancelLink'), testCase.expected, 'cancel link is correct'); + component.set('mode', testCase.mode); + component.set('model', model); + assert.equal(component.get('cancelLink'), testCase.expected, 'cancel link is correct'); + }); }); }); diff --git a/ui/tests/unit/lib/console-helpers-test.js b/ui/tests/unit/lib/console-helpers-test.js index ea63e1e41..4c0c04651 100644 --- a/ui/tests/unit/lib/console-helpers-test.js +++ b/ui/tests/unit/lib/console-helpers-test.js @@ -7,322 +7,330 @@ import { logErrorFromInput, } from 'vault/lib/console-helpers'; -module('lib/console-helpers', 'Unit | Lib | console helpers'); - -const testCommands = [ - { - name: 'write with data', - command: `vault write aws/config/root \ - access_key=AKIAJWVN5Z4FOFT7NLNA \ - secret_key=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 \ - region=us-east-1`, - expected: [ - 'write', - [], - 'aws/config/root', - [ - 'access_key=AKIAJWVN5Z4FOFT7NLNA', - 'secret_key=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', - 'region=us-east-1', +module('Unit | Lib | console helpers', function() { + const testCommands = [ + { + name: 'write with data', + command: `vault write aws/config/root \ + access_key=AKIAJWVN5Z4FOFT7NLNA \ + secret_key=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 \ + region=us-east-1`, + expected: [ + 'write', + [], + 'aws/config/root', + [ + 'access_key=AKIAJWVN5Z4FOFT7NLNA', + 'secret_key=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', + 'region=us-east-1', + ], ], - ], - }, - { - name: 'read with field', - command: `vault read -field=access_key aws/creds/my-role`, - expected: ['read', ['-field=access_key'], 'aws/creds/my-role', []], - }, -]; - -testCommands.forEach(function(testCase) { - test(`#parseCommand: ${testCase.name}`, function(assert) { - let result = parseCommand(testCase.command); - assert.deepEqual(result, testCase.expected); - }); -}); - -test('#parseCommand: invalid commands', function(assert) { - let command = 'vault kv get foo'; - let result = parseCommand(command); - assert.equal(result, false, 'parseCommand returns false by default'); - - assert.throws( - () => { - parseCommand(command, true); }, - /invalid command/, - 'throws on invalid command when `shouldThrow` is true' - ); -}); + { + name: 'read with field', + command: `vault read -field=access_key aws/creds/my-role`, + expected: ['read', ['-field=access_key'], 'aws/creds/my-role', []], + }, + ]; -const testExtractCases = [ - { - name: 'data fields', - input: [ - [ - 'access_key=AKIAJWVN5Z4FOFT7NLNA', - 'secret_key=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', - 'region=us-east-1', + testCommands.forEach(function(testCase) { + test(`#parseCommand: ${testCase.name}`, function(assert) { + let result = parseCommand(testCase.command); + assert.deepEqual(result, testCase.expected); + }); + }); + + test('#parseCommand: invalid commands', function(assert) { + let command = 'vault kv get foo'; + let result = parseCommand(command); + assert.equal(result, false, 'parseCommand returns false by default'); + + assert.throws( + () => { + parseCommand(command, true); + }, + /invalid command/, + 'throws on invalid command when `shouldThrow` is true' + ); + }); + + const testExtractCases = [ + { + name: 'data fields', + input: [ + [ + 'access_key=AKIAJWVN5Z4FOFT7NLNA', + 'secret_key=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', + 'region=us-east-1', + ], + [], ], - [], - ], - expected: { - data: { - access_key: 'AKIAJWVN5Z4FOFT7NLNA', - secret_key: 'R4nm063hgMVo4BTT5xOs5nHLeLXA6lar7ZJ3Nt0i', - region: 'us-east-1', - }, - flags: {}, - }, - }, - { - name: 'repeated data and a flag', - input: [['allowed_domains=example.com', 'allowed_domains=foo.example.com'], ['-wrap-ttl=2h']], - expected: { - data: { - allowed_domains: ['example.com', 'foo.example.com'], - }, - flags: { - wrapTTL: '2h', + expected: { + data: { + access_key: 'AKIAJWVN5Z4FOFT7NLNA', + secret_key: 'R4nm063hgMVo4BTT5xOs5nHLeLXA6lar7ZJ3Nt0i', + region: 'us-east-1', + }, + flags: {}, }, }, - }, - { - name: 'data with more than one equals sign', - input: [['foo=bar=baz', 'foo=baz=bop', 'some=value=val'], []], - expected: { - data: { - foo: ['bar=baz', 'baz=bop'], - some: 'value=val', + { + name: 'repeated data and a flag', + input: [['allowed_domains=example.com', 'allowed_domains=foo.example.com'], ['-wrap-ttl=2h']], + expected: { + data: { + allowed_domains: ['example.com', 'foo.example.com'], + }, + flags: { + wrapTTL: '2h', + }, }, - flags: {}, }, - }, -]; + { + name: 'data with more than one equals sign', + input: [['foo=bar=baz', 'foo=baz=bop', 'some=value=val'], []], + expected: { + data: { + foo: ['bar=baz', 'baz=bop'], + some: 'value=val', + }, + flags: {}, + }, + }, + ]; -testExtractCases.forEach(function(testCase) { - test(`#extractDataAndFlags: ${testCase.name}`, function(assert) { - let { data, flags } = extractDataAndFlags(...testCase.input); - assert.deepEqual(data, testCase.expected.data, 'has expected data'); - assert.deepEqual(flags, testCase.expected.flags, 'has expected flags'); - }); -}); - -let testResponseCases = [ - { - name: 'write response, no content', - args: [null, 'foo/bar', 'write', {}], - expectedData: { - type: 'success', - content: 'Success! Data written to: foo/bar', - }, - }, - { - name: 'delete response, no content', - args: [null, 'foo/bar', 'delete', {}], - expectedData: { - type: 'success', - content: 'Success! Data deleted (if it existed) at: foo/bar', - }, - }, - { - name: 'write, with content', - args: [{ data: { one: 'two' } }, 'foo/bar', 'write', {}], - expectedData: { - type: 'object', - content: { one: 'two' }, - }, - }, - { - name: 'with wrap-ttl flag', - args: [{ wrap_info: { one: 'two' } }, 'foo/bar', 'read', { wrapTTL: '1h' }], - expectedData: { - type: 'object', - content: { one: 'two' }, - }, - }, - { - name: 'with -format=json flag and wrap-ttl flag', - args: [{ foo: 'bar', wrap_info: { one: 'two' } }, 'foo/bar', 'read', { format: 'json', wrapTTL: '1h' }], - expectedData: { - type: 'json', - content: { foo: 'bar', wrap_info: { one: 'two' } }, - }, - }, - { - name: 'with -format=json and -field flags', - args: [{ foo: 'bar', data: { one: 'two' } }, 'foo/bar', 'read', { format: 'json', field: 'one' }], - expectedData: { - type: 'json', - content: 'two', - }, - }, - { - name: 'with -format=json and -field, and -wrap-ttl flags', - args: [ - { foo: 'bar', wrap_info: { one: 'two' } }, - 'foo/bar', - 'read', - { format: 'json', wrapTTL: '1h', field: 'one' }, - ], - expectedData: { - type: 'json', - content: 'two', - }, - }, - { - name: 'with string field flag and wrap-ttl flag', - args: [{ foo: 'bar', wrap_info: { one: 'two' } }, 'foo/bar', 'read', { field: 'one', wrapTTL: '1h' }], - expectedData: { - type: 'text', - content: 'two', - }, - }, - { - name: 'with object field flag and wrap-ttl flag', - args: [ - { foo: 'bar', wrap_info: { one: { two: 'three' } } }, - 'foo/bar', - 'read', - { field: 'one', wrapTTL: '1h' }, - ], - expectedData: { - type: 'object', - content: { two: 'three' }, - }, - }, - { - name: 'with response data and string field flag', - args: [{ foo: 'bar', data: { one: 'two' } }, 'foo/bar', 'read', { field: 'one', wrapTTL: '1h' }], - expectedData: { - type: 'text', - content: 'two', - }, - }, - { - name: 'with response data and object field flag ', - args: [ - { foo: 'bar', data: { one: { two: 'three' } } }, - 'foo/bar', - 'read', - { field: 'one', wrapTTL: '1h' }, - ], - expectedData: { - type: 'object', - content: { two: 'three' }, - }, - }, - { - name: 'response with data', - args: [{ foo: 'bar', data: { one: 'two' } }, 'foo/bar', 'read', {}], - expectedData: { - type: 'object', - content: { one: 'two' }, - }, - }, - { - name: 'with response data, field flag, and field missing', - args: [{ foo: 'bar', data: { one: 'two' } }, 'foo/bar', 'read', { field: 'foo' }], - expectedData: { - type: 'error', - content: 'Field "foo" not present in secret', - }, - }, - { - name: 'with response data and auth block', - args: [{ data: { one: 'two' }, auth: { three: 'four' } }, 'auth/token/create', 'write', {}], - expectedData: { - type: 'object', - content: { three: 'four' }, - }, - }, - { - name: 'with -field and -format with an object field', - args: [{ data: { one: { three: 'two' } } }, 'sys/mounts', 'read', { field: 'one', format: 'json' }], - expectedData: { - type: 'json', - content: { three: 'two' }, - }, - }, - { - name: 'with -field and -format with a string field', - args: [{ data: { one: 'two' } }, 'sys/mounts', 'read', { field: 'one', format: 'json' }], - expectedData: { - type: 'json', - content: 'two', - }, - }, -]; - -testResponseCases.forEach(function(testCase) { - test(`#logFromResponse: ${testCase.name}`, function(assert) { - let data = logFromResponse(...testCase.args); - assert.deepEqual(data, testCase.expectedData); - }); -}); - -let testErrorCases = [ - { - name: 'AdapterError write', - args: [{ httpStatus: 404, path: 'v1/sys/foo', errors: [{}] }, 'sys/foo', 'write'], - expectedContent: 'Error writing to: sys/foo.\nURL: v1/sys/foo\nCode: 404', - }, - { - name: 'AdapterError read', - args: [{ httpStatus: 404, path: 'v1/sys/foo', errors: [{}] }, 'sys/foo', 'read'], - expectedContent: 'Error reading from: sys/foo.\nURL: v1/sys/foo\nCode: 404', - }, - { - name: 'AdapterError list', - args: [{ httpStatus: 404, path: 'v1/sys/foo', errors: [{}] }, 'sys/foo', 'list'], - expectedContent: 'Error listing: sys/foo.\nURL: v1/sys/foo\nCode: 404', - }, - { - name: 'AdapterError delete', - args: [{ httpStatus: 404, path: 'v1/sys/foo', errors: [{}] }, 'sys/foo', 'delete'], - expectedContent: 'Error deleting at: sys/foo.\nURL: v1/sys/foo\nCode: 404', - }, - { - name: 'VaultError single error', - args: [{ httpStatus: 404, path: 'v1/sys/foo', errors: ['no client token'] }, 'sys/foo', 'delete'], - expectedContent: 'Error deleting at: sys/foo.\nURL: v1/sys/foo\nCode: 404\nErrors:\n no client token', - }, - { - name: 'VaultErrors multiple errors', - args: [ - { httpStatus: 404, path: 'v1/sys/foo', errors: ['no client token', 'this is an error'] }, - 'sys/foo', - 'delete', - ], - expectedContent: - 'Error deleting at: sys/foo.\nURL: v1/sys/foo\nCode: 404\nErrors:\n no client token\n this is an error', - }, -]; - -testErrorCases.forEach(function(testCase) { - test(`#logFromError: ${testCase.name}`, function(assert) { - let data = logFromError(...testCase.args); - assert.deepEqual(data, { type: 'error', content: testCase.expectedContent }, 'returns the expected data'); - }); -}); - -const testCommandCases = [ - { - name: 'errors when command does not include a path', - args: [], - expectedContent: 'A path is required to make a request.', - }, - { - name: 'errors when write command does not include data and does not have force tag', - args: ['foo/bar', 'write', {}, []], - expectedContent: 'Must supply data or use -force', - }, -]; - -testCommandCases.forEach(function(testCase) { - test(`#logErrorFromInput: ${testCase.name}`, function(assert) { - let data = logErrorFromInput(...testCase.args); - - assert.deepEqual(data, { type: 'error', content: testCase.expectedContent }, 'returns the pcorrect data'); + testExtractCases.forEach(function(testCase) { + test(`#extractDataAndFlags: ${testCase.name}`, function(assert) { + let { data, flags } = extractDataAndFlags(...testCase.input); + assert.deepEqual(data, testCase.expected.data, 'has expected data'); + assert.deepEqual(flags, testCase.expected.flags, 'has expected flags'); + }); + }); + + let testResponseCases = [ + { + name: 'write response, no content', + args: [null, 'foo/bar', 'write', {}], + expectedData: { + type: 'success', + content: 'Success! Data written to: foo/bar', + }, + }, + { + name: 'delete response, no content', + args: [null, 'foo/bar', 'delete', {}], + expectedData: { + type: 'success', + content: 'Success! Data deleted (if it existed) at: foo/bar', + }, + }, + { + name: 'write, with content', + args: [{ data: { one: 'two' } }, 'foo/bar', 'write', {}], + expectedData: { + type: 'object', + content: { one: 'two' }, + }, + }, + { + name: 'with wrap-ttl flag', + args: [{ wrap_info: { one: 'two' } }, 'foo/bar', 'read', { wrapTTL: '1h' }], + expectedData: { + type: 'object', + content: { one: 'two' }, + }, + }, + { + name: 'with -format=json flag and wrap-ttl flag', + args: [{ foo: 'bar', wrap_info: { one: 'two' } }, 'foo/bar', 'read', { format: 'json', wrapTTL: '1h' }], + expectedData: { + type: 'json', + content: { foo: 'bar', wrap_info: { one: 'two' } }, + }, + }, + { + name: 'with -format=json and -field flags', + args: [{ foo: 'bar', data: { one: 'two' } }, 'foo/bar', 'read', { format: 'json', field: 'one' }], + expectedData: { + type: 'json', + content: 'two', + }, + }, + { + name: 'with -format=json and -field, and -wrap-ttl flags', + args: [ + { foo: 'bar', wrap_info: { one: 'two' } }, + 'foo/bar', + 'read', + { format: 'json', wrapTTL: '1h', field: 'one' }, + ], + expectedData: { + type: 'json', + content: 'two', + }, + }, + { + name: 'with string field flag and wrap-ttl flag', + args: [{ foo: 'bar', wrap_info: { one: 'two' } }, 'foo/bar', 'read', { field: 'one', wrapTTL: '1h' }], + expectedData: { + type: 'text', + content: 'two', + }, + }, + { + name: 'with object field flag and wrap-ttl flag', + args: [ + { foo: 'bar', wrap_info: { one: { two: 'three' } } }, + 'foo/bar', + 'read', + { field: 'one', wrapTTL: '1h' }, + ], + expectedData: { + type: 'object', + content: { two: 'three' }, + }, + }, + { + name: 'with response data and string field flag', + args: [{ foo: 'bar', data: { one: 'two' } }, 'foo/bar', 'read', { field: 'one', wrapTTL: '1h' }], + expectedData: { + type: 'text', + content: 'two', + }, + }, + { + name: 'with response data and object field flag ', + args: [ + { foo: 'bar', data: { one: { two: 'three' } } }, + 'foo/bar', + 'read', + { field: 'one', wrapTTL: '1h' }, + ], + expectedData: { + type: 'object', + content: { two: 'three' }, + }, + }, + { + name: 'response with data', + args: [{ foo: 'bar', data: { one: 'two' } }, 'foo/bar', 'read', {}], + expectedData: { + type: 'object', + content: { one: 'two' }, + }, + }, + { + name: 'with response data, field flag, and field missing', + args: [{ foo: 'bar', data: { one: 'two' } }, 'foo/bar', 'read', { field: 'foo' }], + expectedData: { + type: 'error', + content: 'Field "foo" not present in secret', + }, + }, + { + name: 'with response data and auth block', + args: [{ data: { one: 'two' }, auth: { three: 'four' } }, 'auth/token/create', 'write', {}], + expectedData: { + type: 'object', + content: { three: 'four' }, + }, + }, + { + name: 'with -field and -format with an object field', + args: [{ data: { one: { three: 'two' } } }, 'sys/mounts', 'read', { field: 'one', format: 'json' }], + expectedData: { + type: 'json', + content: { three: 'two' }, + }, + }, + { + name: 'with -field and -format with a string field', + args: [{ data: { one: 'two' } }, 'sys/mounts', 'read', { field: 'one', format: 'json' }], + expectedData: { + type: 'json', + content: 'two', + }, + }, + ]; + + testResponseCases.forEach(function(testCase) { + test(`#logFromResponse: ${testCase.name}`, function(assert) { + let data = logFromResponse(...testCase.args); + assert.deepEqual(data, testCase.expectedData); + }); + }); + + let testErrorCases = [ + { + name: 'AdapterError write', + args: [{ httpStatus: 404, path: 'v1/sys/foo', errors: [{}] }, 'sys/foo', 'write'], + expectedContent: 'Error writing to: sys/foo.\nURL: v1/sys/foo\nCode: 404', + }, + { + name: 'AdapterError read', + args: [{ httpStatus: 404, path: 'v1/sys/foo', errors: [{}] }, 'sys/foo', 'read'], + expectedContent: 'Error reading from: sys/foo.\nURL: v1/sys/foo\nCode: 404', + }, + { + name: 'AdapterError list', + args: [{ httpStatus: 404, path: 'v1/sys/foo', errors: [{}] }, 'sys/foo', 'list'], + expectedContent: 'Error listing: sys/foo.\nURL: v1/sys/foo\nCode: 404', + }, + { + name: 'AdapterError delete', + args: [{ httpStatus: 404, path: 'v1/sys/foo', errors: [{}] }, 'sys/foo', 'delete'], + expectedContent: 'Error deleting at: sys/foo.\nURL: v1/sys/foo\nCode: 404', + }, + { + name: 'VaultError single error', + args: [{ httpStatus: 404, path: 'v1/sys/foo', errors: ['no client token'] }, 'sys/foo', 'delete'], + expectedContent: 'Error deleting at: sys/foo.\nURL: v1/sys/foo\nCode: 404\nErrors:\n no client token', + }, + { + name: 'VaultErrors multiple errors', + args: [ + { httpStatus: 404, path: 'v1/sys/foo', errors: ['no client token', 'this is an error'] }, + 'sys/foo', + 'delete', + ], + expectedContent: + 'Error deleting at: sys/foo.\nURL: v1/sys/foo\nCode: 404\nErrors:\n no client token\n this is an error', + }, + ]; + + testErrorCases.forEach(function(testCase) { + test(`#logFromError: ${testCase.name}`, function(assert) { + let data = logFromError(...testCase.args); + assert.deepEqual( + data, + { type: 'error', content: testCase.expectedContent }, + 'returns the expected data' + ); + }); + }); + + const testCommandCases = [ + { + name: 'errors when command does not include a path', + args: [], + expectedContent: 'A path is required to make a request.', + }, + { + name: 'errors when write command does not include data and does not have force tag', + args: ['foo/bar', 'write', {}, []], + expectedContent: 'Must supply data or use -force', + }, + ]; + + testCommandCases.forEach(function(testCase) { + test(`#logErrorFromInput: ${testCase.name}`, function(assert) { + let data = logErrorFromInput(...testCase.args); + + assert.deepEqual( + data, + { type: 'error', content: testCase.expectedContent }, + 'returns the pcorrect data' + ); + }); }); }); diff --git a/ui/tests/unit/lib/kv-object-test.js b/ui/tests/unit/lib/kv-object-test.js index 6192bcd59..7cf03f189 100644 --- a/ui/tests/unit/lib/kv-object-test.js +++ b/ui/tests/unit/lib/kv-object-test.js @@ -1,102 +1,102 @@ import { module, test } from 'qunit'; import KVObject from 'vault/lib/kv-object'; -module('lib/kv-object', 'Unit | Lib | kv object'); - -let fromJSONTests = [ - [ - 'types', - { string: 'string', false: false, zero: 0, number: 1, null: null, true: true, object: { one: 'two' } }, +module('Unit | Lib | kv object', function() { + let fromJSONTests = [ [ - { name: 'false', value: false }, - { name: 'null', value: null }, - { name: 'number', value: 1 }, - { name: 'object', value: { one: 'two' } }, - { name: 'string', value: 'string' }, - { name: 'true', value: true }, - { name: 'zero', value: 0 }, + 'types', + { string: 'string', false: false, zero: 0, number: 1, null: null, true: true, object: { one: 'two' } }, + [ + { name: 'false', value: false }, + { name: 'null', value: null }, + { name: 'number', value: 1 }, + { name: 'object', value: { one: 'two' } }, + { name: 'string', value: 'string' }, + { name: 'true', value: true }, + { name: 'zero', value: 0 }, + ], ], - ], - [ - 'ordering', - { b: 'b', '1': '1', z: 'z', A: 'A', a: 'a' }, [ - { name: '1', value: '1' }, - { name: 'a', value: 'a' }, - { name: 'A', value: 'A' }, - { name: 'b', value: 'b' }, - { name: 'z', value: 'z' }, + 'ordering', + { b: 'b', '1': '1', z: 'z', A: 'A', a: 'a' }, + [ + { name: '1', value: '1' }, + { name: 'a', value: 'a' }, + { name: 'A', value: 'A' }, + { name: 'b', value: 'b' }, + { name: 'z', value: 'z' }, + ], ], - ], -]; + ]; -fromJSONTests.forEach(function([name, input, content]) { - test(`fromJSON: ${name}`, function(assert) { - let data = KVObject.create({ content: [] }).fromJSON(input); - assert.deepEqual(data.get('content'), content, 'has expected content'); - }); -}); - -test(`fromJSON: non-object input`, function(assert) { - let input = [{ foo: 'bar' }]; - assert.throws( - () => { - KVObject.create({ content: [] }).fromJSON(input); - }, - /Vault expects data to be formatted as an JSON object/, - 'throws when non-object input is used to construct the KVObject' - ); -}); - -fromJSONTests.forEach(function([name, input, content]) { - test(`fromJSONString: ${name}`, function(assert) { - let inputString = JSON.stringify(input, null, 2); - let data = KVObject.create({ content: [] }).fromJSONString(inputString); - assert.deepEqual(data.get('content'), content, 'has expected content'); - }); -}); - -let toJSONTests = [ - [ - 'types', - false, - { string: 'string', false: false, zero: 0, number: 1, null: null, true: true, object: { one: 'two' } }, - { false: false, null: null, number: 1, object: { one: 'two' }, string: 'string', true: true, zero: 0 }, - ], - ['include blanks = true', true, { string: 'string', '': '' }, { string: 'string', '': '' }], - ['include blanks = false', false, { string: 'string', '': '' }, { string: 'string' }], -]; - -toJSONTests.forEach(function([name, includeBlanks, input, output]) { - test(`toJSON: ${name}`, function(assert) { - let data = KVObject.create({ content: [] }).fromJSON(input); - let result = data.toJSON(includeBlanks); - assert.deepEqual(result, output, 'has expected output'); - }); -}); - -toJSONTests.forEach(function([name, includeBlanks, input, output]) { - test(`toJSONString: ${name}`, function(assert) { - let expected = JSON.stringify(output, null, 2); - let data = KVObject.create({ content: [] }).fromJSON(input); - let result = data.toJSONString(includeBlanks); - assert.equal(result, expected, 'has expected output string'); - }); -}); - -let isAdvancedTests = [ - [ - 'advanced', - { string: 'string', false: false, zero: 0, number: 1, null: null, true: true, object: { one: 'two' } }, - true, - ], - ['string-only', { string: 'string', one: 'two' }, false], -]; - -isAdvancedTests.forEach(function([name, input, expected]) { - test(`isAdvanced: ${name}`, function(assert) { - let data = KVObject.create({ content: [] }).fromJSON(input); - - assert.equal(data.isAdvanced(), expected, 'calculates isAdvanced correctly'); + fromJSONTests.forEach(function([name, input, content]) { + test(`fromJSON: ${name}`, function(assert) { + let data = KVObject.create({ content: [] }).fromJSON(input); + assert.deepEqual(data.get('content'), content, 'has expected content'); + }); + }); + + test(`fromJSON: non-object input`, function(assert) { + let input = [{ foo: 'bar' }]; + assert.throws( + () => { + KVObject.create({ content: [] }).fromJSON(input); + }, + /Vault expects data to be formatted as an JSON object/, + 'throws when non-object input is used to construct the KVObject' + ); + }); + + fromJSONTests.forEach(function([name, input, content]) { + test(`fromJSONString: ${name}`, function(assert) { + let inputString = JSON.stringify(input, null, 2); + let data = KVObject.create({ content: [] }).fromJSONString(inputString); + assert.deepEqual(data.get('content'), content, 'has expected content'); + }); + }); + + let toJSONTests = [ + [ + 'types', + false, + { string: 'string', false: false, zero: 0, number: 1, null: null, true: true, object: { one: 'two' } }, + { false: false, null: null, number: 1, object: { one: 'two' }, string: 'string', true: true, zero: 0 }, + ], + ['include blanks = true', true, { string: 'string', '': '' }, { string: 'string', '': '' }], + ['include blanks = false', false, { string: 'string', '': '' }, { string: 'string' }], + ]; + + toJSONTests.forEach(function([name, includeBlanks, input, output]) { + test(`toJSON: ${name}`, function(assert) { + let data = KVObject.create({ content: [] }).fromJSON(input); + let result = data.toJSON(includeBlanks); + assert.deepEqual(result, output, 'has expected output'); + }); + }); + + toJSONTests.forEach(function([name, includeBlanks, input, output]) { + test(`toJSONString: ${name}`, function(assert) { + let expected = JSON.stringify(output, null, 2); + let data = KVObject.create({ content: [] }).fromJSON(input); + let result = data.toJSONString(includeBlanks); + assert.equal(result, expected, 'has expected output string'); + }); + }); + + let isAdvancedTests = [ + [ + 'advanced', + { string: 'string', false: false, zero: 0, number: 1, null: null, true: true, object: { one: 'two' } }, + true, + ], + ['string-only', { string: 'string', one: 'two' }, false], + ]; + + isAdvancedTests.forEach(function([name, input, expected]) { + test(`isAdvanced: ${name}`, function(assert) { + let data = KVObject.create({ content: [] }).fromJSON(input); + + assert.equal(data.isAdvanced(), expected, 'calculates isAdvanced correctly'); + }); }); }); diff --git a/ui/tests/unit/lib/path-to-tree-test.js b/ui/tests/unit/lib/path-to-tree-test.js index 5fd8796a4..4c7788dab 100644 --- a/ui/tests/unit/lib/path-to-tree-test.js +++ b/ui/tests/unit/lib/path-to-tree-test.js @@ -1,60 +1,60 @@ import { module, test } from 'qunit'; import pathToTree from 'vault/lib/path-to-tree'; -module('lib/path-to-tree', 'Unit | Lib | path to tree'); - -let tests = [ - [ - 'basic', - ['one', 'one/two', 'one/two/three/four/five'], - { - one: { - two: { - three: { - four: { - five: null, +module('Unit | Lib | path to tree', function() { + let tests = [ + [ + 'basic', + ['one', 'one/two', 'one/two/three/four/five'], + { + one: { + two: { + three: { + four: { + five: null, + }, }, }, }, }, - }, - ], - [ - 'multiple leaves on a level', - ['one', 'two', 'three/four/five', 'three/four/six', 'three/four/six/one'], - { - one: null, - three: { - four: { - five: null, - six: { - one: null, + ], + [ + 'multiple leaves on a level', + ['one', 'two', 'three/four/five', 'three/four/six', 'three/four/six/one'], + { + one: null, + three: { + four: { + five: null, + six: { + one: null, + }, + }, + }, + two: null, + }, + ], + [ + 'leaves with shared prefix', + ['ns1', 'ns1a', 'ns1a/ns2/ns3', 'ns1a/ns2a/ns3'], + { + ns1: null, + ns1a: { + ns2: { + ns3: null, + }, + ns2a: { + ns3: null, }, }, }, - two: null, - }, - ], - [ - 'leaves with shared prefix', - ['ns1', 'ns1a', 'ns1a/ns2/ns3', 'ns1a/ns2a/ns3'], - { - ns1: null, - ns1a: { - ns2: { - ns3: null, - }, - ns2a: { - ns3: null, - }, - }, - }, - ], -]; + ], + ]; -tests.forEach(function([name, input, expected]) { - test(`pathToTree: ${name}`, function(assert) { - let output = pathToTree(input); - assert.deepEqual(output, expected, 'has expected data'); + tests.forEach(function([name, input, expected]) { + test(`pathToTree: ${name}`, function(assert) { + let output = pathToTree(input); + assert.deepEqual(output, expected, 'has expected data'); + }); }); }); diff --git a/ui/tests/unit/mixins/cluster-route-test.js b/ui/tests/unit/mixins/cluster-route-test.js index 01e4d32c7..9c7671bdd 100644 --- a/ui/tests/unit/mixins/cluster-route-test.js +++ b/ui/tests/unit/mixins/cluster-route-test.js @@ -1,79 +1,83 @@ -import Ember from 'ember'; +import { assign } from '@ember/polyfills'; +import EmberObject from '@ember/object'; import ClusterRouteMixin from 'vault/mixins/cluster-route'; import { INIT, UNSEAL, AUTH, CLUSTER, DR_REPLICATION_SECONDARY } from 'vault/mixins/cluster-route'; import { module, test } from 'qunit'; -module('Unit | Mixin | cluster route'); +module('Unit | Mixin | cluster route', function() { + function createClusterRoute( + clusterModel = {}, + methods = { hasKeyData: () => false, authToken: () => null } + ) { + let ClusterRouteObject = EmberObject.extend( + ClusterRouteMixin, + assign(methods, { clusterModel: () => clusterModel }) + ); + return ClusterRouteObject.create(); + } -function createClusterRoute(clusterModel = {}, methods = { hasKeyData: () => false, authToken: () => null }) { - let ClusterRouteObject = Ember.Object.extend( - ClusterRouteMixin, - Ember.assign(methods, { clusterModel: () => clusterModel }) - ); - return ClusterRouteObject.create(); -} + test('#targetRouteName init', function(assert) { + let subject = createClusterRoute({ needsInit: true }); + subject.routeName = CLUSTER; + assert.equal(subject.targetRouteName(), INIT, 'forwards to INIT when cluster needs init'); -test('#targetRouteName init', function(assert) { - let subject = createClusterRoute({ needsInit: true }); - subject.routeName = CLUSTER; - assert.equal(subject.targetRouteName(), INIT, 'forwards to INIT when cluster needs init'); + subject = createClusterRoute({ needsInit: false, sealed: true }); + subject.routeName = CLUSTER; + assert.equal(subject.targetRouteName(), UNSEAL, 'forwards to UNSEAL if sealed and initialized'); - subject = createClusterRoute({ needsInit: false, sealed: true }); - subject.routeName = CLUSTER; - assert.equal(subject.targetRouteName(), UNSEAL, 'forwards to UNSEAL if sealed and initialized'); + subject = createClusterRoute({ needsInit: false }); + subject.routeName = CLUSTER; + assert.equal(subject.targetRouteName(), AUTH, 'forwards to AUTH if unsealed and initialized'); - subject = createClusterRoute({ needsInit: false }); - subject.routeName = CLUSTER; - assert.equal(subject.targetRouteName(), AUTH, 'forwards to AUTH if unsealed and initialized'); + subject = createClusterRoute({ dr: { isSecondary: true } }); + subject.routeName = CLUSTER; + assert.equal( + subject.targetRouteName(), + DR_REPLICATION_SECONDARY, + 'forwards to DR_REPLICATION_SECONDARY if is a dr secondary' + ); + }); - subject = createClusterRoute({ dr: { isSecondary: true } }); - subject.routeName = CLUSTER; - assert.equal( - subject.targetRouteName(), - DR_REPLICATION_SECONDARY, - 'forwards to DR_REPLICATION_SECONDARY if is a dr secondary' - ); -}); - -test('#targetRouteName when #hasDataKey is true', function(assert) { - let subject = createClusterRoute( - { needsInit: false, sealed: true }, - { hasKeyData: () => true, authToken: () => null } - ); - - subject.routeName = CLUSTER; - assert.equal(subject.targetRouteName(), INIT, 'still land on INIT if there are keys on the controller'); - - subject.routeName = UNSEAL; - assert.equal(subject.targetRouteName(), UNSEAL, 'allowed to proceed to unseal'); - - subject = createClusterRoute( - { needsInit: false, sealed: false }, - { hasKeyData: () => true, authToken: () => null } - ); - - subject.routeName = AUTH; - assert.equal(subject.targetRouteName(), AUTH, 'allowed to proceed to auth'); -}); - -test('#targetRouteName happy path forwards to CLUSTER route', function(assert) { - let subject = createClusterRoute( - { needsInit: false, sealed: false, dr: { isSecondary: false } }, - { hasKeyData: () => false, authToken: () => 'a token' } - ); - subject.routeName = INIT; - assert.equal(subject.targetRouteName(), CLUSTER, 'forwards when inited and navigating to INIT'); - - subject.routeName = UNSEAL; - assert.equal(subject.targetRouteName(), CLUSTER, 'forwards when unsealed and navigating to UNSEAL'); - - subject.routeName = AUTH; - assert.equal(subject.targetRouteName(), CLUSTER, 'forwards when authenticated and navigating to AUTH'); - - subject.routeName = DR_REPLICATION_SECONDARY; - assert.equal( - subject.targetRouteName(), - CLUSTER, - 'forwards when not a DR secondary and navigating to DR_REPLICATION_SECONDARY' - ); + test('#targetRouteName when #hasDataKey is true', function(assert) { + let subject = createClusterRoute( + { needsInit: false, sealed: true }, + { hasKeyData: () => true, authToken: () => null } + ); + + subject.routeName = CLUSTER; + assert.equal(subject.targetRouteName(), INIT, 'still land on INIT if there are keys on the controller'); + + subject.routeName = UNSEAL; + assert.equal(subject.targetRouteName(), UNSEAL, 'allowed to proceed to unseal'); + + subject = createClusterRoute( + { needsInit: false, sealed: false }, + { hasKeyData: () => true, authToken: () => null } + ); + + subject.routeName = AUTH; + assert.equal(subject.targetRouteName(), AUTH, 'allowed to proceed to auth'); + }); + + test('#targetRouteName happy path forwards to CLUSTER route', function(assert) { + let subject = createClusterRoute( + { needsInit: false, sealed: false, dr: { isSecondary: false } }, + { hasKeyData: () => false, authToken: () => 'a token' } + ); + subject.routeName = INIT; + assert.equal(subject.targetRouteName(), CLUSTER, 'forwards when inited and navigating to INIT'); + + subject.routeName = UNSEAL; + assert.equal(subject.targetRouteName(), CLUSTER, 'forwards when unsealed and navigating to UNSEAL'); + + subject.routeName = AUTH; + assert.equal(subject.targetRouteName(), CLUSTER, 'forwards when authenticated and navigating to AUTH'); + + subject.routeName = DR_REPLICATION_SECONDARY; + assert.equal( + subject.targetRouteName(), + CLUSTER, + 'forwards when not a DR secondary and navigating to DR_REPLICATION_SECONDARY' + ); + }); }); diff --git a/ui/tests/unit/models/capabilities-test.js b/ui/tests/unit/models/capabilities-test.js index 1caa7efbb..fdd545022 100644 --- a/ui/tests/unit/models/capabilities-test.js +++ b/ui/tests/unit/models/capabilities-test.js @@ -1,71 +1,84 @@ -import { moduleForModel, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import { SUDO_PATHS, SUDO_PATH_PREFIXES } from 'vault/models/capabilities'; -moduleForModel('capabilities', 'Unit | Model | capabilities', { - needs: ['transform:array'], -}); +import { run } from '@ember/runloop'; -test('it exists', function(assert) { - let model = this.subject(); - assert.ok(!!model); -}); +module('Unit | Model | capabilities', function(hooks) { + setupTest(hooks); -test('it reads capabilities', function(assert) { - let model = this.subject({ - path: 'foo', - capabilities: ['list', 'read'], + test('it exists', function(assert) { + let model = run(() => this.owner.lookup('service:store').createRecord('capabilities')); + assert.ok(!!model); }); - assert.ok(model.get('canRead')); - assert.ok(model.get('canList')); - assert.notOk(model.get('canUpdate')); - assert.notOk(model.get('canDelete')); -}); + test('it reads capabilities', function(assert) { + let model = run(() => + this.owner.lookup('service:store').createRecord('capabilities', { + path: 'foo', + capabilities: ['list', 'read'], + }) + ); -test('it allows everything if root is present', function(assert) { - let model = this.subject({ - path: 'foo', - capabilities: ['root', 'deny', 'read'], + assert.ok(model.get('canRead')); + assert.ok(model.get('canList')); + assert.notOk(model.get('canUpdate')); + assert.notOk(model.get('canDelete')); }); - assert.ok(model.get('canRead')); - assert.ok(model.get('canCreate')); - assert.ok(model.get('canUpdate')); - assert.ok(model.get('canDelete')); - assert.ok(model.get('canList')); -}); -test('it denies everything if deny is present', function(assert) { - let model = this.subject({ - path: 'foo', - capabilities: ['sudo', 'deny', 'read'], + test('it allows everything if root is present', function(assert) { + let model = run(() => + this.owner.lookup('service:store').createRecord('capabilities', { + path: 'foo', + capabilities: ['root', 'deny', 'read'], + }) + ); + assert.ok(model.get('canRead')); + assert.ok(model.get('canCreate')); + assert.ok(model.get('canUpdate')); + assert.ok(model.get('canDelete')); + assert.ok(model.get('canList')); }); - assert.notOk(model.get('canRead')); - assert.notOk(model.get('canCreate')); - assert.notOk(model.get('canUpdate')); - assert.notOk(model.get('canDelete')); - assert.notOk(model.get('canList')); -}); -test('it requires sudo on sudo paths', function(assert) { - let model = this.subject({ - path: SUDO_PATHS[0], - capabilities: ['sudo', 'read'], + test('it denies everything if deny is present', function(assert) { + let model = run(() => + this.owner.lookup('service:store').createRecord('capabilities', { + path: 'foo', + capabilities: ['sudo', 'deny', 'read'], + }) + ); + assert.notOk(model.get('canRead')); + assert.notOk(model.get('canCreate')); + assert.notOk(model.get('canUpdate')); + assert.notOk(model.get('canDelete')); + assert.notOk(model.get('canList')); }); - assert.ok(model.get('canRead')); - assert.notOk(model.get('canCreate'), 'sudo requires the capability to be set as well'); - assert.notOk(model.get('canUpdate')); - assert.notOk(model.get('canDelete')); - assert.notOk(model.get('canList')); -}); -test('it requires sudo on sudo paths prefixes', function(assert) { - let model = this.subject({ - path: SUDO_PATH_PREFIXES[0] + '/foo', - capabilities: ['sudo', 'read'], + test('it requires sudo on sudo paths', function(assert) { + let model = run(() => + this.owner.lookup('service:store').createRecord('capabilities', { + path: SUDO_PATHS[0], + capabilities: ['sudo', 'read'], + }) + ); + assert.ok(model.get('canRead')); + assert.notOk(model.get('canCreate'), 'sudo requires the capability to be set as well'); + assert.notOk(model.get('canUpdate')); + assert.notOk(model.get('canDelete')); + assert.notOk(model.get('canList')); + }); + + test('it requires sudo on sudo paths prefixes', function(assert) { + let model = run(() => + this.owner.lookup('service:store').createRecord('capabilities', { + path: SUDO_PATH_PREFIXES[0] + '/foo', + capabilities: ['sudo', 'read'], + }) + ); + assert.ok(model.get('canRead')); + assert.notOk(model.get('canCreate'), 'sudo requires the capability to be set as well'); + assert.notOk(model.get('canUpdate')); + assert.notOk(model.get('canDelete')); + assert.notOk(model.get('canList')); }); - assert.ok(model.get('canRead')); - assert.notOk(model.get('canCreate'), 'sudo requires the capability to be set as well'); - assert.notOk(model.get('canUpdate')); - assert.notOk(model.get('canDelete')); - assert.notOk(model.get('canList')); }); diff --git a/ui/tests/unit/models/secret-engine-test.js b/ui/tests/unit/models/secret-engine-test.js index 58215a303..b40ffa56a 100644 --- a/ui/tests/unit/models/secret-engine-test.js +++ b/ui/tests/unit/models/secret-engine-test.js @@ -1,36 +1,41 @@ -import { moduleForModel, test } from 'ember-qunit'; -import Ember from 'ember'; +import { run } from '@ember/runloop'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -moduleForModel('secret-engine', 'Unit | Model | secret-engine', { - needs: ['model:mount-options'], -}); +module('Unit | Model | secret-engine', function(hooks) { + setupTest(hooks); -test('modelTypeForKV is secret by default', function(assert) { - let model; - Ember.run(() => { - model = this.subject(); - assert.equal(model.get('modelTypeForKV'), 'secret'); - }); -}); - -test('modelTypeForKV is secret-v2 for kv v2', function(assert) { - let model; - Ember.run(() => { - model = this.subject({ - options: { version: 2 }, - type: 'kv', + test('modelTypeForKV is secret by default', function(assert) { + let model; + run(() => { + model = run(() => this.owner.lookup('service:store').createRecord('secret-engine')); + assert.equal(model.get('modelTypeForKV'), 'secret'); }); - assert.equal(model.get('modelTypeForKV'), 'secret-v2'); }); -}); -test('modelTypeForKV is secret-v2 for generic v2', function(assert) { - let model; - Ember.run(() => { - model = this.subject({ - options: { version: 2 }, - type: 'kv', + test('modelTypeForKV is secret-v2 for kv v2', function(assert) { + let model; + run(() => { + model = run(() => + this.owner.lookup('service:store').createRecord('secret-engine', { + options: { version: 2 }, + type: 'kv', + }) + ); + assert.equal(model.get('modelTypeForKV'), 'secret-v2'); + }); + }); + + test('modelTypeForKV is secret-v2 for generic v2', function(assert) { + let model; + run(() => { + model = run(() => + this.owner.lookup('service:store').createRecord('secret-engine', { + options: { version: 2 }, + type: 'kv', + }) + ); + assert.equal(model.get('modelTypeForKV'), 'secret-v2'); }); - assert.equal(model.get('modelTypeForKV'), 'secret-v2'); }); }); diff --git a/ui/tests/unit/models/transit-key-test.js b/ui/tests/unit/models/transit-key-test.js index ef4e7e951..3917bb8ee 100644 --- a/ui/tests/unit/models/transit-key-test.js +++ b/ui/tests/unit/models/transit-key-test.js @@ -1,60 +1,69 @@ -import Ember from 'ember'; -import { moduleForModel, test } from 'ember-qunit'; +import { run } from '@ember/runloop'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -moduleForModel('transit-key', 'Unit | Model | transit key'); +module('Unit | Model | transit key', function(hooks) { + setupTest(hooks); -test('it exists', function(assert) { - let model = this.subject(); - assert.ok(!!model); -}); - -test('supported actions', function(assert) { - let model = this.subject({ - supportsEncryption: true, - supportsDecryption: true, - supportsSigning: false, + test('it exists', function(assert) { + let model = run(() => this.owner.lookup('service:store').createRecord('transit-key')); + assert.ok(!!model); }); - let supportedActions = model.get('supportedActions'); - assert.deepEqual(['encrypt', 'decrypt', 'datakey', 'rewrap', 'hmac', 'verify'], supportedActions); -}); - -test('encryption key versions', function(assert) { - let done = assert.async(); - let model = this.subject({ - keyVersions: [1, 2, 3, 4, 5], - minDecryptionVersion: 1, - latestVersion: 5, - }); - assert.deepEqual([5, 4, 3, 2, 1], model.get('encryptionKeyVersions'), 'lists all available versions'); - Ember.run(() => { - model.set('minDecryptionVersion', 3); - assert.deepEqual( - [5, 4, 3], - model.get('encryptionKeyVersions'), - 'adjusts to a change in minDecryptionVersion' + test('supported actions', function(assert) { + let model = run(() => + this.owner.lookup('service:store').createRecord('transit-key', { + supportsEncryption: true, + supportsDecryption: true, + supportsSigning: false, + }) ); - done(); - }); -}); - -test('keys for encryption', function(assert) { - let done = assert.async(); - let model = this.subject({ - keyVersions: [1, 2, 3, 4, 5], - minDecryptionVersion: 1, - latestVersion: 5, - }); - - assert.deepEqual( - [5, 4, 3, 2, 1], - model.get('keysForEncryption'), - 'lists all available versions when no min is set' - ); - - Ember.run(() => { - model.set('minEncryptionVersion', 4); - assert.deepEqual([5, 4], model.get('keysForEncryption'), 'calculates using minEncryptionVersion'); - done(); + + let supportedActions = model.get('supportedActions'); + assert.deepEqual(['encrypt', 'decrypt', 'datakey', 'rewrap', 'hmac', 'verify'], supportedActions); + }); + + test('encryption key versions', function(assert) { + let done = assert.async(); + let model = run(() => + this.owner.lookup('service:store').createRecord('transit-key', { + keyVersions: [1, 2, 3, 4, 5], + minDecryptionVersion: 1, + latestVersion: 5, + }) + ); + assert.deepEqual([5, 4, 3, 2, 1], model.get('encryptionKeyVersions'), 'lists all available versions'); + run(() => { + model.set('minDecryptionVersion', 3); + assert.deepEqual( + [5, 4, 3], + model.get('encryptionKeyVersions'), + 'adjusts to a change in minDecryptionVersion' + ); + done(); + }); + }); + + test('keys for encryption', function(assert) { + let done = assert.async(); + let model = run(() => + this.owner.lookup('service:store').createRecord('transit-key', { + keyVersions: [1, 2, 3, 4, 5], + minDecryptionVersion: 1, + latestVersion: 5, + }) + ); + + assert.deepEqual( + [5, 4, 3, 2, 1], + model.get('keysForEncryption'), + 'lists all available versions when no min is set' + ); + + run(() => { + model.set('minEncryptionVersion', 4); + assert.deepEqual([5, 4], model.get('keysForEncryption'), 'calculates using minEncryptionVersion'); + done(); + }); }); }); diff --git a/ui/tests/unit/serializers/policy-test.js b/ui/tests/unit/serializers/policy-test.js index 47f7f7c79..12d6c8a64 100644 --- a/ui/tests/unit/serializers/policy-test.js +++ b/ui/tests/unit/serializers/policy-test.js @@ -1,69 +1,72 @@ -import { moduleFor, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -moduleFor('serializer:policy', 'Unit | Serializer | policy'); +module('Unit | Serializer | policy', function(hooks) { + setupTest(hooks); -const POLICY_LIST_RESPONSE = { - keys: ['default', 'root'], - policies: ['default', 'root'], - request_id: '3a6a3d67-dc3b-a086-2fc7-902bdc4dec3a', - lease_id: '', - renewable: false, - lease_duration: 0, - data: { + const POLICY_LIST_RESPONSE = { keys: ['default', 'root'], policies: ['default', 'root'], - }, - wrap_info: null, - warnings: null, - auth: null, -}; + request_id: '3a6a3d67-dc3b-a086-2fc7-902bdc4dec3a', + lease_id: '', + renewable: false, + lease_duration: 0, + data: { + keys: ['default', 'root'], + policies: ['default', 'root'], + }, + wrap_info: null, + warnings: null, + auth: null, + }; -const EMBER_DATA_EXPECTS_FOR_POLICY_LIST = [{ name: 'default' }, { name: 'root' }]; + const EMBER_DATA_EXPECTS_FOR_POLICY_LIST = [{ name: 'default' }, { name: 'root' }]; -const POLICY_SHOW_RESPONSE = { - name: 'default', - rules: - '\n# Allow tokens to look up their own properties\npath "auth/token/lookup-self" {\n capabilities = ["read"]\n}\n\n# Allow tokens to renew themselves\npath "auth/token/renew-self" {\n capabilities = ["update"]\n}\n\n# Allow tokens to revoke themselves\npath "auth/token/revoke-self" {\n capabilities = ["update"]\n}\n\n# Allow a token to look up its own capabilities on a path\npath "sys/capabilities-self" {\n capabilities = ["update"]\n}\n\n# Allow a token to renew a lease via lease_id in the request body\npath "sys/renew" {\n capabilities = ["update"]\n}\n\n# Allow a token to manage its own cubbyhole\npath "cubbyhole/*" {\n capabilities = ["create", "read", "update", "delete", "list"]\n}\n\n# Allow a token to list its cubbyhole (not covered by the splat above)\npath "cubbyhole" {\n capabilities = ["list"]\n}\n\n# Allow a token to wrap arbitrary values in a response-wrapping token\npath "sys/wrapping/wrap" {\n capabilities = ["update"]\n}\n\n# Allow a token to look up the creation time and TTL of a given\n# response-wrapping token\npath "sys/wrapping/lookup" {\n capabilities = ["update"]\n}\n\n# Allow a token to unwrap a response-wrapping token. This is a convenience to\n# avoid client token swapping since this is also part of the response wrapping\n# policy.\npath "sys/wrapping/unwrap" {\n capabilities = ["update"]\n}\n', - request_id: '890eabf8-d418-07af-f978-928d328a7e64', - lease_id: '', - renewable: false, - lease_duration: 0, - data: { + const POLICY_SHOW_RESPONSE = { name: 'default', rules: '\n# Allow tokens to look up their own properties\npath "auth/token/lookup-self" {\n capabilities = ["read"]\n}\n\n# Allow tokens to renew themselves\npath "auth/token/renew-self" {\n capabilities = ["update"]\n}\n\n# Allow tokens to revoke themselves\npath "auth/token/revoke-self" {\n capabilities = ["update"]\n}\n\n# Allow a token to look up its own capabilities on a path\npath "sys/capabilities-self" {\n capabilities = ["update"]\n}\n\n# Allow a token to renew a lease via lease_id in the request body\npath "sys/renew" {\n capabilities = ["update"]\n}\n\n# Allow a token to manage its own cubbyhole\npath "cubbyhole/*" {\n capabilities = ["create", "read", "update", "delete", "list"]\n}\n\n# Allow a token to list its cubbyhole (not covered by the splat above)\npath "cubbyhole" {\n capabilities = ["list"]\n}\n\n# Allow a token to wrap arbitrary values in a response-wrapping token\npath "sys/wrapping/wrap" {\n capabilities = ["update"]\n}\n\n# Allow a token to look up the creation time and TTL of a given\n# response-wrapping token\npath "sys/wrapping/lookup" {\n capabilities = ["update"]\n}\n\n# Allow a token to unwrap a response-wrapping token. This is a convenience to\n# avoid client token swapping since this is also part of the response wrapping\n# policy.\npath "sys/wrapping/unwrap" {\n capabilities = ["update"]\n}\n', - }, - wrap_info: null, - warnings: null, - auth: null, -}; + request_id: '890eabf8-d418-07af-f978-928d328a7e64', + lease_id: '', + renewable: false, + lease_duration: 0, + data: { + name: 'default', + rules: + '\n# Allow tokens to look up their own properties\npath "auth/token/lookup-self" {\n capabilities = ["read"]\n}\n\n# Allow tokens to renew themselves\npath "auth/token/renew-self" {\n capabilities = ["update"]\n}\n\n# Allow tokens to revoke themselves\npath "auth/token/revoke-self" {\n capabilities = ["update"]\n}\n\n# Allow a token to look up its own capabilities on a path\npath "sys/capabilities-self" {\n capabilities = ["update"]\n}\n\n# Allow a token to renew a lease via lease_id in the request body\npath "sys/renew" {\n capabilities = ["update"]\n}\n\n# Allow a token to manage its own cubbyhole\npath "cubbyhole/*" {\n capabilities = ["create", "read", "update", "delete", "list"]\n}\n\n# Allow a token to list its cubbyhole (not covered by the splat above)\npath "cubbyhole" {\n capabilities = ["list"]\n}\n\n# Allow a token to wrap arbitrary values in a response-wrapping token\npath "sys/wrapping/wrap" {\n capabilities = ["update"]\n}\n\n# Allow a token to look up the creation time and TTL of a given\n# response-wrapping token\npath "sys/wrapping/lookup" {\n capabilities = ["update"]\n}\n\n# Allow a token to unwrap a response-wrapping token. This is a convenience to\n# avoid client token swapping since this is also part of the response wrapping\n# policy.\npath "sys/wrapping/unwrap" {\n capabilities = ["update"]\n}\n', + }, + wrap_info: null, + warnings: null, + auth: null, + }; -const EMBER_DATA_EXPECTS_FOR_POLICY_SHOW = { - name: 'default', - rules: - '\n# Allow tokens to look up their own properties\npath "auth/token/lookup-self" {\n capabilities = ["read"]\n}\n\n# Allow tokens to renew themselves\npath "auth/token/renew-self" {\n capabilities = ["update"]\n}\n\n# Allow tokens to revoke themselves\npath "auth/token/revoke-self" {\n capabilities = ["update"]\n}\n\n# Allow a token to look up its own capabilities on a path\npath "sys/capabilities-self" {\n capabilities = ["update"]\n}\n\n# Allow a token to renew a lease via lease_id in the request body\npath "sys/renew" {\n capabilities = ["update"]\n}\n\n# Allow a token to manage its own cubbyhole\npath "cubbyhole/*" {\n capabilities = ["create", "read", "update", "delete", "list"]\n}\n\n# Allow a token to list its cubbyhole (not covered by the splat above)\npath "cubbyhole" {\n capabilities = ["list"]\n}\n\n# Allow a token to wrap arbitrary values in a response-wrapping token\npath "sys/wrapping/wrap" {\n capabilities = ["update"]\n}\n\n# Allow a token to look up the creation time and TTL of a given\n# response-wrapping token\npath "sys/wrapping/lookup" {\n capabilities = ["update"]\n}\n\n# Allow a token to unwrap a response-wrapping token. This is a convenience to\n# avoid client token swapping since this is also part of the response wrapping\n# policy.\npath "sys/wrapping/unwrap" {\n capabilities = ["update"]\n}\n', -}; + const EMBER_DATA_EXPECTS_FOR_POLICY_SHOW = { + name: 'default', + rules: + '\n# Allow tokens to look up their own properties\npath "auth/token/lookup-self" {\n capabilities = ["read"]\n}\n\n# Allow tokens to renew themselves\npath "auth/token/renew-self" {\n capabilities = ["update"]\n}\n\n# Allow tokens to revoke themselves\npath "auth/token/revoke-self" {\n capabilities = ["update"]\n}\n\n# Allow a token to look up its own capabilities on a path\npath "sys/capabilities-self" {\n capabilities = ["update"]\n}\n\n# Allow a token to renew a lease via lease_id in the request body\npath "sys/renew" {\n capabilities = ["update"]\n}\n\n# Allow a token to manage its own cubbyhole\npath "cubbyhole/*" {\n capabilities = ["create", "read", "update", "delete", "list"]\n}\n\n# Allow a token to list its cubbyhole (not covered by the splat above)\npath "cubbyhole" {\n capabilities = ["list"]\n}\n\n# Allow a token to wrap arbitrary values in a response-wrapping token\npath "sys/wrapping/wrap" {\n capabilities = ["update"]\n}\n\n# Allow a token to look up the creation time and TTL of a given\n# response-wrapping token\npath "sys/wrapping/lookup" {\n capabilities = ["update"]\n}\n\n# Allow a token to unwrap a response-wrapping token. This is a convenience to\n# avoid client token swapping since this is also part of the response wrapping\n# policy.\npath "sys/wrapping/unwrap" {\n capabilities = ["update"]\n}\n', + }; -test('it transforms a list request payload', function(assert) { - let serializer = this.subject(); + test('it transforms a list request payload', function(assert) { + let serializer = this.owner.lookup('serializer:policy'); - let transformedPayload = serializer.normalizePolicies(POLICY_LIST_RESPONSE); + let transformedPayload = serializer.normalizePolicies(POLICY_LIST_RESPONSE); - assert.deepEqual( - transformedPayload, - EMBER_DATA_EXPECTS_FOR_POLICY_LIST, - 'transformed payload matches the expected payload' - ); -}); - -test('it transforms a list request payload', function(assert) { - let serializer = this.subject(); - - let transformedPayload = serializer.normalizePolicies(POLICY_SHOW_RESPONSE); - - assert.deepEqual( - transformedPayload, - EMBER_DATA_EXPECTS_FOR_POLICY_SHOW, - 'transformed payload matches the expected payload' - ); + assert.deepEqual( + transformedPayload, + EMBER_DATA_EXPECTS_FOR_POLICY_LIST, + 'transformed payload matches the expected payload' + ); + }); + + test('it transforms a list request payload', function(assert) { + let serializer = this.owner.lookup('serializer:policy'); + + let transformedPayload = serializer.normalizePolicies(POLICY_SHOW_RESPONSE); + + assert.deepEqual( + transformedPayload, + EMBER_DATA_EXPECTS_FOR_POLICY_SHOW, + 'transformed payload matches the expected payload' + ); + }); }); diff --git a/ui/tests/unit/services/auth-test.js b/ui/tests/unit/services/auth-test.js index 9518c7fce..2915f2836 100644 --- a/ui/tests/unit/services/auth-test.js +++ b/ui/tests/unit/services/auth-test.js @@ -1,6 +1,8 @@ -import { moduleFor, test } from 'ember-qunit'; +import { run } from '@ember/runloop'; +import { copy } from '@ember/object/internals'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import { TOKEN_SEPARATOR, TOKEN_PREFIX, ROOT_PREFIX } from 'vault/services/auth'; -import Ember from 'ember'; import Pretender from 'pretender'; function storage() { @@ -117,34 +119,29 @@ let GITHUB_RESPONSE = { }, }; -moduleFor('service:auth', 'Unit | Service | auth', { - needs: [ - 'service:flash-messages', - 'adapter:cluster', - 'service:version', - 'service:control-group', - 'service:namespace', - ], - beforeEach: function() { - Ember.getOwner(this).lookup('service:flash-messages').registerTypes(['warning']); +module('Unit | Service | auth', function(hooks) { + setupTest(hooks); + + hooks.beforeEach(function() { + this.owner.lookup('service:flash-messages').registerTypes(['warning']); this.store = storage(); this.memStore = storage(); this.server = new Pretender(function() { this.get('/v1/auth/token/lookup-self', function(request) { - let resp = Ember.copy(ROOT_TOKEN_RESPONSE, true); + let resp = copy(ROOT_TOKEN_RESPONSE, true); resp.id = request.requestHeaders['X-Vault-Token']; resp.data.id = request.requestHeaders['X-Vault-Token']; return [200, {}, resp]; }); this.post('/v1/auth/userpass/login/:username', function(request) { const { username } = request.params; - let resp = Ember.copy(USERPASS_RESPONSE, true); + let resp = copy(USERPASS_RESPONSE, true); resp.auth.metadata.username = username; return [200, {}, resp]; }); this.post('/v1/auth/github/login', function() { - let resp = Ember.copy(GITHUB_RESPONSE, true); + let resp = copy(GITHUB_RESPONSE, true); return [200, {}, resp]; }); }); @@ -157,187 +154,190 @@ moduleFor('service:auth', 'Unit | Service | auth', { headers['content-type'] = 'application/javascript'; return headers; }; - }, + }); - afterEach: function() { + hooks.afterEach(function() { this.server.shutdown(); - }, -}); - -test('token authentication: root token', function(assert) { - let done = assert.async(); - let self = this; - let service = this.subject({ - storage(tokenName) { - if ( - tokenName && - tokenName.indexOf(`${TOKEN_PREFIX}${ROOT_PREFIX}`) === 0 && - this.environment() !== 'development' - ) { - return self.memStore; - } else { - return self.store; - } - }, }); - Ember.run(() => { - service.authenticate({ clusterId: '1', backend: 'token', data: { token: 'test' } }).then(() => { - const clusterTokenName = service.get('currentTokenName'); - const clusterToken = service.get('currentToken'); - const authData = service.get('authData'); - const expectedTokenName = `${TOKEN_PREFIX}${ROOT_PREFIX}${TOKEN_SEPARATOR}1`; - assert.equal('test', clusterToken, 'token is saved properly'); - assert.equal( - `${TOKEN_PREFIX}${ROOT_PREFIX}${TOKEN_SEPARATOR}1`, - clusterTokenName, - 'token name is saved properly' - ); - assert.equal('token', authData.backend.type, 'backend is saved properly'); - assert.equal( - ROOT_TOKEN_RESPONSE.data.display_name, - authData.displayName, - 'displayName is saved properly' - ); - assert.ok(this.memStore.keys().includes(expectedTokenName), 'root token is stored in the memory store'); - assert.equal(this.store.keys().length, 0, 'normal storage is empty'); - done(); + test('token authentication: root token', function(assert) { + let done = assert.async(); + let self = this; + let service = this.owner.factoryFor('service:auth').create({ + storage(tokenName) { + if ( + tokenName && + tokenName.indexOf(`${TOKEN_PREFIX}${ROOT_PREFIX}`) === 0 && + this.environment() !== 'development' + ) { + return self.memStore; + } else { + return self.store; + } + }, }); - }); -}); - -test('token authentication: root token in ember development environment', function(assert) { - let done = assert.async(); - let self = this; - let service = this.subject({ - storage(tokenName) { - if ( - tokenName && - tokenName.indexOf(`${TOKEN_PREFIX}${ROOT_PREFIX}`) === 0 && - this.environment() !== 'development' - ) { - return self.memStore; - } else { - return self.store; - } - }, - environment: () => 'development', - }); - Ember.run(() => { - service.authenticate({ clusterId: '1', backend: 'token', data: { token: 'test' } }).then(() => { - const clusterTokenName = service.get('currentTokenName'); - const clusterToken = service.get('currentToken'); - const authData = service.get('authData'); - - const expectedTokenName = `${TOKEN_PREFIX}${ROOT_PREFIX}${TOKEN_SEPARATOR}1`; - assert.equal('test', clusterToken, 'token is saved properly'); - assert.equal( - `${TOKEN_PREFIX}${ROOT_PREFIX}${TOKEN_SEPARATOR}1`, - clusterTokenName, - 'token name is saved properly' - ); - assert.equal('token', authData.backend.type, 'backend is saved properly'); - assert.equal( - ROOT_TOKEN_RESPONSE.data.display_name, - authData.displayName, - 'displayName is saved properly' - ); - assert.ok(this.store.keys().includes(expectedTokenName), 'root token is stored in the store'); - assert.equal(this.memStore.keys().length, 0, 'mem storage is empty'); - done(); - }); - }); -}); - -test('github authentication', function(assert) { - let done = assert.async(); - let service = this.subject({ - storage: type => (type === 'memory' ? this.memStore : this.store), - }); - - Ember.run(() => { - service.authenticate({ clusterId: '1', backend: 'github', data: { token: 'test' } }).then(() => { - const clusterTokenName = service.get('currentTokenName'); - const clusterToken = service.get('currentToken'); - const authData = service.get('authData'); - const expectedTokenName = `${TOKEN_PREFIX}github${TOKEN_SEPARATOR}1`; - - assert.equal(GITHUB_RESPONSE.auth.client_token, clusterToken, 'token is saved properly'); - assert.equal(expectedTokenName, clusterTokenName, 'token name is saved properly'); - assert.equal('github', authData.backend.type, 'backend is saved properly'); - assert.equal( - GITHUB_RESPONSE.auth.metadata.org + '/' + GITHUB_RESPONSE.auth.metadata.username, - authData.displayName, - 'displayName is saved properly' - ); - assert.equal(this.memStore.keys().length, 0, 'mem storage is empty'); - assert.ok(this.store.keys().includes(expectedTokenName), 'normal storage contains the token'); - done(); - }); - }); -}); - -test('userpass authentication', function(assert) { - let done = assert.async(); - let service = this.subject({ storage: () => this.store }); - Ember.run(() => { - service - .authenticate({ - clusterId: '1', - backend: 'userpass', - data: { username: USERPASS_RESPONSE.auth.metadata.username, password: 'passoword' }, - }) - .then(() => { + run(() => { + service.authenticate({ clusterId: '1', backend: 'token', data: { token: 'test' } }).then(() => { const clusterTokenName = service.get('currentTokenName'); const clusterToken = service.get('currentToken'); const authData = service.get('authData'); - assert.equal(USERPASS_RESPONSE.auth.client_token, clusterToken, 'token is saved properly'); + const expectedTokenName = `${TOKEN_PREFIX}${ROOT_PREFIX}${TOKEN_SEPARATOR}1`; + assert.equal('test', clusterToken, 'token is saved properly'); assert.equal( - `${TOKEN_PREFIX}userpass${TOKEN_SEPARATOR}1`, + `${TOKEN_PREFIX}${ROOT_PREFIX}${TOKEN_SEPARATOR}1`, clusterTokenName, 'token name is saved properly' ); - assert.equal('userpass', authData.backend.type, 'backend is saved properly'); + assert.equal('token', authData.backend.type, 'backend is saved properly'); assert.equal( - USERPASS_RESPONSE.auth.metadata.username, + ROOT_TOKEN_RESPONSE.data.display_name, authData.displayName, 'displayName is saved properly' ); + assert.ok( + this.memStore.keys().includes(expectedTokenName), + 'root token is stored in the memory store' + ); + assert.equal(this.store.keys().length, 0, 'normal storage is empty'); done(); }); - }); -}); - -test('token auth expiry with non-root token', function(assert) { - const tokenResp = TOKEN_NON_ROOT_RESPONSE(); - this.server.map(function() { - this.get('/v1/auth/token/lookup-self', function(request) { - let resp = Ember.copy(tokenResp, true); - resp.id = request.requestHeaders['X-Vault-Token']; - resp.data.id = request.requestHeaders['X-Vault-Token']; - return [200, {}, resp]; }); }); - let done = assert.async(); - let service = this.subject({ storage: () => this.store }); - Ember.run(() => { - service.authenticate({ clusterId: '1', backend: 'token', data: { token: 'test' } }).then(() => { - const clusterTokenName = service.get('currentTokenName'); - const clusterToken = service.get('currentToken'); - const authData = service.get('authData'); + test('token authentication: root token in ember development environment', function(assert) { + let done = assert.async(); + let self = this; + let service = this.owner.factoryFor('service:auth').create({ + storage(tokenName) { + if ( + tokenName && + tokenName.indexOf(`${TOKEN_PREFIX}${ROOT_PREFIX}`) === 0 && + this.environment() !== 'development' + ) { + return self.memStore; + } else { + return self.store; + } + }, + environment: () => 'development', + }); + run(() => { + service.authenticate({ clusterId: '1', backend: 'token', data: { token: 'test' } }).then(() => { + const clusterTokenName = service.get('currentTokenName'); + const clusterToken = service.get('currentToken'); + const authData = service.get('authData'); - assert.equal('test', clusterToken, 'token is saved properly'); - assert.equal( - `${TOKEN_PREFIX}token${TOKEN_SEPARATOR}1`, - clusterTokenName, - 'token name is saved properly' - ); - assert.equal(authData.backend.type, 'token', 'backend is saved properly'); - assert.equal(authData.displayName, tokenResp.data.display_name, 'displayName is saved properly'); - assert.equal(service.get('tokenExpired'), false, 'token is not expired'); - done(); + const expectedTokenName = `${TOKEN_PREFIX}${ROOT_PREFIX}${TOKEN_SEPARATOR}1`; + assert.equal('test', clusterToken, 'token is saved properly'); + assert.equal( + `${TOKEN_PREFIX}${ROOT_PREFIX}${TOKEN_SEPARATOR}1`, + clusterTokenName, + 'token name is saved properly' + ); + assert.equal('token', authData.backend.type, 'backend is saved properly'); + assert.equal( + ROOT_TOKEN_RESPONSE.data.display_name, + authData.displayName, + 'displayName is saved properly' + ); + assert.ok(this.store.keys().includes(expectedTokenName), 'root token is stored in the store'); + assert.equal(this.memStore.keys().length, 0, 'mem storage is empty'); + done(); + }); + }); + }); + + test('github authentication', function(assert) { + let done = assert.async(); + let service = this.owner.factoryFor('service:auth').create({ + storage: type => (type === 'memory' ? this.memStore : this.store), + }); + + run(() => { + service.authenticate({ clusterId: '1', backend: 'github', data: { token: 'test' } }).then(() => { + const clusterTokenName = service.get('currentTokenName'); + const clusterToken = service.get('currentToken'); + const authData = service.get('authData'); + const expectedTokenName = `${TOKEN_PREFIX}github${TOKEN_SEPARATOR}1`; + + assert.equal(GITHUB_RESPONSE.auth.client_token, clusterToken, 'token is saved properly'); + assert.equal(expectedTokenName, clusterTokenName, 'token name is saved properly'); + assert.equal('github', authData.backend.type, 'backend is saved properly'); + assert.equal( + GITHUB_RESPONSE.auth.metadata.org + '/' + GITHUB_RESPONSE.auth.metadata.username, + authData.displayName, + 'displayName is saved properly' + ); + assert.equal(this.memStore.keys().length, 0, 'mem storage is empty'); + assert.ok(this.store.keys().includes(expectedTokenName), 'normal storage contains the token'); + done(); + }); + }); + }); + + test('userpass authentication', function(assert) { + let done = assert.async(); + let service = this.owner.factoryFor('service:auth').create({ storage: () => this.store }); + run(() => { + service + .authenticate({ + clusterId: '1', + backend: 'userpass', + data: { username: USERPASS_RESPONSE.auth.metadata.username, password: 'passoword' }, + }) + .then(() => { + const clusterTokenName = service.get('currentTokenName'); + const clusterToken = service.get('currentToken'); + const authData = service.get('authData'); + + assert.equal(USERPASS_RESPONSE.auth.client_token, clusterToken, 'token is saved properly'); + assert.equal( + `${TOKEN_PREFIX}userpass${TOKEN_SEPARATOR}1`, + clusterTokenName, + 'token name is saved properly' + ); + assert.equal('userpass', authData.backend.type, 'backend is saved properly'); + assert.equal( + USERPASS_RESPONSE.auth.metadata.username, + authData.displayName, + 'displayName is saved properly' + ); + done(); + }); + }); + }); + + test('token auth expiry with non-root token', function(assert) { + const tokenResp = TOKEN_NON_ROOT_RESPONSE(); + this.server.map(function() { + this.get('/v1/auth/token/lookup-self', function(request) { + let resp = copy(tokenResp, true); + resp.id = request.requestHeaders['X-Vault-Token']; + resp.data.id = request.requestHeaders['X-Vault-Token']; + return [200, {}, resp]; + }); + }); + + let done = assert.async(); + let service = this.owner.factoryFor('service:auth').create({ storage: () => this.store }); + run(() => { + service.authenticate({ clusterId: '1', backend: 'token', data: { token: 'test' } }).then(() => { + const clusterTokenName = service.get('currentTokenName'); + const clusterToken = service.get('currentToken'); + const authData = service.get('authData'); + + assert.equal('test', clusterToken, 'token is saved properly'); + assert.equal( + `${TOKEN_PREFIX}token${TOKEN_SEPARATOR}1`, + clusterTokenName, + 'token name is saved properly' + ); + assert.equal(authData.backend.type, 'token', 'backend is saved properly'); + assert.equal(authData.displayName, tokenResp.data.display_name, 'displayName is saved properly'); + assert.equal(service.get('tokenExpired'), false, 'token is not expired'); + done(); + }); }); }); }); diff --git a/ui/tests/unit/services/console-test.js b/ui/tests/unit/services/console-test.js index 0f4adca4d..408e26a2b 100644 --- a/ui/tests/unit/services/console-test.js +++ b/ui/tests/unit/services/console-test.js @@ -1,94 +1,95 @@ -import { moduleFor, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import { sanitizePath, ensureTrailingSlash } from 'vault/services/console'; import sinon from 'sinon'; -moduleFor('service:console', 'Unit | Service | console', { - needs: ['service:auth'], - beforeEach() {}, - afterEach() {}, -}); +module('Unit | Service | console', function(hooks) { + setupTest(hooks); + hooks.beforeEach(function() {}); + hooks.afterEach(function() {}); -test('#sanitizePath', function(assert) { - assert.equal(sanitizePath(' /foo/bar/baz/ '), 'foo/bar/baz', 'removes spaces and slashs on either side'); - assert.equal(sanitizePath('//foo/bar/baz/'), 'foo/bar/baz', 'removes more than one slash'); -}); - -test('#ensureTrailingSlash', function(assert) { - assert.equal(ensureTrailingSlash('foo/bar'), 'foo/bar/', 'adds trailing slash'); - assert.equal(ensureTrailingSlash('baz/'), 'baz/', 'keeps trailing slash if there is one'); -}); - -let testCases = [ - { - method: 'read', - args: ['/sys/health', {}], - expectedURL: 'sys/health', - expectedVerb: 'GET', - expectedOptions: { data: undefined, wrapTTL: undefined }, - }, - - { - method: 'read', - args: ['/secrets/foo/bar', {}, '30m'], - expectedURL: 'secrets/foo/bar', - expectedVerb: 'GET', - expectedOptions: { data: undefined, wrapTTL: '30m' }, - }, - - { - method: 'write', - args: ['aws/roles/my-other-role', { arn: 'arn=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess' }], - expectedURL: 'aws/roles/my-other-role', - expectedVerb: 'POST', - expectedOptions: { - data: { arn: 'arn=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess' }, - wrapTTL: undefined, - }, - }, - - { - method: 'list', - args: ['secret/mounts', {}], - expectedURL: 'secret/mounts/', - expectedVerb: 'GET', - expectedOptions: { data: { list: true }, wrapTTL: undefined }, - }, - - { - method: 'list', - args: ['secret/mounts', {}, '1h'], - expectedURL: 'secret/mounts/', - expectedVerb: 'GET', - expectedOptions: { data: { list: true }, wrapTTL: '1h' }, - }, - - { - method: 'delete', - args: ['secret/secrets/kv'], - expectedURL: 'secret/secrets/kv', - expectedVerb: 'DELETE', - expectedOptions: { data: undefined, wrapTTL: undefined }, - }, -]; - -test('it reads, writes, lists, deletes', function(assert) { - let ajax = sinon.stub(); - let uiConsole = this.subject({ - adapter() { - return { - buildURL(url) { - return url; - }, - ajax, - }; - }, + test('#sanitizePath', function(assert) { + assert.equal(sanitizePath(' /foo/bar/baz/ '), 'foo/bar/baz', 'removes spaces and slashs on either side'); + assert.equal(sanitizePath('//foo/bar/baz/'), 'foo/bar/baz', 'removes more than one slash'); }); - testCases.forEach(testCase => { - uiConsole[testCase.method](...testCase.args); - let [url, verb, options] = ajax.lastCall.args; - assert.equal(url, testCase.expectedURL, `${testCase.method}: uses trimmed passed url`); - assert.equal(verb, testCase.expectedVerb, `${testCase.method}: uses the correct verb`); - assert.deepEqual(options, testCase.expectedOptions, `${testCase.method}: uses the correct options`); + test('#ensureTrailingSlash', function(assert) { + assert.equal(ensureTrailingSlash('foo/bar'), 'foo/bar/', 'adds trailing slash'); + assert.equal(ensureTrailingSlash('baz/'), 'baz/', 'keeps trailing slash if there is one'); + }); + + let testCases = [ + { + method: 'read', + args: ['/sys/health', {}], + expectedURL: 'sys/health', + expectedVerb: 'GET', + expectedOptions: { data: undefined, wrapTTL: undefined }, + }, + + { + method: 'read', + args: ['/secrets/foo/bar', {}, '30m'], + expectedURL: 'secrets/foo/bar', + expectedVerb: 'GET', + expectedOptions: { data: undefined, wrapTTL: '30m' }, + }, + + { + method: 'write', + args: ['aws/roles/my-other-role', { arn: 'arn=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess' }], + expectedURL: 'aws/roles/my-other-role', + expectedVerb: 'POST', + expectedOptions: { + data: { arn: 'arn=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess' }, + wrapTTL: undefined, + }, + }, + + { + method: 'list', + args: ['secret/mounts', {}], + expectedURL: 'secret/mounts/', + expectedVerb: 'GET', + expectedOptions: { data: { list: true }, wrapTTL: undefined }, + }, + + { + method: 'list', + args: ['secret/mounts', {}, '1h'], + expectedURL: 'secret/mounts/', + expectedVerb: 'GET', + expectedOptions: { data: { list: true }, wrapTTL: '1h' }, + }, + + { + method: 'delete', + args: ['secret/secrets/kv'], + expectedURL: 'secret/secrets/kv', + expectedVerb: 'DELETE', + expectedOptions: { data: undefined, wrapTTL: undefined }, + }, + ]; + + test('it reads, writes, lists, deletes', function(assert) { + let ajax = sinon.stub(); + let uiConsole = this.owner.factoryFor('service:console').create({ + adapter() { + return { + buildURL(url) { + return url; + }, + ajax, + }; + }, + }); + + testCases.forEach(testCase => { + uiConsole[testCase.method](...testCase.args); + let [url, verb, options] = ajax.lastCall.args; + assert.equal(url, testCase.expectedURL, `${testCase.method}: uses trimmed passed url`); + assert.equal(verb, testCase.expectedVerb, `${testCase.method}: uses the correct verb`); + assert.deepEqual(options, testCase.expectedOptions, `${testCase.method}: uses the correct options`); + }); }); }); diff --git a/ui/tests/unit/services/control-group-test.js b/ui/tests/unit/services/control-group-test.js index 1dc14ec91..022680fa3 100644 --- a/ui/tests/unit/services/control-group-test.js +++ b/ui/tests/unit/services/control-group-test.js @@ -1,11 +1,13 @@ -import { moduleFor, test } from 'ember-qunit'; +import { set } from '@ember/object'; +import Service from '@ember/service'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import sinon from 'sinon'; -import Ember from 'ember'; import { storageKey, CONTROL_GROUP_PREFIX, TOKEN_SEPARATOR } from 'vault/services/control-group'; -let versionStub = Ember.Service.extend(); -let routerStub = Ember.Service.extend({ +let versionStub = Service.extend(); +let routerStub = Service.extend({ transitionTo: sinon.stub(), urlFor: sinon.stub().returns('/ui/vault/foo'), }); @@ -32,234 +34,237 @@ function storage() { }; } -moduleFor('service:control-group', 'Unit | Service | control group', { - beforeEach() { - this.register('service:version', versionStub); - this.inject.service('version', { as: 'version' }); - this.register('service:router', routerStub); - this.inject.service('router', { as: 'router' }); - }, - afterEach() {}, -}); +module('Unit | Service | control group', function(hooks) { + setupTest(hooks); -let isOSS = context => Ember.set(context, 'version.isOSS', true); -let isEnt = context => Ember.set(context, 'version.isOSS', false); -let resolvesArgs = (assert, result, expectedArgs) => { - return result.then((...args) => { - return assert.deepEqual(args, expectedArgs, 'resolves with the passed args'); + hooks.beforeEach(function() { + this.owner.register('service:version', versionStub); + this.version = this.owner.lookup('service:version'); + this.owner.register('service:router', routerStub); + this.router = this.owner.lookup('service:router'); }); -}; -[ + hooks.afterEach(function() {}); + + let isOSS = context => set(context, 'version.isOSS', true); + let isEnt = context => set(context, 'version.isOSS', false); + let resolvesArgs = (assert, result, expectedArgs) => { + return result.then((...args) => { + return assert.deepEqual(args, expectedArgs, 'resolves with the passed args'); + }); + }; + [ - 'it resolves isOSS:true, wrapTTL: true, response: has wrap_info', - isOSS, - [[{ one: 'two', three: 'four' }], { wrap_info: { token: 'foo', accessor: 'bar' } }, true], - (assert, result) => resolvesArgs(assert, result, [{ one: 'two', three: 'four' }]), - ], - [ - 'it resolves isOSS:true, wrapTTL: false, response: has no wrap_info', - isOSS, - [[{ one: 'two', three: 'four' }], { wrap_info: null }, false], - (assert, result) => resolvesArgs(assert, result, [{ one: 'two', three: 'four' }]), - ], - [ - 'it resolves isOSS: false and wrapTTL:true response: has wrap_info', - isEnt, - [[{ one: 'two', three: 'four' }], { wrap_info: { token: 'foo', accessor: 'bar' } }, true], - (assert, result) => resolvesArgs(assert, result, [{ one: 'two', three: 'four' }]), - ], - [ - 'it resolves isOSS: false and wrapTTL:false response: has no wrap_info', - isEnt, - [[{ one: 'two', three: 'four' }], { wrap_info: null }, false], - (assert, result) => resolvesArgs(assert, result, [{ one: 'two', three: 'four' }]), - ], - [ - 'it rejects isOSS: false, wrapTTL:false, response: has wrap_info', - isEnt, [ - [{ one: 'two', three: 'four' }], - { foo: 'bar', wrap_info: { token: 'secret', accessor: 'lookup' } }, - false, + 'it resolves isOSS:true, wrapTTL: true, response: has wrap_info', + isOSS, + [[{ one: 'two', three: 'four' }], { wrap_info: { token: 'foo', accessor: 'bar' } }, true], + (assert, result) => resolvesArgs(assert, result, [{ one: 'two', three: 'four' }]), ], - (assert, result) => { - // ensure failure if we ever don't reject - assert.expect(2); + [ + 'it resolves isOSS:true, wrapTTL: false, response: has no wrap_info', + isOSS, + [[{ one: 'two', three: 'four' }], { wrap_info: null }, false], + (assert, result) => resolvesArgs(assert, result, [{ one: 'two', three: 'four' }]), + ], + [ + 'it resolves isOSS: false and wrapTTL:true response: has wrap_info', + isEnt, + [[{ one: 'two', three: 'four' }], { wrap_info: { token: 'foo', accessor: 'bar' } }, true], + (assert, result) => resolvesArgs(assert, result, [{ one: 'two', three: 'four' }]), + ], + [ + 'it resolves isOSS: false and wrapTTL:false response: has no wrap_info', + isEnt, + [[{ one: 'two', three: 'four' }], { wrap_info: null }, false], + (assert, result) => resolvesArgs(assert, result, [{ one: 'two', three: 'four' }]), + ], + [ + 'it rejects isOSS: false, wrapTTL:false, response: has wrap_info', + isEnt, + [ + [{ one: 'two', three: 'four' }], + { foo: 'bar', wrap_info: { token: 'secret', accessor: 'lookup' } }, + false, + ], + (assert, result) => { + // ensure failure if we ever don't reject + assert.expect(2); - return result.then( - () => {}, - err => { - assert.equal(err.token, 'secret'); - assert.equal(err.accessor, 'lookup'); - } - ); - }, - ], -].forEach(function([name, setup, args, expectation]) { - test(`checkForControlGroup: ${name}`, function(assert) { - if (setup) { - setup(this); - } - let service = this.subject(); - let result = service.checkForControlGroup(...args); - return expectation(assert, result); - }); -}); - -test(`handleError: transitions to accessor when there is no transition passed in`, function(assert) { - let error = { - accessor: '12345', - token: 'token', - creation_path: 'kv/', - creation_time: new Date().toISOString(), - ttl: 400, - }; - let url; - let expected = { ...error, uiParams: { url } }; - let transition = { - targetName: 'vault.cluster.foo', - }; - let service = this.subject({ - urlFromTransition: sinon.spy(), - storeControlGroupToken: sinon.spy(), - }); - service.handleError(error, transition); - assert.ok(service.urlFromTransition.calledWith(transition), 'calls urlFromTransition'); - assert.ok(service.storeControlGroupToken.calledWith(expected), 'calls storeControlGroupToken'); - assert.ok( - this.router.transitionTo.calledWith('vault.cluster.access.control-group-accessor', '12345'), - 'calls router transitionTo' - ); -}); - -test(`logFromError: returns correct content string`, function(assert) { - let error = { - accessor: '12345', - token: 'token', - creation_path: 'kv/', - creation_time: new Date().toISOString(), - ttl: 400, - }; - let service = this.subject({ - storeControlGroupToken: sinon.spy(), - }); - let contentString = service.logFromError(error); - assert.ok( - this.router.urlFor.calledWith('vault.cluster.access.control-group-accessor', '12345'), - 'calls urlFor with accessor' - ); - assert.ok(service.storeControlGroupToken.calledWith(error), 'calls storeControlGroupToken'); - assert.ok(contentString.content.includes('12345'), 'contains accessor'); - assert.ok(contentString.content.includes('kv/'), 'contains creation path'); - assert.ok(contentString.content.includes('token'), 'contains token'); -}); - -test('urlFromTransition', function(assert) { - let transition = { - targetName: 'vault.cluster.foo', - params: { - vault: {}, - cluster: { cluster_name: 'vault' }, - foo: { bar: '1' }, - }, - queryParams: {}, - }; - let expected = [transition.targetName, { cluster_name: 'vault' }, { bar: '1' }, { queryParams: {} }]; - let service = this.subject(); - service.urlFromTransition(transition); - assert.ok(this.router.urlFor.calledWith(...expected), 'calls urlFor with expected args'); -}); - -test('storageKey', function(assert) { - let accessor = '12345'; - let path = 'kv/foo/bar'; - let expectedKey = `${CONTROL_GROUP_PREFIX}${accessor}${TOKEN_SEPARATOR}${path}`; - assert.equal(storageKey(accessor, path), expectedKey, 'uses expected key'); -}); - -test('keyFromAccessor', function(assert) { - let store = storage(); - let accessor = '12345'; - let path = 'kv/foo/bar'; - let data = { foo: 'bar' }; - let expectedKey = `${CONTROL_GROUP_PREFIX}${accessor}${TOKEN_SEPARATOR}${path}`; - let subject = this.subject({ - storage() { - return store; - }, + return result.then( + () => {}, + err => { + assert.equal(err.token, 'secret'); + assert.equal(err.accessor, 'lookup'); + } + ); + }, + ], + ].forEach(function([name, setup, args, expectation]) { + test(`checkForControlGroup: ${name}`, function(assert) { + if (setup) { + setup(this); + } + let service = this.owner.lookup('service:control-group'); + let result = service.checkForControlGroup(...args); + return expectation(assert, result); + }); }); - store.setItem(expectedKey, data); - store.setItem(`${CONTROL_GROUP_PREFIX}2345${TOKEN_SEPARATOR}${path}`, 'ok'); - - assert.equal(subject.keyFromAccessor(accessor), expectedKey, 'finds key given the accessor'); - assert.equal(subject.keyFromAccessor('foo'), null, 'returns null if no key was found'); -}); - -test('storeControlGroupToken', function(assert) { - let store = storage(); - let subject = this.subject({ - storage() { - return store; - }, - }); - let info = { - accessor: '12345', - creation_path: 'foo/', - creation_time: new Date().toISOString(), - ttl: 300, - }; - let key = `${CONTROL_GROUP_PREFIX}${info.accessor}${TOKEN_SEPARATOR}${info.creation_path}`; - - subject.storeControlGroupToken(info); - assert.deepEqual(store.items[key], JSON.stringify(info), 'stores the whole info object'); -}); - -test('deleteControlGroupToken', function(assert) { - let store = storage(); - let subject = this.subject({ - storage() { - return store; - }, - }); - let accessor = 'foo'; - let path = 'kv/one'; - - let expectedKey = `${CONTROL_GROUP_PREFIX}${accessor}${TOKEN_SEPARATOR}${path}`; - store.setItem(expectedKey, { one: '2' }); - subject.deleteControlGroupToken(accessor); - assert.equal(Object.keys(store.items).length, 0, 'there are no keys stored in storage'); -}); - -test('deleteTokens', function(assert) { - let store = storage(); - let subject = this.subject({ - storage() { - return store; - }, + test(`handleError: transitions to accessor when there is no transition passed in`, function(assert) { + let error = { + accessor: '12345', + token: 'token', + creation_path: 'kv/', + creation_time: new Date().toISOString(), + ttl: 400, + }; + let url; + let expected = { ...error, uiParams: { url } }; + let transition = { + targetName: 'vault.cluster.foo', + }; + let service = this.owner.factoryFor('service:control-group').create({ + urlFromTransition: sinon.spy(), + storeControlGroupToken: sinon.spy(), + }); + service.handleError(error, transition); + assert.ok(service.urlFromTransition.calledWith(transition), 'calls urlFromTransition'); + assert.ok(service.storeControlGroupToken.calledWith(expected), 'calls storeControlGroupToken'); + assert.ok( + this.router.transitionTo.calledWith('vault.cluster.access.control-group-accessor', '12345'), + 'calls router transitionTo' + ); }); - let keyOne = `${CONTROL_GROUP_PREFIX}foo`; - let keyTwo = `${CONTROL_GROUP_PREFIX}bar`; - store.setItem(keyOne, { one: '2' }); - store.setItem(keyTwo, { two: '2' }); - store.setItem('value', 'one'); - assert.equal(Object.keys(store.items).length, 3, 'stores 3 values'); - subject.deleteTokens(); - assert.equal(Object.keys(store.items).length, 1, 'removes tokens with control group prefix'); - assert.equal(store.getItem('value'), 'one', 'keeps the non-prefixed value'); -}); - -test('wrapInfoForAccessor', function(assert) { - let store = storage(); - let subject = this.subject({ - storage() { - return store; - }, + test(`logFromError: returns correct content string`, function(assert) { + let error = { + accessor: '12345', + token: 'token', + creation_path: 'kv/', + creation_time: new Date().toISOString(), + ttl: 400, + }; + let service = this.owner.factoryFor('service:control-group').create({ + storeControlGroupToken: sinon.spy(), + }); + let contentString = service.logFromError(error); + assert.ok( + this.router.urlFor.calledWith('vault.cluster.access.control-group-accessor', '12345'), + 'calls urlFor with accessor' + ); + assert.ok(service.storeControlGroupToken.calledWith(error), 'calls storeControlGroupToken'); + assert.ok(contentString.content.includes('12345'), 'contains accessor'); + assert.ok(contentString.content.includes('kv/'), 'contains creation path'); + assert.ok(contentString.content.includes('token'), 'contains token'); }); - let keyOne = `${CONTROL_GROUP_PREFIX}foo`; - store.setItem(keyOne, { one: '2' }); - assert.deepEqual(subject.wrapInfoForAccessor('foo'), { one: '2' }); + test('urlFromTransition', function(assert) { + let transition = { + targetName: 'vault.cluster.foo', + params: { + vault: {}, + cluster: { cluster_name: 'vault' }, + foo: { bar: '1' }, + }, + queryParams: {}, + }; + let expected = [transition.targetName, { cluster_name: 'vault' }, { bar: '1' }, { queryParams: {} }]; + let service = this.owner.lookup('service:control-group'); + service.urlFromTransition(transition); + assert.ok(this.router.urlFor.calledWith(...expected), 'calls urlFor with expected args'); + }); + + test('storageKey', function(assert) { + let accessor = '12345'; + let path = 'kv/foo/bar'; + let expectedKey = `${CONTROL_GROUP_PREFIX}${accessor}${TOKEN_SEPARATOR}${path}`; + assert.equal(storageKey(accessor, path), expectedKey, 'uses expected key'); + }); + + test('keyFromAccessor', function(assert) { + let store = storage(); + let accessor = '12345'; + let path = 'kv/foo/bar'; + let data = { foo: 'bar' }; + let expectedKey = `${CONTROL_GROUP_PREFIX}${accessor}${TOKEN_SEPARATOR}${path}`; + let subject = this.owner.factoryFor('service:control-group').create({ + storage() { + return store; + }, + }); + + store.setItem(expectedKey, data); + store.setItem(`${CONTROL_GROUP_PREFIX}2345${TOKEN_SEPARATOR}${path}`, 'ok'); + + assert.equal(subject.keyFromAccessor(accessor), expectedKey, 'finds key given the accessor'); + assert.equal(subject.keyFromAccessor('foo'), null, 'returns null if no key was found'); + }); + + test('storeControlGroupToken', function(assert) { + let store = storage(); + let subject = this.owner.factoryFor('service:control-group').create({ + storage() { + return store; + }, + }); + let info = { + accessor: '12345', + creation_path: 'foo/', + creation_time: new Date().toISOString(), + ttl: 300, + }; + let key = `${CONTROL_GROUP_PREFIX}${info.accessor}${TOKEN_SEPARATOR}${info.creation_path}`; + + subject.storeControlGroupToken(info); + assert.deepEqual(store.items[key], JSON.stringify(info), 'stores the whole info object'); + }); + + test('deleteControlGroupToken', function(assert) { + let store = storage(); + let subject = this.owner.factoryFor('service:control-group').create({ + storage() { + return store; + }, + }); + let accessor = 'foo'; + let path = 'kv/one'; + + let expectedKey = `${CONTROL_GROUP_PREFIX}${accessor}${TOKEN_SEPARATOR}${path}`; + store.setItem(expectedKey, { one: '2' }); + subject.deleteControlGroupToken(accessor); + assert.equal(Object.keys(store.items).length, 0, 'there are no keys stored in storage'); + }); + + test('deleteTokens', function(assert) { + let store = storage(); + let subject = this.owner.factoryFor('service:control-group').create({ + storage() { + return store; + }, + }); + + let keyOne = `${CONTROL_GROUP_PREFIX}foo`; + let keyTwo = `${CONTROL_GROUP_PREFIX}bar`; + store.setItem(keyOne, { one: '2' }); + store.setItem(keyTwo, { two: '2' }); + store.setItem('value', 'one'); + assert.equal(Object.keys(store.items).length, 3, 'stores 3 values'); + subject.deleteTokens(); + assert.equal(Object.keys(store.items).length, 1, 'removes tokens with control group prefix'); + assert.equal(store.getItem('value'), 'one', 'keeps the non-prefixed value'); + }); + + test('wrapInfoForAccessor', function(assert) { + let store = storage(); + let subject = this.owner.factoryFor('service:control-group').create({ + storage() { + return store; + }, + }); + + let keyOne = `${CONTROL_GROUP_PREFIX}foo`; + store.setItem(keyOne, { one: '2' }); + assert.deepEqual(subject.wrapInfoForAccessor('foo'), { one: '2' }); + }); }); diff --git a/ui/tests/unit/services/store-test.js b/ui/tests/unit/services/store-test.js index 2b5b62026..1a5ba7a8d 100644 --- a/ui/tests/unit/services/store-test.js +++ b/ui/tests/unit/services/store-test.js @@ -1,235 +1,242 @@ -import { moduleFor, test } from 'ember-qunit'; +import { resolve } from 'rsvp'; +import { run } from '@ember/runloop'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import { normalizeModelName, keyForCache } from 'vault/services/store'; import clamp from 'vault/utils/clamp'; -import Ember from 'ember'; -moduleFor('service:store', 'Unit | Service | store', { - // Specify the other units that are required for this test. - needs: ['model:transit-key', 'serializer:transit-key'], -}); +module('Unit | Service | store', function(hooks) { + setupTest(hooks); -test('normalizeModelName', function(assert) { - assert.equal(normalizeModelName('oneThing'), 'one-thing', 'dasherizes modelName'); -}); + test('normalizeModelName', function(assert) { + assert.equal(normalizeModelName('oneThing'), 'one-thing', 'dasherizes modelName'); + }); -test('keyForCache', function(assert) { - const query = { id: 1 }; - const queryWithSize = { id: 1, size: 1 }; - assert.deepEqual(keyForCache(query), JSON.stringify(query), 'generated the correct cache key'); - assert.deepEqual(keyForCache(queryWithSize), JSON.stringify(query), 'excludes size from query cache'); -}); + test('keyForCache', function(assert) { + const query = { id: 1 }; + const queryWithSize = { id: 1, size: 1 }; + assert.deepEqual(keyForCache(query), JSON.stringify(query), 'generated the correct cache key'); + assert.deepEqual(keyForCache(queryWithSize), JSON.stringify(query), 'excludes size from query cache'); + }); -test('clamp', function(assert) { - assert.equal(clamp('foo', 0, 100), 0, 'returns the min if passed a non-number'); - assert.equal(clamp(0, 1, 100), 1, 'returns the min when passed number is less than the min'); - assert.equal(clamp(200, 1, 100), 100, 'returns the max passed number is greater than the max'); - assert.equal(clamp(50, 1, 100), 50, 'returns the passed number when it is in range'); -}); + test('clamp', function(assert) { + assert.equal(clamp('foo', 0, 100), 0, 'returns the min if passed a non-number'); + assert.equal(clamp(0, 1, 100), 1, 'returns the min when passed number is less than the min'); + assert.equal(clamp(200, 1, 100), 100, 'returns the max passed number is greater than the max'); + assert.equal(clamp(50, 1, 100), 50, 'returns the passed number when it is in range'); + }); -test('store.storeDataset', function(assert) { - const arr = ['one', 'two']; - const store = this.subject(); - const query = { id: 1 }; - store.storeDataset('data', query, {}, arr); + test('store.storeDataset', function(assert) { + const arr = ['one', 'two']; + const store = this.owner.lookup('service:store'); + const query = { id: 1 }; + store.storeDataset('data', query, {}, arr); - assert.deepEqual(store.getDataset('data', query).dataset, arr, 'it stores the array as .dataset'); - assert.deepEqual(store.getDataset('data', query).response, {}, 'it stores the response as .response'); - assert.ok(store.get('lazyCaches').has('data'), 'it stores model map'); - assert.ok(store.get('lazyCaches').get('data').has(keyForCache(query)), 'it stores data on the model map'); -}); + assert.deepEqual(store.getDataset('data', query).dataset, arr, 'it stores the array as .dataset'); + assert.deepEqual(store.getDataset('data', query).response, {}, 'it stores the response as .response'); + assert.ok(store.get('lazyCaches').has('data'), 'it stores model map'); + assert.ok( + store + .get('lazyCaches') + .get('data') + .has(keyForCache(query)), + 'it stores data on the model map' + ); + }); -test('store.clearDataset with a prefix', function(assert) { - const store = this.subject(); - const arr = ['one', 'two']; - const arr2 = ['one', 'two', 'three', 'four']; - store.storeDataset('data', { id: 1 }, {}, arr); - store.storeDataset('transit-key', { id: 2 }, {}, arr2); - assert.equal(store.get('lazyCaches').size, 2, 'it stores both keys'); + test('store.clearDataset with a prefix', function(assert) { + const store = this.owner.lookup('service:store'); + const arr = ['one', 'two']; + const arr2 = ['one', 'two', 'three', 'four']; + store.storeDataset('data', { id: 1 }, {}, arr); + store.storeDataset('transit-key', { id: 2 }, {}, arr2); + assert.equal(store.get('lazyCaches').size, 2, 'it stores both keys'); - store.clearDataset('transit-key'); - assert.equal(store.get('lazyCaches').size, 1, 'deletes one key'); - assert.notOk(store.get('lazyCaches').has(), 'cache is no longer stored'); -}); + store.clearDataset('transit-key'); + assert.equal(store.get('lazyCaches').size, 1, 'deletes one key'); + assert.notOk(store.get('lazyCaches').has(), 'cache is no longer stored'); + }); -test('store.clearAllDatasets', function(assert) { - const store = this.subject(); - const arr = ['one', 'two']; - const arr2 = ['one', 'two', 'three', 'four']; - store.storeDataset('data', { id: 1 }, {}, arr); - store.storeDataset('transit-key', { id: 2 }, {}, arr2); - assert.equal(store.get('lazyCaches').size, 2, 'it stores both keys'); + test('store.clearAllDatasets', function(assert) { + const store = this.owner.lookup('service:store'); + const arr = ['one', 'two']; + const arr2 = ['one', 'two', 'three', 'four']; + store.storeDataset('data', { id: 1 }, {}, arr); + store.storeDataset('transit-key', { id: 2 }, {}, arr2); + assert.equal(store.get('lazyCaches').size, 2, 'it stores both keys'); - store.clearAllDatasets(); - assert.equal(store.get('lazyCaches').size, 0, 'deletes all of the keys'); - assert.notOk(store.get('lazyCaches').has('transit-key'), 'first cache key is no longer stored'); - assert.notOk(store.get('lazyCaches').has('data'), 'second cache key is no longer stored'); -}); + store.clearAllDatasets(); + assert.equal(store.get('lazyCaches').size, 0, 'deletes all of the keys'); + assert.notOk(store.get('lazyCaches').has('transit-key'), 'first cache key is no longer stored'); + assert.notOk(store.get('lazyCaches').has('data'), 'second cache key is no longer stored'); + }); -test('store.getDataset', function(assert) { - const arr = ['one', 'two']; - const store = this.subject(); - store.storeDataset('data', { id: 1 }, {}, arr); + test('store.getDataset', function(assert) { + const arr = ['one', 'two']; + const store = this.owner.lookup('service:store'); + store.storeDataset('data', { id: 1 }, {}, arr); - assert.deepEqual(store.getDataset('data', { id: 1 }), { response: {}, dataset: arr }); -}); + assert.deepEqual(store.getDataset('data', { id: 1 }), { response: {}, dataset: arr }); + }); -test('store.constructResponse', function(assert) { - const arr = ['one', 'two', 'three', 'fifteen', 'twelve']; - const store = this.subject(); - store.storeDataset('data', { id: 1 }, {}, arr); + test('store.constructResponse', function(assert) { + const arr = ['one', 'two', 'three', 'fifteen', 'twelve']; + const store = this.owner.lookup('service:store'); + store.storeDataset('data', { id: 1 }, {}, arr); - assert.deepEqual( - store.constructResponse('data', { id: 1, pageFilter: 't', page: 1, size: 3, responsePath: 'data' }), - { - data: ['two', 'three', 'fifteen'], - meta: { currentPage: 1, lastPage: 2, nextPage: 2, prevPage: 1, total: 5, filteredTotal: 4 }, - }, - 'it returns filtered results' - ); -}); + assert.deepEqual( + store.constructResponse('data', { id: 1, pageFilter: 't', page: 1, size: 3, responsePath: 'data' }), + { + data: ['two', 'three', 'fifteen'], + meta: { currentPage: 1, lastPage: 2, nextPage: 2, prevPage: 1, total: 5, filteredTotal: 4 }, + }, + 'it returns filtered results' + ); + }); -test('store.fetchPage', function(assert) { - let done = assert.async(4); - const keys = ['zero', 'one', 'two', 'three', 'four', 'five', 'six']; - const data = { - data: { - keys, - }, - }; - const store = this.subject(); - const pageSize = 2; - const query = { - size: pageSize, - page: 1, - responsePath: 'data.keys', - }; - store.storeDataset('transit-key', query, data, keys); + test('store.fetchPage', function(assert) { + let done = assert.async(4); + const keys = ['zero', 'one', 'two', 'three', 'four', 'five', 'six']; + const data = { + data: { + keys, + }, + }; + const store = this.owner.lookup('service:store'); + const pageSize = 2; + const query = { + size: pageSize, + page: 1, + responsePath: 'data.keys', + }; + store.storeDataset('transit-key', query, data, keys); - let result; - Ember.run(() => { - store.fetchPage('transit-key', query).then(r => { - result = r; - done(); + let result; + run(() => { + store.fetchPage('transit-key', query).then(r => { + result = r; + done(); + }); }); + + assert.ok(result.get('length'), pageSize, 'returns the correct number of items'); + assert.deepEqual(result.mapBy('id'), keys.slice(0, pageSize), 'returns the first page of items'); + assert.deepEqual( + result.get('meta'), + { + nextPage: 2, + prevPage: 1, + currentPage: 1, + lastPage: 4, + total: 7, + filteredTotal: 7, + }, + 'returns correct meta values' + ); + + run(() => { + store + .fetchPage('transit-key', { + size: pageSize, + page: 3, + responsePath: 'data.keys', + }) + .then(r => { + result = r; + done(); + }); + }); + + const pageThreeEnd = 3 * pageSize; + const pageThreeStart = pageThreeEnd - pageSize; + assert.deepEqual( + result.mapBy('id'), + keys.slice(pageThreeStart, pageThreeEnd), + 'returns the third page of items' + ); + + run(() => { + store + .fetchPage('transit-key', { + size: pageSize, + page: 99, + responsePath: 'data.keys', + }) + .then(r => { + result = r; + done(); + }); + }); + + assert.deepEqual( + result.mapBy('id'), + keys.slice(keys.length - 1), + 'returns the last page when the page value is beyond the of bounds' + ); + + run(() => { + store + .fetchPage('transit-key', { + size: pageSize, + page: 0, + responsePath: 'data.keys', + }) + .then(r => { + result = r; + done(); + }); + }); + assert.deepEqual( + result.mapBy('id'), + keys.slice(0, pageSize), + 'returns the first page when page value is under the bounds' + ); }); - assert.ok(result.get('length'), pageSize, 'returns the correct number of items'); - assert.deepEqual(result.mapBy('id'), keys.slice(0, pageSize), 'returns the first page of items'); - assert.deepEqual( - result.get('meta'), - { - nextPage: 2, - prevPage: 1, - currentPage: 1, - lastPage: 4, - total: 7, - filteredTotal: 7, - }, - 'returns correct meta values' - ); + test('store.lazyPaginatedQuery', function(assert) { + let response = { + data: ['foo'], + }; + const store = this.owner.factoryFor('service:store').create({ + adapterFor() { + return { + query() { + return resolve(response); + }, + }; + }, + fetchPage() {}, + }); - Ember.run(() => { - store - .fetchPage('transit-key', { - size: pageSize, - page: 3, - responsePath: 'data.keys', - }) - .then(r => { - result = r; - done(); - }); + const query = { page: 1, size: 1, responsePath: 'data' }; + run(function() { + store.lazyPaginatedQuery('transit-key', query); + }); + assert.deepEqual( + store.getDataset('transit-key', query), + { response: { data: null }, dataset: ['foo'] }, + 'stores returned dataset' + ); + assert.throws( + () => { + store.lazyPaginatedQuery('transit-key', {}); + }, + /responsePath is required/, + 'requires responsePath' + ); + assert.throws( + () => { + store.lazyPaginatedQuery('transit-key', { responsePath: 'foo' }); + }, + /page is required/, + 'requires page' + ); + assert.throws( + () => { + store.lazyPaginatedQuery('transit-key', { responsePath: 'foo', page: 1 }); + }, + /size is required/, + 'requires size' + ); }); - - const pageThreeEnd = 3 * pageSize; - const pageThreeStart = pageThreeEnd - pageSize; - assert.deepEqual( - result.mapBy('id'), - keys.slice(pageThreeStart, pageThreeEnd), - 'returns the third page of items' - ); - - Ember.run(() => { - store - .fetchPage('transit-key', { - size: pageSize, - page: 99, - responsePath: 'data.keys', - }) - .then(r => { - result = r; - done(); - }); - }); - - assert.deepEqual( - result.mapBy('id'), - keys.slice(keys.length - 1), - 'returns the last page when the page value is beyond the of bounds' - ); - - Ember.run(() => { - store - .fetchPage('transit-key', { - size: pageSize, - page: 0, - responsePath: 'data.keys', - }) - .then(r => { - result = r; - done(); - }); - }); - assert.deepEqual( - result.mapBy('id'), - keys.slice(0, pageSize), - 'returns the first page when page value is under the bounds' - ); -}); - -test('store.lazyPaginatedQuery', function(assert) { - let response = { - data: ['foo'], - }; - const store = this.subject({ - adapterFor() { - return { - query() { - return Ember.RSVP.resolve(response); - }, - }; - }, - fetchPage() {}, - }); - - const query = { page: 1, size: 1, responsePath: 'data' }; - Ember.run(function() { - store.lazyPaginatedQuery('transit-key', query); - }); - assert.deepEqual( - store.getDataset('transit-key', query), - { response: { data: null }, dataset: ['foo'] }, - 'stores returned dataset' - ); - assert.throws( - () => { - store.lazyPaginatedQuery('transit-key', {}); - }, - /responsePath is required/, - 'requires responsePath' - ); - assert.throws( - () => { - store.lazyPaginatedQuery('transit-key', { responsePath: 'foo' }); - }, - /page is required/, - 'requires page' - ); - assert.throws( - () => { - store.lazyPaginatedQuery('transit-key', { responsePath: 'foo', page: 1 }); - }, - /size is required/, - 'requires size' - ); }); diff --git a/ui/tests/unit/services/version-test.js b/ui/tests/unit/services/version-test.js index 717e08ff2..e52d0399e 100644 --- a/ui/tests/unit/services/version-test.js +++ b/ui/tests/unit/services/version-test.js @@ -1,38 +1,41 @@ -import { moduleFor, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -moduleFor('service:version', 'Unit | Service | version'); +module('Unit | Service | version', function(hooks) { + setupTest(hooks); -test('setting version computes isOSS properly', function(assert) { - let service = this.subject(); - service.set('version', '0.9.5'); - assert.equal(service.get('isOSS'), true); - assert.equal(service.get('isEnterprise'), false); -}); - -test('setting version computes isEnterprise properly', function(assert) { - let service = this.subject(); - service.set('version', '0.9.5+prem'); - assert.equal(service.get('isOSS'), false); - assert.equal(service.get('isEnterprise'), true); -}); - -test('setting version with hsm ending computes isEnterprise properly', function(assert) { - let service = this.subject(); - service.set('version', '0.9.5+prem.hsm'); - assert.equal(service.get('isOSS'), false); - assert.equal(service.get('isEnterprise'), true); -}); - -test('hasPerfReplication', function(assert) { - let service = this.subject(); - assert.equal(service.get('hasPerfReplication'), false); - service.set('_features', ['Performance Replication']); - assert.equal(service.get('hasPerfReplication'), true); -}); - -test('hasDRReplication', function(assert) { - let service = this.subject(); - assert.equal(service.get('hasDRReplication'), false); - service.set('_features', ['DR Replication']); - assert.equal(service.get('hasDRReplication'), true); + test('setting version computes isOSS properly', function(assert) { + let service = this.owner.lookup('service:version'); + service.set('version', '0.9.5'); + assert.equal(service.get('isOSS'), true); + assert.equal(service.get('isEnterprise'), false); + }); + + test('setting version computes isEnterprise properly', function(assert) { + let service = this.owner.lookup('service:version'); + service.set('version', '0.9.5+prem'); + assert.equal(service.get('isOSS'), false); + assert.equal(service.get('isEnterprise'), true); + }); + + test('setting version with hsm ending computes isEnterprise properly', function(assert) { + let service = this.owner.lookup('service:version'); + service.set('version', '0.9.5+prem.hsm'); + assert.equal(service.get('isOSS'), false); + assert.equal(service.get('isEnterprise'), true); + }); + + test('hasPerfReplication', function(assert) { + let service = this.owner.lookup('service:version'); + assert.equal(service.get('hasPerfReplication'), false); + service.set('_features', ['Performance Replication']); + assert.equal(service.get('hasPerfReplication'), true); + }); + + test('hasDRReplication', function(assert) { + let service = this.owner.lookup('service:version'); + assert.equal(service.get('hasDRReplication'), false); + service.set('_features', ['DR Replication']); + assert.equal(service.get('hasDRReplication'), true); + }); }); diff --git a/ui/tests/unit/utils/decode-config-from-jwt-test.js b/ui/tests/unit/utils/decode-config-from-jwt-test.js index 83db8d079..2b1f48848 100644 --- a/ui/tests/unit/utils/decode-config-from-jwt-test.js +++ b/ui/tests/unit/utils/decode-config-from-jwt-test.js @@ -1,30 +1,30 @@ import decodeConfigFromJWT from 'vault/utils/decode-config-from-jwt'; import { module, test } from 'qunit'; -module('Unit | Util | decode config from jwt'); +module('Unit | Util | decode config from jwt', function() { + const PADDING_STRIPPED_TOKEN = + 'eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJhZGRyIjoiaHR0cDovLzE5Mi4xNjguNTAuMTUwOjgyMDAiLCJleHAiOjE1MTczNjkwNzUsImlhdCI6MTUxNzM2NzI3NSwianRpIjoiN2IxZDZkZGUtZmViZC00ZGU1LTc0MWUtZDU2ZTg0ZTNjZDk2IiwidHlwZSI6IndyYXBwaW5nIn0.MIGIAkIB6s2zbohbxLimwhM6cg16OISK2DgoTgy1vHbTjPT8uG4hsrJndZp5COB8dX-djWjx78ZFMk-3a6Ij51su_By9xsoCQgFXV8y3DzH_YzYvdL9x38dMSWaVHpR_lpoKWsQnMvAukSchJp1FfHZQ8JcSkPu5IAVZdfwlG5esJ_ZOMxA3KIQFnA'; + const NO_PADDING_TOKEN = + 'eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJhZGRyIjoiaHR0cDovLzEyNy4wLjAuMTo4MjAwIiwiZXhwIjoxNTE3NDM0NDA2LCJpYXQiOjE1MTc0MzI2MDYsImp0aSI6IjBiYmI1ZWMyLWM0ODgtMzRjYi0wMzY5LTkxZmJiMjVkZTFiYSIsInR5cGUiOiJ3cmFwcGluZyJ9.MIGHAkIBAGzB5EW6PolAi2rYOzZNvfJnR902WxprtRqnSF2E2I2ye9XLGX--L7npSBjBhnd27ocQ4ZO9VhfDIFqMzu1TNiwCQT52O6xAoz9ElRrq76PjkEHO4ns5_ZgjSKXuKaqdGysHYSlry8KEjWLGQECvZWg9LQeIf35jwqeQUfyJUfmwl5r_'; + const INVALID_JSON_TOKEN = `foo.${btoa({ addr: 'http://127.0.0.1' })}.bar`; -const PADDING_STRIPPED_TOKEN = - 'eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJhZGRyIjoiaHR0cDovLzE5Mi4xNjguNTAuMTUwOjgyMDAiLCJleHAiOjE1MTczNjkwNzUsImlhdCI6MTUxNzM2NzI3NSwianRpIjoiN2IxZDZkZGUtZmViZC00ZGU1LTc0MWUtZDU2ZTg0ZTNjZDk2IiwidHlwZSI6IndyYXBwaW5nIn0.MIGIAkIB6s2zbohbxLimwhM6cg16OISK2DgoTgy1vHbTjPT8uG4hsrJndZp5COB8dX-djWjx78ZFMk-3a6Ij51su_By9xsoCQgFXV8y3DzH_YzYvdL9x38dMSWaVHpR_lpoKWsQnMvAukSchJp1FfHZQ8JcSkPu5IAVZdfwlG5esJ_ZOMxA3KIQFnA'; -const NO_PADDING_TOKEN = - 'eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJhZGRyIjoiaHR0cDovLzEyNy4wLjAuMTo4MjAwIiwiZXhwIjoxNTE3NDM0NDA2LCJpYXQiOjE1MTc0MzI2MDYsImp0aSI6IjBiYmI1ZWMyLWM0ODgtMzRjYi0wMzY5LTkxZmJiMjVkZTFiYSIsInR5cGUiOiJ3cmFwcGluZyJ9.MIGHAkIBAGzB5EW6PolAi2rYOzZNvfJnR902WxprtRqnSF2E2I2ye9XLGX--L7npSBjBhnd27ocQ4ZO9VhfDIFqMzu1TNiwCQT52O6xAoz9ElRrq76PjkEHO4ns5_ZgjSKXuKaqdGysHYSlry8KEjWLGQECvZWg9LQeIf35jwqeQUfyJUfmwl5r_'; -const INVALID_JSON_TOKEN = `foo.${btoa({ addr: 'http://127.0.0.1' })}.bar`; + test('it decodes token with no padding', function(assert) { + const config = decodeConfigFromJWT(NO_PADDING_TOKEN); -test('it decodes token with no padding', function(assert) { - const config = decodeConfigFromJWT(NO_PADDING_TOKEN); + assert.ok(!!config, 'config was decoded'); + assert.ok(!!config.addr, 'config.addr is present'); + }); - assert.ok(!!config, 'config was decoded'); - assert.ok(!!config.addr, 'config.addr is present'); -}); - -test('it decodes token with stripped padding', function(assert) { - const config = decodeConfigFromJWT(PADDING_STRIPPED_TOKEN); - - assert.ok(!!config, 'config was decoded'); - assert.ok(!!config.addr, 'config.addr is present'); -}); - -test('it returns nothing if the config is invalid JSON', function(assert) { - const config = decodeConfigFromJWT(INVALID_JSON_TOKEN); - - assert.notOk(config, 'config is not present'); + test('it decodes token with stripped padding', function(assert) { + const config = decodeConfigFromJWT(PADDING_STRIPPED_TOKEN); + + assert.ok(!!config, 'config was decoded'); + assert.ok(!!config.addr, 'config.addr is present'); + }); + + test('it returns nothing if the config is invalid JSON', function(assert) { + const config = decodeConfigFromJWT(INVALID_JSON_TOKEN); + + assert.notOk(config, 'config is not present'); + }); }); diff --git a/ui/tests/unit/utils/trim-right-test.js b/ui/tests/unit/utils/trim-right-test.js index db9ed02ad..0515de525 100644 --- a/ui/tests/unit/utils/trim-right-test.js +++ b/ui/tests/unit/utils/trim-right-test.js @@ -1,28 +1,28 @@ import trimRight from 'vault/utils/trim-right'; import { module, test } from 'qunit'; -module('Unit | Util | trim right'); +module('Unit | Util | trim right', function() { + test('it trims extension array from end of string', function(assert) { + const trimmedName = trimRight('my-file-name-is-cool.json', ['.json', '.txt', '.hcl', '.policy']); -test('it trims extension array from end of string', function(assert) { - const trimmedName = trimRight('my-file-name-is-cool.json', ['.json', '.txt', '.hcl', '.policy']); + assert.equal(trimmedName, 'my-file-name-is-cool'); + }); - assert.equal(trimmedName, 'my-file-name-is-cool'); -}); - -test('it only trims extension array from the very end of string', function(assert) { - const trimmedName = trimRight('my-file-name.json-is-cool.json', ['.json', '.txt', '.hcl', '.policy']); - - assert.equal(trimmedName, 'my-file-name.json-is-cool'); -}); - -test('it returns string as is if trim array is empty', function(assert) { - const trimmedName = trimRight('my-file-name-is-cool.json', []); - - assert.equal(trimmedName, 'my-file-name-is-cool.json'); -}); - -test('it returns string as is if trim array is not passed in', function(assert) { - const trimmedName = trimRight('my-file-name-is-cool.json'); - - assert.equal(trimmedName, 'my-file-name-is-cool.json'); + test('it only trims extension array from the very end of string', function(assert) { + const trimmedName = trimRight('my-file-name.json-is-cool.json', ['.json', '.txt', '.hcl', '.policy']); + + assert.equal(trimmedName, 'my-file-name.json-is-cool'); + }); + + test('it returns string as is if trim array is empty', function(assert) { + const trimmedName = trimRight('my-file-name-is-cool.json', []); + + assert.equal(trimmedName, 'my-file-name-is-cool.json'); + }); + + test('it returns string as is if trim array is not passed in', function(assert) { + const trimmedName = trimRight('my-file-name-is-cool.json'); + + assert.equal(trimmedName, 'my-file-name-is-cool.json'); + }); }); diff --git a/ui/yarn.lock b/ui/yarn.lock index 73b621ae6..ff36e5e22 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2,85 +2,249 @@ # yarn lockfile v1 -"@glimmer/compiler@^0.22.3": - version "0.22.3" - resolved "https://registry.yarnpkg.com/@glimmer/compiler/-/compiler-0.22.3.tgz#3aef9448460af1d320a82423323498a6ff38a0c6" +"@ember/jquery@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@ember/jquery/-/jquery-0.5.2.tgz#fe312c03ada0022fa092d23f7cd7e2eb0374b53a" dependencies: - "@glimmer/syntax" "^0.22.3" - "@glimmer/util" "^0.22.3" - "@glimmer/wire-format" "^0.22.3" - simple-html-tokenizer "^0.3.0" + broccoli-funnel "^2.0.1" + ember-cli-babel "^6.6.0" + jquery "^3.3.1" + resolve "^1.7.1" + +"@ember/optional-features@^0.6.3": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@ember/optional-features/-/optional-features-0.6.4.tgz#8199f853c1781234fcb1f05090cddd0b822bff69" + dependencies: + chalk "^2.3.0" + co "^4.6.0" + ember-cli-version-checker "^2.1.0" + glob "^7.1.2" + inquirer "^3.3.0" + mkdirp "^0.5.1" + silent-error "^1.1.0" + util.promisify "^1.0.0" + +"@ember/ordered-set@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@ember/ordered-set/-/ordered-set-2.0.0.tgz#54f34aba3a1fb75b7c2912a39ab41a4a2e9d266d" + dependencies: + ember-cli-babel "^6.16.0" + ember-compatibility-helpers "^1.0.0" + +"@ember/test-helpers@^0.7.18": + version "0.7.25" + resolved "https://registry.yarnpkg.com/@ember/test-helpers/-/test-helpers-0.7.25.tgz#b4014c108b40ffaf74f3c4d5918800917541541d" + dependencies: + broccoli-funnel "^2.0.1" + ember-cli-babel "^6.12.0" + ember-cli-htmlbars-inline-precompile "^1.0.0" + +"@glimmer/compiler@^0.36.2": + version "0.36.2" + resolved "https://registry.yarnpkg.com/@glimmer/compiler/-/compiler-0.36.2.tgz#c44e08e9795e2c003a54ec605c70870aa61cb6df" + dependencies: + "@glimmer/interfaces" "^0.36.2" + "@glimmer/syntax" "^0.36.2" + "@glimmer/util" "^0.36.2" + "@glimmer/wire-format" "^0.36.2" "@glimmer/di@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@glimmer/di/-/di-0.2.0.tgz#73bfd4a6ee4148a80bf092e8a5d29bcac9d4ce7e" + version "0.2.1" + resolved "https://registry.yarnpkg.com/@glimmer/di/-/di-0.2.1.tgz#5286b6b32040232b751138f6d006130c728d4b3d" -"@glimmer/interfaces@^0.22.3": - version "0.22.3" - resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.22.3.tgz#1c2e3289ae41a750f0c8ddcc64529b9e90dda604" +"@glimmer/interfaces@^0.36.2": + version "0.36.2" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.36.2.tgz#04e2542d06e08cce2e243a9870e0c97edb512f87" dependencies: - "@glimmer/wire-format" "^0.22.3" - -"@glimmer/node@^0.22.3": - version "0.22.3" - resolved "https://registry.yarnpkg.com/@glimmer/node/-/node-0.22.3.tgz#ff33eea6e65147a20c1bd1f05fdc4a6c3595c54c" - dependencies: - "@glimmer/runtime" "^0.22.3" - simple-dom "^0.3.0" - -"@glimmer/object-reference@^0.22.3": - version "0.22.3" - resolved "https://registry.yarnpkg.com/@glimmer/object-reference/-/object-reference-0.22.3.tgz#31db68c8912324c63509b1ef83213f7ad4ef312b" - dependencies: - "@glimmer/reference" "^0.22.3" - "@glimmer/util" "^0.22.3" - -"@glimmer/object@^0.22.3": - version "0.22.3" - resolved "https://registry.yarnpkg.com/@glimmer/object/-/object-0.22.3.tgz#1fc9fd7465c7d12e5b92464ad40038b595de8ed0" - dependencies: - "@glimmer/object-reference" "^0.22.3" - "@glimmer/util" "^0.22.3" - -"@glimmer/reference@^0.22.3": - version "0.22.3" - resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.22.3.tgz#6f2ef8cd97fe756d89fef75f8c3c79003502a2a9" - dependencies: - "@glimmer/util" "^0.22.3" + "@glimmer/wire-format" "^0.36.2" "@glimmer/resolver@^0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@glimmer/resolver/-/resolver-0.4.1.tgz#cd9644572c556e7e799de1cf8eff2b999cf5b878" + version "0.4.3" + resolved "https://registry.yarnpkg.com/@glimmer/resolver/-/resolver-0.4.3.tgz#b1baae5c3291b4621002ccf8d7870466097e841d" dependencies: "@glimmer/di" "^0.2.0" -"@glimmer/runtime@^0.22.3": - version "0.22.3" - resolved "https://registry.yarnpkg.com/@glimmer/runtime/-/runtime-0.22.3.tgz#b8cb28efc9cc86c406ee996f5c2cf6730620d404" - dependencies: - "@glimmer/interfaces" "^0.22.3" - "@glimmer/object" "^0.22.3" - "@glimmer/object-reference" "^0.22.3" - "@glimmer/reference" "^0.22.3" - "@glimmer/util" "^0.22.3" - "@glimmer/wire-format" "^0.22.3" - -"@glimmer/syntax@^0.22.3": - version "0.22.3" - resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.22.3.tgz#8528d19324bf7f920f5cfd31925e452e51781b44" +"@glimmer/syntax@^0.36.2": + version "0.36.2" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.36.2.tgz#86b294693c57ba8a28bfadeb4c09391f2dbf09b7" dependencies: + "@glimmer/interfaces" "^0.36.2" + "@glimmer/util" "^0.36.2" handlebars "^4.0.6" - simple-html-tokenizer "^0.3.0" + simple-html-tokenizer "^0.5.6" -"@glimmer/util@^0.22.3": - version "0.22.3" - resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.22.3.tgz#8272f50905d1bb904ee371e8ade83fd779b51508" +"@glimmer/util@^0.36.2": + version "0.36.2" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.36.2.tgz#6c0f99d0235659969bacffa47f8104f82b28fabe" -"@glimmer/wire-format@^0.22.3": - version "0.22.3" - resolved "https://registry.yarnpkg.com/@glimmer/wire-format/-/wire-format-0.22.3.tgz#19b226d9b93ba6ee54472d9ffb1d48e7c0d80a0d" +"@glimmer/wire-format@^0.36.2": + version "0.36.2" + resolved "https://registry.yarnpkg.com/@glimmer/wire-format/-/wire-format-0.36.2.tgz#49891cc237baa90059d87cb480ec021820bcbfc5" dependencies: - "@glimmer/util" "^0.22.3" + "@glimmer/util" "^0.36.2" + +"@mike-north/js-lib-semantic-release-config@^0.0.0-development": + version "0.0.0-development" + resolved "https://registry.yarnpkg.com/@mike-north/js-lib-semantic-release-config/-/js-lib-semantic-release-config-0.0.0-development.tgz#b3c0f8972036c74dea94208a7f57b5d3a2f7dc1b" + dependencies: + "@semantic-release/changelog" "^3.0.0" + "@semantic-release/error" "^2.2.0" + "@semantic-release/exec" "^3.0.2" + "@semantic-release/git" "^7.0.1" + "@semantic-release/github" "^5.0.2" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.2.tgz#54c5a964462be3d4d78af631363c18d6fa91ac26" + +"@octokit/rest@^15.2.0": + version "15.11.1" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-15.11.1.tgz#ef4e7462ec8f94e535a82220f7b5212111fc2647" + dependencies: + before-after-hook "^1.1.0" + btoa-lite "^1.0.0" + debug "^3.1.0" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.0" + lodash "^4.17.4" + node-fetch "^2.1.1" + url-template "^2.0.8" + +"@semantic-release/changelog@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@semantic-release/changelog/-/changelog-3.0.0.tgz#e01514b517e775cea47aef7df5f5685c7aff2bf2" + dependencies: + "@semantic-release/error" "^2.1.0" + aggregate-error "^1.0.0" + fs-extra "^7.0.0" + lodash "^4.17.4" + +"@semantic-release/commit-analyzer@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-6.0.0.tgz#e26ef70938059f03525573560f65212164953121" + dependencies: + conventional-changelog-angular "^5.0.0" + conventional-commits-filter "^2.0.0" + conventional-commits-parser "^3.0.0" + debug "^3.1.0" + import-from "^2.1.0" + lodash "^4.17.4" + +"@semantic-release/error@^2.1.0", "@semantic-release/error@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@semantic-release/error/-/error-2.2.0.tgz#ee9d5a09c9969eade1ec864776aeda5c5cddbbf0" + +"@semantic-release/exec@^3.0.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@semantic-release/exec/-/exec-3.1.2.tgz#4ed89e5422d02aca9b86fbfd318d230cd29b7065" + dependencies: + "@semantic-release/error" "^2.1.0" + debug "^3.1.0" + execa "^1.0.0" + lodash "^4.17.4" + parse-json "^4.0.0" + +"@semantic-release/git@^7.0.1": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@semantic-release/git/-/git-7.0.3.tgz#758ffbb0156e236f1d731c5d36e2bbf46a8098f2" + dependencies: + "@semantic-release/error" "^2.1.0" + aggregate-error "^1.0.0" + debug "^3.1.0" + dir-glob "^2.0.0" + execa "^1.0.0" + fs-extra "^7.0.0" + globby "^8.0.1" + lodash "^4.17.4" + micromatch "^3.1.4" + p-reduce "^1.0.0" + +"@semantic-release/github@^5.0.0", "@semantic-release/github@^5.0.2": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@semantic-release/github/-/github-5.0.4.tgz#09a870e3fb7ccd1a3eedc4d72a7f0a33c1dce794" + dependencies: + "@octokit/rest" "^15.2.0" + "@semantic-release/error" "^2.2.0" + aggregate-error "^1.0.0" + bottleneck "^2.0.1" + debug "^3.1.0" + dir-glob "^2.0.0" + fs-extra "^7.0.0" + globby "^8.0.0" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + issue-parser "^3.0.0" + lodash "^4.17.4" + mime "^2.0.3" + p-filter "^1.0.0" + p-retry "^2.0.0" + parse-github-url "^1.0.1" + url-join "^4.0.0" + +"@semantic-release/npm@^5.0.1": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@semantic-release/npm/-/npm-5.0.4.tgz#bef4ff31c9a70cc6db7583e08d2d29741b32d2f8" + dependencies: + "@semantic-release/error" "^2.2.0" + aggregate-error "^1.0.0" + detect-indent "^5.0.0" + detect-newline "^2.1.0" + execa "^1.0.0" + fs-extra "^7.0.0" + lodash "^4.17.4" + nerf-dart "^1.0.0" + normalize-url "^3.0.0" + npm "^6.3.0" + parse-json "^4.0.0" + rc "^1.2.8" + read-pkg "^4.0.0" + registry-auth-token "^3.3.1" + +"@semantic-release/release-notes-generator@^7.0.0": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@semantic-release/release-notes-generator/-/release-notes-generator-7.0.1.tgz#300c06b56e965a0aec5d7a83f164b0d7e497ea7b" + dependencies: + conventional-changelog-angular "^5.0.0" + conventional-changelog-writer "^4.0.0" + conventional-commits-filter "^2.0.0" + conventional-commits-parser "^3.0.0" + debug "^3.1.0" + get-stream "^4.0.0" + git-url-parse "^10.0.1" + import-from "^2.1.0" + into-stream "^3.1.0" + lodash "^4.17.4" + +"@sinonjs/formatio@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2" + dependencies: + samsam "1.3.0" + +"@types/acorn@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/acorn/-/acorn-4.0.3.tgz#d1f3e738dde52536f9aad3d3380d14e448820afd" + dependencies: + "@types/estree" "*" + +"@types/estree@*": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + +"@types/estree@0.0.38": + version "0.0.38" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.38.tgz#c1be40aa933723c608820a99a373a16d215a1ca2" + +"@types/node@^9.6.0": + version "9.6.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.31.tgz#4d1722987f8d808b4c194dceb8c213bd92f028e5" "@webassemblyjs/ast@1.5.13": version "1.5.13" @@ -225,19 +389,30 @@ Duration.js@icholy/Duration.js#golang_compatible: chai "~1.7.2" mocha "~1.13.0" +JSONStream@^1.0.4, JSONStream@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.4.tgz#615bb2adb0cd34c8f4c447b5f6512fa1d8f16a2e" + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + "JSV@>= 4.0.x": version "4.0.2" resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57" -abbrev@1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" +abab@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" -accepts@1.3.3, accepts@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" +abbrev@1, abbrev@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +accepts@~1.3.4, accepts@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" dependencies: - mime-types "~2.1.11" + mime-types "~2.1.18" negotiator "0.6.1" acorn-dynamic-import@^3.0.0: @@ -246,6 +421,12 @@ acorn-dynamic-import@^3.0.0: dependencies: acorn "^5.0.0" +acorn-globals@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" + dependencies: + acorn "^5.0.0" + acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" @@ -256,94 +437,60 @@ acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" -acorn@^4.0.3: - version "4.0.13" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" +acorn@^5.0.0, acorn@^5.5.0, acorn@^5.5.3, acorn@^5.6.2: + version "5.7.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.2.tgz#91fa871883485d06708800318404e72bfb26dcc5" -acorn@^5.0.0, acorn@^5.6.2: - version "5.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" -acorn@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75" +agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + dependencies: + es6-promisify "^5.0.0" -after@0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/after/-/after-0.8.1.tgz#ab5d4fb883f596816d3515f8f791c0af486dd627" +agentkeepalive@^3.4.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.1.tgz#4eba75cf2ad258fc09efd506cdb8d8c2971d35a4" + dependencies: + humanize-ms "^1.2.1" -ajv-keywords@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" +aggregate-error@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-1.0.0.tgz#888344dad0220a72e3af50906117f48771925fac" + dependencies: + clean-stack "^1.0.0" + indent-string "^3.0.0" + +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" ajv-keywords@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" -ajv@^4.7.0, ajv@^4.9.1: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" - -ajv@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39" +ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" - json-stable-stringify "^1.0.1" ajv@^6.1.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360" + version "6.5.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9" dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" - uri-js "^4.2.1" + uri-js "^4.2.2" -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - -alter@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/alter/-/alter-0.2.0.tgz#c7588808617572034aae62480af26b1d4d1cb3cd" - dependencies: - stable "~0.1.3" - -amd-name-resolver@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/amd-name-resolver/-/amd-name-resolver-0.0.5.tgz#76962dac876ed3311b05d29c6a58c14e1ef3304b" - dependencies: - ensure-posix-path "^1.0.1" - -amd-name-resolver@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/amd-name-resolver/-/amd-name-resolver-0.0.6.tgz#d3e4ba2dfcaab1d820c1be9de947c67828cfe595" - dependencies: - ensure-posix-path "^1.0.1" - -amd-name-resolver@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/amd-name-resolver/-/amd-name-resolver-0.0.7.tgz#814301adfe8a2f109f6e84d5e935196efb669615" - dependencies: - ensure-posix-path "^1.0.1" - -amd-name-resolver@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/amd-name-resolver/-/amd-name-resolver-1.0.0.tgz#0e593b28d6fa3326ab1798107edaea961046e8d8" - dependencies: - ensure-posix-path "^1.0.1" - -amd-name-resolver@1.2.0: +amd-name-resolver@1.2.0, amd-name-resolver@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/amd-name-resolver/-/amd-name-resolver-1.2.0.tgz#fc41b3848824b557313897d71f8d5a0184fbe679" dependencies: @@ -353,19 +500,21 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + dependencies: + string-width "^2.0.0" + ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" -ansi-escapes@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" -ansi-regex@^0.2.0, ansi-regex@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9" - -ansi-regex@^2.0.0, ansi-regex@^2.1.1: +ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -373,21 +522,11 @@ ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" -ansi-styles@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" - ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@^3.0.0, ansi-styles@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.1.0.tgz#09c202d5c917ec23188caa5c9cb9179cd9547750" - dependencies: - color-convert "^1.0.0" - -ansi-styles@^3.2.1: +ansi-styles@^3.0.0, ansi-styles@^3.1.0, ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" dependencies: @@ -401,12 +540,13 @@ ansicolors@~0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" -anymatch@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" - dependencies: - arrify "^1.0.0" - micromatch "^2.1.5" +ansicolors@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" + +ansistyles@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539" anymatch@^2.0.0: version "2.0.0" @@ -429,27 +569,35 @@ applause@1.2.2: js-yaml "^3.3.0" lodash "^3.10.0" -aproba@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" - -aproba@^1.1.1: +aproba@^1.0.3, aproba@^1.1.1, aproba@^1.1.2, aproba@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" +"aproba@^1.1.2 || 2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + +archy@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" dependencies: delegates "^1.0.0" readable-stream "^2.0.6" argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" dependencies: sprintf-js "~1.0.2" +argv-formatter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/argv-formatter/-/argv-formatter-1.0.0.tgz#a0ca0cbc29a5b73e836eebe1cbf6c5e0e4eb82f9" + arr-diff@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" @@ -480,6 +628,10 @@ array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" +array-ify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + array-to-error@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/array-to-error/-/array-to-error-1.1.1.tgz#d68812926d14097a205579a667eeaf1856a44c07" @@ -496,7 +648,7 @@ array-union@^1.0.1: dependencies: array-uniq "^1.0.1" -array-uniq@^1.0.1: +array-uniq@^1.0.0, array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" @@ -508,14 +660,18 @@ array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" -arraybuffer.slice@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca" +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" +asap@^2.0.0: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -525,17 +681,15 @@ asn1.js@^4.0.0: minimalistic-assert "^1.0.0" asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + dependencies: + safer-buffer "~2.1.0" assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - assert@^1.1.1: version "1.4.1" resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" @@ -550,21 +704,13 @@ assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" -ast-traverse@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ast-traverse/-/ast-traverse-0.1.1.tgz#69cf2b8386f19dcda1bb1e05d68fe359d8897de6" - -ast-types@0.8.12: - version "0.8.12" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.12.tgz#a0d90e4351bb887716c83fd637ebf818af4adfcc" - ast-types@0.9.6: version "0.9.6" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" async-disk-cache@^1.2.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/async-disk-cache/-/async-disk-cache-1.3.2.tgz#ac53d6152843df202c9406e28d774362608d74dd" + version "1.3.3" + resolved "https://registry.yarnpkg.com/async-disk-cache/-/async-disk-cache-1.3.3.tgz#6040486660b370e4051cd9fa9fee275e1fae3728" dependencies: debug "^2.1.3" heimdalljs "^0.2.3" @@ -582,41 +728,42 @@ async-foreach@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" -async-promise-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/async-promise-queue/-/async-promise-queue-1.0.3.tgz#70c9c37635620f894978814b6c65e6e14e2573ee" +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + +async-promise-queue@^1.0.3, async-promise-queue@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/async-promise-queue/-/async-promise-queue-1.0.4.tgz#308baafbc74aff66a0bb6e7f4a18d4fe8434440c" dependencies: async "^2.4.1" + debug "^2.6.8" -async@^1.4.0, async@^1.5.0, async@^1.5.2: +async@^1.5.0, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" -async@^2.4.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" +async@^2.4.1, async@^2.5.0, async@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" dependencies: - lodash "^4.14.0" + lodash "^4.17.10" async@~0.2.9: version "0.2.10" resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" -async@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" -atob@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" autoprefixer@^7.0.0: version "7.2.6" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.2.6.tgz#256672f86f7c735da849c4f07d008abb056067dc" + resolved "http://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz#256672f86f7c735da849c4f07d008abb056067dc" dependencies: browserslist "^2.11.3" caniuse-lite "^1.0.30000805" @@ -629,23 +776,15 @@ autosize@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/autosize/-/autosize-4.0.2.tgz#073cfd07c8bf45da4b9fd153437f5bafbba1e4c9" -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" -aws4@^1.2.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" +aws4@^1.6.0, aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" -babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" - dependencies: - chalk "^1.1.0" - esutils "^2.0.2" - js-tokens "^3.0.0" - -babel-code-frame@^6.26.0: +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -653,82 +792,7 @@ babel-code-frame@^6.26.0: esutils "^2.0.2" js-tokens "^3.0.2" -babel-core@^5.0.0: - version "5.8.38" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-5.8.38.tgz#1fcaee79d7e61b750b00b8e54f6dfc9d0af86558" - dependencies: - babel-plugin-constant-folding "^1.0.1" - babel-plugin-dead-code-elimination "^1.0.2" - babel-plugin-eval "^1.0.1" - babel-plugin-inline-environment-variables "^1.0.1" - babel-plugin-jscript "^1.0.4" - babel-plugin-member-expression-literals "^1.0.1" - babel-plugin-property-literals "^1.0.1" - babel-plugin-proto-to-assign "^1.0.3" - babel-plugin-react-constant-elements "^1.0.3" - babel-plugin-react-display-name "^1.0.3" - babel-plugin-remove-console "^1.0.1" - babel-plugin-remove-debugger "^1.0.1" - babel-plugin-runtime "^1.0.7" - babel-plugin-undeclared-variables-check "^1.0.2" - babel-plugin-undefined-to-void "^1.1.6" - babylon "^5.8.38" - bluebird "^2.9.33" - chalk "^1.0.0" - convert-source-map "^1.1.0" - core-js "^1.0.0" - debug "^2.1.1" - detect-indent "^3.0.0" - esutils "^2.0.0" - fs-readdir-recursive "^0.1.0" - globals "^6.4.0" - home-or-tmp "^1.0.0" - is-integer "^1.0.4" - js-tokens "1.0.1" - json5 "^0.4.0" - lodash "^3.10.0" - minimatch "^2.0.3" - output-file-sync "^1.1.0" - path-exists "^1.0.0" - path-is-absolute "^1.0.0" - private "^0.1.6" - regenerator "0.8.40" - regexpu "^1.3.0" - repeating "^1.1.2" - resolve "^1.1.6" - shebang-regex "^1.0.0" - slash "^1.0.0" - source-map "^0.5.0" - source-map-support "^0.2.10" - to-fast-properties "^1.0.0" - trim-right "^1.0.0" - try-resolve "^1.0.0" - -babel-core@^6.14.0, babel-core@^6.24.1: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729" - dependencies: - babel-code-frame "^6.22.0" - babel-generator "^6.25.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.25.0" - babel-traverse "^6.25.0" - babel-types "^6.25.0" - babylon "^6.17.2" - convert-source-map "^1.1.0" - debug "^2.1.1" - json5 "^0.5.0" - lodash "^4.2.0" - minimatch "^3.0.2" - path-is-absolute "^1.0.0" - private "^0.1.6" - slash "^1.0.0" - source-map "^0.5.0" - -babel-core@^6.26.0, babel-core@^6.26.3: +babel-core@^6.24.1, babel-core@^6.26.0, babel-core@^6.26.3: version "6.26.3" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" dependencies: @@ -752,19 +816,6 @@ babel-core@^6.26.0, babel-core@^6.26.3: slash "^1.0.0" source-map "^0.5.7" -babel-generator@^6.25.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.25.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.2.0" - source-map "^0.5.0" - trim-right "^1.0.1" - babel-generator@^6.26.0: version "6.26.1" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" @@ -796,13 +847,13 @@ babel-helper-call-delegate@^6.24.1: babel-types "^6.24.1" babel-helper-define-map@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz#7a9747f258d8947d32d515f6aa1c7bd02204a080" + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" dependencies: babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - lodash "^4.2.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" babel-helper-explode-assignable-expression@^6.24.1: version "6.24.1" @@ -844,12 +895,12 @@ babel-helper-optimise-call-expression@^6.24.1: babel-types "^6.24.1" babel-helper-regex@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz#d36e22fab1008d79d88648e32116868128456ce8" + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - lodash "^4.2.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" babel-helper-remap-async-to-generator@^6.24.1: version "6.24.1" @@ -891,115 +942,57 @@ babel-plugin-check-es2015-constants@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-constant-folding@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-constant-folding/-/babel-plugin-constant-folding-1.0.1.tgz#8361d364c98e449c3692bdba51eff0844290aa8e" - -babel-plugin-dead-code-elimination@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-dead-code-elimination/-/babel-plugin-dead-code-elimination-1.0.2.tgz#5f7c451274dcd7cccdbfbb3e0b85dd28121f0f65" - babel-plugin-debug-macros@^0.1.10, babel-plugin-debug-macros@^0.1.11: version "0.1.11" resolved "https://registry.yarnpkg.com/babel-plugin-debug-macros/-/babel-plugin-debug-macros-0.1.11.tgz#6c562bf561fccd406ce14ab04f42c218cf956605" dependencies: semver "^5.3.0" -babel-plugin-ember-modules-api-polyfill@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-1.4.2.tgz#e254f8ed0ba7cf32ea6a71c4770b3568a8577402" +babel-plugin-debug-macros@^0.2.0-beta.6: + version "0.2.0-beta.6" + resolved "https://registry.yarnpkg.com/babel-plugin-debug-macros/-/babel-plugin-debug-macros-0.2.0-beta.6.tgz#ecdf6e408d5c863ab21740d7ad7f43f027d2f912" dependencies: - ember-rfc176-data "^0.2.0" + semver "^5.3.0" -babel-plugin-ember-modules-api-polyfill@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-2.0.1.tgz#baaf26dcebe2ed1de120021bc42be29f520497b3" - dependencies: - ember-rfc176-data "^0.2.7" - -babel-plugin-ember-modules-api-polyfill@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-2.3.0.tgz#0c01f359658cfb9c797f705af6b09f6220205ae0" +babel-plugin-ember-modules-api-polyfill@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-2.3.2.tgz#56ea34bea963498d070a2b7dc2ce18a92c434093" dependencies: ember-rfc176-data "^0.3.0" -babel-plugin-eval@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-eval/-/babel-plugin-eval-1.0.1.tgz#a2faed25ce6be69ade4bfec263f70169195950da" - -babel-plugin-feature-flags@^0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/babel-plugin-feature-flags/-/babel-plugin-feature-flags-0.2.3.tgz#81d81ed77bda2014098fa8243abcf03a551cbd4d" +babel-plugin-ember-modules-api-polyfill@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-2.4.0.tgz#3db44fb214b56a1965f80b9f042ca1b6670559fb" dependencies: - json-stable-stringify "^1.0.1" + ember-rfc176-data "^0.3.4" -babel-plugin-filter-imports@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/babel-plugin-filter-imports/-/babel-plugin-filter-imports-0.2.1.tgz#784f96a892f2f7ed2ccf0955688bd8916cd2e212" - dependencies: - json-stable-stringify "^1.0.1" +babel-plugin-feature-flags@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-feature-flags/-/babel-plugin-feature-flags-0.3.1.tgz#9c827cf9a4eb9a19f725ccb239e85cab02036fc1" -babel-plugin-htmlbars-inline-precompile@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-0.2.3.tgz#cd365e278af409bfa6be7704c4354beee742446b" +babel-plugin-filter-imports@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-filter-imports/-/babel-plugin-filter-imports-0.3.1.tgz#e7859b56886b175dd2616425d277b219e209ea8b" -babel-plugin-inline-environment-variables@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-inline-environment-variables/-/babel-plugin-inline-environment-variables-1.0.1.tgz#1f58ce91207ad6a826a8bf645fafe68ff5fe3ffe" - -babel-plugin-jscript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/babel-plugin-jscript/-/babel-plugin-jscript-1.0.4.tgz#8f342c38276e87a47d5fa0a8bd3d5eb6ccad8fcc" - -babel-plugin-member-expression-literals@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-member-expression-literals/-/babel-plugin-member-expression-literals-1.0.1.tgz#cc5edb0faa8dc927170e74d6d1c02440021624d3" - -babel-plugin-property-literals@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-property-literals/-/babel-plugin-property-literals-1.0.1.tgz#0252301900192980b1c118efea48ce93aab83336" - -babel-plugin-proto-to-assign@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/babel-plugin-proto-to-assign/-/babel-plugin-proto-to-assign-1.0.4.tgz#c49e7afd02f577bc4da05ea2df002250cf7cd123" - dependencies: - lodash "^3.9.3" - -babel-plugin-react-constant-elements@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/babel-plugin-react-constant-elements/-/babel-plugin-react-constant-elements-1.0.3.tgz#946736e8378429cbc349dcff62f51c143b34e35a" - -babel-plugin-react-display-name@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/babel-plugin-react-display-name/-/babel-plugin-react-display-name-1.0.3.tgz#754fe38926e8424a4e7b15ab6ea6139dee0514fc" - -babel-plugin-remove-console@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-remove-console/-/babel-plugin-remove-console-1.0.1.tgz#d8f24556c3a05005d42aaaafd27787f53ff013a7" - -babel-plugin-remove-debugger@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-remove-debugger/-/babel-plugin-remove-debugger-1.0.1.tgz#fd2ea3cd61a428ad1f3b9c89882ff4293e8c14c7" - -babel-plugin-runtime@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/babel-plugin-runtime/-/babel-plugin-runtime-1.0.7.tgz#bf7c7d966dd56ecd5c17fa1cb253c9acb7e54aaf" +babel-plugin-htmlbars-inline-precompile@^0.2.5: + version "0.2.6" + resolved "https://registry.yarnpkg.com/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-0.2.6.tgz#c00b8a3f4b32ca04bf0f0d5169fcef3b5a66d69d" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + resolved "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" babel-plugin-syntax-dynamic-import@^6.18.0: version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + resolved "http://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + resolved "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + resolved "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" @@ -1025,15 +1018,15 @@ babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576" +babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es2015-block-scoping@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - lodash "^4.2.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" babel-plugin-transform-es2015-classes@^6.23.0: version "6.24.1" @@ -1098,13 +1091,13 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015 babel-template "^6.24.1" babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe" + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" dependencies: babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-types "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" babel-plugin-transform-es2015-modules-systemjs@^6.23.0: version "6.24.1" @@ -1190,17 +1183,17 @@ babel-plugin-transform-exponentiation-operator@^6.22.0: babel-runtime "^6.22.0" babel-plugin-transform-object-rest-spread@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz#875d6bc9be761c58a2ae3feee5dc4895d8c7f921" + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" dependencies: babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-runtime "^6.22.0" + babel-runtime "^6.26.0" babel-plugin-transform-regenerator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418" + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" dependencies: - regenerator-transform "0.9.11" + regenerator-transform "^0.10.0" babel-plugin-transform-strict-mode@^6.24.1: version "6.24.1" @@ -1209,24 +1202,6 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-runtime "^6.22.0" babel-types "^6.24.1" -babel-plugin-undeclared-variables-check@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-undeclared-variables-check/-/babel-plugin-undeclared-variables-check-1.0.2.tgz#5cf1aa539d813ff64e99641290af620965f65dee" - dependencies: - leven "^1.0.2" - -babel-plugin-undefined-to-void@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/babel-plugin-undefined-to-void/-/babel-plugin-undefined-to-void-1.1.6.tgz#7f578ef8b78dfae6003385d8417a61eda06e2f81" - -babel-polyfill@^6.16.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" - dependencies: - babel-runtime "^6.22.0" - core-js "^2.4.0" - regenerator-runtime "^0.10.0" - babel-polyfill@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" @@ -1235,41 +1210,6 @@ babel-polyfill@^6.26.0: core-js "^2.5.0" regenerator-runtime "^0.10.5" -babel-preset-env@^1.5.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.0.tgz#2de1c782a780a0a5d605d199c957596da43c44e4" - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^2.1.2" - invariant "^2.2.2" - semver "^5.3.0" - babel-preset-env@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" @@ -1305,18 +1245,6 @@ babel-preset-env@^1.7.0: invariant "^2.2.2" semver "^5.3.0" -babel-register@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f" - dependencies: - babel-core "^6.24.1" - babel-runtime "^6.22.0" - core-js "^2.4.0" - home-or-tmp "^2.0.0" - lodash "^4.2.0" - mkdirp "^0.5.1" - source-map-support "^0.4.2" - babel-register@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" @@ -1329,31 +1257,14 @@ babel-register@^6.26.0: mkdirp "^0.5.1" source-map-support "^0.4.15" -babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.10.0" - -babel-runtime@^6.26.0: +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" dependencies: core-js "^2.4.0" regenerator-runtime "^0.11.0" -babel-template@^6.24.1, babel-template@^6.25.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.25.0" - babel-types "^6.25.0" - babylon "^6.17.2" - lodash "^4.2.0" - -babel-template@^6.26.0: +babel-template@^6.24.1, babel-template@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" dependencies: @@ -1363,21 +1274,7 @@ babel-template@^6.26.0: babylon "^6.18.0" lodash "^4.17.4" -babel-traverse@^6.24.1, babel-traverse@^6.25.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1" - dependencies: - babel-code-frame "^6.22.0" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.25.0" - babylon "^6.17.2" - debug "^2.2.0" - globals "^9.0.0" - invariant "^2.2.0" - lodash "^4.2.0" - -babel-traverse@^6.26.0: +babel-traverse@^6.24.1, babel-traverse@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" dependencies: @@ -1391,16 +1288,7 @@ babel-traverse@^6.26.0: invariant "^2.2.2" lodash "^4.17.4" -babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.25.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" - dependencies: - babel-runtime "^6.22.0" - esutils "^2.0.2" - lodash "^4.2.0" - to-fast-properties "^1.0.1" - -babel-types@^6.26.0: +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" dependencies: @@ -1409,21 +1297,13 @@ babel-types@^6.26.0: lodash "^4.17.4" to-fast-properties "^1.0.3" -babel5-plugin-strip-class-callcheck@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/babel5-plugin-strip-class-callcheck/-/babel5-plugin-strip-class-callcheck-5.1.0.tgz#77d4a40c8614d367b8a21a53908159806dba5f91" +babel6-plugin-strip-class-callcheck@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/babel6-plugin-strip-class-callcheck/-/babel6-plugin-strip-class-callcheck-6.0.0.tgz#de841c1abebbd39f78de0affb2c9a52ee228fddf" -babel5-plugin-strip-heimdall@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/babel5-plugin-strip-heimdall/-/babel5-plugin-strip-heimdall-5.0.2.tgz#e1fe191c34de79686564d50a86f4217b8df629c1" - -babylon@^5.8.38: - version "5.8.38" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-5.8.38.tgz#ec9b120b11bf6ccd4173a18bf217e60b79859ffd" - -babylon@^6.17.2: - version "6.17.4" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a" +babel6-plugin-strip-heimdall@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/babel6-plugin-strip-heimdall/-/babel6-plugin-strip-heimdall-6.0.1.tgz#35f80eddec1f7fffdc009811dfbd46d9965072b6" babylon@^6.18.0: version "6.18.0" @@ -1455,9 +1335,9 @@ base64-js@^1.0.2: version "1.3.0" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" -base64id@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/base64id/-/base64id-0.1.0.tgz#02ce0fdeee0cef4f40080e1e73e834f0b1bfce3f" +base64id@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" base@^0.11.1: version "0.11.2" @@ -1471,16 +1351,22 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -basic-auth@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.1.0.tgz#45221ee429f7ee1e5035be3f51533f1cdfd29884" +basic-auth@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.0.tgz#015db3f353e02e56377755f962742e8981e7bbba" + dependencies: + safe-buffer "5.1.1" bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" dependencies: tweetnacl "^0.14.3" +before-after-hook@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.1.0.tgz#83165e15a59460d13702cb8febd6a1807896db5a" + better-assert@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" @@ -1495,13 +1381,23 @@ bignumber.js@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8" +bin-links@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.2.tgz#fb74bd54bae6b7befc6c6221f25322ac830d9757" + dependencies: + bluebird "^3.5.0" + cmd-shim "^2.0.2" + gentle-fs "^2.0.0" + graceful-fs "^4.1.11" + write-file-atomic "^2.3.0" + binary-extensions@^1.0.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" + version "1.11.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" "binaryextensions@1 || 2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.0.0.tgz#e597d1a7a6a3558a2d1c7241a16c99965e6aa40f" + version "2.1.1" + resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935" blank-object@^1.0.1: version "1.0.2" @@ -1517,17 +1413,9 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@^2.9.33: - version "2.11.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" - -bluebird@^3.1.1, bluebird@^3.3.5, bluebird@^3.4.6: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" - -bluebird@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" +bluebird@^3.1.1, bluebird@^3.3.5, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@~3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.2.tgz#1be0908e054a751754549c270489c1505d4ab15a" bmp-js@0.0.1: version "0.0.1" @@ -1541,7 +1429,7 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" -body-parser@^1.17.0: +body-parser@1.18.2: version "1.18.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" dependencies: @@ -1556,6 +1444,21 @@ body-parser@^1.17.0: raw-body "2.3.2" type-is "~1.6.15" +body-parser@^1.17.0: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" + on-finished "~2.3.0" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" + body@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/body/-/body-5.1.0.tgz#e4ba0ce410a46936323367609ecb4e6553125069" @@ -1573,15 +1476,13 @@ boolify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/boolify/-/boolify-1.0.1.tgz#b5c09e17cacd113d11b7bb3ed384cc012994d86b" -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - dependencies: - hoek "2.x.x" +bottleneck@^2.0.1: + version "2.9.0" + resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.9.0.tgz#1cf11c3c9db1b65075fae03967418ea03ba66814" bower-config@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/bower-config/-/bower-config-1.4.0.tgz#16c38c1135f8071c19f25938d61b0d8cbf18d3f1" + version "1.4.1" + resolved "https://registry.yarnpkg.com/bower-config/-/bower-config-1.4.1.tgz#85fd9df367c2b8dbbd0caa4c5f2bad40cd84c2cc" dependencies: graceful-fs "^4.1.3" mout "^1.0.0" @@ -1593,9 +1494,21 @@ bower-endpoint-parser@0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz#00b565adbfab6f2d35addde977e97962acbcb3f6" -brace-expansion@^1.0.0, brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -1623,18 +1536,22 @@ braces@^2.3.0, braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -breakable@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/breakable/-/breakable-1.0.0.tgz#784a797915a38ead27bad456b5572cb4bbaa78c1" +broccoli-amd-funnel@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/broccoli-amd-funnel/-/broccoli-amd-funnel-1.3.0.tgz#c4426b4fce976e44295bd74f34725f53bdeb08e3" + dependencies: + broccoli-plugin "^1.3.0" + symlink-or-copy "^1.2.0" -broccoli-asset-rev@^2.4.5: - version "2.5.0" - resolved "https://registry.yarnpkg.com/broccoli-asset-rev/-/broccoli-asset-rev-2.5.0.tgz#f5f66eac962bf9f086286921f0eaeaab6d00d819" +broccoli-asset-rev@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/broccoli-asset-rev/-/broccoli-asset-rev-2.7.0.tgz#c73da1d97c4180366fa442a87624ca1b7fb99161" dependencies: broccoli-asset-rewrite "^1.1.0" broccoli-filter "^1.2.2" + broccoli-persistent-filter "^1.4.3" json-stable-stringify "^1.0.0" - matcher-collection "^1.0.1" + minimatch "^3.0.4" rsvp "^3.0.6" broccoli-asset-rewrite@^1.1.0: @@ -1651,54 +1568,9 @@ broccoli-autoprefixer@^5.0.0: broccoli-persistent-filter "^1.1.6" postcss "^6.0.1" -broccoli-babel-transpiler@^5.5.0, broccoli-babel-transpiler@^5.6.2: - version "5.7.1" - resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-5.7.1.tgz#e10d831faed1c57e37272e4223748ba71a7926d1" - dependencies: - babel-core "^5.0.0" - broccoli-funnel "^1.0.0" - broccoli-merge-trees "^1.0.0" - broccoli-persistent-filter "^1.4.2" - clone "^0.2.0" - hash-for-dep "^1.0.2" - heimdalljs-logger "^0.1.7" - json-stable-stringify "^1.0.0" - rsvp "^3.5.0" - workerpool "^2.2.1" - -broccoli-babel-transpiler@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-6.1.1.tgz#938f470e1ddb47047a77ef5e38f34c21de0e85a8" - dependencies: - babel-core "^6.14.0" - broccoli-funnel "^1.0.0" - broccoli-merge-trees "^1.0.0" - broccoli-persistent-filter "^1.4.0" - clone "^2.0.0" - hash-for-dep "^1.0.2" - heimdalljs-logger "^0.1.7" - json-stable-stringify "^1.0.0" - rsvp "^3.5.0" - workerpool "^2.2.1" - -broccoli-babel-transpiler@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-6.1.2.tgz#26019c045b5ea3e44cfef62821302f9bd483cabd" - dependencies: - babel-core "^6.14.0" - broccoli-funnel "^1.0.0" - broccoli-merge-trees "^1.0.0" - broccoli-persistent-filter "^1.4.0" - clone "^2.0.0" - hash-for-dep "^1.0.2" - heimdalljs-logger "^0.1.7" - json-stable-stringify "^1.0.0" - rsvp "^3.5.0" - workerpool "^2.2.1" - -broccoli-babel-transpiler@^6.4.2: - version "6.4.3" - resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-6.4.3.tgz#06e399298d41700cdc10d675b1d808a89ef6b2d0" +broccoli-babel-transpiler@^6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-6.5.0.tgz#aa501a227b298a99742fdd0309b1eaad7124bba0" dependencies: babel-core "^6.26.0" broccoli-funnel "^2.0.1" @@ -1711,16 +1583,11 @@ broccoli-babel-transpiler@^6.4.2: rsvp "^4.8.2" workerpool "^2.3.0" -broccoli-brocfile-loader@^0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/broccoli-brocfile-loader/-/broccoli-brocfile-loader-0.18.0.tgz#2e86021c805c34ffc8d29a2fb721cf273e819e4b" - dependencies: - findup-sync "^0.4.2" - -broccoli-builder@^0.18.8: - version "0.18.11" - resolved "https://registry.yarnpkg.com/broccoli-builder/-/broccoli-builder-0.18.11.tgz#a42393c7b10bb0380df255a616307945f5e26efb" +broccoli-builder@^0.18.14: + version "0.18.14" + resolved "https://registry.yarnpkg.com/broccoli-builder/-/broccoli-builder-0.18.14.tgz#4b79e2f844de11a4e1b816c3f49c6df4776c312d" dependencies: + broccoli-node-info "^1.1.0" heimdalljs "^0.2.0" promise-map-series "^0.2.1" quick-temp "^0.1.2" @@ -1759,24 +1626,24 @@ broccoli-clean-css@^1.1.0: inline-source-map-comment "^1.0.5" json-stable-stringify "^1.0.0" -broccoli-concat@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/broccoli-concat/-/broccoli-concat-3.2.2.tgz#86ffdc52606eb590ba9f6b894c5ec7a016f5b7b9" +broccoli-concat@^3.2.2, broccoli-concat@^3.5.1, broccoli-concat@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/broccoli-concat/-/broccoli-concat-3.7.1.tgz#22ba97420b33f5254549adc5bc41163f97bd1793" dependencies: + broccoli-debug "^0.6.4" broccoli-kitchen-sink-helpers "^0.3.1" broccoli-plugin "^1.3.0" - broccoli-stew "^1.3.3" ensure-posix-path "^1.0.2" - fast-sourcemap-concat "^1.0.1" + fast-sourcemap-concat "^1.4.0" find-index "^1.1.0" - fs-extra "^1.0.0" - fs-tree-diff "^0.5.6" - lodash.merge "^4.3.0" + fs-extra "^4.0.3" + fs-tree-diff "^0.5.7" + lodash.merge "^4.3.1" lodash.omit "^4.1.0" lodash.uniq "^4.2.0" - walk-sync "^0.3.1" + walk-sync "^0.3.2" -broccoli-config-loader@^1.0.0: +broccoli-config-loader@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/broccoli-config-loader/-/broccoli-config-loader-1.0.1.tgz#d10aaf8ebc0cb45c1da5baa82720e1d88d28c80a" dependencies: @@ -1791,19 +1658,7 @@ broccoli-config-replace@^1.1.2: debug "^2.2.0" fs-extra "^0.24.0" -broccoli-debug@^0.6.1, broccoli-debug@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/broccoli-debug/-/broccoli-debug-0.6.2.tgz#4c6e89459fc3de7d5d4fc7b77e57f46019f44db1" - dependencies: - broccoli-plugin "^1.2.1" - fs-tree-diff "^0.5.2" - heimdalljs "^0.2.1" - heimdalljs-logger "^0.1.7" - minimatch "^3.0.3" - symlink-or-copy "^1.1.8" - tree-sync "^1.2.2" - -broccoli-debug@^0.6.3, broccoli-debug@^0.6.4: +broccoli-debug@^0.6.1, broccoli-debug@^0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/broccoli-debug/-/broccoli-debug-0.6.4.tgz#986eb3d2005e00e3bb91f9d0a10ab137210cd150" dependencies: @@ -1823,16 +1678,19 @@ broccoli-favicon@1.0.0: favicons "^4.7.1" lodash "^4.10.0" -broccoli-file-creator@^1.0.0, broccoli-file-creator@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/broccoli-file-creator/-/broccoli-file-creator-1.1.1.tgz#1b35b67d215abdfadd8d49eeb69493c39e6c3450" +broccoli-file-creator@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/broccoli-file-creator/-/broccoli-file-creator-1.2.0.tgz#27f1b25b1b00e7bb7bf3d5d7abed5f4d5388df4d" + dependencies: + broccoli-plugin "^1.1.0" + mkdirp "^0.5.1" + +broccoli-file-creator@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/broccoli-file-creator/-/broccoli-file-creator-2.1.1.tgz#7351dd2496c762cfce7736ce9b49e3fce0c7b7db" dependencies: - broccoli-kitchen-sink-helpers "~0.2.0" broccoli-plugin "^1.1.0" - broccoli-writer "~0.1.1" mkdirp "^0.5.1" - rsvp "~3.0.6" - symlink-or-copy "^1.0.1" broccoli-filter@^0.1.11: version "0.1.14" @@ -1847,9 +1705,9 @@ broccoli-filter@^0.1.11: symlink-or-copy "^1.0.1" walk-sync "^0.1.3" -broccoli-filter@^1.0.1, broccoli-filter@^1.2.2, broccoli-filter@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/broccoli-filter/-/broccoli-filter-1.2.4.tgz#409afb94b9a3a6da9fac8134e91e205f40cc7330" +broccoli-filter@^1.2.2, broccoli-filter@^1.2.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/broccoli-filter/-/broccoli-filter-1.3.0.tgz#71e3a8e32a17f309e12261919c5b1006d6766de6" dependencies: broccoli-kitchen-sink-helpers "^0.3.1" broccoli-plugin "^1.0.0" @@ -1865,7 +1723,7 @@ broccoli-funnel-reducer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/broccoli-funnel-reducer/-/broccoli-funnel-reducer-1.0.0.tgz#11365b2a785aec9b17972a36df87eef24c5cc0ea" -broccoli-funnel@^1.0.0, broccoli-funnel@^1.0.1, broccoli-funnel@^1.0.2, broccoli-funnel@^1.0.6, broccoli-funnel@^1.1.0, broccoli-funnel@^1.2.0: +broccoli-funnel@^1.0.0, broccoli-funnel@^1.0.1, broccoli-funnel@^1.0.2, broccoli-funnel@^1.1.0, broccoli-funnel@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-1.2.0.tgz#cddc3afc5ff1685a8023488fff74ce6fb5a51296" dependencies: @@ -1902,7 +1760,7 @@ broccoli-funnel@^2.0.0, broccoli-funnel@^2.0.1: symlink-or-copy "^1.0.0" walk-sync "^0.3.1" -broccoli-kitchen-sink-helpers@^0.2.5, broccoli-kitchen-sink-helpers@^0.2.6, broccoli-kitchen-sink-helpers@~0.2.0: +broccoli-kitchen-sink-helpers@^0.2.5, broccoli-kitchen-sink-helpers@^0.2.6: version "0.2.9" resolved "https://registry.yarnpkg.com/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.2.9.tgz#a5e0986ed8d76fb5984b68c3f0450d3a96e36ecc" dependencies: @@ -1916,19 +1774,19 @@ broccoli-kitchen-sink-helpers@^0.3.1: glob "^5.0.10" mkdirp "^0.5.1" -broccoli-lint-eslint@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/broccoli-lint-eslint/-/broccoli-lint-eslint-4.1.0.tgz#dccfa1150dc62407cd66fd56a619273c5479a10e" +broccoli-lint-eslint@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/broccoli-lint-eslint/-/broccoli-lint-eslint-4.2.1.tgz#f780dc083a7357a9746a9cfa8f76feb092777477" dependencies: aot-test-generators "^0.1.0" broccoli-concat "^3.2.2" - broccoli-persistent-filter "^1.2.0" + broccoli-persistent-filter "^1.4.3" eslint "^4.0.0" json-stable-stringify "^1.0.1" lodash.defaultsdeep "^4.6.0" md5-hex "^2.0.0" -broccoli-merge-trees@^1.0.0, broccoli-merge-trees@^1.1.0, broccoli-merge-trees@^1.1.1, broccoli-merge-trees@^1.1.4: +broccoli-merge-trees@^1.0.0, broccoli-merge-trees@^1.1.0, broccoli-merge-trees@^1.1.1, broccoli-merge-trees@^1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/broccoli-merge-trees/-/broccoli-merge-trees-1.2.4.tgz#a001519bb5067f06589d91afa2942445a2d0fdb5" dependencies: @@ -1942,39 +1800,48 @@ broccoli-merge-trees@^1.0.0, broccoli-merge-trees@^1.1.0, broccoli-merge-trees@^ symlink-or-copy "^1.0.0" broccoli-merge-trees@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/broccoli-merge-trees/-/broccoli-merge-trees-2.0.0.tgz#10aea46dd5cebcc8b8f7d5a54f0a84a4f0bb90b9" + version "2.0.1" + resolved "https://registry.yarnpkg.com/broccoli-merge-trees/-/broccoli-merge-trees-2.0.1.tgz#14d4b7fc1a90318c12b16f843e6ba2693808100c" dependencies: broccoli-plugin "^1.3.0" merge-trees "^1.0.1" -broccoli-middleware@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/broccoli-middleware/-/broccoli-middleware-1.2.1.tgz#a21f255f8bfe5a21c2f0fbf2417addd9d24c9436" +broccoli-merge-trees@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/broccoli-merge-trees/-/broccoli-merge-trees-3.0.1.tgz#545dfe9f695cec43372b3ee7e63c7203713ea554" + dependencies: + broccoli-plugin "^1.3.0" + merge-trees "^2.0.0" + +broccoli-middleware@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/broccoli-middleware/-/broccoli-middleware-2.0.1.tgz#093314f13e52fad7fa8c4254a4e4a4560c857a65" dependencies: handlebars "^4.0.4" mime-types "^2.1.18" -broccoli-persistent-filter@^1.0.3, broccoli-persistent-filter@^1.1.6, broccoli-persistent-filter@^1.2.0, broccoli-persistent-filter@^1.4.0, broccoli-persistent-filter@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/broccoli-persistent-filter/-/broccoli-persistent-filter-1.4.2.tgz#17af1278a25ff2556f9d7d23e115accfad3a7ce7" +broccoli-module-normalizer@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/broccoli-module-normalizer/-/broccoli-module-normalizer-1.3.0.tgz#f9982d9cbb776b4ed754161cc6547784d3eb19de" dependencies: - async-disk-cache "^1.2.1" - async-promise-queue "^1.0.3" - broccoli-plugin "^1.0.0" - crypto "0.0.3" - fs-tree-diff "^0.5.2" - hash-for-dep "^1.0.2" - heimdalljs "^0.2.1" - heimdalljs-logger "^0.1.7" - mkdirp "^0.5.1" - promise-map-series "^0.2.1" - rimraf "^2.6.1" - rsvp "^3.0.18" - symlink-or-copy "^1.0.1" - walk-sync "^0.3.1" + broccoli-plugin "^1.3.0" + merge-trees "^1.0.1" + rimraf "^2.6.2" + symlink-or-copy "^1.1.8" -broccoli-persistent-filter@^1.1.5, broccoli-persistent-filter@^1.4.3: +broccoli-module-unification-reexporter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/broccoli-module-unification-reexporter/-/broccoli-module-unification-reexporter-1.0.0.tgz#031909c5d3f159ec11d5f9e2346f2861db8acb3e" + dependencies: + broccoli-plugin "^1.3.0" + mkdirp "^0.5.1" + walk-sync "^0.3.2" + +broccoli-node-info@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/broccoli-node-info/-/broccoli-node-info-1.1.0.tgz#3aa2e31e07e5bdb516dd25214f7c45ba1c459412" + +broccoli-persistent-filter@^1.0.3, broccoli-persistent-filter@^1.1.5, broccoli-persistent-filter@^1.1.6, broccoli-persistent-filter@^1.2.0, broccoli-persistent-filter@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/broccoli-persistent-filter/-/broccoli-persistent-filter-1.4.3.tgz#3511bc52fc53740cda51621f58a28152d9911bc1" dependencies: @@ -2002,8 +1869,8 @@ broccoli-plugin@1.1.0: symlink-or-copy "^1.0.1" broccoli-plugin@^1.0.0, broccoli-plugin@^1.1.0, broccoli-plugin@^1.2.0, broccoli-plugin@^1.2.1, broccoli-plugin@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/broccoli-plugin/-/broccoli-plugin-1.3.0.tgz#bee704a8e42da08cb58e513aaa436efb7f0ef1ee" + version "1.3.1" + resolved "https://registry.yarnpkg.com/broccoli-plugin/-/broccoli-plugin-1.3.1.tgz#a26315732fb99ed2d9fb58f12a1e14e986b4fabd" dependencies: promise-map-series "^0.2.1" quick-temp "^0.1.3" @@ -2018,6 +1885,22 @@ broccoli-replace@^0.12.0: broccoli-persistent-filter "^1.2.0" minimatch "^3.0.0" +broccoli-rollup@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/broccoli-rollup/-/broccoli-rollup-2.1.1.tgz#0b77dc4b7560a53e998ea85f3b56772612d4988d" + dependencies: + "@types/node" "^9.6.0" + amd-name-resolver "^1.2.0" + broccoli-plugin "^1.2.1" + fs-tree-diff "^0.5.2" + heimdalljs "^0.2.1" + heimdalljs-logger "^0.1.7" + magic-string "^0.24.0" + node-modules-path "^1.0.1" + rollup "^0.57.1" + symlink-or-copy "^1.1.8" + walk-sync "^0.3.1" + broccoli-sass-source-maps@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/broccoli-sass-source-maps/-/broccoli-sass-source-maps-2.2.0.tgz#1f1a0794136152b096188638b59b42b17a4bdc68" @@ -2049,26 +1932,45 @@ broccoli-sri-hash@^2.1.0, broccoli-sri-hash@meirish/broccoli-sri-hash#rooturl: sri-toolbox "^0.2.0" symlink-or-copy "^1.0.1" -broccoli-stew@^1.0.0, broccoli-stew@^1.2.0, broccoli-stew@^1.3.3, broccoli-stew@^1.4.0, broccoli-stew@^1.4.2, broccoli-stew@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/broccoli-stew/-/broccoli-stew-1.5.0.tgz#d7af8c18511dce510e49d308a62e5977f461883c" +broccoli-stew@^1.2.0, broccoli-stew@^1.4.2, broccoli-stew@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/broccoli-stew/-/broccoli-stew-1.6.0.tgz#01f6d92806ed6679ddbe48d405066a0e164dfbef" dependencies: broccoli-debug "^0.6.1" - broccoli-funnel "^1.0.1" - broccoli-merge-trees "^1.0.0" + broccoli-funnel "^2.0.0" + broccoli-merge-trees "^2.0.0" broccoli-persistent-filter "^1.1.6" broccoli-plugin "^1.3.0" - chalk "^1.1.3" - debug "^2.4.0" + chalk "^2.4.1" + debug "^3.1.0" ensure-posix-path "^1.0.1" - fs-extra "^2.0.0" - minimatch "^3.0.2" - resolve "^1.1.6" - rsvp "^3.0.16" - symlink-or-copy "^1.1.8" + fs-extra "^5.0.0" + minimatch "^3.0.4" + resolve "^1.8.1" + rsvp "^4.8.3" + symlink-or-copy "^1.2.0" walk-sync "^0.3.0" -broccoli-string-replace@^0.1.1: +broccoli-stew@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/broccoli-stew/-/broccoli-stew-2.0.0.tgz#68f3d94f13b4a79aa15d582703574fb4c3215e50" + dependencies: + broccoli-debug "^0.6.1" + broccoli-funnel "^2.0.0" + broccoli-merge-trees "^3.0.0" + broccoli-persistent-filter "^1.1.6" + broccoli-plugin "^1.3.0" + chalk "^2.4.1" + debug "^3.1.0" + ensure-posix-path "^1.0.1" + fs-extra "^6.0.1" + minimatch "^3.0.4" + resolve "^1.8.1" + rsvp "^4.8.3" + symlink-or-copy "^1.2.0" + walk-sync "^0.3.0" + +broccoli-string-replace@^0.1.1, broccoli-string-replace@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/broccoli-string-replace/-/broccoli-string-replace-0.1.2.tgz#1ed92f85680af8d503023925e754e4e33676b91f" dependencies: @@ -2077,25 +1979,27 @@ broccoli-string-replace@^0.1.1: broccoli-templater@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/broccoli-templater/-/broccoli-templater-1.0.0.tgz#7c054aacf596d1868d1a44291f9ec7b907d30ecf" + resolved "http://registry.npmjs.org/broccoli-templater/-/broccoli-templater-1.0.0.tgz#7c054aacf596d1868d1a44291f9ec7b907d30ecf" dependencies: broccoli-filter "^0.1.11" broccoli-stew "^1.2.0" lodash.template "^3.3.2" -broccoli-uglify-sourcemap@^1.0.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/broccoli-uglify-sourcemap/-/broccoli-uglify-sourcemap-1.5.2.tgz#04f84ab0db539031fa868ccfa563c9932d50cedb" +broccoli-uglify-sourcemap@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/broccoli-uglify-sourcemap/-/broccoli-uglify-sourcemap-2.2.0.tgz#2ff49389bdf342a550c3596750ba2dde95a8f7d4" dependencies: + async-promise-queue "^1.0.4" broccoli-plugin "^1.2.1" - debug "^2.2.0" - lodash.merge "^4.5.1" - matcher-collection "^1.0.0" + debug "^3.1.0" + lodash.defaultsdeep "^4.6.0" + matcher-collection "^1.0.5" mkdirp "^0.5.0" - source-map-url "^0.3.0" + source-map-url "^0.4.0" symlink-or-copy "^1.0.1" - uglify-js "^2.7.0" - walk-sync "^0.1.3" + terser "^3.7.5" + walk-sync "^0.3.2" + workerpool "^2.3.0" broccoli-unwatched-tree@^0.1.1: version "0.1.3" @@ -2103,7 +2007,7 @@ broccoli-unwatched-tree@^0.1.1: dependencies: broccoli-source "^1.1.0" -broccoli-writer@^0.1.1, broccoli-writer@~0.1.1: +broccoli-writer@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/broccoli-writer/-/broccoli-writer-0.1.1.tgz#d4d71aa8f2afbc67a3866b91a2da79084b96ab2d" dependencies: @@ -2114,6 +2018,10 @@ brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" +browser-process-hrtime@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e" + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -2167,13 +2075,6 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^2.1.2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.2.0.tgz#5e35ec993e467c6464b8cb708447386891de9f50" - dependencies: - caniuse-lite "^1.0.30000701" - electron-to-chromium "^1.3.15" - browserslist@^2.11.3: version "2.11.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" @@ -2181,7 +2082,7 @@ browserslist@^2.11.3: caniuse-lite "^1.0.30000792" electron-to-chromium "^1.3.30" -browserslist@^3.2.6: +browserslist@^3.1.1, browserslist@^3.2.6: version "3.2.8" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" dependencies: @@ -2194,28 +2095,32 @@ bser@^2.0.0: dependencies: node-int64 "^0.4.0" -buffer-alloc-unsafe@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-0.1.1.tgz#ffe1f67551dd055737de253337bfe853dfab1a6a" +btoa-lite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" -buffer-alloc@^1.1.0: +buffer-alloc-unsafe@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.1.0.tgz#05514d33bf1656d3540c684f65b1202e90eca303" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + +buffer-alloc@^1.1.0, buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" dependencies: - buffer-alloc-unsafe "^0.1.0" - buffer-fill "^0.1.0" + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" buffer-equal@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" -buffer-fill@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-0.1.0.tgz#ca9470e8d4d1b977fd7543f4e2ab6a7dc95101a8" +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" buffer-from@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.0.tgz#87fcaa3a298358e0ade6e442cfce840740d1ad04" + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" buffer-xor@^1.0.3: version "1.0.3" @@ -2223,7 +2128,7 @@ buffer-xor@^1.0.3: buffer@^4.3.0: version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + resolved "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -2261,17 +2166,21 @@ bulma-switch@^0.0.1: resolved "https://registry.yarnpkg.com/bulma-switch/-/bulma-switch-0.0.1.tgz#2de6eb7c602244de7c5efa880b3b19b8464012a9" bulma@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.5.2.tgz#b5c4695075700b9539619555840d8f4f9f84b3a5" + version "0.5.3" + resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.5.3.tgz#be93afb6246192505c30df3f9c1c29a97d319a13" + +byline@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" + +byte-size@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.3.tgz#b7c095efc68eadf82985fccd9a2df43a74fa2ccd" bytes@1: version "1.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" -bytes@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.5.0.tgz#4c9423ea2d252c270c41b2bdefeff9bb6b62c06a" - bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -2294,6 +2203,25 @@ cacache@^10.0.4: unique-filename "^1.1.0" y18n "^4.0.0" +cacache@^11.0.1, cacache@^11.0.2, cacache@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.2.0.tgz#617bdc0b02844af56310e411c0878941d5739965" + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + figgy-pudding "^3.1.0" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.3" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^6.0.0" + unique-filename "^1.1.0" + y18n "^4.0.0" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -2308,12 +2236,20 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -calculate-cache-key-for-tree@^1.0.0: +calculate-cache-key-for-tree@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/calculate-cache-key-for-tree/-/calculate-cache-key-for-tree-1.1.0.tgz#0c3e42c9c134f3c9de5358c0f16793627ea976d6" dependencies: json-stable-stringify "^1.0.1" +call-limit@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.0.tgz#6fd61b03f3da42a2cd0ec2b60f02bd0e71991fea" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -2335,18 +2271,14 @@ camelcase-keys@^2.0.0: camelcase "^2.0.0" map-obj "^1.0.0" -camelcase-keys@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.1.0.tgz#214d348cc5457f39316a2c31cc3e37246325e73f" +camelcase-keys@^4.0.0, camelcase-keys@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" dependencies: camelcase "^4.1.0" map-obj "^2.0.0" quick-lru "^1.0.0" -camelcase@^1.0.2, camelcase@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - camelcase@^2.0.0, camelcase@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" @@ -2355,7 +2287,7 @@ camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" -camelcase@^4.1.0: +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -2365,24 +2297,20 @@ can-symlink@^1.0.0: dependencies: tmp "0.0.28" -caniuse-lite@^1.0.30000701: - version "1.0.30000701" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000701.tgz#9d673cf6b74dcb3d5c21d213176b011ac6a45baa" +caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805, caniuse-lite@^1.0.30000844: + version "1.0.30000885" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000885.tgz#e889e9f8e7e50e769f2a49634c932b8aee622984" -caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805: - version "1.0.30000830" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000830.tgz#cb96b8a2dd3cbfe04acea2af3c4e894249095328" - -caniuse-lite@^1.0.30000844: - version "1.0.30000855" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000855.tgz#d5a26a9093b932d6266bf4ed9294b41b84945d14" - -capture-exit@^1.1.0: +capture-exit@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" dependencies: rsvp "^3.3.3" +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + cardinal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-1.0.0.tgz#50e21c1b0aa37729f9377def196b5a9cec932ee9" @@ -2390,9 +2318,12 @@ cardinal@^1.0.0: ansicolors "~0.2.1" redeyed "~1.0.0" -caseless@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" +cardinal@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-2.1.1.tgz#7cc1055d822d212954d07b085dea251cc7bc5505" + dependencies: + ansicolors "~0.3.2" + redeyed "~2.1.0" caseless@~0.12.0: version "0.12.0" @@ -2402,32 +2333,23 @@ ceibo@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ceibo/-/ceibo-2.0.0.tgz#9a61eb054a91c09934588d4e45d9dd2c3bf04eee" -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - chai@~1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/chai/-/chai-1.7.2.tgz#ba07ebd4e1ac138a296cdf69077ce74b7f4a1317" dependencies: assertion-error "1.0.0" -chalk@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" +chalk@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" dependencies: - ansi-styles "^1.1.0" - escape-string-regexp "^1.0.0" - has-ansi "^0.1.0" - strip-ansi "^0.3.0" - supports-color "^0.2.0" + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" -chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -2435,15 +2357,7 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.0.1.tgz#dbec49436d2ae15f536114e76d14656cdbc0f44d" - dependencies: - ansi-styles "^3.1.0" - escape-string-regexp "^1.0.5" - supports-color "^4.0.0" - -chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" dependencies: @@ -2451,22 +2365,18 @@ chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - chalk@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + resolved "http://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" dependencies: ansi-styles "~1.0.0" has-color "~0.1.0" strip-ansi "~0.1.0" +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + charm@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/charm/-/charm-1.0.2.tgz#8add367153a6d9a581331052c4090991da995e35" @@ -2483,21 +2393,6 @@ cheerio@^0.19.0: htmlparser2 "~3.8.1" lodash "^3.2.0" -chokidar@1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" - dependencies: - anymatch "^1.3.0" - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^2.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - optionalDependencies: - fsevents "^1.0.0" - chokidar@^2.0.2: version "2.0.4" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" @@ -2517,7 +2412,7 @@ chokidar@^2.0.2: optionalDependencies: fsevents "^1.2.2" -chownr@^1.0.1: +chownr@^1.0.1, chownr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" @@ -2527,6 +2422,20 @@ chrome-trace-event@^1.0.0: dependencies: tslib "^1.9.0" +ci-info@^1.1.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.5.1.tgz#17e8eb5de6f8b2b6038f0cbb714d410bfa9f3030" + +ci-info@^1.3.0, ci-info@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.5.0.tgz#38327c69e98dab18487744b84e5d6e841a09a1a7" + +cidr-regex@^2.0.8: + version "2.0.9" + resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-2.0.9.tgz#9c17bb2b18e15af07f7d0c3b994b961d687ed1c9" + dependencies: + ip-regex "^2.1.0" + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -2535,8 +2444,8 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: safe-buffer "^5.0.1" circular-json@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" class-utils@^0.3.5: version "0.3.6" @@ -2566,6 +2475,25 @@ clean-css@^3.4.5: commander "2.8.x" source-map "0.4.x" +clean-stack@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31" + +clean-up-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clean-up-path/-/clean-up-path-1.0.0.tgz#de9e8196519912e749c9eaf67c13d64fac72a3e5" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + +cli-columns@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cli-columns/-/cli-columns-3.1.2.tgz#6732d972979efc2ae444a1f08e08fa139c96a18e" + dependencies: + string-width "^2.0.0" + strip-ansi "^3.0.1" + cli-cursor@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" @@ -2582,12 +2510,12 @@ cli-spinners@^1.1.0: version "1.3.1" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.3.1.tgz#002c1990912d0d59580c93bd36c056de99e4259a" -cli-table2@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/cli-table2/-/cli-table2-0.2.0.tgz#2d1ef7f218a0e786e214540562d4bd177fe32d97" +cli-table3@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" dependencies: - lodash "^3.10.1" - string-width "^1.0.1" + object-assign "^4.1.0" + string-width "^2.1.1" optionalDependencies: colors "^1.1.2" @@ -2598,8 +2526,8 @@ cli-table@^0.3.1: colors "1.0.3" cli-width@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" clipboard@^1.7.1: version "1.7.1" @@ -2609,14 +2537,6 @@ clipboard@^1.7.1: select "^1.1.2" tiny-emitter "^2.0.0" -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - cliui@^3.0.3, cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" @@ -2625,21 +2545,32 @@ cliui@^3.0.3, cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + clone-stats@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" -clone@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" - clone@^1.0.0, clone@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" clone@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + +cmd-shim@^2.0.2, cmd-shim@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" + dependencies: + graceful-fs "^4.1.2" + mkdirp "~0.5.0" co@^4.6.0: version "4.6.0" @@ -2664,95 +2595,107 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.0.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" dependencies: - color-name "^1.1.1" + color-name "1.1.3" -color-convert@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" - dependencies: - color-name "^1.1.1" - -color-name@^1.1.1: +color-name@1.1.3, color-name@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" -colors@1.0.3, colors@1.0.x: +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colornames@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" + +colors@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" -colors@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" +colors@^1.1.2, colors@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b" -columnify@^1.5.4: +colorspace@1.1.x: + version "1.1.1" + resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.1.tgz#9ac2491e1bc6f8fb690e2176814f8d091636d972" + dependencies: + color "3.0.x" + text-hex "1.0.x" + +columnify@^1.5.4, columnify@~1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" dependencies: strip-ansi "^3.0.0" wcwidth "^1.0.0" -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" +combined-stream@1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" dependencies: delayed-stream "~1.0.0" commander@0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" + resolved "http://registry.npmjs.org/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" + +commander@2.12.2: + version "2.12.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" commander@2.8.x: version "2.8.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + resolved "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" dependencies: graceful-readlink ">= 1.0.0" -commander@2.9.0, commander@^2.5.0, commander@^2.6.0, commander@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - dependencies: - graceful-readlink ">= 1.0.0" +commander@^2.6.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + common-tags@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.4.0.tgz#1187be4f3d4cf0c0427d43f74eef1f73501614c0" - dependencies: - babel-runtime "^6.18.0" + version "1.8.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" -commoner@~0.10.3: - version "0.10.8" - resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.8.tgz#34fc3672cd24393e8bb47e70caa0293811f4f2c5" +compare-func@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" dependencies: - commander "^2.5.0" - detective "^4.3.1" - glob "^5.0.15" - graceful-fs "^4.1.2" - iconv-lite "^0.4.5" - mkdirp "^0.5.0" - private "^0.1.6" - q "^1.1.2" - recast "^0.11.17" + array-ify "^1.0.0" + dot-prop "^3.0.0" component-bind@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" -component-emitter@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.1.2.tgz#296594f2753daa63996d2af08d15a95116c9aec3" - component-emitter@1.2.1, component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" @@ -2761,45 +2704,29 @@ component-inherit@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" -compressible@~2.0.10: - version "2.0.10" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.10.tgz#feda1c7f7617912732b29bf8cf26252a20b9eecd" +compressible@~2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.14.tgz#326c5f507fbb055f54116782b969a81b67a29da7" dependencies: - mime-db ">= 1.27.0 < 2" + mime-db ">= 1.34.0 < 2" -compression@^1.4.4: - version "1.7.0" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.0.tgz#030c9f198f1643a057d776a738e922da4373012d" +compression@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db" dependencies: - accepts "~1.3.3" - bytes "2.5.0" - compressible "~2.0.10" - debug "2.6.8" + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.14" + debug "2.6.9" on-headers "~1.0.1" - safe-buffer "5.1.1" - vary "~1.1.1" + safe-buffer "5.1.2" + vary "~1.1.2" concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.0.tgz#53f7d43c51c5e43f81c8fdd03321c631be68d611" - dependencies: - inherits "~2.0.1" - readable-stream "~2.0.0" - typedarray "~0.0.5" - -concat-stream@^1.4.7, concat-stream@^1.5.2, concat-stream@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" - dependencies: - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -concat-stream@^1.5.0: +concat-stream@1.6.2, concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@^1.5.2, concat-stream@^1.6.0: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" dependencies: @@ -2808,9 +2735,27 @@ concat-stream@^1.5.0: readable-stream "^2.2.2" typedarray "^0.0.6" +config-chain@~1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.11.tgz#aba09747dfbe4c3e70e766a6e41586e1859fc6f2" + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + configstore@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.0.tgz#45df907073e26dfa1cf4b2d52f5b60545eaa11d1" + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +configstore@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-4.0.0.tgz#5933311e95d3687efb592c528b922d9262d227e7" dependencies: dot-prop "^4.1.0" graceful-fs "^4.1.2" @@ -2825,11 +2770,11 @@ console-browserify@^1.1.0: dependencies: date-now "^0.1.4" -console-control-strings@^1.0.0, console-control-strings@~1.1.0: +console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" -console-ui@^2.0.0: +console-ui@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/console-ui/-/console-ui-2.2.2.tgz#b294a2934de869dd06789ab4be69555411edef29" dependencies: @@ -2840,9 +2785,9 @@ console-ui@^2.0.0: through "^2.3.8" user-info "^1.0.0" -consolidate@^0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.14.5.tgz#5a25047bc76f73072667c8cb52c989888f494c63" +consolidate@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" dependencies: bluebird "^3.1.1" @@ -2854,10 +2799,6 @@ content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" -content-type@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" - content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" @@ -2866,13 +2807,52 @@ continuable-cache@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f" -convert-source-map@^1.1.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" +conventional-changelog-angular@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.1.tgz#f96431b76de453333a909decd02b15cb5bd2d364" + dependencies: + compare-func "^1.3.1" + q "^1.5.1" + +conventional-changelog-writer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.0.tgz#3ed983c8ef6a3aa51fe44e82c9c75e86f1b5aa42" + dependencies: + compare-func "^1.3.1" + conventional-commits-filter "^2.0.0" + dateformat "^3.0.0" + handlebars "^4.0.2" + json-stringify-safe "^5.0.1" + lodash "^4.2.1" + meow "^4.0.0" + semver "^5.5.0" + split "^1.0.0" + through2 "^2.0.0" + +conventional-commits-filter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.0.tgz#a0ce1d1ff7a1dd7fab36bee8e8256d348d135651" + dependencies: + is-subset "^0.1.1" + modify-values "^1.0.0" + +conventional-commits-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.0.tgz#7f604549a50bd8f60443fbe515484b1c2f06a5c4" + dependencies: + JSONStream "^1.0.4" + is-text-path "^1.0.0" + lodash "^4.2.1" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + trim-off-newlines "^1.0.0" convert-source-map@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + dependencies: + safe-buffer "~5.1.1" cookie-signature@1.0.6: version "1.0.6" @@ -2905,32 +2885,28 @@ copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" -core-js@^1.0.0: - version "1.2.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" - -core-js@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" - -core-js@^2.5.0: +core-js@^2.4.0, core-js@^2.5.0: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" -core-object@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/core-object/-/core-object-1.1.0.tgz#86d63918733cf9da1a5aae729e62c0a88e66ad0a" - -core-object@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/core-object/-/core-object-3.1.3.tgz#df399b3311bdb0c909e8aae8929fc3c1c4b25880" +core-object@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/core-object/-/core-object-3.1.5.tgz#fa627b87502adc98045e44678e9a8ec3b9c0d2a9" dependencies: - chalk "^1.1.3" + chalk "^2.0.0" -core-util-is@~1.0.0: +core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" +cosmiconfig@^5.0.1: + version "5.0.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.6.tgz#dca6cf680a0bd03589aff684700858c81abeeb39" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" @@ -2938,6 +2914,12 @@ create-ecdh@^4.0.0: bn.js "^4.1.0" elliptic "^6.0.0" +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + create-hash@^1.1.0, create-hash@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" @@ -2974,11 +2956,15 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" dependencies: - boom "2.x.x" + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" crypto-browserify@^3.11.0: version "3.12.0" @@ -3000,10 +2986,6 @@ crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" -crypto@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/crypto/-/crypto-0.0.3.tgz#470a81b86be4c5ee17acc8207a1f5315ae20dbb0" - cson-parser@^1.1.0: version "1.3.5" resolved "https://registry.yarnpkg.com/cson-parser/-/cson-parser-1.3.5.tgz#7ec675e039145533bf2a6a856073f1599d9c2d24" @@ -3027,26 +3009,26 @@ cssmin@0.3.x: version "0.3.2" resolved "https://registry.yarnpkg.com/cssmin/-/cssmin-0.3.2.tgz#ddce4c547b510ae0d594a8f1fbf8aaf8e2c5c00d" +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797" + +cssstyle@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.1.1.tgz#18b038a9c44d65f7a8e428a653b9f6fe42faf5fb" + dependencies: + cssom "0.3.x" + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" dependencies: array-find-index "^1.0.1" -cycle@1.0.x: - version "1.0.3" - resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" - cyclist@~0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" -d@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" - dependencies: - es5-ext "^0.10.9" - dag-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/dag-map/-/dag-map-2.0.2.tgz#9714b472de82a1843de2fba9b6876938cab44c68" @@ -3057,54 +3039,67 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +data-urls@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.0.1.tgz#d416ac3896918f29ca84d81085bc3705834da579" + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.1.0" + whatwg-url "^7.0.0" + date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -debug@*, debug@^3.1.0: +date-time@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/date-time/-/date-time-2.1.0.tgz#0286d1b4c769633b3ca13e1e62558d2dbdc2eba2" + dependencies: + time-zone "^1.0.0" + +dateformat@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + +debug@*, debug@3.1.0, debug@^3.1.0, debug@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" dependencies: ms "2.0.0" -debug@0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" - -debug@2.2.0, debug@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" - dependencies: - ms "0.7.1" - -debug@2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c" - dependencies: - ms "0.7.2" - -debug@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e" - dependencies: - ms "2.0.0" - -debug@2.6.8, debug@^2.1.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.4.0, debug@^2.6.8, debug@~2.6.7: - version "2.6.8" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" - dependencies: - ms "2.0.0" - -debug@2.6.9, debug@^2.1.2, debug@^2.3.3, debug@^2.6.9: +debug@2.6.9, debug@^2.1.0, debug@^2.1.1, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: ms "2.0.0" -decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: +debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +debuglog@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" +decamelize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" + dependencies: + xregexp "4.0.0" + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -3113,10 +3108,6 @@ deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" -deep-extend@~0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" - deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -3131,6 +3122,12 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + dependencies: + object-keys "^1.0.12" + define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -3150,25 +3147,6 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - -defs@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/defs/-/defs-1.1.1.tgz#b22609f2c7a11ba7a3db116805c139b1caffa9d2" - dependencies: - alter "~0.2.0" - ast-traverse "~0.1.1" - breakable "~1.0.0" - esprima-fb "~15001.1001.0-dev-harmony-fb" - simple-fmt "~0.1.0" - simple-is "~0.2.0" - stringmap "~0.2.2" - stringset "~0.2.1" - tryor "~0.1.2" - yargs "~3.27.0" - del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" @@ -3186,17 +3164,13 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" delegate@^3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.1.3.tgz#9a8251a777d7025faa55737bc3b071742127a9fd" + version "3.2.0" + resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" -depd@1.1.0, depd@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" - depd@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" @@ -3216,19 +3190,9 @@ destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" -detect-file@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63" - dependencies: - fs-exists-sync "^0.1.0" - -detect-indent@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-3.0.1.tgz#9dc5e5ddbceef8325764b9451b02bc6d54084f75" - dependencies: - get-stdin "^4.0.1" - minimist "^1.1.0" - repeating "^1.1.0" +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" detect-indent@^4.0.0: version "4.0.0" @@ -3236,28 +3200,40 @@ detect-indent@^4.0.0: dependencies: repeating "^2.0.0" +detect-indent@^5.0.0, detect-indent@~5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" -detective@^4.3.1: - version "4.5.0" - resolved "https://registry.yarnpkg.com/detective/-/detective-4.5.0.tgz#6e5a8c6b26e6c7a254b1c6b6d7490d98ec91edd1" +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + +dezalgo@^1.0.0, dezalgo@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" dependencies: - acorn "^4.0.3" - defined "^1.0.0" + asap "^2.0.0" + wrappy "1" + +diagnostics@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a" + dependencies: + colorspace "1.1.x" + enabled "1.0.x" + kuler "1.0.x" diff@1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/diff/-/diff-1.0.7.tgz#24bbb001c4a7d5522169e7cabdb2c2814ed91cf4" -diff@^3.1.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" - -diff@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9" +diff@^3.1.0, diff@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" diffie-hellman@^5.0.0: version "5.0.3" @@ -3267,16 +3243,22 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" -dlv@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.0.tgz#fee1a7c43f63be75f3f679e85262da5f102764a7" - -doctrine@^2.0.0: +dir-glob@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +dlv@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.2.tgz#270f6737b30d25b6657a7e962c784403f85137e5" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" dependencies: esutils "^2.0.2" - isarray "^1.0.0" dom-serializer@0, dom-serializer@~0.1.0: version "0.1.0" @@ -3293,10 +3275,20 @@ domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" -domelementtype@1, domelementtype@~1.1.1: +domelementtype@1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" + +domelementtype@~1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + dependencies: + webidl-conversions "^4.0.2" + domhandler@2.3: version "2.3.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" @@ -3316,12 +3308,32 @@ domutils@1.5: dom-serializer "0" domelementtype "1" -dot-prop@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.1.1.tgz#a8493f0b7b5eeec82525b5c7587fa7de7ca859c1" +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" dependencies: is-obj "^1.0.0" +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + dependencies: + is-obj "^1.0.0" + +dotenv@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" + +duplexer2@~0.1.0: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + dependencies: + readable-stream "^2.0.2" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + duplexify@^3.4.2, duplexify@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" @@ -3332,34 +3344,31 @@ duplexify@^3.4.2, duplexify@^3.6.0: stream-shift "^1.0.0" ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" dependencies: jsbn "~0.1.0" + safer-buffer "^2.1.0" editions@^1.1.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.3.tgz#0907101bdda20fac3cbe334c27cbd0688dc99a5b" + version "1.3.4" + resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" + +editor@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742" ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -electron-to-chromium@^1.3.15: - version "1.3.15" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.15.tgz#08397934891cbcfaebbd18b82a95b5a481138369" - -electron-to-chromium@^1.3.30: - version "1.3.42" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.42.tgz#95c33bf01d0cc405556aec899fe61fd4d76ea0f9" - -electron-to-chromium@^1.3.47: - version "1.3.48" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.48.tgz#d3b0d8593814044e092ece2108fc3ac9aea4b900" +electron-to-chromium@^1.3.30, electron-to-chromium@^1.3.47: + version "1.3.64" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.64.tgz#39f5a93bf84ab7e10cfbb7522ccfc3f1feb756cf" elliptic@^6.0.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -3369,24 +3378,21 @@ elliptic@^6.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" -ember-ajax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ember-ajax/-/ember-ajax-3.0.0.tgz#8f21e9da0c1d433cf879aa855fce464d517e9ab5" +ember-ajax@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/ember-ajax/-/ember-ajax-3.1.1.tgz#dcb55aaf1a9fe8b2ce04206863384709ebc2358b" dependencies: - ember-cli-babel "^6.0.0" - -ember-angle-bracket-invocation-polyfill@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ember-angle-bracket-invocation-polyfill/-/ember-angle-bracket-invocation-polyfill-1.0.2.tgz#b8e43e91161c0da1b442c995e1f270b64c7d8d00" - dependencies: - ember-cli-babel "^6.6.0" - ember-cli-version-checker "^2.1.2" + ember-cli-babel "^6.16.0" + najax "^1.0.3" ember-api-actions@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/ember-api-actions/-/ember-api-actions-0.1.8.tgz#651031b9d61a320c221dd75b20f7e8f783e6393d" + version "0.1.9" + resolved "https://registry.yarnpkg.com/ember-api-actions/-/ember-api-actions-0.1.9.tgz#6a90af17bf79c42daa9b3b06b86a6f60bc098e7f" dependencies: - ember-cli-babel "^6.0.0" + ember-cli-babel "^6.6.0" + optionalDependencies: + "@mike-north/js-lib-semantic-release-config" "^0.0.0-development" + semantic-release "^15.9.12" ember-assign-helper@^0.1.2: version "0.1.2" @@ -3395,18 +3401,15 @@ ember-assign-helper@^0.1.2: ember-cli-babel "^6.0.0-beta.9" ember-auto-import@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-1.2.3.tgz#7a553aafc303182c5013fd2237df9e477b08f96f" + version "1.2.13" + resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-1.2.13.tgz#8f6f5d1c64e173f9093dd0c5031dc1d446b7cff1" dependencies: babel-core "^6.26.3" babel-plugin-syntax-dynamic-import "^6.18.0" babel-template "^6.26.0" babylon "^6.18.0" - broccoli-concat "^3.2.2" broccoli-debug "^0.6.4" - broccoli-funnel "^2.0.1" broccoli-plugin "^1.3.0" - broccoli-source "^1.1.0" debug "^3.1.0" ember-cli-babel "^6.6.0" enhanced-resolve "^4.0.0" @@ -3434,8 +3437,8 @@ ember-basic-dropdown-hover@^0.5.0: ember-cli-htmlbars "^2.0.3" ember-basic-dropdown@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ember-basic-dropdown/-/ember-basic-dropdown-1.0.1.tgz#413f929572028d613024966726992fb45351880c" + version "1.0.3" + resolved "https://registry.yarnpkg.com/ember-basic-dropdown/-/ember-basic-dropdown-1.0.3.tgz#bd785c84ea2b366951e0630f173c84677ed53b6c" dependencies: ember-cli-babel "^6.12.0" ember-cli-htmlbars "^2.0.3" @@ -3448,79 +3451,17 @@ ember-cli-autoprefixer@^0.8.1: broccoli-autoprefixer "^5.0.0" lodash "^4.0.0" -ember-cli-babel@^5.0.0, ember-cli-babel@^5.1.5, ember-cli-babel@^5.1.6, ember-cli-babel@^5.1.7: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-5.2.4.tgz#5ce4f46b08ed6f6d21e878619fb689719d6e8e13" - dependencies: - broccoli-babel-transpiler "^5.6.2" - broccoli-funnel "^1.0.0" - clone "^2.0.0" - ember-cli-version-checker "^1.0.2" - resolve "^1.1.2" - -ember-cli-babel@^6.0.0, ember-cli-babel@^6.3.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-6.6.0.tgz#a8362bc44841bfdf89b389f3197f104d7ba526da" - dependencies: - amd-name-resolver "0.0.6" - babel-plugin-debug-macros "^0.1.11" - babel-plugin-ember-modules-api-polyfill "^1.4.1" - babel-plugin-transform-es2015-modules-amd "^6.24.0" - babel-polyfill "^6.16.0" - babel-preset-env "^1.5.1" - broccoli-babel-transpiler "^6.0.0" - broccoli-debug "^0.6.2" - broccoli-funnel "^1.0.0" - broccoli-source "^1.1.0" - clone "^2.0.0" - ember-cli-version-checker "^2.0.0" - -ember-cli-babel@^6.0.0-beta.4, ember-cli-babel@^6.10.0, ember-cli-babel@^6.8.2: - version "6.11.0" - resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-6.11.0.tgz#79cb184bac3c05bfe181ddc306bac100ab1f9493" - dependencies: - amd-name-resolver "0.0.7" - babel-plugin-debug-macros "^0.1.11" - babel-plugin-ember-modules-api-polyfill "^2.3.0" - babel-plugin-transform-es2015-modules-amd "^6.24.0" - babel-polyfill "^6.16.0" - babel-preset-env "^1.5.1" - broccoli-babel-transpiler "^6.1.2" - broccoli-debug "^0.6.2" - broccoli-funnel "^1.0.0" - broccoli-source "^1.1.0" - clone "^2.0.0" - ember-cli-version-checker "^2.1.0" - semver "^5.4.1" - -ember-cli-babel@^6.0.0-beta.7, ember-cli-babel@^6.1.0, ember-cli-babel@^6.6.0, ember-cli-babel@^6.8.1: - version "6.8.2" - resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-6.8.2.tgz#eac2785964f4743f4c815cd53c6288f00cc087d7" - dependencies: - amd-name-resolver "0.0.7" - babel-plugin-debug-macros "^0.1.11" - babel-plugin-ember-modules-api-polyfill "^2.0.1" - babel-plugin-transform-es2015-modules-amd "^6.24.0" - babel-polyfill "^6.16.0" - babel-preset-env "^1.5.1" - broccoli-babel-transpiler "^6.1.2" - broccoli-debug "^0.6.2" - broccoli-funnel "^1.0.0" - broccoli-source "^1.1.0" - clone "^2.0.0" - ember-cli-version-checker "^2.0.0" - -ember-cli-babel@^6.0.0-beta.9, ember-cli-babel@^6.11.0, ember-cli-babel@^6.12.0: - version "6.14.1" - resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-6.14.1.tgz#796339229035910b625593caffbc2683792ada68" +ember-cli-babel@^6.0.0, ember-cli-babel@^6.0.0-beta.4, ember-cli-babel@^6.0.0-beta.7, ember-cli-babel@^6.0.0-beta.9, ember-cli-babel@^6.10.0, ember-cli-babel@^6.11.0, ember-cli-babel@^6.12.0, ember-cli-babel@^6.3.0, ember-cli-babel@^6.6.0, ember-cli-babel@^6.7.2, ember-cli-babel@^6.8.0, ember-cli-babel@^6.8.1, ember-cli-babel@^6.8.2, ember-cli-babel@^6.9.0, ember-cli-babel@^6.9.2: + version "6.17.0" + resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-6.17.0.tgz#1f3e8ed9f4e2338caef6bc2c3d08d3c9928d0ddd" dependencies: amd-name-resolver "1.2.0" - babel-plugin-debug-macros "^0.1.11" - babel-plugin-ember-modules-api-polyfill "^2.3.0" + babel-plugin-debug-macros "^0.2.0-beta.6" + babel-plugin-ember-modules-api-polyfill "^2.3.2" babel-plugin-transform-es2015-modules-amd "^6.24.0" babel-polyfill "^6.26.0" babel-preset-env "^1.7.0" - broccoli-babel-transpiler "^6.4.2" + broccoli-babel-transpiler "^6.5.0" broccoli-debug "^0.6.4" broccoli-funnel "^2.0.0" broccoli-source "^1.1.0" @@ -3528,23 +3469,41 @@ ember-cli-babel@^6.0.0-beta.9, ember-cli-babel@^6.11.0, ember-cli-babel@^6.12.0: ember-cli-version-checker "^2.1.2" semver "^5.5.0" -ember-cli-broccoli-sane-watcher@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/ember-cli-broccoli-sane-watcher/-/ember-cli-broccoli-sane-watcher-2.0.4.tgz#f43f42f75b7509c212fb926cd9aea86ae19264c6" +ember-cli-babel@^6.16.0: + version "6.17.1" + resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-6.17.1.tgz#db2d325da1975149b688177f44915903fa2ecb9f" + dependencies: + amd-name-resolver "1.2.0" + babel-plugin-debug-macros "^0.2.0-beta.6" + babel-plugin-ember-modules-api-polyfill "^2.4.0" + babel-plugin-transform-es2015-modules-amd "^6.24.0" + babel-polyfill "^6.26.0" + babel-preset-env "^1.7.0" + broccoli-babel-transpiler "^6.5.0" + broccoli-debug "^0.6.4" + broccoli-funnel "^2.0.0" + broccoli-source "^1.1.0" + clone "^2.0.0" + ember-cli-version-checker "^2.1.2" + semver "^5.5.0" + +ember-cli-broccoli-sane-watcher@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ember-cli-broccoli-sane-watcher/-/ember-cli-broccoli-sane-watcher-2.1.1.tgz#1687adada9022de26053fba833dc7dd10f03dd08" dependencies: broccoli-slow-trees "^3.0.1" heimdalljs "^0.2.1" heimdalljs-logger "^0.1.7" rsvp "^3.0.18" - sane "^1.1.1" + sane "^2.4.1" ember-cli-clipboard@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/ember-cli-clipboard/-/ember-cli-clipboard-0.8.0.tgz#c2e91290b2746c1a4903097f5d7a55406de539b1" + version "0.8.1" + resolved "https://registry.yarnpkg.com/ember-cli-clipboard/-/ember-cli-clipboard-0.8.1.tgz#59f8eb6ba471a7668dff592fcebb7b06014240dd" dependencies: broccoli-funnel "^1.1.0" clipboard "^1.7.1" - ember-cli-babel "^6.3.0" + ember-cli-babel "^6.8.0" ember-cli-htmlbars "^2.0.2" fastboot-transform "0.1.1" @@ -3555,37 +3514,39 @@ ember-cli-content-security-policy@^1.0.0: body-parser "^1.17.0" chalk "^2.0.0" -ember-cli-dependency-checker@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ember-cli-dependency-checker/-/ember-cli-dependency-checker-1.4.0.tgz#2b13f977e1eea843fc1a21a001be6ca5d4ef1942" +ember-cli-dependency-checker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-dependency-checker/-/ember-cli-dependency-checker-3.0.0.tgz#61245f5f79f881dece043303111d5f41efb8621f" dependencies: - chalk "^0.5.1" - is-git-url "^0.2.0" - semver "^4.1.0" + chalk "^2.3.0" + find-yarn-workspace-root "^1.1.0" + is-git-url "^1.0.0" + resolve "^1.5.0" + semver "^5.3.0" -ember-cli-eslint@4: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ember-cli-eslint/-/ember-cli-eslint-4.1.0.tgz#50e43224e71849b7c03f73d5e5c4647b48993033" +ember-cli-eslint@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/ember-cli-eslint/-/ember-cli-eslint-4.2.3.tgz#2844d3f5e8184f19b2d7132ba99eb0b370b55598" dependencies: - broccoli-lint-eslint "^4.0.0" - ember-cli-version-checker "^2.0.0" - rsvp "^3.2.1" + broccoli-lint-eslint "^4.2.1" + ember-cli-version-checker "^2.1.0" + rsvp "^4.6.1" walk-sync "^0.3.0" -ember-cli-favicon@1.0.0-beta.4: - version "1.0.0-beta.4" - resolved "https://registry.yarnpkg.com/ember-cli-favicon/-/ember-cli-favicon-1.0.0-beta.4.tgz#8c27d47cb4124691939b3f0f7602848a265b0594" +ember-cli-favicon@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-favicon/-/ember-cli-favicon-1.0.0.tgz#2f6781e939acf33b368841645e076bfd77061c34" dependencies: broccoli-favicon "1.0.0" - broccoli-merge-trees "^1.1.1" + broccoli-merge-trees "^2.0.0" broccoli-replace "^0.12.0" - ember-cli-babel "^5.1.6" + ember-cli-babel "^6.8.2" -ember-cli-flash@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/ember-cli-flash/-/ember-cli-flash-1.5.0.tgz#d4e0edf618376ffbf648512d92d5ff7a0f0ffb0c" +ember-cli-flash@^1.6.6: + version "1.6.6" + resolved "https://registry.yarnpkg.com/ember-cli-flash/-/ember-cli-flash-1.6.6.tgz#f3d005c8ac41ecd0ac6a00304adaa57c8a07bc36" dependencies: - ember-cli-babel "^6.3.0" + ember-cli-babel "^6.10.0" ember-cli-htmlbars "^2.0.1" ember-runtime-enumerable-includes-polyfill "^2.0.0" @@ -3593,20 +3554,17 @@ ember-cli-get-component-path-option@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ember-cli-get-component-path-option/-/ember-cli-get-component-path-option-1.0.0.tgz#0d7b595559e2f9050abed804f1d8eff1b08bc771" -ember-cli-get-dependency-depth@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ember-cli-get-dependency-depth/-/ember-cli-get-dependency-depth-1.0.0.tgz#e0afecf82a2d52f00f28ab468295281aec368d11" - -ember-cli-htmlbars-inline-precompile@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/ember-cli-htmlbars-inline-precompile/-/ember-cli-htmlbars-inline-precompile-0.4.3.tgz#4123f507fea6c59ba4c272ef7e713a6d55ba06c9" +ember-cli-htmlbars-inline-precompile@^1.0.0, ember-cli-htmlbars-inline-precompile@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ember-cli-htmlbars-inline-precompile/-/ember-cli-htmlbars-inline-precompile-1.0.3.tgz#332ff96c06fc522965162f1090d78a615379c3c2" dependencies: - babel-plugin-htmlbars-inline-precompile "^0.2.3" - ember-cli-version-checker "^2.0.0" - hash-for-dep "^1.0.2" + babel-plugin-htmlbars-inline-precompile "^0.2.5" + ember-cli-version-checker "^2.1.2" + hash-for-dep "^1.2.3" + heimdalljs-logger "^0.1.9" silent-error "^1.1.0" -ember-cli-htmlbars@^1.0.10: +ember-cli-htmlbars@^1.1.1: version "1.3.4" resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-1.3.4.tgz#461289724b34af372a6a0c4b6635819156963353" dependencies: @@ -3616,54 +3574,38 @@ ember-cli-htmlbars@^1.0.10: json-stable-stringify "^1.0.0" strip-bom "^2.0.0" -ember-cli-htmlbars@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-2.0.2.tgz#230a9ace7c3454b3acff2768a50f963813a90c38" +ember-cli-htmlbars@^2.0.1, ember-cli-htmlbars@^2.0.2, ember-cli-htmlbars@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-2.0.4.tgz#0bcda483f14271663c38756e1fd1cb89da6a50cf" dependencies: - broccoli-persistent-filter "^1.0.3" - hash-for-dep "^1.0.2" + broccoli-persistent-filter "^1.4.3" + hash-for-dep "^1.2.3" json-stable-stringify "^1.0.0" strip-bom "^3.0.0" -ember-cli-htmlbars@^2.0.2, ember-cli-htmlbars@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-2.0.3.tgz#e116e1500dba12f29c94b05b9ec90f52cb8bb042" +ember-cli-htmlbars@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-3.0.0.tgz#4977b9eddbc725f8da25090ecdbba64533b2eadc" dependencies: - broccoli-persistent-filter "^1.0.3" - hash-for-dep "^1.0.2" + broccoli-persistent-filter "^1.4.3" + hash-for-dep "^1.2.3" json-stable-stringify "^1.0.0" strip-bom "^3.0.0" -ember-cli-inject-live-reload@^1.4.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/ember-cli-inject-live-reload/-/ember-cli-inject-live-reload-1.7.0.tgz#af94336e015336127dfb98080ad442bb233e37ed" +ember-cli-import-polyfill@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ember-cli-import-polyfill/-/ember-cli-import-polyfill-0.2.0.tgz#c1a08a8affb45c97b675926272fe78cf4ca166f2" + +ember-cli-inject-live-reload@^1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/ember-cli-inject-live-reload/-/ember-cli-inject-live-reload-1.8.2.tgz#29f875ad921e9a1dec65d2d75018891972d240bc" + dependencies: + clean-base-url "^1.0.0" ember-cli-is-package-missing@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ember-cli-is-package-missing/-/ember-cli-is-package-missing-1.0.0.tgz#6e6184cafb92635dd93ca6c946b104292d4e3390" -ember-cli-legacy-blueprints@^0.1.2: - version "0.1.5" - resolved "https://registry.yarnpkg.com/ember-cli-legacy-blueprints/-/ember-cli-legacy-blueprints-0.1.5.tgz#93c15ca242ec5107d62a8af7ec30f6ac538f3ad9" - dependencies: - chalk "^1.1.1" - ember-cli-get-component-path-option "^1.0.0" - ember-cli-get-dependency-depth "^1.0.0" - ember-cli-is-package-missing "^1.0.0" - ember-cli-lodash-subset "^1.0.7" - ember-cli-normalize-entity-name "^1.0.0" - ember-cli-path-utils "^1.0.0" - ember-cli-string-utils "^1.0.0" - ember-cli-test-info "^1.0.0" - ember-cli-valid-component-name "^1.0.0" - ember-cli-version-checker "^1.1.7" - ember-router-generator "^1.0.0" - exists-sync "0.0.3" - fs-extra "^0.24.0" - inflection "^1.7.1" - rsvp "^3.0.17" - silent-error "^1.0.0" - ember-cli-lodash-subset@^1.0.7: version "1.0.12" resolved "https://registry.yarnpkg.com/ember-cli-lodash-subset/-/ember-cli-lodash-subset-1.0.12.tgz#af2e77eba5dcb0d77f3308d3a6fd7d3450f6e537" @@ -3673,37 +3615,39 @@ ember-cli-lodash-subset@^2.0.1: resolved "https://registry.yarnpkg.com/ember-cli-lodash-subset/-/ember-cli-lodash-subset-2.0.1.tgz#20cb68a790fe0fde2488ddfd8efbb7df6fe766f2" ember-cli-mirage@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/ember-cli-mirage/-/ember-cli-mirage-0.4.1.tgz#bfdfe61e5e74dc3881ed31f12112dae1a29f0d4c" + version "0.4.9" + resolved "https://registry.yarnpkg.com/ember-cli-mirage/-/ember-cli-mirage-0.4.9.tgz#c49bfe875d0cdf88c85a6ee55103d1980175b914" dependencies: broccoli-funnel "^1.0.2" broccoli-merge-trees "^1.1.0" broccoli-stew "^1.5.0" + broccoli-string-replace "^0.1.2" chalk "^1.1.1" ember-cli-babel "^6.8.2" ember-cli-node-assets "^0.1.4" ember-get-config "^0.2.2" ember-inflector "^2.0.0" ember-lodash "^4.17.3" - exists-sync "0.0.3" fake-xml-http-request "^1.4.0" faker "^3.0.0" + jsdom "^11.12.0" pretender "^1.6.1" route-recognizer "^0.2.3" -ember-cli-moment-shim@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ember-cli-moment-shim/-/ember-cli-moment-shim-2.2.1.tgz#78870872a626177d0b04223c9eb6be0729590e61" +ember-cli-moment-shim@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/ember-cli-moment-shim/-/ember-cli-moment-shim-3.7.1.tgz#3ad691c5027c1f38a4890fe47d74b5224cc98e32" dependencies: - broccoli-funnel "^1.0.0" - broccoli-merge-trees "^1.0.0" - broccoli-stew "^1.0.0" - chalk "^1.1.1" - ember-cli-babel "^5.0.0" - exists-sync "0.0.3" - lodash.defaults "^4.1.0" - moment "^2.13.0" - moment-timezone "^0.5.0" + broccoli-funnel "^2.0.0" + broccoli-merge-trees "^2.0.0" + broccoli-source "^1.1.0" + broccoli-stew "^1.5.0" + chalk "^1.1.3" + ember-cli-babel "^6.6.0" + ember-cli-import-polyfill "^0.2.0" + lodash.defaults "^4.2.0" + moment "^2.19.3" + moment-timezone "^0.5.13" ember-cli-node-assets@^0.1.4: version "0.1.6" @@ -3733,12 +3677,14 @@ ember-cli-normalize-entity-name@^1.0.0: dependencies: silent-error "^1.0.0" -ember-cli-page-object@1.14: - version "1.14.1" - resolved "https://registry.yarnpkg.com/ember-cli-page-object/-/ember-cli-page-object-1.14.1.tgz#2e3599c204c56440c6c8154fc686c603816f877a" +ember-cli-page-object@1.15.0-beta.3: + version "1.15.0-beta.3" + resolved "https://registry.yarnpkg.com/ember-cli-page-object/-/ember-cli-page-object-1.15.0-beta.3.tgz#e41f3a33e35a6717c507b1a4c13fc990950c7d35" dependencies: + broccoli-file-creator "^2.1.1" + broccoli-merge-trees "^2.0.0" ceibo "~2.0.0" - ember-cli-babel "^6.6.0" + ember-cli-babel "^6.12.0" ember-cli-node-assets "^0.2.2" ember-native-dom-helpers "^0.5.3" jquery "^3.2.1" @@ -3748,60 +3694,43 @@ ember-cli-path-utils@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ember-cli-path-utils/-/ember-cli-path-utils-1.0.0.tgz#4e39af8b55301cddc5017739b77a804fba2071ed" -ember-cli-preprocess-registry@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/ember-cli-preprocess-registry/-/ember-cli-preprocess-registry-3.1.1.tgz#38456c21c4d2b64945850cf9ec68db6ba769288a" +ember-cli-preprocess-registry@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/ember-cli-preprocess-registry/-/ember-cli-preprocess-registry-3.1.2.tgz#083efb21fd922c021ceba9e08f4d9278249fc4db" dependencies: broccoli-clean-css "^1.1.0" broccoli-funnel "^1.0.0" broccoli-merge-trees "^1.0.0" debug "^2.2.0" ember-cli-lodash-subset "^1.0.7" - exists-sync "0.0.3" process-relative-require "^1.0.0" silent-error "^1.0.0" -ember-cli-pretender@0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/ember-cli-pretender/-/ember-cli-pretender-0.7.0.tgz#ef56225cdd773db6dd1369912df2657d7a74b752" +ember-cli-pretender@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ember-cli-pretender/-/ember-cli-pretender-1.0.1.tgz#35540babddef6f2778e91c627d190c73505103cd" dependencies: - broccoli-funnel "^1.0.6" - broccoli-merge-trees "^1.1.4" - pretender "^1.1.0" - resolve "^1.1.7" + broccoli-funnel "^1.1.0" + broccoli-merge-trees "^1.2.1" + pretender "^1.4.2" + resolve "^1.2.0" -ember-cli-qunit@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/ember-cli-qunit/-/ember-cli-qunit-4.0.0.tgz#1f0022469a5bd64f627b8102880a25e94e533a3b" +ember-cli-qunit@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ember-cli-qunit/-/ember-cli-qunit-4.3.2.tgz#cfd89ad3b0dbc28a9c2223d532b52eeade7c602c" dependencies: - broccoli-funnel "^1.0.1" - broccoli-merge-trees "^2.0.0" - ember-cli-babel "^6.0.0-beta.7" - ember-cli-test-loader "^2.0.0" - ember-cli-version-checker "^1.1.4" - ember-qunit "^2.1.3" - qunit-notifications "^0.1.1" - qunitjs "^2.0.1" - resolve "^1.1.6" - silent-error "^1.0.0" + ember-cli-babel "^6.11.0" + ember-qunit "^3.3.2" ember-cli-sass@^7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/ember-cli-sass/-/ember-cli-sass-7.1.7.tgz#66899134788ec8d2406a45f5346d4db47a2aa012" + version "7.2.0" + resolved "http://registry.npmjs.org/ember-cli-sass/-/ember-cli-sass-7.2.0.tgz#293d1a94c43c1fdbb3835378e43d255e8ad5c961" dependencies: broccoli-funnel "^1.0.0" broccoli-merge-trees "^1.1.0" broccoli-sass-source-maps "^2.1.0" ember-cli-version-checker "^2.1.0" -ember-cli-shims@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ember-cli-shims/-/ember-cli-shims-1.1.0.tgz#0e3b8a048be865b4f81cc81d397ff1eeb13f75b6" - dependencies: - ember-cli-babel "^6.0.0-beta.7" - ember-cli-version-checker "^1.2.0" - silent-error "^1.0.1" - ember-cli-sri@meirish/ember-cli-sri#rooturl: version "2.1.0" resolved "https://codeload.github.com/meirish/ember-cli-sri/tar.gz/1c0ff776a61f09121d1ea69ce16e4653da5e1efa" @@ -3809,33 +3738,50 @@ ember-cli-sri@meirish/ember-cli-sri#rooturl: broccoli-sri-hash "^2.1.0" ember-cli-string-helpers@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/ember-cli-string-helpers/-/ember-cli-string-helpers-1.5.0.tgz#b7c1b27ffd4bb4bf4846b3167f730f0125a96f44" + version "1.9.0" + resolved "https://registry.yarnpkg.com/ember-cli-string-helpers/-/ember-cli-string-helpers-1.9.0.tgz#2c1605bc5768ff58cecd2fa1bd0d13d81e47f3d3" dependencies: broccoli-funnel "^1.0.1" - ember-cli-babel "^6.3.0" + ember-cli-babel "^6.6.0" ember-cli-string-utils@^1.0.0, ember-cli-string-utils@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ember-cli-string-utils/-/ember-cli-string-utils-1.1.0.tgz#39b677fc2805f55173735376fcef278eaa4452a1" +ember-cli-template-lint@^1.0.0-beta.1: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/ember-cli-template-lint/-/ember-cli-template-lint-1.0.0-beta.2.tgz#0ebd2f8c1f9ca47f9ee3b42755d66262440c14f6" + dependencies: + aot-test-generators "^0.1.0" + broccoli-concat "^3.7.1" + broccoli-persistent-filter "^1.4.3" + chalk "^2.4.1" + debug "^3.1.0" + ember-cli-version-checker "^2.1.2" + ember-template-lint "^1.0.0-beta.5" + json-stable-stringify "^1.0.1" + md5-hex "^2.0.0" + strip-ansi "^4.0.0" + walk-sync "^0.3.3" + ember-cli-test-info@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ember-cli-test-info/-/ember-cli-test-info-1.0.0.tgz#ed4e960f249e97523cf891e4aed2072ce84577b4" dependencies: ember-cli-string-utils "^1.0.0" -ember-cli-test-loader@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ember-cli-test-loader/-/ember-cli-test-loader-2.1.0.tgz#16163bae0ac32cad1af13c4ed94c6c698b54d431" +ember-cli-test-loader@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ember-cli-test-loader/-/ember-cli-test-loader-2.2.0.tgz#3fb8d5d1357e4460d3f0a092f5375e71b6f7c243" dependencies: - ember-cli-babel "^6.0.0-beta.7" + ember-cli-babel "^6.8.1" -ember-cli-uglify@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ember-cli-uglify/-/ember-cli-uglify-1.2.0.tgz#3208c32b54bc2783056e8bb0d5cfe9bbaf17ffb2" +ember-cli-uglify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ember-cli-uglify/-/ember-cli-uglify-2.1.0.tgz#4a0641fe4768d7ab7d4807aca9924cc77c544184" dependencies: - broccoli-uglify-sourcemap "^1.0.0" + broccoli-uglify-sourcemap "^2.1.1" + lodash.defaultsdeep "^4.6.0" ember-cli-valid-component-name@^1.0.0: version "1.0.0" @@ -3843,128 +3789,125 @@ ember-cli-valid-component-name@^1.0.0: dependencies: silent-error "^1.0.0" -ember-cli-version-checker@1.3.1, ember-cli-version-checker@^1.0.2, ember-cli-version-checker@^1.1.4, ember-cli-version-checker@^1.1.6, ember-cli-version-checker@^1.1.7, ember-cli-version-checker@^1.2.0, ember-cli-version-checker@^1.3.1: +ember-cli-version-checker@^1.0.2: version "1.3.1" resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-1.3.1.tgz#0bc2d134c830142da64bf9627a0eded10b61ae72" dependencies: semver "^5.3.0" -ember-cli-version-checker@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-2.0.0.tgz#e1f7d8e4cdcd752ac35f1611e4daa8836db4c4c7" - dependencies: - resolve "^1.3.3" - semver "^5.3.0" - -ember-cli-version-checker@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-2.1.0.tgz#fc79a56032f3717cf844ada7cbdec1a06fedb604" - dependencies: - resolve "^1.3.3" - semver "^5.3.0" - -ember-cli-version-checker@^2.1.2: +ember-cli-version-checker@^2.0.0, ember-cli-version-checker@^2.1.0, ember-cli-version-checker@^2.1.1, ember-cli-version-checker@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-2.1.2.tgz#305ce102390c66e4e0f1432dea9dc5c7c19fed98" dependencies: resolve "^1.3.3" semver "^5.3.0" -ember-cli@~2.16.0: - version "2.16.2" - resolved "https://registry.yarnpkg.com/ember-cli/-/ember-cli-2.16.2.tgz#53b922073a8e6f34255a6e0dcb1794a91ba3e1b7" +ember-cli@~3.4.2: + version "3.4.2" + resolved "https://registry.yarnpkg.com/ember-cli/-/ember-cli-3.4.2.tgz#b1eee393ecb1bd0d41fcac25460f0c2a882de741" dependencies: - amd-name-resolver "1.0.0" - babel-plugin-transform-es2015-modules-amd "^6.24.0" + amd-name-resolver "^1.2.0" + babel-plugin-transform-es2015-modules-amd "^6.24.1" bower-config "^1.3.0" bower-endpoint-parser "0.2.2" - broccoli-babel-transpiler "^6.0.0" - broccoli-brocfile-loader "^0.18.0" - broccoli-builder "^0.18.8" - broccoli-concat "^3.2.2" - broccoli-config-loader "^1.0.0" + broccoli-amd-funnel "^1.3.0" + broccoli-babel-transpiler "^6.5.0" + broccoli-builder "^0.18.14" + broccoli-concat "^3.5.1" + broccoli-config-loader "^1.0.1" broccoli-config-replace "^1.1.2" - broccoli-debug "^0.6.3" - broccoli-funnel "^2.0.0" + broccoli-debug "^0.6.4" + broccoli-funnel "^2.0.1" broccoli-funnel-reducer "^1.0.0" - broccoli-merge-trees "^2.0.0" - broccoli-middleware "^1.0.0" + broccoli-merge-trees "^3.0.0" + broccoli-middleware "^2.0.1" + broccoli-module-normalizer "^1.3.0" + broccoli-module-unification-reexporter "^1.0.0" broccoli-source "^1.1.0" - broccoli-stew "^1.2.0" - calculate-cache-key-for-tree "^1.0.0" - capture-exit "^1.1.0" - chalk "^2.0.1" + broccoli-stew "^2.0.0" + calculate-cache-key-for-tree "^1.1.0" + capture-exit "^1.2.0" + chalk "^2.4.1" + ci-info "^1.1.3" clean-base-url "^1.0.0" - compression "^1.4.4" - configstore "^3.0.0" - console-ui "^2.0.0" - core-object "^3.1.3" + compression "^1.7.3" + configstore "^4.0.0" + console-ui "^2.2.2" + core-object "^3.1.5" dag-map "^2.0.2" - diff "^3.2.0" - ember-cli-broccoli-sane-watcher "^2.0.4" + diff "^3.5.0" + ember-cli-broccoli-sane-watcher "^2.1.1" ember-cli-is-package-missing "^1.0.0" - ember-cli-legacy-blueprints "^0.1.2" ember-cli-lodash-subset "^2.0.1" ember-cli-normalize-entity-name "^1.0.0" - ember-cli-preprocess-registry "^3.1.0" - ember-cli-string-utils "^1.0.0" - ember-try "^0.2.15" + ember-cli-preprocess-registry "^3.1.2" + ember-cli-string-utils "^1.1.0" ensure-posix-path "^1.0.2" - execa "^0.8.0" - exists-sync "0.0.4" + execa "^0.10.0" exit "^0.1.2" - express "^4.12.3" - filesize "^3.1.3" - find-up "^2.1.0" - fs-extra "^4.0.0" - fs-tree-diff "^0.5.2" + express "^4.16.3" + filesize "^3.6.1" + find-up "^3.0.0" + find-yarn-workspace-root "^1.1.0" + fixturify-project "^1.5.3" + fs-extra "^7.0.0" + fs-tree-diff "^0.5.7" get-caller-file "^1.0.0" - git-repo-info "^1.4.1" - glob "7.1.1" - heimdalljs "^0.2.3" - heimdalljs-fs-monitor "^0.1.0" - heimdalljs-graph "^0.3.1" - heimdalljs-logger "^0.1.7" - http-proxy "^1.9.0" - inflection "^1.7.0" + git-repo-info "^2.0.0" + glob "^7.1.2" + heimdalljs "^0.2.5" + heimdalljs-fs-monitor "^0.2.2" + heimdalljs-graph "^0.3.4" + heimdalljs-logger "^0.1.9" + http-proxy "^1.17.0" + inflection "^1.12.0" is-git-url "^1.0.0" - isbinaryfile "^3.0.0" - js-yaml "^3.6.1" + isbinaryfile "^3.0.3" + js-yaml "^3.12.0" json-stable-stringify "^1.0.1" leek "0.0.24" - lodash.template "^4.2.5" - markdown-it "^8.3.0" + lodash.template "^4.4.0" + markdown-it "^8.4.2" markdown-it-terminal "0.1.0" - minimatch "^3.0.0" - morgan "^1.8.1" - node-modules-path "^1.0.0" + minimatch "^3.0.4" + morgan "^1.9.0" + node-modules-path "^1.0.1" nopt "^3.0.6" - npm-package-arg "^4.1.1" - portfinder "^1.0.7" - promise-map-series "^0.2.1" + npm-package-arg "^6.1.0" + portfinder "^1.0.15" + promise-map-series "^0.2.3" quick-temp "^0.1.8" - resolve "^1.3.0" - rsvp "^3.6.0" - sane "^1.6.0" - semver "^5.1.1" - silent-error "^1.0.0" - sort-package-json "^1.4.0" - symlink-or-copy "^1.1.8" + resolve "^1.8.1" + rsvp "^4.8.3" + sane "^3.0.0" + semver "^5.5.0" + silent-error "^1.1.0" + sort-package-json "^1.15.0" + symlink-or-copy "^1.2.0" temp "0.8.3" - testem "^1.18.0" - tiny-lr "^1.0.3" - tree-sync "^1.2.1" - uuid "^3.0.0" + testem "^2.9.2" + tiny-lr "^1.1.1" + tree-sync "^1.2.2" + uuid "^3.3.2" validate-npm-package-name "^3.0.0" - walk-sync "^0.3.0" - yam "0.0.22" + walk-sync "^0.3.2" + watch-detector "^0.1.0" + yam "^0.0.24" + +ember-compatibility-helpers@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ember-compatibility-helpers/-/ember-compatibility-helpers-1.0.2.tgz#a7eb8969747d063720fe44658af5448589b437ba" + dependencies: + babel-plugin-debug-macros "^0.1.11" + ember-cli-version-checker "^2.1.1" + semver "^5.4.1" ember-composable-helpers@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/ember-composable-helpers/-/ember-composable-helpers-2.0.3.tgz#9b5e595bf5a45bc4431adfe27821f23b1d534be0" + version "2.1.0" + resolved "https://registry.yarnpkg.com/ember-composable-helpers/-/ember-composable-helpers-2.1.0.tgz#71f75ab2de1c696d21939b5f9dcc62eaf2c947e5" dependencies: broccoli-funnel "^1.0.1" - ember-cli-babel "^6.1.0" + ember-cli-babel "^6.6.0" ember-computed-query@^0.1.1: version "0.1.1" @@ -3973,51 +3916,61 @@ ember-computed-query@^0.1.1: ember-cli-babel "^6.3.0" ember-concurrency@^0.8.14: - version "0.8.14" - resolved "https://registry.yarnpkg.com/ember-concurrency/-/ember-concurrency-0.8.14.tgz#4017133e5fbb9d088082ef6ab5b91839ed33107b" + version "0.8.20" + resolved "https://registry.yarnpkg.com/ember-concurrency/-/ember-concurrency-0.8.20.tgz#2c4f84ed3eb86cd0c7be9c2d21dd23f560757ac7" dependencies: babel-core "^6.24.1" ember-cli-babel "^6.8.2" ember-maybe-import-regenerator "^0.1.5" -ember-data-model-fragments@2.11.x: - version "2.11.5" - resolved "https://registry.yarnpkg.com/ember-data-model-fragments/-/ember-data-model-fragments-2.11.5.tgz#756809c0931eab78b90aaf4973ff8010a9c251b2" +ember-copy@1.0.0, ember-copy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-copy/-/ember-copy-1.0.0.tgz#426554ba6cf65920f31d24d0a3ca2cb1be16e4aa" dependencies: - broccoli-file-creator "^1.1.1" - broccoli-merge-trees "^2.0.0" - ember-cli-babel "^6.0.0" - exists-sync "^0.0.4" - git-repo-info "^1.4.1" + ember-cli-babel "^6.6.0" + +ember-data-model-fragments@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ember-data-model-fragments/-/ember-data-model-fragments-3.3.0.tgz#93e3ddba6fab2150435f995e07d25a4d88694886" + dependencies: + broccoli-file-creator "^2.1.1" + broccoli-merge-trees "^3.0.0" + calculate-cache-key-for-tree "^1.1.0" + ember-cli-babel "^6.8.0" + ember-copy "1.0.0" + git-repo-info "^2.0.0" npm-git-info "^1.0.3" -ember-data@2.12.1: - version "2.12.1" - resolved "https://registry.yarnpkg.com/ember-data/-/ember-data-2.12.1.tgz#c06d47b14ff4956e6579b04960f62060b8ce7a70" +ember-data@~3.4.0: + version "3.4.2" + resolved "https://registry.yarnpkg.com/ember-data/-/ember-data-3.4.2.tgz#675cc4f1be8df1f5c0bfe4191afa6986377721c0" dependencies: - amd-name-resolver "0.0.5" - babel-plugin-feature-flags "^0.2.1" - babel-plugin-filter-imports "^0.2.0" - babel5-plugin-strip-class-callcheck "^5.1.0" - babel5-plugin-strip-heimdall "^5.0.2" - broccoli-babel-transpiler "^5.5.0" - broccoli-file-creator "^1.0.0" - broccoli-merge-trees "^1.0.0" - chalk "^1.1.1" - ember-cli-babel "^5.1.6" + "@ember/ordered-set" "^2.0.0" + babel-plugin-feature-flags "^0.3.1" + babel-plugin-filter-imports "^0.3.1" + babel-plugin-transform-es2015-block-scoping "^6.26.0" + babel6-plugin-strip-class-callcheck "^6.0.0" + babel6-plugin-strip-heimdall "^6.0.1" + broccoli-debug "^0.6.4" + broccoli-file-creator "^2.1.1" + broccoli-funnel "^2.0.1" + broccoli-merge-trees "^3.0.0" + broccoli-rollup "^2.1.1" + calculate-cache-key-for-tree "^1.1.0" + chalk "^2.4.1" + ember-cli-babel "^6.16.0" ember-cli-path-utils "^1.0.0" - ember-cli-string-utils "^1.0.0" + ember-cli-string-utils "^1.1.0" ember-cli-test-info "^1.0.0" - ember-cli-version-checker "^1.1.4" - ember-inflector "^1.9.4" - ember-runtime-enumerable-includes-polyfill "^1.0.0" - exists-sync "0.0.3" - git-repo-info "^1.1.2" + ember-cli-version-checker "^2.1.2" + ember-inflector "^3.0.0" + git-repo-info "^2.0.0" heimdalljs "^0.3.0" - inflection "^1.8.0" - npm-git-info "^1.0.0" - semver "^5.1.0" - silent-error "^1.0.0" + inflection "^1.12.0" + npm-git-info "^1.0.3" + resolve "^1.8.1" + semver "^5.5.0" + silent-error "^1.1.0" ember-export-application-global@^2.0.0: version "2.0.0" @@ -4025,14 +3978,20 @@ ember-export-application-global@^2.0.0: dependencies: ember-cli-babel "^6.0.0-beta.7" +ember-factory-for-polyfill@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/ember-factory-for-polyfill/-/ember-factory-for-polyfill-1.3.1.tgz#b446ed64916d293c847a4955240eb2c993b86eae" + dependencies: + ember-cli-version-checker "^2.1.0" + ember-fetch@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/ember-fetch/-/ember-fetch-3.4.3.tgz#fb8ba73148bb2399a82b037e4fdf9a953cd496ba" + version "3.4.5" + resolved "https://registry.yarnpkg.com/ember-fetch/-/ember-fetch-3.4.5.tgz#2967df9cbdbe0993402588216332580be3950b92" dependencies: broccoli-funnel "^1.2.0" broccoli-stew "^1.4.2" broccoli-templater "^1.0.0" - ember-cli-babel "^6.8.1" + ember-cli-babel "^6.8.2" node-fetch "^2.0.0-alpha.9" whatwg-fetch "^2.0.3" @@ -4043,15 +4002,16 @@ ember-get-config@^0.2.2: broccoli-file-creator "^1.1.1" ember-cli-babel "^6.3.0" -ember-inflector@^1.9.4: - version "1.12.1" - resolved "https://registry.yarnpkg.com/ember-inflector/-/ember-inflector-1.12.1.tgz#d8bd2ca2f327b439720f89923fe614d46b5da1ca" +ember-getowner-polyfill@^2.0.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ember-getowner-polyfill/-/ember-getowner-polyfill-2.2.0.tgz#38e7dccbcac69d5ec694000329ec0b2be651d2b2" dependencies: - ember-cli-babel "^5.1.7" + ember-cli-version-checker "^2.1.0" + ember-factory-for-polyfill "^1.3.1" ember-inflector@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ember-inflector/-/ember-inflector-2.1.0.tgz#afcb92d022a4eab58f08ff4578eafc3a1de2d09b" + version "2.3.0" + resolved "https://registry.yarnpkg.com/ember-inflector/-/ember-inflector-2.3.0.tgz#94797eba0eea98d902aa1e5da0f0aeef6053317f" dependencies: ember-cli-babel "^6.0.0" @@ -4061,11 +4021,11 @@ ember-inflector@^3.0.0: dependencies: ember-cli-babel "^6.6.0" -ember-load-initializers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ember-load-initializers/-/ember-load-initializers-1.0.0.tgz#4919eaf06f6dfeca7e134633d8c05a6c9921e6e7" +ember-load-initializers@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ember-load-initializers/-/ember-load-initializers-1.1.0.tgz#4edacc0f3a14d9f53d241ac3e5561804c8377978" dependencies: - ember-cli-babel "^6.0.0-beta.7" + ember-cli-babel "^6.6.0" ember-lodash@^4.17.3: version "4.18.0" @@ -4078,7 +4038,16 @@ ember-lodash@^4.17.3: ember-cli-babel "^6.10.0" lodash-es "^4.17.4" -ember-maybe-import-regenerator@^0.1.5: +ember-macro-helpers@^0.17.0: + version "0.17.1" + resolved "https://registry.yarnpkg.com/ember-macro-helpers/-/ember-macro-helpers-0.17.1.tgz#34836e9158cc260ee1c540935371d11f52ec98d9" + dependencies: + ember-cli-babel "^6.6.0" + ember-cli-string-utils "^1.1.0" + ember-cli-test-info "^1.0.0" + ember-weakmap "^3.0.0" + +ember-maybe-import-regenerator@^0.1.5, ember-maybe-import-regenerator@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ember-maybe-import-regenerator/-/ember-maybe-import-regenerator-0.1.6.tgz#35d41828afa6d6a59bc0da3ce47f34c573d776ca" dependencies: @@ -4093,49 +4062,50 @@ ember-maybe-in-element@^0.1.3: dependencies: ember-cli-babel "^6.11.0" -ember-moment@7.0.0-beta.5: - version "7.0.0-beta.5" - resolved "https://registry.yarnpkg.com/ember-moment/-/ember-moment-7.0.0-beta.5.tgz#b62c144d32f6ad0acaadd588ba93f4ddeb72ba89" +ember-moment@^7.7.0: + version "7.7.0" + resolved "https://registry.yarnpkg.com/ember-moment/-/ember-moment-7.7.0.tgz#febf7cc5bfc665c8f1d45fa24e5c7a5f5f91afa5" dependencies: - ember-cli-babel "^5.1.6" + ember-cli-babel "^6.7.2" + ember-getowner-polyfill "^2.0.1" + ember-macro-helpers "^0.17.0" ember-native-dom-helpers@^0.5.3: - version "0.5.4" - resolved "https://registry.yarnpkg.com/ember-native-dom-helpers/-/ember-native-dom-helpers-0.5.4.tgz#0bc1506a643fb7adc0abf1d09c44a7914459296b" + version "0.5.10" + resolved "https://registry.yarnpkg.com/ember-native-dom-helpers/-/ember-native-dom-helpers-0.5.10.tgz#9c7172e4ddfa5dd86830c46a936e2f8eca3e5896" dependencies: broccoli-funnel "^1.1.0" ember-cli-babel "^6.6.0" -ember-qunit-assert-helpers@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ember-qunit-assert-helpers/-/ember-qunit-assert-helpers-0.1.3.tgz#6ba2acf63a3c45c6f6764bc1b5cffd42942df678" +ember-qunit@^3.3.2: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ember-qunit/-/ember-qunit-3.4.1.tgz#204a2d39a5d44d494c56bf17cf3fd12f06210359" dependencies: - broccoli-filter "^1.0.1" - ember-cli-babel "^5.1.7" - -ember-qunit@^2.1.3: - version "2.1.4" - resolved "https://registry.yarnpkg.com/ember-qunit/-/ember-qunit-2.1.4.tgz#5732794e668f753d8fe1a353692ffeda73742d29" - dependencies: - ember-test-helpers "^0.6.3" + "@ember/test-helpers" "^0.7.18" + broccoli-funnel "^2.0.1" + broccoli-merge-trees "^2.0.0" + common-tags "^1.4.0" + ember-cli-babel "^6.8.2" + ember-cli-test-loader "^2.2.0" + qunit "^2.5.0" ember-radio-button@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ember-radio-button/-/ember-radio-button-1.1.1.tgz#e5ae8361ff032a4f1be91a810295e196eb2acf97" + version "1.2.4" + resolved "https://registry.yarnpkg.com/ember-radio-button/-/ember-radio-button-1.2.4.tgz#7ca1ac03f79036954dbeeb2926350965ee4db497" dependencies: - ember-cli-babel "^5.1.7" - ember-cli-htmlbars "^1.0.10" + ember-cli-babel "^6.9.2" + ember-cli-htmlbars "^1.1.1" -ember-resolver@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ember-resolver/-/ember-resolver-4.3.0.tgz#aaf0e43646be2e7da14399a0c2e9574c2130ce69" +ember-resolver@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ember-resolver/-/ember-resolver-5.0.1.tgz#21740b92e1e4a65f94018de22aa1c73434dc3b2f" dependencies: "@glimmer/resolver" "^0.4.1" babel-plugin-debug-macros "^0.1.10" - broccoli-funnel "^1.1.0" - broccoli-merge-trees "^2.0.0" - ember-cli-babel "^6.3.0" - ember-cli-version-checker "1.3.1" + broccoli-funnel "^2.0.1" + broccoli-merge-trees "^3.0.0" + ember-cli-babel "^6.8.1" + ember-cli-version-checker "^2.0.0" resolve "^1.3.3" ember-responsive@^3.0.0-beta.3: @@ -4144,43 +4114,26 @@ ember-responsive@^3.0.0-beta.3: dependencies: ember-cli-babel "^6.6.0" -ember-rfc176-data@^0.2.0: - version "0.2.5" - resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.2.5.tgz#b26f62d9c03d3b02485153cf31137e089299839a" +ember-rfc176-data@^0.3.0, ember-rfc176-data@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.3.3.tgz#27fba08d540a7463a4366c48eaa19c5a44971a39" -ember-rfc176-data@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.2.7.tgz#bd355bc9b473e08096b518784170a23388bc973b" +ember-rfc176-data@^0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.3.4.tgz#566fd3b7192d02a9a0bfe7e22bbaa4d3a1682e4a" -ember-rfc176-data@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.3.1.tgz#6a5a4b8b82ec3af34f3010965fa96b936ca94519" - -ember-router-generator@^1.0.0: +ember-router-generator@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/ember-router-generator/-/ember-router-generator-1.2.3.tgz#8ed2ca86ff323363120fc14278191e9e8f1315ee" dependencies: recast "^0.11.3" -ember-router-service-polyfill@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ember-router-service-polyfill/-/ember-router-service-polyfill-1.0.2.tgz#6e5565f196fa7045cbe06a6fab861f9e766fe62a" - dependencies: - ember-cli-babel "^6.8.2" - -ember-runtime-enumerable-includes-polyfill@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/ember-runtime-enumerable-includes-polyfill/-/ember-runtime-enumerable-includes-polyfill-1.0.4.tgz#16a7612e347a2edf07da8b2f2f09dbfee70deba0" - dependencies: - ember-cli-babel "^5.1.6" - ember-cli-version-checker "^1.1.6" - ember-runtime-enumerable-includes-polyfill@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ember-runtime-enumerable-includes-polyfill/-/ember-runtime-enumerable-includes-polyfill-2.0.0.tgz#6e9ba118bc909d1d7762de1b03a550d8955308a9" + version "2.1.0" + resolved "https://registry.yarnpkg.com/ember-runtime-enumerable-includes-polyfill/-/ember-runtime-enumerable-includes-polyfill-2.1.0.tgz#dc6d4a028471e4acc350dfd2a149874fb20913f5" dependencies: - ember-cli-babel "^6.0.0" - ember-cli-version-checker "^1.1.6" + ember-cli-babel "^6.9.0" + ember-cli-version-checker "^2.1.0" ember-sinon@^1.0.1: version "1.0.1" @@ -4191,83 +4144,70 @@ ember-sinon@^1.0.1: ember-cli-babel "^6.3.0" sinon "^3.2.1" -ember-source@~2.14.0: - version "2.14.1" - resolved "https://registry.yarnpkg.com/ember-source/-/ember-source-2.14.1.tgz#4abf0b4c916f2da8bf317349df4750905df7e628" +ember-source@~3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ember-source/-/ember-source-3.4.1.tgz#75cfc19bd54ad006729c8ec12539901308e8cef0" dependencies: - "@glimmer/compiler" "^0.22.3" - "@glimmer/node" "^0.22.3" - "@glimmer/reference" "^0.22.3" - "@glimmer/runtime" "^0.22.3" - "@glimmer/util" "^0.22.3" - broccoli-funnel "^1.2.0" + broccoli-funnel "^2.0.1" broccoli-merge-trees "^2.0.0" + chalk "^2.3.0" ember-cli-get-component-path-option "^1.0.0" + ember-cli-is-package-missing "^1.0.0" ember-cli-normalize-entity-name "^1.0.0" ember-cli-path-utils "^1.0.0" ember-cli-string-utils "^1.1.0" - ember-cli-test-info "^1.0.0" ember-cli-valid-component-name "^1.0.0" - ember-cli-version-checker "^1.3.1" - handlebars "^4.0.6" - jquery "^3.2.1" - resolve "^1.3.3" - rsvp "^3.5.0" - simple-dom "^0.3.0" - simple-html-tokenizer "^0.4.1" + ember-cli-version-checker "^2.1.0" + ember-router-generator "^1.2.3" + inflection "^1.12.0" + jquery "^3.3.1" + resolve "^1.6.0" -ember-test-helpers@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/ember-test-helpers/-/ember-test-helpers-0.6.3.tgz#f864cdf6f4e75f3f8768d6537785b5ab6e82d907" - -ember-test-selectors@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/ember-test-selectors/-/ember-test-selectors-0.3.6.tgz#38fa62f3f82381793047fda98a37093ec891a211" +ember-template-lint@^1.0.0-beta.5: + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/ember-template-lint/-/ember-template-lint-1.0.0-beta.5.tgz#b9c3459752b9fb6c93f676f5a99e18372ad60af2" dependencies: - broccoli-stew "^1.4.0" - ember-cli-babel "^6.6.0" + "@glimmer/compiler" "^0.36.2" + chalk "^2.0.0" + globby "^8.0.1" + minimatch "^3.0.4" + resolve "^1.1.3" + strip-bom "^3.0.0" + +ember-test-selectors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-test-selectors/-/ember-test-selectors-1.0.0.tgz#a2f8cd86f4fb4c320004a2bf0e4c450d41668a21" + dependencies: + ember-cli-babel "^6.8.2" ember-cli-version-checker "^2.0.0" -ember-truth-helpers@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ember-truth-helpers/-/ember-truth-helpers-1.2.0.tgz#e63cffeaa8211882ae61a958816fded3790d065b" - dependencies: - ember-cli-babel "^5.1.5" - -ember-try-config@^2.0.1: +ember-truth-helpers@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/ember-try-config/-/ember-try-config-2.1.0.tgz#e0e156229a542346a58ee6f6ad605104c98edfe0" + resolved "https://registry.yarnpkg.com/ember-truth-helpers/-/ember-truth-helpers-2.1.0.tgz#d4dab4eee7945aa2388126485977baeb33ca0798" dependencies: - lodash "^4.6.1" - node-fetch "^1.3.3" - rsvp "^3.2.1" - semver "^5.1.0" + ember-cli-babel "^6.6.0" -ember-try@^0.2.15: - version "0.2.16" - resolved "https://registry.yarnpkg.com/ember-try/-/ember-try-0.2.16.tgz#cf7092d8a8fea9701d7faa73cbdbff37a8ada330" +ember-weakmap@^3.0.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/ember-weakmap/-/ember-weakmap-3.3.1.tgz#5188b035f5bfb17397067ea635300ae4e1205e11" dependencies: - chalk "^1.0.0" - cli-table2 "^0.2.0" - core-object "^1.1.0" - debug "^2.2.0" - ember-cli-version-checker "^1.1.6" - ember-try-config "^2.0.1" - extend "^3.0.0" - fs-extra "^0.26.0" - promise-map-series "^0.2.1" - resolve "^1.1.6" - rimraf "^2.3.2" - rsvp "^3.0.17" - semver "^5.1.0" + browserslist "^3.1.1" + debug "^3.1.0" + ember-cli-babel "^6.6.0" emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" -encodeurl@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" +enabled@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93" + dependencies: + env-variable "0.0.x" + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" encoding@^0.1.11: version "0.1.12" @@ -4281,44 +4221,42 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" -engine.io-client@1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.8.0.tgz#7b730e4127414087596d9be3c88d2bc5fdb6cf5c" +engine.io-client@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36" dependencies: component-emitter "1.2.1" component-inherit "0.0.3" - debug "2.3.3" - engine.io-parser "1.3.1" + debug "~3.1.0" + engine.io-parser "~2.1.1" has-cors "1.1.0" indexof "0.0.1" - parsejson "0.0.3" parseqs "0.0.5" parseuri "0.0.5" - ws "1.1.1" - xmlhttprequest-ssl "1.5.3" + ws "~3.3.1" + xmlhttprequest-ssl "~1.5.4" yeast "0.1.2" -engine.io-parser@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.3.1.tgz#9554f1ae33107d6fbd170ca5466d2f833f6a07cf" +engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.2.tgz#4c0f4cff79aaeecbbdcfdea66a823c6085409196" dependencies: - after "0.8.1" - arraybuffer.slice "0.0.6" + after "0.8.2" + arraybuffer.slice "~0.0.7" base64-arraybuffer "0.1.5" blob "0.0.4" - has-binary "0.1.6" - wtf-8 "1.0.0" + has-binary2 "~1.0.2" -engine.io@1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.0.tgz#3eeb5f264cb75dbbec1baaea26d61f5a4eace2aa" +engine.io@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.2.0.tgz#54332506f42f2edc71690d2f2a42349359f3bf7d" dependencies: - accepts "1.3.3" - base64id "0.1.0" + accepts "~1.3.4" + base64id "1.0.0" cookie "0.3.1" - debug "2.3.3" - engine.io-parser "1.3.1" - ws "1.1.1" + debug "~3.1.0" + engine.io-parser "~2.1.0" + ws "~3.3.1" enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: version "4.1.0" @@ -4340,15 +4278,30 @@ entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" +env-ci@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/env-ci/-/env-ci-2.4.0.tgz#1ceacee17a6860fffa04436cea586d15534b4c4d" + dependencies: + execa "^1.0.0" + java-properties "^0.2.9" + +env-variable@0.0.x: + version "0.0.4" + resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.4.tgz#0d6280cf507d84242befe35a512b5ae4be77c54e" + +err-code@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" + errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" dependencies: prr "~1.0.1" -error-ex@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" dependencies: is-arrayish "^0.2.1" @@ -4359,86 +4312,67 @@ error@^7.0.0: string-template "~0.2.1" xtend "~4.0.0" -es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.30" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.30.tgz#7141a16836697dbabfaaaeee41495ce29f52c939" +es-abstract@^1.5.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" dependencies: - es6-iterator "2" - es6-symbol "~3.1" + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" -es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" dependencies: - d "1" - es5-ext "^0.10.14" - es6-symbol "^3.1" - -es6-map@^0.1.3: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-set "~0.1.5" - es6-symbol "~3.1.1" - event-emitter "~0.3.5" + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" es6-promise@^3.0.2: version "3.3.1" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" -es6-promise@~4.0.3: - version "4.0.5" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.0.5.tgz#7882f30adde5b240ccfa7f7d78c548330951ae42" +es6-promise@^4.0.3: + version "4.2.4" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" -es6-set@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-symbol "3.1.1" - event-emitter "~0.3.5" - -es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" - dependencies: - d "1" - es5-ext "~0.10.14" - -es6-weak-map@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" - dependencies: - d "1" - es5-ext "^0.10.14" - es6-iterator "^2.0.1" - es6-symbol "^3.1.1" + es6-promise "^4.0.3" escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" -escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" -escope@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" +escodegen@^1.9.1: + version "1.11.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589" dependencies: - es6-map "^0.1.3" - es6-weak-map "^2.0.1" - esrecurse "^4.1.0" - estraverse "^4.1.1" + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-plugin-ember@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-ember/-/eslint-plugin-ember-5.2.0.tgz#fa436e0497dfc01d1d38608229cd616e7c5b6067" + dependencies: + ember-rfc176-data "^0.3.3" + snake-case "^2.1.0" eslint-scope@^3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + version "3.7.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" @@ -4450,70 +4384,36 @@ eslint-scope@^4.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint@^3.19.0: - version "3.19.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" - dependencies: - babel-code-frame "^6.16.0" - chalk "^1.1.3" - concat-stream "^1.5.2" - debug "^2.1.1" - doctrine "^2.0.0" - escope "^3.6.0" - espree "^3.4.0" - esquery "^1.0.0" - estraverse "^4.2.0" - esutils "^2.0.2" - file-entry-cache "^2.0.0" - glob "^7.0.3" - globals "^9.14.0" - ignore "^3.2.0" - imurmurhash "^0.1.4" - inquirer "^0.12.0" - is-my-json-valid "^2.10.0" - is-resolvable "^1.0.0" - js-yaml "^3.5.1" - json-stable-stringify "^1.0.0" - levn "^0.3.0" - lodash "^4.0.0" - mkdirp "^0.5.0" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.1" - pluralize "^1.2.1" - progress "^1.1.8" - require-uncached "^1.0.2" - shelljs "^0.7.5" - strip-bom "^3.0.0" - strip-json-comments "~2.0.1" - table "^3.7.8" - text-table "~0.2.0" - user-home "^2.0.0" +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" -eslint@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.2.0.tgz#a2b3184111b198e02e9c7f3cca625a5e01c56b3d" +eslint@^4.0.0, eslint@^4.5.0: + version "4.19.1" + resolved "http://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" dependencies: - ajv "^5.2.0" + ajv "^5.3.0" babel-code-frame "^6.22.0" - chalk "^1.1.3" + chalk "^2.1.0" concat-stream "^1.6.0" - debug "^2.6.8" - doctrine "^2.0.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.1.0" eslint-scope "^3.7.1" - espree "^3.4.3" + eslint-visitor-keys "^1.0.0" + espree "^3.5.4" esquery "^1.0.0" - estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" glob "^7.1.2" - globals "^9.17.0" + globals "^11.0.1" ignore "^3.3.3" imurmurhash "^0.1.4" inquirer "^3.0.6" is-resolvable "^1.0.0" - js-yaml "^3.8.4" - json-stable-stringify "^1.0.1" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" lodash "^4.17.4" minimatch "^3.0.2" @@ -4521,75 +4421,66 @@ eslint@^4.0.0: natural-compare "^1.4.0" optionator "^0.8.2" path-is-inside "^1.0.2" - pluralize "^4.0.0" + pluralize "^7.0.0" progress "^2.0.0" + regexpp "^1.0.1" require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" strip-json-comments "~2.0.1" - table "^4.0.1" + table "4.0.2" text-table "~0.2.0" -espree@^3.4.0, espree@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.3.tgz#2910b5ccd49ce893c2ffffaab4fd8b3a31b82374" +espree@^3.5.2, espree@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" dependencies: - acorn "^5.0.1" + acorn "^5.5.0" acorn-jsx "^3.0.0" -esprima-fb@~15001.1001.0-dev-harmony-fb: - version "15001.1001.0-dev-harmony-fb" - resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz#43beb57ec26e8cf237d3dd8b33e42533577f2659" +esprima@^3.1.3, esprima@~3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" -esprima@^2.6.0: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - -esprima@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" +esprima@^4.0.0, esprima@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" esprima@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.0.0.tgz#53cf247acda77313e551c3aa2e73342d3fb4f7d9" -esprima@~3.1.0: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - esquery@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" dependencies: estraverse "^4.0.0" esrecurse@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" dependencies: estraverse "^4.1.0" - object-assign "^4.0.1" estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" -esutils@^2.0.0, esutils@^2.0.2: +estree-walker@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.2.tgz#d3850be7529c9580d815600b53126515e146dd39" + +esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" -etag@~1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051" +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" -event-emitter@~0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - dependencies: - d "1" - es5-ext "~0.10.14" - -eventemitter3@1.x.x: - version "1.2.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" +eventemitter3@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" events-to-array@^1.0.1: version "1.1.2" @@ -4615,14 +4506,38 @@ exec-file-sync@^2.0.0: spawn-sync "^1.0.11" exec-sh@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.0.tgz#14f75de3f20d286ef933099b2ce50a90359cef10" + version "0.2.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" dependencies: - merge "^1.1.3" + merge "^1.2.0" -execa@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" +execa@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" + dependencies: + cross-spawn "^6.0.0" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.11.0.tgz#0b3c71daf9b9159c252a863cd981af1b4410d97a" + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -4632,19 +4547,27 @@ execa@^0.8.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + exif-parser@^0.1.9: - version "0.1.11" - resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.11.tgz#8a97d1c9315ffd4754b6ae938ce4488d1b1a26b7" + version "0.1.12" + resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" exists-stat@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/exists-stat/-/exists-stat-1.0.0.tgz#0660e3525a2e89d9e446129440c272edfa24b529" -exists-sync@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/exists-sync/-/exists-sync-0.0.3.tgz#b910000bedbb113b378b82f5f5a7638107622dcf" - -exists-sync@0.0.4, exists-sync@^0.0.4: +exists-sync@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/exists-sync/-/exists-sync-0.0.4.tgz#9744c2c428cc03b01060db454d4b12f0ef3c8879" @@ -4680,44 +4603,46 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -expand-tilde@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449" +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" dependencies: - os-homedir "^1.0.1" + homedir-polyfill "^1.0.1" -express@^4.10.7, express@^4.12.3: - version "4.15.3" - resolved "https://registry.yarnpkg.com/express/-/express-4.15.3.tgz#bab65d0f03aa80c358408972fc700f916944b662" +express@^4.10.7, express@^4.16.3: + version "4.16.3" + resolved "http://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" dependencies: - accepts "~1.3.3" + accepts "~1.3.5" array-flatten "1.1.1" + body-parser "1.18.2" content-disposition "0.5.2" - content-type "~1.0.2" + content-type "~1.0.4" cookie "0.3.1" cookie-signature "1.0.6" - debug "2.6.7" - depd "~1.1.0" - encodeurl "~1.0.1" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" escape-html "~1.0.3" - etag "~1.8.0" - finalhandler "~1.0.3" - fresh "0.5.0" + etag "~1.8.1" + finalhandler "1.1.1" + fresh "0.5.2" merge-descriptors "1.0.1" methods "~1.1.2" on-finished "~2.3.0" - parseurl "~1.3.1" + parseurl "~1.3.2" path-to-regexp "0.1.7" - proxy-addr "~1.1.4" - qs "6.4.0" + proxy-addr "~2.0.3" + qs "6.5.1" range-parser "~1.2.0" - send "0.15.3" - serve-static "1.12.3" - setprototypeof "1.0.3" - statuses "~1.3.1" - type-is "~1.6.15" - utils-merge "1.0.0" - vary "~1.1.1" + safe-buffer "5.1.1" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + utils-merge "1.0.1" + vary "~1.1.2" extend-shallow@^2.0.1: version "2.0.1" @@ -4732,25 +4657,25 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@^3.0.0, extend@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" +extend@^3.0.0, extend@~3.0.1, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" external-editor@^1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-1.1.1.tgz#12d7b0db850f7ff7e7081baf4005700060c4600b" + resolved "http://registry.npmjs.org/external-editor/-/external-editor-1.1.1.tgz#12d7b0db850f7ff7e7081baf4005700060c4600b" dependencies: extend "^3.0.0" spawn-sync "^1.0.15" tmp "^0.0.29" external-editor@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" + version "2.2.0" + resolved "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" dependencies: + chardet "^0.4.0" iconv-lite "^0.4.17" - jschardet "^1.4.2" - tmp "^0.0.31" + tmp "^0.0.33" extglob@^0.3.1: version "0.3.2" @@ -4771,22 +4696,22 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extract-zip@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.5.0.tgz#92ccf6d81ef70a9fa4c1747114ccef6d8688a6c4" +extract-zip@^1.6.5: + version "1.6.7" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9" dependencies: - concat-stream "1.5.0" - debug "0.7.4" - mkdirp "0.5.0" + concat-stream "1.6.2" + debug "2.6.9" + mkdirp "0.5.1" yauzl "2.4.1" -extsprintf@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" -eyes@0.1.x: - version "0.1.8" - resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" fake-xml-http-request@^1.4.0, fake-xml-http-request@^1.6.0: version "1.6.0" @@ -4797,13 +4722,24 @@ faker@^3.0.0: resolved "https://registry.yarnpkg.com/faker/-/faker-3.1.0.tgz#0f908faf4e6ec02524e54a57e432c5c013e08c9f" fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" +fast-glob@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.2.tgz#71723338ac9b4e0e2fff1d6748a2a13d5ed352bf" + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.0.1" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.1" + micromatch "^3.1.10" + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -4818,18 +4754,22 @@ fast-ordered-set@^1.0.0, fast-ordered-set@^1.0.2: dependencies: blank-object "^1.0.1" -fast-sourcemap-concat@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fast-sourcemap-concat/-/fast-sourcemap-concat-1.1.0.tgz#a800767abed5eda02e67238ec063a709be61f9d4" +fast-safe-stringify@^2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2" + +fast-sourcemap-concat@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/fast-sourcemap-concat/-/fast-sourcemap-concat-1.4.0.tgz#122c330d4a2afaff16ad143bc9674b87cd76c8ad" dependencies: - chalk "^0.5.1" - debug "^2.2.0" - fs-extra "^0.30.0" - memory-streams "^0.1.0" + chalk "^2.0.0" + fs-extra "^5.0.0" + heimdalljs-logger "^0.1.9" + memory-streams "^0.1.3" mkdirp "^0.5.0" - rsvp "^3.0.14" source-map "^0.4.2" source-map-url "^0.3.0" + sourcemap-validator "^1.1.0" fastboot-transform@0.1.1: version "0.1.1" @@ -4878,12 +4818,13 @@ fd-slicer@~1.0.1: dependencies: pend "~1.2.0" -figures@^1.3.5: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" - dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" +fecha@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" + +figgy-pudding@^3.0.0, figgy-pudding@^3.1.0, figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" figures@^2.0.0: version "2.0.0" @@ -4906,17 +4847,17 @@ filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" -filesize@^3.1.3: - version "3.5.10" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.10.tgz#fc8fa23ddb4ef9e5e0ab6e1e64f679a24a56761f" +filesize@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" dependencies: is-number "^2.1.0" isobject "^2.0.0" - randomatic "^1.1.3" + randomatic "^3.0.0" repeat-element "^1.1.2" repeat-string "^1.5.2" @@ -4929,16 +4870,16 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" -finalhandler@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.3.tgz#ef47e77950e999780e86022a560e3217e0d0cc89" +finalhandler@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" dependencies: - debug "2.6.7" - encodeurl "~1.0.1" + debug "2.6.9" + encodeurl "~1.0.2" escape-html "~1.0.3" on-finished "~2.3.0" - parseurl "~1.3.1" - statuses "~1.3.1" + parseurl "~1.3.2" + statuses "~1.4.0" unpipe "~1.0.0" find-cache-dir@^1.0.0: @@ -4953,6 +4894,10 @@ find-index@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-index/-/find-index-1.1.0.tgz#53007c79cd30040d6816d79458e8837d5c5705ef" +find-npm-prefix@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -4960,20 +4905,40 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^2.1.0: +find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" dependencies: locate-path "^2.0.0" -findup-sync@0.4.3, findup-sync@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.4.3.tgz#40043929e7bc60adf0b7f4827c4c6e75a0deca12" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" dependencies: - detect-file "^0.1.0" - is-glob "^2.0.1" - micromatch "^2.3.7" - resolve-dir "^0.1.0" + locate-path "^3.0.0" + +find-versions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-2.0.0.tgz#2ad90d490f6828c1aa40292cf709ac3318210c3c" + dependencies: + array-uniq "^1.0.0" + semver-regex "^1.0.0" + +find-yarn-workspace-root@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" + dependencies: + fs-extra "^4.0.3" + micromatch "^3.1.4" + +findup-sync@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" fireworm@^0.7.0: version "0.7.1" @@ -4985,9 +4950,23 @@ fireworm@^0.7.0: lodash.flatten "^3.0.2" minimatch "^3.0.2" +fixturify-project@^1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/fixturify-project/-/fixturify-project-1.5.3.tgz#2ba4ffec59c1d79ae6638f818c0847eb974d179b" + dependencies: + fixturify "^0.3.4" + tmp "^0.0.33" + +fixturify@^0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/fixturify/-/fixturify-0.3.4.tgz#c676de404a7f8ee8e64d0b76118e62ec95ab7b25" + dependencies: + fs-extra "^0.30.0" + matcher-collection "^1.0.4" + flat-cache@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" + version "1.3.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" dependencies: circular-json "^0.3.1" del "^2.0.2" @@ -5007,11 +4986,17 @@ flush-write-stream@^1.0.0: inherits "^2.0.1" readable-stream "^2.0.4" -for-each@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4" +follow-redirects@^1.0.0: + version "1.5.7" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.7.tgz#a39e4804dacb90202bca76a9e2ac10433ca6a69a" dependencies: - is-function "~1.0.0" + debug "^3.1.0" + +for-each@^0.3.2: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + dependencies: + is-callable "^1.1.3" for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" @@ -5027,23 +5012,23 @@ forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" -form-data@~2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" +form-data@~2.3.1, form-data@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" dependencies: asynckit "^0.4.0" - combined-stream "^1.0.5" + combined-stream "1.0.6" mime-types "^2.1.12" -formatio@1.2.0, formatio@^1.2.0: +formatio@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb" dependencies: samsam "1.x" -forwarded@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363" +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" fragment-cache@^0.2.1: version "0.2.1" @@ -5051,21 +5036,24 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -fresh@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e" +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" -from2@^2.1.0: +from2@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-1.3.0.tgz#88413baaa5f9a597cfde9221d86986cd3c061dfd" + dependencies: + inherits "~2.0.1" + readable-stream "~1.1.10" + +from2@^2.1.0, from2@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" dependencies: inherits "^2.0.1" readable-stream "^2.0.0" -fs-exists-sync@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" - fs-extra@^0.24.0: version "0.24.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.24.0.tgz#d4e4342a96675cb7846633a6099249332b539952" @@ -5075,16 +5063,6 @@ fs-extra@^0.24.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" -fs-extra@^0.26.0: - version "0.26.7" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - fs-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" @@ -5095,7 +5073,7 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" -fs-extra@^1.0.0, fs-extra@~1.0.0: +fs-extra@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" dependencies: @@ -5103,14 +5081,7 @@ fs-extra@^1.0.0, fs-extra@~1.0.0: jsonfile "^2.1.0" klaw "^1.0.0" -fs-extra@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.1.2.tgz#046c70163cef9aad46b0e4a7fa467fb22d71de35" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - -fs-extra@^4.0.0: +fs-extra@^4.0.2, fs-extra@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" dependencies: @@ -5118,6 +5089,14 @@ fs-extra@^4.0.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-extra@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b" @@ -5126,35 +5105,48 @@ fs-extra@^6.0.1: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.0.tgz#8cc3f47ce07ef7b3593a11b9fb245f7e34c041d6" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" dependencies: minipass "^2.2.1" -fs-readdir-recursive@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz#315b4fb8c1ca5b8c47defef319d073dad3568059" - -fs-tree-diff@^0.5.2, fs-tree-diff@^0.5.3, fs-tree-diff@^0.5.4, fs-tree-diff@^0.5.6: - version "0.5.6" - resolved "https://registry.yarnpkg.com/fs-tree-diff/-/fs-tree-diff-0.5.6.tgz#342665749e8dca406800b672268c8f5073f3e623" +fs-tree-diff@^0.5.2, fs-tree-diff@^0.5.3, fs-tree-diff@^0.5.4, fs-tree-diff@^0.5.6, fs-tree-diff@^0.5.7: + version "0.5.9" + resolved "https://registry.yarnpkg.com/fs-tree-diff/-/fs-tree-diff-0.5.9.tgz#a4ec6182c2f5bd80b9b83c8e23e4522e6f5fd946" dependencies: heimdalljs-logger "^0.1.7" object-assign "^4.1.0" path-posix "^1.0.0" symlink-or-copy "^1.1.8" -fs-tree-diff@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/fs-tree-diff/-/fs-tree-diff-0.5.7.tgz#315e2b098d5fe7f622880ac965b1b051868ac871" +fs-updater@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/fs-updater/-/fs-updater-1.0.4.tgz#2329980f99ae9176e9a0e84f7637538a182ce63b" dependencies: - heimdalljs-logger "^0.1.7" - object-assign "^4.1.0" - path-posix "^1.0.0" - symlink-or-copy "^1.1.8" + can-symlink "^1.0.0" + clean-up-path "^1.0.0" + heimdalljs "^0.2.5" + heimdalljs-logger "^0.1.9" + rimraf "^2.6.2" -fs-write-stream-atomic@^1.0.8: +fs-vacuum@^1.2.10, fs-vacuum@~1.2.10: + version "1.2.10" + resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" + dependencies: + graceful-fs "^4.1.2" + path-is-inside "^1.0.1" + rimraf "^2.5.2" + +fs-write-stream-atomic@^1.0.8, fs-write-stream-atomic@~1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" dependencies: @@ -5167,29 +5159,14 @@ fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" -fsevents@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.2.tgz#3282b713fb3ad80ede0e9fcf4611b5aa6fc033f4" - dependencies: - nan "^2.3.0" - node-pre-gyp "^0.6.36" - -fsevents@^1.2.2: +fsevents@^1.2.2, fsevents@^1.2.3: version "1.2.4" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" dependencies: nan "^2.9.2" node-pre-gyp "^0.10.0" -fstream-ignore@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" - dependencies: - fstream "^1.0.0" - inherits "2" - minimatch "^3.0.0" - -fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: +fstream@^1.0.0, fstream@^1.0.2: version "1.0.11" resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" dependencies: @@ -5198,6 +5175,14 @@ fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: mkdirp ">=0.5 0" rimraf "2" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -5212,24 +5197,31 @@ gauge@~2.7.3: wide-align "^1.1.0" gaze@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105" + version "1.1.3" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" dependencies: globule "^1.0.0" -generate-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" +genfun@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/genfun/-/genfun-4.0.1.tgz#ed10041f2e4a7f1b0a38466d17a5c3e27df1dfc1" -generate-object-property@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" +gentle-fs@^2.0.0, gentle-fs@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.0.1.tgz#585cfd612bfc5cd52471fdb42537f016a5ce3687" dependencies: - is-property "^1.0.0" + aproba "^1.1.2" + fs-vacuum "^1.2.10" + graceful-fs "^4.1.11" + iferr "^0.1.5" + mkdirp "^0.5.1" + path-is-inside "^1.0.2" + read-cmd-shim "^1.0.1" + slide "^1.1.6" get-caller-file@^1.0.0, get-caller-file@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" get-stdin@^4.0.1: version "4.0.1" @@ -5250,6 +5242,12 @@ get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" +get-stream@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.0.0.tgz#9e074cb898bd2b9ebabb445a1766d7f43576d977" + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -5260,9 +5258,33 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -git-repo-info@^1.1.2, git-repo-info@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/git-repo-info/-/git-repo-info-1.4.1.tgz#2a072823254aaf62fcf0766007d7b6651bd41943" +git-log-parser@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/git-log-parser/-/git-log-parser-1.2.0.tgz#2e6a4c1b13fc00028207ba795a7ac31667b9fd4a" + dependencies: + argv-formatter "~1.0.0" + spawn-error-forwarder "~1.0.0" + split2 "~1.0.0" + stream-combiner2 "~1.1.1" + through2 "~2.0.0" + traverse "~0.6.6" + +git-repo-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-repo-info/-/git-repo-info-2.0.0.tgz#2e7a68ba3d0253e8e885c4138f922e6561de59bb" + +git-up@^2.0.0: + version "2.0.10" + resolved "https://registry.yarnpkg.com/git-up/-/git-up-2.0.10.tgz#20fe6bafbef4384cae253dc4f463c49a0c3bd2ec" + dependencies: + is-ssh "^1.3.0" + parse-url "^1.3.0" + +git-url-parse@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-10.0.1.tgz#75f153b24ac7297447fc583cf9fac23a5ae687c1" + dependencies: + git-up "^2.0.0" glob-base@^0.3.0: version "0.3.0" @@ -5284,6 +5306,10 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + glob@3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.3.tgz#e313eeb249c7affaa5c475286b0e115b59839467" @@ -5292,18 +5318,7 @@ glob@3.2.3: inherits "2" minimatch "~0.2.11" -glob@7.1.1, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^5.0.10, glob@^5.0.15: +glob@^5.0.10: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" dependencies: @@ -5313,19 +5328,9 @@ glob@^5.0.10, glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.1.2, glob@~7.1.1: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" +glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -5345,21 +5350,29 @@ glob@~7.0.6: once "^1.3.0" path-is-absolute "^1.0.0" -global-modules@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d" +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" dependencies: - global-prefix "^0.1.4" - is-windows "^0.2.0" - -global-prefix@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f" - dependencies: - homedir-polyfill "^1.0.0" ini "^1.3.4" - is-windows "^0.2.0" - which "^1.2.12" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" global@~4.3.0: version "4.3.2" @@ -5368,11 +5381,11 @@ global@~4.3.0: min-document "^2.19.0" process "~0.5.1" -globals@^6.4.0: - version "6.4.1" - resolved "https://registry.yarnpkg.com/globals/-/globals-6.4.1.tgz#8498032b3b6d1cc81eebc5f79690d8fe29fabf4f" +globals@^11.0.1: + version "11.7.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673" -globals@^9.0.0, globals@^9.14.0, globals@^9.17.0, globals@^9.18.0: +globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -5387,12 +5400,24 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globby@^8.0.0, globby@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + globule@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09" + version "1.2.1" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" dependencies: glob "~7.1.1" - lodash "~4.17.4" + lodash "~4.17.10" minimatch "~3.0.2" good-listener@^1.2.2: @@ -5401,7 +5426,23 @@ good-listener@^1.2.2: dependencies: delegate "^3.1.2" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +got@^6.7.1: + version "6.7.1" + resolved "http://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@~4.1.11: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -5421,55 +5462,37 @@ growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" -handlebars@^4.0.11: - version "4.0.11" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" +handlebars@^4.0.11, handlebars@^4.0.2, handlebars@^4.0.4, handlebars@^4.0.6: + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" dependencies: - async "^1.4.0" + async "^2.5.0" optimist "^0.6.1" - source-map "^0.4.4" + source-map "^0.6.1" optionalDependencies: - uglify-js "^2.6" + uglify-js "^3.1.4" -handlebars@^4.0.4, handlebars@^4.0.6: - version "4.0.10" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" dependencies: - async "^1.4.0" - optimist "^0.6.1" - source-map "^0.4.4" - optionalDependencies: - uglify-js "^2.6" + ajv "^5.1.0" + har-schema "^2.0.0" -har-schema@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" - -har-validator@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" +har-validator@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29" dependencies: - chalk "^1.1.1" - commander "^2.9.0" - is-my-json-valid "^2.12.4" - pinkie-promise "^2.0.0" - -har-validator@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" - dependencies: - ajv "^4.9.1" - har-schema "^1.0.5" + ajv "^5.3.0" + har-schema "^2.0.0" harmony-reflect@^1.4.2: - version "1.5.1" - resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.5.1.tgz#b54ca617b00cc8aef559bbb17b3d85431dc7e329" - -has-ansi@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e" - dependencies: - ansi-regex "^0.2.0" + version "1.6.0" + resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.0.tgz#9c28a77386ec225f7b5d370f9861ba09c4eea58f" has-ansi@^2.0.0: version "2.0.0" @@ -5477,17 +5500,11 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -has-binary@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.6.tgz#25326f39cfa4f616ad8787894e3af2cfbc7b6e10" +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" dependencies: - isarray "0.0.1" - -has-binary@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.7.tgz#68e61eb16210c9545a0a5cce06a873912fe1e68c" - dependencies: - isarray "0.0.1" + isarray "2.0.1" has-color@~0.1.0: version "0.1.7" @@ -5505,7 +5522,7 @@ has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" -has-unicode@^2.0.0: +has-unicode@^2.0.0, has-unicode@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -5536,6 +5553,12 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" +has@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + dependencies: + function-bind "^1.1.1" + hash-base@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" @@ -5543,16 +5566,7 @@ hash-base@^3.0.0: inherits "^2.0.1" safe-buffer "^5.0.1" -hash-for-dep@^1.0.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/hash-for-dep/-/hash-for-dep-1.1.2.tgz#e3347ed92960eb0bb53a2c6c2b70e36d75b7cd0c" - dependencies: - broccoli-kitchen-sink-helpers "^0.3.1" - heimdalljs "^0.2.3" - heimdalljs-logger "^0.1.7" - resolve "^1.1.6" - -hash-for-dep@^1.2.3: +hash-for-dep@^1.0.2, hash-for-dep@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/hash-for-dep/-/hash-for-dep-1.2.3.tgz#5ec69fca32c23523972d52acb5bb65ffc3664cab" dependencies: @@ -5568,43 +5582,34 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hasha@~2.2.0: +hasha@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/hasha/-/hasha-2.2.0.tgz#78d7cbfc1e6d66303fe79837365984517b2f6ee1" dependencies: is-stream "^1.0.1" pinkie-promise "^2.0.0" -hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" +heimdalljs-fs-monitor@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/heimdalljs-fs-monitor/-/heimdalljs-fs-monitor-0.2.2.tgz#a76d98f52dbf3aa1b7c20cebb0132e2f5eeb9204" dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - -heimdalljs-fs-monitor@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/heimdalljs-fs-monitor/-/heimdalljs-fs-monitor-0.1.0.tgz#d404a65688c6714c485469ed3495da4853440272" - dependencies: - heimdalljs "^0.2.0" + heimdalljs "^0.2.3" heimdalljs-logger "^0.1.7" -heimdalljs-graph@^0.3.1: - version "0.3.3" - resolved "https://registry.yarnpkg.com/heimdalljs-graph/-/heimdalljs-graph-0.3.3.tgz#ea801dbba659c8d522fe1cb83b2d605726e4918f" +heimdalljs-graph@^0.3.4: + version "0.3.5" + resolved "https://registry.yarnpkg.com/heimdalljs-graph/-/heimdalljs-graph-0.3.5.tgz#420fbbc8fc3aec5963ddbbf1a5fb47921c4a5927" -heimdalljs-logger@^0.1.7: - version "0.1.9" - resolved "https://registry.yarnpkg.com/heimdalljs-logger/-/heimdalljs-logger-0.1.9.tgz#d76ada4e45b7bb6f786fc9c010a68eb2e2faf176" +heimdalljs-logger@^0.1.7, heimdalljs-logger@^0.1.9: + version "0.1.10" + resolved "https://registry.yarnpkg.com/heimdalljs-logger/-/heimdalljs-logger-0.1.10.tgz#90cad58aabb1590a3c7e640ddc6a4cd3a43faaf7" dependencies: debug "^2.2.0" - heimdalljs "^0.2.0" + heimdalljs "^0.2.6" -heimdalljs@^0.2.0, heimdalljs@^0.2.1, heimdalljs@^0.2.3: - version "0.2.5" - resolved "https://registry.yarnpkg.com/heimdalljs/-/heimdalljs-0.2.5.tgz#6aa54308eee793b642cff9cf94781445f37730ac" +heimdalljs@^0.2.0, heimdalljs@^0.2.1, heimdalljs@^0.2.3, heimdalljs@^0.2.5, heimdalljs@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/heimdalljs/-/heimdalljs-0.2.6.tgz#b0eebabc412813aeb9542f9cc622cb58dbdcd9fe" dependencies: rsvp "~3.2.1" @@ -5622,17 +5627,6 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - -home-or-tmp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-1.0.0.tgz#4b9f1e40800c3e50c6c27f781676afcce71f3985" - dependencies: - os-tmpdir "^1.0.1" - user-home "^1.1.1" - home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -5640,15 +5634,25 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" -homedir-polyfill@^1.0.0: +homedir-polyfill@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" dependencies: parse-passwd "^1.0.0" -hosted-git-info@^2.1.4, hosted-git-info@^2.1.5: - version "2.5.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" +hook-std@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hook-std/-/hook-std-1.1.0.tgz#7f76b74b6f96d3cd4106afb50a66bdb0af2d2a2d" + +hosted-git-info@^2.1.4, hosted-git-info@^2.6.0, hosted-git-info@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + dependencies: + whatwg-encoding "^1.0.1" htmlparser2@~3.8.1: version "3.8.3" @@ -5660,6 +5664,10 @@ htmlparser2@~3.8.1: entities "1.0" readable-stream "1.1" +http-cache-semantics@^3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + http-errors@1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" @@ -5669,36 +5677,39 @@ http-errors@1.6.2: setprototypeof "1.0.3" statuses ">= 1.3.1 < 2" -http-errors@~1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.1.tgz#5f8b8ed98aca545656bf572997387f904a722257" - dependencies: - depd "1.1.0" - inherits "2.0.3" - setprototypeof "1.0.3" - statuses ">= 1.3.1 < 2" - -http-errors@~1.6.2: +http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" dependencies: depd "~1.1.2" inherits "2.0.3" setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -http-proxy@^1.13.1, http-proxy@^1.9.0: - version "1.16.2" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742" - dependencies: - eventemitter3 "1.x.x" - requires-port "1.x.x" +http-parser-js@>=0.4.0: + version "0.4.13" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.13.tgz#3bd6d6fde6e3172c9334c3b33b6c193d80fe1137" -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" dependencies: - assert-plus "^0.2.0" + agent-base "4" + debug "3.1.0" + +http-proxy@^1.13.1, http-proxy@^1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" + dependencies: + eventemitter3 "^3.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" jsprim "^1.2.2" sshpk "^1.7.0" @@ -5706,20 +5717,35 @@ https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" +https-proxy-agent@^2.2.0, https-proxy-agent@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + dependencies: + ms "^2.0.0" + iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" -iconv-lite@^0.4.17, iconv-lite@^0.4.5, iconv-lite@~0.4.13: - version "0.4.18" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" - -iconv-lite@^0.4.4: +iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + dependencies: + safer-buffer ">= 2.1.2 < 3" + ieee754@^1.1.11, ieee754@^1.1.4: version "1.1.12" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" @@ -5728,15 +5754,19 @@ iferr@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" +iferr@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-1.0.2.tgz#e9fde49a9da06dc4a4194c6c9ed6d08305037a6d" + ignore-walk@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" dependencies: minimatch "^3.0.4" -ignore@^3.2.0, ignore@^3.2.7, ignore@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" +ignore@^3.2.7, ignore@^3.3.3, ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" image-size@^0.4.0: version "0.4.0" @@ -5746,6 +5776,16 @@ image-size@^0.5.0: version "0.5.5" resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + dependencies: + resolve-from "^3.0.0" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -5764,7 +5804,7 @@ indent-string@^2.1.0: dependencies: repeating "^2.0.0" -indent-string@^3.1.0: +indent-string@^3.0.0, indent-string@^3.1.0, indent-string@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" @@ -5772,11 +5812,11 @@ indexof@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" -inflection@^1.7.0, inflection@^1.7.1, inflection@^1.8.0: +inflection@^1.12.0: version "1.12.0" resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.12.0.tgz#a200935656d6f5f6bc4dc7502e1aecb703228416" -inflight@^1.0.4: +inflight@^1.0.4, inflight@~1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" dependencies: @@ -5791,9 +5831,22 @@ inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" -ini@^1.3.4, ini@~1.3.0: - version "1.3.4" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" +ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +init-package-json@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.10.3.tgz#45ffe2f610a8ca134f2bd1db5637b235070f6cbe" + dependencies: + glob "^7.1.1" + npm-package-arg "^4.0.0 || ^5.0.0 || ^6.0.0" + promzard "^0.3.0" + read "~1.0.1" + read-package-json "1 || 2" + semver "2.x || 3.x || 4 || 5" + validate-npm-package-license "^3.0.1" + validate-npm-package-name "^3.0.0" inline-source-map-comment@^1.0.5: version "1.0.5" @@ -5805,24 +5858,6 @@ inline-source-map-comment@^1.0.5: sum-up "^1.0.1" xtend "^4.0.0" -inquirer@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" - dependencies: - ansi-escapes "^1.1.0" - ansi-regex "^2.0.0" - chalk "^1.0.0" - cli-cursor "^1.0.1" - cli-width "^2.0.0" - figures "^1.3.5" - lodash "^4.3.0" - readline2 "^1.0.1" - run-async "^0.1.0" - rx-lite "^3.1.2" - string-width "^1.0.1" - strip-ansi "^3.0.0" - through "^2.3.6" - inquirer@^2: version "2.0.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-2.0.0.tgz#e1351687b90d150ca403ceaa3cefb1e3065bef4b" @@ -5842,11 +5877,11 @@ inquirer@^2: strip-ansi "^3.0.0" through "^2.3.6" -inquirer@^3.0.6: - version "3.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.0.tgz#45b44c2160c729d7578c54060b3eed94487bb42b" +inquirer@^3.0.6, inquirer@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" dependencies: - ansi-escapes "^2.0.0" + ansi-escapes "^3.0.0" chalk "^2.0.0" cli-cursor "^2.1.0" cli-width "^2.0.0" @@ -5861,13 +5896,16 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" -interpret@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90" +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" -invariant@^2.2.0, invariant@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" dependencies: loose-envify "^1.0.0" @@ -5875,13 +5913,25 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + ip-regex@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd" -ipaddr.js@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.3.0.tgz#1e03a52fdad83a8bbb2b25cbf4998b4cffcd3dec" +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + +ip@^1.1.4, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + +ipaddr.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" is-accessor-descriptor@^0.1.6: version "0.1.6" @@ -5899,6 +5949,10 @@ is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -5906,8 +5960,8 @@ is-binary-path@^1.0.0: binary-extensions "^1.0.0" is-buffer@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" is-buffer@~2.0.3: version "2.0.3" @@ -5919,6 +5973,22 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + +is-ci@^1.0.10: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.0.tgz#3f4a08d6303a09882cef3f0fb97439c5f5ce2d53" + dependencies: + ci-info "^1.3.0" + +is-cidr@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-2.0.6.tgz#4b01c9693d8e18399dacd18a4f3d60ea5871ac60" + dependencies: + cidr-regex "^2.0.8" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -5931,6 +6001,10 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -5947,6 +6021,10 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -5991,14 +6069,10 @@ is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" -is-function@^1.0.1, is-function@~1.0.0: +is-function@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" -is-git-url@^0.2.0: - version "0.2.3" - resolved "https://registry.yarnpkg.com/is-git-url/-/is-git-url-0.2.3.tgz#445200d6fbd6da028fb5e01440d9afc93f3ccb64" - is-git-url@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-git-url/-/is-git-url-1.0.0.tgz#53f684cd143285b52c3244b4e6f28253527af66b" @@ -6021,20 +6095,16 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" -is-integer@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-integer/-/is-integer-1.0.7.tgz#6bde81aacddf78b659b6629d629cadc51a886d5c" +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" dependencies: - is-finite "^1.0.0" + global-dirs "^0.1.0" + is-path-inside "^1.0.0" -is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: - version "2.16.0" - resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" - dependencies: - generate-function "^2.0.0" - generate-object-property "^1.1.0" - jsonpointer "^4.0.0" - xtend "^4.0.0" +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" is-number@^2.1.0: version "2.1.0" @@ -6056,28 +6126,26 @@ is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" -is-odd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" - dependencies: - is-number "^4.0.0" - is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" is-path-in-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" dependencies: is-path-inside "^1.0.0" is-path-inside@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" dependencies: path-is-inside "^1.0.1" +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -6096,20 +6164,54 @@ is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" -is-property@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + +is-reference@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.1.0.tgz#50e6ef3f64c361e2c53c0416cdc9420037f2685b" + dependencies: + "@types/estree" "0.0.38" + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" is-resolvable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" - dependencies: - tryit "^1.0.1" + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" -is-stream@^1.0.1, is-stream@^1.1.0: +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-ssh@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.3.0.tgz#ebea1169a2614da392a63740366c3ce049d8dff6" + dependencies: + protocols "^1.1.0" + +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" +is-subset@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" + +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + +is-text-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" + dependencies: + text-extensions "^1.0.0" + is-type@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/is-type/-/is-type-0.0.1.tgz#f651d85c365d44955d14a51d8d7061f3f6b4779c" @@ -6124,11 +6226,7 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" -is-windows@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" - -is-windows@^1.0.2: +is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -6140,9 +6238,15 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" -isbinaryfile@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621" +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + +isbinaryfile@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" + dependencies: + buffer-alloc "^1.2.0" isexe@^2.0.0: version "2.0.0" @@ -6158,10 +6262,20 @@ isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" -isstream@0.1.x, isstream@~0.1.2: +isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" +issue-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/issue-parser/-/issue-parser-3.0.0.tgz#729d3fd5d6b86379cb0f513acc33b62f47ebd681" + dependencies: + lodash.capitalize "^4.2.1" + lodash.escaperegexp "^4.1.2" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.uniqby "^4.7.0" + istextorbinary@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.1.0.tgz#dbed2a6f51be2f7475b68f89465811141b758874" @@ -6185,6 +6299,10 @@ jade@0.26.3: commander "0.6.1" mkdirp "0.3.0" +java-properties@^0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/java-properties/-/java-properties-0.2.10.tgz#2551560c25fa1ad94d998218178f233ad9b18f60" + jimp@^0.2.13, jimp@^0.2.21: version "0.2.28" resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.2.28.tgz#dd529a937190f42957a7937d1acc3a7762996ea2" @@ -6214,27 +6332,31 @@ jpeg-js@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.2.0.tgz#53e448ec9d263e683266467e9442d2c5a2ef5482" -jquery@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.2.1.tgz#5c4d9de652af6cd0a770154a631bba12b015c787" +jquery-deferred@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/jquery-deferred/-/jquery-deferred-0.3.1.tgz#596eca1caaff54f61b110962b23cafea74c35355" + +jquery@^3.2.1, jquery@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca" js-base64@^2.1.8: - version "2.1.9" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce" + version "2.4.9" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.9.tgz#748911fb04f48a60c4771b375cac45a80df11c03" -js-reporters@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/js-reporters/-/js-reporters-1.2.0.tgz#7cf2cb698196684790350d0c4ca07f4aed9ec17e" +js-reporters@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/js-reporters/-/js-reporters-1.2.1.tgz#f88c608e324a3373a95bcc45ad305e5c979c459b" js-string-escape@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" -js-tokens@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-1.0.1.tgz#cc435a5c8b94ad15acb7983140fc80182c89aeae" +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" -js-tokens@^3.0.0, js-tokens@^3.0.2: +js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" @@ -6242,9 +6364,9 @@ js-yaml@0.3.x: version "0.3.7" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-0.3.7.tgz#d739d8ee86461e54b354d6a7d7d1f2ad9a167f62" -js-yaml@^3.2.5, js-yaml@^3.2.7, js-yaml@^3.3.0, js-yaml@^3.5.1, js-yaml@^3.6.1, js-yaml@^3.8.4: - version "3.9.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.0.tgz#4ffbbf25c2ac963b8299dc74da7e3740de1c18ce" +js-yaml@^3.12.0, js-yaml@^3.2.5, js-yaml@^3.2.7, js-yaml@^3.3.0, js-yaml@^3.9.0, js-yaml@^3.9.1: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -6253,9 +6375,36 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" -jschardet@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.5.0.tgz#a61f310306a5a71188e1b1acd08add3cfbb08b1e" +jsdom@^11.12.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" jsesc@^1.3.0: version "1.3.0" @@ -6265,6 +6414,10 @@ jsesc@^2.5.0: version "2.5.1" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" +jsesc@~0.3.x: + version "0.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.3.0.tgz#1bf5ee63b4539fe2e26d0c1e99c240b97a457972" + jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" @@ -6273,7 +6426,7 @@ jsmin@1.x: version "1.0.1" resolved "https://registry.yarnpkg.com/jsmin/-/jsmin-1.0.1.tgz#e7bd0dcd6496c3bf4863235bf461a3d98aa3b98c" -json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -6289,31 +6442,27 @@ json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" dependencies: jsonify "~0.0.0" -json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" -json3@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" - -json5@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.4.0.tgz#054352e4c4c80c86c0923877d449de176a732c8d" - json5@^0.5.0, json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" jsonfile@^2.1.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + resolved "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" optionalDependencies: graceful-fs "^4.1.6" @@ -6334,26 +6483,26 @@ jsonlint@1.6.0: JSV ">= 4.0.x" nomnom ">= 1.5.x" -jsonpointer@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" jsontoxml@0.0.11: version "0.0.11" resolved "https://registry.yarnpkg.com/jsontoxml/-/jsontoxml-0.0.11.tgz#373ab5b2070be3737a5fb3e32fd1b7b81870caa4" jsprim@^1.2.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918" + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" dependencies: assert-plus "1.0.0" - extsprintf "1.0.2" + extsprintf "1.3.0" json-schema "0.2.3" - verror "1.3.6" + verror "1.10.0" -just-extend@^1.1.26: - version "1.1.27" - resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.27.tgz#ec6e79410ff914e472652abfa0e603c03d60e905" +just-extend@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-3.0.0.tgz#cee004031eaabf6406da03a7b84e4fe9d78ef288" jxLoader@*: version "0.1.1" @@ -6364,7 +6513,7 @@ jxLoader@*: promised-io "*" walker "1.x" -kew@~0.7.0: +kew@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" @@ -6394,9 +6543,21 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" +kuler@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.0.tgz#904ad31c373b781695854d32be33818bf1d60250" + dependencies: + colornames "^1.1.1" + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + dependencies: + package-json "^4.0.0" + +lazy-property@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazy-property/-/lazy-property-1.0.0.tgz#84ddc4b370679ba8bd4cdcfa4c06b43d57111147" lcid@^1.0.0: version "1.0.0" @@ -6404,6 +6565,12 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + dependencies: + invert-kv "^2.0.0" + leek@0.0.24: version "0.0.24" resolved "https://registry.yarnpkg.com/leek/-/leek-0.0.24.tgz#e400e57f0e60d8ef2bd4d068dc428a54345dbcda" @@ -6412,9 +6579,9 @@ leek@0.0.24: lodash.assign "^3.2.0" rsvp "^3.0.21" -leven@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/leven/-/leven-1.0.2.tgz#9144b6eebca5f1d0680169f1a6770dcea60b75c3" +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" levn@^0.3.0, levn@~0.3.0: version "0.3.0" @@ -6423,25 +6590,65 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +libcipm@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/libcipm/-/libcipm-2.0.2.tgz#4f38c2b37acf2ec156936cef1cbf74636568fc7b" + dependencies: + bin-links "^1.1.2" + bluebird "^3.5.1" + find-npm-prefix "^1.0.2" + graceful-fs "^4.1.11" + lock-verify "^2.0.2" + mkdirp "^0.5.1" + npm-lifecycle "^2.0.3" + npm-logical-tree "^1.2.1" + npm-package-arg "^6.1.0" + pacote "^8.1.6" + protoduck "^5.0.0" + read-package-json "^2.0.13" + rimraf "^2.6.2" + worker-farm "^1.6.0" + +libnpmhook@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-4.0.1.tgz#63641654de772cbeb96a88527a7fd5456ec3c2d7" + dependencies: + figgy-pudding "^3.1.0" + npm-registry-fetch "^3.0.0" + +libnpx@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/libnpx/-/libnpx-10.2.0.tgz#1bf4a1c9f36081f64935eb014041da10855e3102" + dependencies: + dotenv "^5.0.1" + npm-package-arg "^6.0.0" + rimraf "^2.6.2" + safe-buffer "^5.1.0" + update-notifier "^2.3.0" + which "^1.3.0" + y18n "^4.0.0" + yargs "^11.0.0" + linkify-it@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.0.3.tgz#d94a4648f9b1c179d64fa97291268bdb6ce9434f" dependencies: uc.micro "^1.0.1" -livereload-js@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.2.2.tgz#6c87257e648ab475bc24ea257457edcc1f8d0bc2" +livereload-js@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.3.0.tgz#c3ab22e8aaf5bf3505d80d098cbad67726548c9a" load-bmfont@^1.2.3: - version "1.3.0" - resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.3.0.tgz#bb7e7c710de6bcafcb13cb3b8c81e0c0131ecbc9" + version "1.4.0" + resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.0.tgz#75f17070b14a8c785fe7f5bee2e6fd4f98093b6b" dependencies: buffer-equal "0.0.1" mime "^1.3.4" parse-bmfont-ascii "^1.0.3" parse-bmfont-binary "^1.0.5" - parse-bmfont-xml "^1.1.0" + parse-bmfont-xml "^1.1.4" + phin "^2.9.1" xhr "^2.0.1" xtend "^4.0.0" @@ -6455,6 +6662,15 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" @@ -6467,9 +6683,13 @@ loader-utils@^1.1.0: emojis-list "^2.0.0" json5 "^0.5.0" -loader.js@^4.2.3: - version "4.5.1" - resolved "https://registry.yarnpkg.com/loader.js/-/loader.js-4.5.1.tgz#c15ab15a6b8376bd4fbf7ea56f8d76cc557331da" +loader.js@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/loader.js/-/loader.js-4.7.0.tgz#a1a52902001c83631efde9688b8ab3799325ef1f" + +locate-character@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/locate-character/-/locate-character-2.0.5.tgz#f2d2614d49820ecb3c92d80d193b8db755f74c0f" locate-path@^2.0.0: version "2.0.0" @@ -6478,9 +6698,29 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lock-verify@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lock-verify/-/lock-verify-2.0.2.tgz#148e4f85974915c9e3c34d694b7de9ecb18ee7a8" + dependencies: + npm-package-arg "^5.1.2 || 6" + semver "^5.4.1" + +lockfile@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609" + dependencies: + signal-exit "^3.0.2" + lodash-es@^4.17.4: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" + version "4.17.10" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.10.tgz#62cd7104cdf5dd87f235a837f0ede0e8e5117e05" lodash._baseassign@^3.0.0: version "3.2.0" @@ -6489,10 +6729,44 @@ lodash._baseassign@^3.0.0: lodash._basecopy "^3.0.0" lodash.keys "^3.0.0" +lodash._basebind@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._basebind/-/lodash._basebind-2.3.0.tgz#2b5bc452a0e106143b21869f233bdb587417d248" + dependencies: + lodash._basecreate "~2.3.0" + lodash._setbinddata "~2.3.0" + lodash.isobject "~2.3.0" + lodash._basecopy@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" +lodash._basecreate@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-2.3.0.tgz#9b88a86a4dcff7b7f3c61d83a2fcfc0671ec9de0" + dependencies: + lodash._renative "~2.3.0" + lodash.isobject "~2.3.0" + lodash.noop "~2.3.0" + +lodash._basecreatecallback@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._basecreatecallback/-/lodash._basecreatecallback-2.3.0.tgz#37b2ab17591a339e988db3259fcd46019d7ac362" + dependencies: + lodash._setbinddata "~2.3.0" + lodash.bind "~2.3.0" + lodash.identity "~2.3.0" + lodash.support "~2.3.0" + +lodash._basecreatewrapper@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.3.0.tgz#aa0c61ad96044c3933376131483a9759c3651247" + dependencies: + lodash._basecreate "~2.3.0" + lodash._setbinddata "~2.3.0" + lodash._slice "~2.3.0" + lodash.isobject "~2.3.0" + lodash._baseflatten@^3.0.0: version "3.1.4" resolved "https://registry.yarnpkg.com/lodash._baseflatten/-/lodash._baseflatten-3.1.4.tgz#0770ff80131af6e34f3b511796a7ba5214e65ff7" @@ -6504,6 +6778,13 @@ lodash._basetostring@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" +lodash._baseuniq@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" + dependencies: + lodash._createset "~4.0.0" + lodash._root "~3.0.0" + lodash._basevalues@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" @@ -6520,22 +6801,84 @@ lodash._createassigner@^3.0.0: lodash._isiterateecall "^3.0.0" lodash.restparam "^3.0.0" +lodash._createset@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" + +lodash._createwrapper@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._createwrapper/-/lodash._createwrapper-2.3.0.tgz#d1aae1102dadf440e8e06fc133a6edd7fe146075" + dependencies: + lodash._basebind "~2.3.0" + lodash._basecreatewrapper "~2.3.0" + lodash.isfunction "~2.3.0" + +lodash._escapehtmlchar@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.3.0.tgz#d03da6bd82eedf38dc0a5b503d740ecd0e894592" + dependencies: + lodash._htmlescapes "~2.3.0" + +lodash._escapestringchar@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._escapestringchar/-/lodash._escapestringchar-2.3.0.tgz#cce73ae60fc6da55d2bf8a0679c23ca2bab149fc" + lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" +lodash._htmlescapes@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._htmlescapes/-/lodash._htmlescapes-2.3.0.tgz#1ca98863cadf1fa1d82c84f35f31e40556a04f3a" + lodash._isiterateecall@^3.0.0: version "3.0.9" resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" +lodash._objecttypes@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._objecttypes/-/lodash._objecttypes-2.3.0.tgz#6a3ea3987dd6eeb8021b2d5c9c303549cc2bae1e" + lodash._reinterpolate@^3.0.0, lodash._reinterpolate@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" -lodash._root@^3.0.0: +lodash._reinterpolate@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-2.3.0.tgz#03ee9d85c0e55cbd590d71608a295bdda51128ec" + +lodash._renative@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._renative/-/lodash._renative-2.3.0.tgz#77d8edd4ced26dd5971f9e15a5f772e4e317fbd3" + +lodash._reunescapedhtml@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.3.0.tgz#db920b55ac7f3ff825939aceb9ba2c231713d24d" + dependencies: + lodash._htmlescapes "~2.3.0" + lodash.keys "~2.3.0" + +lodash._root@^3.0.0, lodash._root@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" +lodash._setbinddata@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._setbinddata/-/lodash._setbinddata-2.3.0.tgz#e5610490acd13277d59858d95b5f2727f1508f04" + dependencies: + lodash._renative "~2.3.0" + lodash.noop "~2.3.0" + +lodash._shimkeys@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._shimkeys/-/lodash._shimkeys-2.3.0.tgz#611f93149e3e6c721096b48769ef29537ada8ba9" + dependencies: + lodash._objecttypes "~2.3.0" + +lodash._slice@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash._slice/-/lodash._slice-2.3.0.tgz#147198132859972e4680ca29a5992c855669aa5c" + lodash.assign@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" @@ -6552,7 +6895,23 @@ lodash.assignin@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" -lodash.clonedeep@^4.3.2, lodash.clonedeep@^4.4.1: +lodash.bind@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-2.3.0.tgz#c2a8e18b68e5ecc152e2b168266116fea5b016cc" + dependencies: + lodash._createwrapper "~2.3.0" + lodash._renative "~2.3.0" + lodash._slice "~2.3.0" + +lodash.capitalize@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz#f826c9b4e2a8511d84e3aca29db05e1a4f3b72a9" + +lodash.castarray@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115" + +lodash.clonedeep@^4.3.2, lodash.clonedeep@^4.4.1, lodash.clonedeep@~4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" @@ -6566,10 +6925,17 @@ lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" -lodash.defaults@^4.1.0: +lodash.defaults@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" +lodash.defaults@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-2.3.0.tgz#a832b001f138f3bb9721c2819a2a7cc5ae21ed25" + dependencies: + lodash._objecttypes "~2.3.0" + lodash.keys "~2.3.0" + lodash.defaultsdeep@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.0.tgz#bec1024f85b1bd96cbea405b23c14ad6443a6f81" @@ -6580,6 +6946,18 @@ lodash.escape@^3.0.0: dependencies: lodash._root "^3.0.0" +lodash.escape@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-2.3.0.tgz#844c38c58f844e1362ebe96726159b62cf5f2a58" + dependencies: + lodash._escapehtmlchar "~2.3.0" + lodash._reunescapedhtml "~2.3.0" + lodash.keys "~2.3.0" + +lodash.escaperegexp@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" + lodash.find@^4.5.1: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1" @@ -6591,10 +6969,29 @@ lodash.flatten@^3.0.2: lodash._baseflatten "^3.0.0" lodash._isiterateecall "^3.0.0" +lodash.foreach@~2.3.x: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-2.3.0.tgz#083404c91e846ee77245fdf9d76519c68b2af168" + dependencies: + lodash._basecreatecallback "~2.3.0" + lodash.forown "~2.3.0" + +lodash.forown@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.forown/-/lodash.forown-2.3.0.tgz#24fb4aaf800d45fc2dc60bfec3ce04c836a3ad7f" + dependencies: + lodash._basecreatecallback "~2.3.0" + lodash._objecttypes "~2.3.0" + lodash.keys "~2.3.0" + lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" +lodash.identity@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.identity/-/lodash.identity-2.3.0.tgz#6b01a210c9485355c2a913b48b6711219a173ded" + lodash.isarguments@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" @@ -6603,6 +7000,24 @@ lodash.isarray@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" +lodash.isfunction@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-2.3.0.tgz#6b2973e47a647cf12e70d676aea13643706e5267" + +lodash.isobject@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.3.0.tgz#2e16d3fc583da9831968953f2d8e6d73434f6799" + dependencies: + lodash._objecttypes "~2.3.0" + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + lodash.keys@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" @@ -6611,17 +7026,29 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" +lodash.keys@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-2.3.0.tgz#b350f4f92caa9f45a4a2ecf018454cf2f28ae253" + dependencies: + lodash._renative "~2.3.0" + lodash._shimkeys "~2.3.0" + lodash.isobject "~2.3.0" + lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" -lodash.merge@^4.3.0, lodash.merge@^4.4.0, lodash.merge@^4.5.1, lodash.merge@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" +lodash.merge@^4.3.1, lodash.merge@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" lodash.mergewith@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55" + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" + +lodash.noop@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-2.3.0.tgz#3059d628d51bbf937cd2a0b6fc3a7f212a669c2c" lodash.omit@^4.1.0: version "4.5.0" @@ -6631,6 +7058,16 @@ lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + +lodash.support@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.support/-/lodash.support-2.3.0.tgz#7eaf038af4f0d6aab776b44aa6dcfc80334c9bfd" + dependencies: + lodash._renative "~2.3.0" + lodash.template@^3.3.2: version "3.6.2" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" @@ -6645,13 +7082,25 @@ lodash.template@^3.3.2: lodash.restparam "^3.0.0" lodash.templatesettings "^3.0.0" -lodash.template@^4.2.5: +lodash.template@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" dependencies: lodash._reinterpolate "~3.0.0" lodash.templatesettings "^4.0.0" +lodash.template@~2.3.x: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-2.3.0.tgz#4e3e29c433b4cfea675ec835e6f12391c61fd22b" + dependencies: + lodash._escapestringchar "~2.3.0" + lodash._reinterpolate "~2.3.0" + lodash.defaults "~2.3.0" + lodash.escape "~2.3.0" + lodash.keys "~2.3.0" + lodash.templatesettings "~2.3.0" + lodash.values "~2.3.0" + lodash.templatesettings@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" @@ -6665,7 +7114,26 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "~3.0.0" -lodash.uniq@^4.2.0: +lodash.templatesettings@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-2.3.0.tgz#303d132c342710040d5a18efaa2d572fd03f8cdc" + dependencies: + lodash._reinterpolate "~2.3.0" + lodash.escape "~2.3.0" + +lodash.toarray@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" + +lodash.unescape@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" + +lodash.union@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" + +lodash.uniq@^4.2.0, lodash.uniq@~4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" @@ -6673,21 +7141,27 @@ lodash.uniqby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" -lodash@^3.10.0, lodash@^3.10.1, lodash@^3.2.0, lodash@^3.9.3: +lodash.values@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-2.3.0.tgz#ca96fbe60a20b0b0ec2ba2ba5fc6a765bd14a3ba" + dependencies: + lodash.keys "~2.3.0" + +lodash.without@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" + +lodash@^3.10.0, lodash@^3.2.0: version "3.10.1" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + resolved "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.0.0, lodash@^4.10.0, lodash@^4.14.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1, lodash@~4.17.4: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - -lodash@^4.17.10: +lodash@^4.0.0, lodash@^4.10.0, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1, lodash@~4.17.10: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" lodash@~2.4.1: version "2.4.2" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" + resolved "http://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" log-symbols@^2.2.0: version "2.2.0" @@ -6695,6 +7169,16 @@ log-symbols@^2.2.0: dependencies: chalk "^2.0.1" +logform@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/logform/-/logform-1.9.1.tgz#58b29d7b11c332456d7a217e17b48a13ad69d60a" + dependencies: + colors "^1.2.1" + fast-safe-stringify "^2.0.4" + fecha "^2.3.3" + ms "^2.1.1" + triple-beam "^1.2.0" + loglevel-colored-level-prefix@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/loglevel-colored-level-prefix/-/loglevel-colored-level-prefix-1.0.0.tgz#6a40218fdc7ae15fc76c3d0f3e676c465388603e" @@ -6703,16 +7187,12 @@ loglevel-colored-level-prefix@^1.0.0: loglevel "^1.4.1" loglevel@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.4.1.tgz#95b383f91a3c2756fd4ab093667e4309161f2bcd" + version "1.6.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" -lolex@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6" - -lolex@^2.1.2: - version "2.3.1" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.1.tgz#3d2319894471ea0950ef64692ead2a5318cff362" +lolex@^2.1.2, lolex@^2.3.2: + version "2.7.4" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.4.tgz#6514de2c3291e9d6f09d49ddce4a95f7d4d5a93f" long@4.0.0: version "4.0.0" @@ -6722,15 +7202,11 @@ long@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - loose-envify@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" dependencies: - js-tokens "^3.0.0" + js-tokens "^3.0.0 || ^4.0.0" loud-rejection@^1.0.0: version "1.6.0" @@ -6739,33 +7215,72 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + lru-cache@2: version "2.7.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" -lru-cache@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lru-cache@^4.1.1: +lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2, lru-cache@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" dependencies: pseudomap "^1.0.2" yallist "^2.1.2" -make-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.0.0.tgz#97a011751e91dd87cfadef58832ebb04936de978" +magic-string@^0.24.0: + version "0.24.1" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.24.1.tgz#7e38e5f126cae9f15e71f0cf8e450818ca7d5a8f" dependencies: - pify "^2.3.0" + sourcemap-codec "^1.4.1" -make-plural@~3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-3.0.6.tgz#2033a03bac290b8f3bb91258f65b9df7e8b01ca7" +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + dependencies: + pify "^3.0.0" + +"make-fetch-happen@^2.5.0 || 3 || 4", make-fetch-happen@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz#141497cb878f243ba93136c83d8aba12c216c083" + dependencies: + agentkeepalive "^3.4.1" + cacache "^11.0.1" + http-cache-semantics "^3.8.1" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + lru-cache "^4.1.2" + mississippi "^3.0.0" + node-fetch-npm "^2.0.2" + promise-retry "^1.1.1" + socks-proxy-agent "^4.0.0" + ssri "^6.0.0" + +make-fetch-happen@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-3.0.0.tgz#7b661d2372fc4710ab5cc8e1fa3c290eea69a961" + dependencies: + agentkeepalive "^3.4.1" + cacache "^10.0.4" + http-cache-semantics "^3.8.1" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.0" + lru-cache "^4.1.2" + mississippi "^3.0.0" + node-fetch-npm "^2.0.2" + promise-retry "^1.1.1" + socks-proxy-agent "^3.0.1" + ssri "^5.2.4" + +make-plural@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-4.2.0.tgz#03edfc34a2aee630a57e209369ef26ee3ca69590" optionalDependencies: minimist "^1.2.0" @@ -6779,6 +7294,12 @@ mamacro@^0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" +map-age-cleaner@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.2.tgz#098fb15538fd3dbe461f12745b0ca8568d4e3f74" + dependencies: + p-defer "^1.0.0" + map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -6807,22 +7328,40 @@ markdown-it-terminal@0.1.0: lodash.merge "^4.6.0" markdown-it "^8.3.1" -markdown-it@^8.3.0, markdown-it@^8.3.1: - version "8.3.1" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.3.1.tgz#2f4b622948ccdc193d66f3ca2d43125ac4ac7323" +markdown-it@^8.3.1, markdown-it@^8.4.2: + version "8.4.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" dependencies: argparse "^1.0.7" entities "~1.1.1" linkify-it "^2.0.0" mdurl "^1.0.1" - uc.micro "^1.0.3" + uc.micro "^1.0.5" -matcher-collection@^1.0.0, matcher-collection@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/matcher-collection/-/matcher-collection-1.0.4.tgz#2f66ae0869996f29e43d0b62c83dd1d43e581755" +marked-terminal@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-3.1.1.tgz#1e726816ddc4552a83393228ff0952b6cd4e5e04" + dependencies: + cardinal "^2.1.1" + chalk "^2.4.1" + cli-table "^0.3.1" + lodash.assign "^4.2.0" + node-emoji "^1.4.1" + +marked@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.5.0.tgz#9e590bad31584a48ff405b33ab1c0dd25172288e" + +matcher-collection@^1.0.0, matcher-collection@^1.0.4, matcher-collection@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/matcher-collection/-/matcher-collection-1.0.5.tgz#2ee095438372cb8884f058234138c05c644ec339" dependencies: minimatch "^3.0.2" +math-random@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + md5-hex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" @@ -6844,10 +7383,28 @@ mdurl@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" +meant@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.1.tgz#66044fea2f23230ec806fb515efea29c44d2115d" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + +mem@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^1.0.0" + p-is-promise "^1.1.0" + memory-fs@^0.4.0, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -6855,9 +7412,9 @@ memory-fs@^0.4.0, memory-fs@~0.4.1: errno "^0.1.3" readable-stream "^2.0.1" -memory-streams@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/memory-streams/-/memory-streams-0.1.2.tgz#273ff777ab60fec599b116355255282cca2c50c2" +memory-streams@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/memory-streams/-/memory-streams-0.1.3.tgz#d9b0017b4b87f1d92f55f2745c9caacb1dc93ceb" dependencies: readable-stream "~1.0.2" @@ -6876,6 +7433,20 @@ meow@^3.4.0, meow@^3.7.0: redent "^1.0.0" trim-newlines "^1.0.0" +meow@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.1.tgz#d48598f6f4b1472f35bf6317a95945ace347f975" + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist "^1.1.3" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + merge-defaults@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/merge-defaults/-/merge-defaults-0.2.1.tgz#dd42248eb96bb6a51521724321c72ff9583dde80" @@ -6897,29 +7468,40 @@ merge-trees@^1.0.1: rimraf "^2.4.3" symlink-or-copy "^1.0.0" -merge@^1.1.3: +merge-trees@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-trees/-/merge-trees-2.0.0.tgz#a560d796e566c5d9b2c40472a2967cca48d85161" + dependencies: + fs-updater "^1.0.4" + heimdalljs "^0.2.5" + +merge2@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.2.tgz#03212e3da8d86c4d8523cebd6318193414f94e34" + +merge@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" -messageformat-parser@^1.0.0: +messageformat-parser@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/messageformat-parser/-/messageformat-parser-1.1.0.tgz#13ba2250a76bbde8e0fca0dbb3475f95c594a90a" messageformat@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/messageformat/-/messageformat-1.0.2.tgz#908f4691f29ff28dae35c45436a24cff93402388" + version "1.1.1" + resolved "https://registry.yarnpkg.com/messageformat/-/messageformat-1.1.1.tgz#ceaa2e6c86929d4807058275a7372b1bd963bdf6" dependencies: glob "~7.0.6" - make-plural "~3.0.6" - messageformat-parser "^1.0.0" + make-plural "^4.1.1" + messageformat-parser "^1.1.0" nopt "~3.0.6" - reserved-words "^0.1.1" + reserved-words "^0.1.2" methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" -micromatch@^2.1.5, micromatch@^2.3.7: +micromatch@^2.3.11: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" dependencies: @@ -6937,7 +7519,7 @@ micromatch@^2.1.5, micromatch@^2.3.7: parse-glob "^3.0.4" regex-cache "^0.4.2" -micromatch@^3.1.4, micromatch@^3.1.8: +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" dependencies: @@ -6962,41 +7544,31 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -"mime-db@>= 1.27.0 < 2": - version "1.29.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.29.0.tgz#48d26d235589651704ac5916ca06001914266878" +"mime-db@>= 1.34.0 < 2", mime-db@~1.36.0: + version "1.36.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" -mime-db@~1.27.0: - version "1.27.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" - -mime-db@~1.33.0: - version "1.33.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" - -mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.7: - version "2.1.15" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" +mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19: + version "2.1.20" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" dependencies: - mime-db "~1.27.0" + mime-db "~1.36.0" -mime-types@^2.1.18: - version "2.1.18" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" - dependencies: - mime-db "~1.33.0" - -mime@1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" mime@^1.3.4: - version "1.3.6" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0" + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + +mime@^2.0.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.3.1.tgz#b1621c54d63b97c47d3cfe7f7215f7d64517c369" mimic-fn@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" min-document@^2.19.0: version "2.19.0" @@ -7018,12 +7590,6 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: dependencies: brace-expansion "^1.1.7" -minimatch@^2.0.3: - version "2.0.10" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" - dependencies: - brace-expansion "^1.0.0" - minimatch@~0.2.11: version "0.2.14" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" @@ -7031,17 +7597,28 @@ minimatch@~0.2.11: lru-cache "2" sigmund "~1.0.0" -minimist@0.0.8, minimist@~0.0.1: +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + +minimist@0.0.8: version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" -minipass@^2.2.1, minipass@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.3.tgz#a7dcc8b7b833f5d368759cce544dccb55f50f233" +minimist@~0.0.1: + version "0.0.10" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +minipass@^2.2.0, minipass@^2.2.1, minipass@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -7067,6 +7644,21 @@ mississippi@^2.0.0: stream-each "^1.1.0" through2 "^2.0.0" +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" @@ -7076,21 +7668,15 @@ mixin-deep@^1.2.0: mkdirp@0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" mkdirp@0.3.5, mkdirp@^0.3.5: version "0.3.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" + resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" -mkdirp@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" - dependencies: - minimist "0.0.8" - -mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" @@ -7100,7 +7686,7 @@ mktemp@~0.4.0: mocha@~1.13.0: version "1.13.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-1.13.0.tgz#8d8fa4e310b94cc6efeb3ed26aeca96dea93307c" + resolved "http://registry.npmjs.org/mocha/-/mocha-1.13.0.tgz#8d8fa4e310b94cc6efeb3ed26aeca96dea93307c" dependencies: commander "0.6.1" debug "*" @@ -7110,33 +7696,37 @@ mocha@~1.13.0: jade "0.26.3" mkdirp "0.3.5" -moment-timezone@^0.5.0: - version "0.5.13" - resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.13.tgz#99ce5c7d827262eb0f1f702044177f60745d7b90" +modify-values@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" + +moment-timezone@^0.5.13: + version "0.5.21" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.21.tgz#3cba247d84492174dbf71de2a9848fa13207b845" dependencies: moment ">= 2.9.0" -"moment@>= 2.9.0", moment@^2.13.0: - version "2.18.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" +"moment@>= 2.9.0", moment@^2.19.3: + version "2.22.2" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" moo-server@*, moo-server@1.3.x: version "1.3.0" resolved "https://registry.yarnpkg.com/moo-server/-/moo-server-1.3.0.tgz#5dc79569565a10d6efed5439491e69d2392e58f1" -morgan@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.8.2.tgz#784ac7734e4a453a9c6e6e8680a9329275c8b687" +morgan@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" dependencies: - basic-auth "~1.1.0" - debug "2.6.8" - depd "~1.1.0" + basic-auth "~2.0.0" + debug "2.6.9" + depd "~1.1.2" on-finished "~2.3.0" on-headers "~1.0.1" mout@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/mout/-/mout-1.0.0.tgz#9bdf1d4af57d66d47cb353a6335a3281098e1501" + version "1.1.0" + resolved "https://registry.yarnpkg.com/mout/-/mout-1.1.0.tgz#0b29d41e6a80fa9e2d4a5be9d602e1d9d02177f6" move-concurrently@^1.0.1: version "1.0.1" @@ -7153,48 +7743,47 @@ ms@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" -ms@0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -mustache@^2.2.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.0.tgz#4028f7778b17708a489930a6e52ac3bca0da41d0" +ms@^2.0.0, ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" -mute-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" +mustache@^2.2.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.2.tgz#a6d4d9c3f91d13359ab889a812954f9230a3d0c5" mute-stream@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db" -mute-stream@0.0.7: +mute-stream@0.0.7, mute-stream@~0.0.4: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" -nan@^2.10.0, nan@^2.9.2: - version "2.10.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" +najax@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/najax/-/najax-1.0.4.tgz#63fd8dbf15d18f24dc895b3a16fec66c136b8084" + dependencies: + jquery-deferred "^0.3.0" + lodash.defaultsdeep "^4.6.0" + qs "^6.2.0" -nan@^2.3.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" +nan@^2.10.0, nan@^2.9.2: + version "2.11.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099" nanomatch@^1.2.9: - version "1.2.9" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" define-property "^2.0.2" extend-shallow "^3.0.2" fragment-cache "^0.2.1" - is-odd "^2.0.0" is-windows "^1.0.2" kind-of "^6.0.2" object.pick "^1.3.0" @@ -7211,8 +7800,8 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" needle@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" + version "2.2.2" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.2.tgz#1120ca4c41f2fcc6976fd28a8968afe239929418" dependencies: debug "^2.1.2" iconv-lite "^0.4.4" @@ -7223,43 +7812,63 @@ negotiator@0.6.1: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" neo-async@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.1.tgz#acb909e327b1e87ec9ef15f41b8a269512ad41ee" + version "2.5.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.2.tgz#489105ce7bc54e709d736b195f82135048c50fcc" + +nerf-dart@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/nerf-dart/-/nerf-dart-1.0.0.tgz#e6dab7febf5ad816ea81cf5c629c5a0ebde72c1a" + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" nise@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.0.tgz#079d6cadbbcb12ba30e38f1c999f36ad4d6baa53" + version "1.4.4" + resolved "https://registry.yarnpkg.com/nise/-/nise-1.4.4.tgz#b8d9dd35334c99e514b75e46fcc38e358caecdd0" dependencies: - formatio "^1.2.0" - just-extend "^1.1.26" - lolex "^1.6.0" + "@sinonjs/formatio" "^2.0.0" + just-extend "^3.0.0" + lolex "^2.3.2" path-to-regexp "^1.7.0" text-encoding "^0.6.4" -node-fetch@^1.3.3: - version "1.7.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.1.tgz#899cb3d0a3c92f952c47f1b876f4c8aeabd400d5" +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + dependencies: + lower-case "^1.1.1" + +node-emoji@^1.4.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.8.1.tgz#6eec6bfb07421e2148c75c6bba72421f8530a826" + dependencies: + lodash.toarray "^4.4.0" + +node-fetch-npm@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7" dependencies: encoding "^0.1.11" - is-stream "^1.0.1" + json-parse-better-errors "^1.0.0" + safe-buffer "^5.1.1" -node-fetch@^2.0.0-alpha.9: - version "2.0.0-alpha.9" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.0.0-alpha.9.tgz#990c0634f510f76449a0d6f6eaec96b22f273628" +node-fetch@^2.0.0-alpha.9, node-fetch@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5" -node-gyp@^3.3.1: - version "3.6.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.6.2.tgz#9bfbe54562286284838e750eac05295853fa1c60" +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" dependencies: fstream "^1.0.0" glob "^7.0.3" graceful-fs "^4.1.2" - minimatch "^3.0.2" mkdirp "^0.5.0" nopt "2 || 3" npmlog "0 || 1 || 2 || 3 || 4" osenv "0" - request "2" + request "^2.87.0" rimraf "2" semver "~5.3.0" tar "^2.0.0" @@ -7297,18 +7906,18 @@ node-libs-browser@^2.0.0: util "^0.10.3" vm-browserify "0.0.4" -node-modules-path@^1.0.0: +node-modules-path@^1.0.0, node-modules-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/node-modules-path/-/node-modules-path-1.0.1.tgz#40096b08ce7ad0ea14680863af449c7c75a5d1c8" node-notifier@^5.0.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.1.2.tgz#2fa9e12605fa10009d44549d6fcd8a63dde0e4ff" + version "5.2.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea" dependencies: growly "^1.3.0" - semver "^5.3.0" - shellwords "^0.1.0" - which "^1.2.12" + semver "^5.4.1" + shellwords "^0.1.1" + which "^1.3.0" node-pre-gyp@^0.10.0: version "0.10.3" @@ -7325,20 +7934,6 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -node-pre-gyp@^0.6.36: - version "0.6.36" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" - dependencies: - mkdirp "^0.5.1" - nopt "^4.0.1" - npmlog "^4.0.2" - rc "^1.1.7" - request "^2.81.0" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^2.2.1" - tar-pack "^3.4.0" - node-rest-client@^1.5.1: version "1.8.0" resolved "https://registry.yarnpkg.com/node-rest-client/-/node-rest-client-1.8.0.tgz#8d3c566b817e27394cb7273783a41caefe3e5955" @@ -7347,8 +7942,8 @@ node-rest-client@^1.5.1: xml2js ">=0.2.4" node-sass@^4.7.2: - version "4.9.0" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.9.0.tgz#d1b8aa855d98ed684d6848db929a20771cc2ae52" + version "4.9.3" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.9.3.tgz#f407cf3d66f78308bb1e346b24fa428703196224" dependencies: async-foreach "^0.1.3" chalk "^1.1.1" @@ -7363,9 +7958,9 @@ node-sass@^4.7.2: meow "^3.7.0" mkdirp "^0.5.1" nan "^2.10.0" - node-gyp "^3.3.1" + node-gyp "^3.8.0" npmlog "^4.0.0" - request "~2.79.0" + request "2.87.0" sass-graph "^2.2.4" stdout-stream "^1.4.0" "true-case-path" "^1.0.2" @@ -7383,14 +7978,14 @@ node-sass@^4.7.2: dependencies: abbrev "1" -nopt@^4.0.1: +nopt@^4.0.1, nopt@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" dependencies: abbrev "1" osenv "^0.1.4" -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: +normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.4.0, "normalize-package-data@~1.0.1 || ^2.0.0", normalize-package-data@~2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" dependencies: @@ -7409,39 +8004,251 @@ normalize-range@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" +normalize-url@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + normalize.css@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-4.1.1.tgz#4f0b1d5a235383252b04d8566b866cc5fcad9f0c" -npm-bundled@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" +npm-audit-report@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-1.3.1.tgz#e79ea1fcb5ffaf3031102b389d5222c2b0459632" + dependencies: + cli-table3 "^0.5.0" + console-control-strings "^1.1.0" -npm-git-info@^1.0.0, npm-git-info@^1.0.3: +npm-bundled@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + +npm-cache-filename@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11" + +npm-git-info@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/npm-git-info/-/npm-git-info-1.0.3.tgz#a933c42ec321e80d3646e0d6e844afe94630e1d5" -npm-package-arg@^4.1.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-4.2.1.tgz#593303fdea85f7c422775f17f9eb7670f680e3ec" +npm-install-checks@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.0.tgz#d4aecdfd51a53e3723b7b2f93b2ee28e307bc0d7" dependencies: - hosted-git-info "^2.1.5" - semver "^5.1.0" + semver "^2.3.0 || 3.x || 4 || 5" -npm-packlist@^1.1.6: - version "1.1.10" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.10.tgz#1039db9e985727e464df066f4cf0ab6ef85c398a" +npm-lifecycle@^2.0.3, npm-lifecycle@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-2.1.0.tgz#1eda2eedb82db929e3a0c50341ab0aad140ed569" + dependencies: + byline "^5.0.0" + graceful-fs "^4.1.11" + node-gyp "^3.8.0" + resolve-from "^4.0.0" + slide "^1.1.6" + uid-number "0.0.6" + umask "^1.1.0" + which "^1.3.1" + +npm-logical-tree@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/npm-logical-tree/-/npm-logical-tree-1.2.1.tgz#44610141ca24664cad35d1e607176193fd8f5b88" + +"npm-package-arg@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", "npm-package-arg@^5.1.2 || 6", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.0.tgz#15ae1e2758a5027efb4c250554b85a737db7fcc1" + dependencies: + hosted-git-info "^2.6.0" + osenv "^0.1.5" + semver "^5.5.0" + validate-npm-package-name "^3.0.0" + +npm-packlist@^1.1.10, npm-packlist@^1.1.11, npm-packlist@^1.1.6: + version "1.1.11" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" +npm-pick-manifest@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-2.1.0.tgz#dc381bdd670c35d81655e1d5a94aa3dd4d87fce5" + dependencies: + npm-package-arg "^6.0.0" + semver "^5.4.1" + +npm-profile@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/npm-profile/-/npm-profile-3.0.2.tgz#58d568f1b56ef769602fd0aed8c43fa0e0de0f57" + dependencies: + aproba "^1.1.2 || 2" + make-fetch-happen "^2.5.0 || 3 || 4" + +npm-registry-client@^8.6.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/npm-registry-client/-/npm-registry-client-8.6.0.tgz#7f1529f91450732e89f8518e0f21459deea3e4c4" + dependencies: + concat-stream "^1.5.2" + graceful-fs "^4.1.6" + normalize-package-data "~1.0.1 || ^2.0.0" + npm-package-arg "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + once "^1.3.3" + request "^2.74.0" + retry "^0.10.0" + safe-buffer "^5.1.1" + semver "2 >=2.2.1 || 3.x || 4 || 5" + slide "^1.1.3" + ssri "^5.2.4" + optionalDependencies: + npmlog "2 || ^3.1.0 || ^4.0.0" + +npm-registry-fetch@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-1.1.1.tgz#710bc5947d9ee2c549375072dab6d5d17baf2eb2" + dependencies: + bluebird "^3.5.1" + figgy-pudding "^3.0.0" + lru-cache "^4.1.2" + make-fetch-happen "^3.0.0" + npm-package-arg "^6.0.0" + safe-buffer "^5.1.1" + +npm-registry-fetch@^3.0.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-3.8.0.tgz#aa7d9a7c92aff94f48dba0984bdef4bd131c88cc" + dependencies: + JSONStream "^1.3.4" + bluebird "^3.5.1" + figgy-pudding "^3.4.1" + lru-cache "^4.1.3" + make-fetch-happen "^4.0.1" + npm-package-arg "^6.1.0" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" dependencies: path-key "^2.0.0" -"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: +npm-user-validate@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.0.tgz#8ceca0f5cea04d4e93519ef72d0557a75122e951" + +npm@^6.3.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/npm/-/npm-6.4.1.tgz#4f39f9337b557a28faed4a771d5c8802d6b4288b" + dependencies: + JSONStream "^1.3.4" + abbrev "~1.1.1" + ansicolors "~0.3.2" + ansistyles "~0.1.3" + aproba "~1.2.0" + archy "~1.0.0" + bin-links "^1.1.2" + bluebird "~3.5.1" + byte-size "^4.0.3" + cacache "^11.2.0" + call-limit "~1.1.0" + chownr "~1.0.1" + ci-info "^1.4.0" + cli-columns "^3.1.2" + cli-table3 "^0.5.0" + cmd-shim "~2.0.2" + columnify "~1.5.4" + config-chain "~1.1.11" + detect-indent "~5.0.0" + detect-newline "^2.1.0" + dezalgo "~1.0.3" + editor "~1.0.0" + figgy-pudding "^3.4.1" + find-npm-prefix "^1.0.2" + fs-vacuum "~1.2.10" + fs-write-stream-atomic "~1.0.10" + gentle-fs "^2.0.1" + glob "~7.1.2" + graceful-fs "~4.1.11" + has-unicode "~2.0.1" + hosted-git-info "^2.7.1" + iferr "^1.0.2" + inflight "~1.0.6" + inherits "~2.0.3" + ini "^1.3.5" + init-package-json "^1.10.3" + is-cidr "^2.0.6" + json-parse-better-errors "^1.0.2" + lazy-property "~1.0.0" + libcipm "^2.0.2" + libnpmhook "^4.0.1" + libnpx "^10.2.0" + lock-verify "^2.0.2" + lockfile "^1.0.4" + lodash._baseuniq "~4.6.0" + lodash.clonedeep "~4.5.0" + lodash.union "~4.6.0" + lodash.uniq "~4.5.0" + lodash.without "~4.4.0" + lru-cache "^4.1.3" + meant "~1.0.1" + mississippi "^3.0.0" + mkdirp "~0.5.1" + move-concurrently "^1.0.1" + node-gyp "^3.8.0" + nopt "~4.0.1" + normalize-package-data "~2.4.0" + npm-audit-report "^1.3.1" + npm-cache-filename "~1.0.2" + npm-install-checks "~3.0.0" + npm-lifecycle "^2.1.0" + npm-package-arg "^6.1.0" + npm-packlist "^1.1.11" + npm-pick-manifest "^2.1.0" + npm-profile "^3.0.2" + npm-registry-client "^8.6.0" + npm-registry-fetch "^1.1.0" + npm-user-validate "~1.0.0" + npmlog "~4.1.2" + once "~1.4.0" + opener "^1.5.0" + osenv "^0.1.5" + pacote "^8.1.6" + path-is-inside "~1.0.2" + promise-inflight "~1.0.1" + qrcode-terminal "^0.12.0" + query-string "^6.1.0" + qw "~1.0.1" + read "~1.0.7" + read-cmd-shim "~1.0.1" + read-installed "~4.0.3" + read-package-json "^2.0.13" + read-package-tree "^5.2.1" + readable-stream "^2.3.6" + request "^2.88.0" + retry "^0.12.0" + rimraf "~2.6.2" + safe-buffer "^5.1.2" + semver "^5.5.0" + sha "~2.0.1" + slide "~1.1.6" + sorted-object "~2.0.1" + sorted-union-stream "~2.1.3" + ssri "^6.0.0" + stringify-package "^1.0.0" + tar "^4.4.6" + text-table "~0.2.0" + tiny-relative-date "^1.3.0" + uid-number "0.0.6" + umask "~1.1.0" + unique-filename "~1.1.0" + unpipe "~1.0.0" + update-notifier "^2.5.0" + uuid "^3.3.2" + validate-npm-package-license "^3.0.4" + validate-npm-package-name "~3.0.0" + which "^1.3.1" + worker-farm "^1.6.0" + write-file-atomic "^2.3.0" + +"npmlog@0 || 1 || 2 || 3 || 4", "npmlog@2 || ^3.1.0 || ^4.0.0", npmlog@^4.0.0, npmlog@^4.0.2, npmlog@~4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" dependencies: @@ -7464,13 +8271,17 @@ number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -oauth-sign@~0.8.1: +nwsapi@^2.0.7: + version "2.0.9" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016" + +oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" -object-assign@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" @@ -7492,12 +8303,23 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-keys@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" dependencies: isobject "^3.0.0" +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -7521,15 +8343,19 @@ on-headers@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" -once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0, once@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: wrappy "1" +one-time@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e" + onetime@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" onetime@^2.0.0: version "2.0.1" @@ -7537,6 +8363,10 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" +opener@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" + optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -7544,7 +8374,7 @@ optimist@^0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" -optionator@^0.8.2: +optionator@^0.8.1, optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" dependencies: @@ -7555,10 +8385,6 @@ optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" -options@>=0.0.5: - version "0.0.6" - resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" - ora@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ora/-/ora-2.1.0.tgz#6caf2830eb924941861ec53a173799e008b51e5b" @@ -7580,40 +8406,70 @@ os-homedir@^1.0.0, os-homedir@^1.0.1: os-locale@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + resolved "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" dependencies: lcid "^1.0.0" +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-locale@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" + dependencies: + execa "^0.10.0" + lcid "^2.0.0" + mem "^4.0.0" + os-shim@^0.1.2: version "0.1.3" resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" -osenv@0, osenv@^0.1.3, osenv@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" +osenv@0, osenv@^0.1.3, osenv@^0.1.4, osenv@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -output-file-sync@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + +p-filter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-1.0.0.tgz#629d317150209c8fd508ba137713ef4bb920e9db" dependencies: - graceful-fs "^4.1.4" - mkdirp "^0.5.1" - object-assign "^4.1.0" + p-map "^1.0.0" p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" -p-limit@^1.1.0: +p-is-promise@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" + dependencies: + p-try "^2.0.0" p-locate@^2.0.0: version "2.0.0" @@ -7621,6 +8477,73 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + dependencies: + p-limit "^2.0.0" + +p-map@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + +p-retry@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-2.0.0.tgz#b97f1f4d6d81a3c065b2b40107b811e995c1bfba" + dependencies: + retry "^0.12.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +pacote@^8.1.6: + version "8.1.6" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-8.1.6.tgz#8e647564d38156367e7a9dc47a79ca1ab278d46e" + dependencies: + bluebird "^3.5.1" + cacache "^11.0.2" + get-stream "^3.0.0" + glob "^7.1.2" + lru-cache "^4.1.3" + make-fetch-happen "^4.0.1" + minimatch "^3.0.4" + minipass "^2.3.3" + mississippi "^3.0.0" + mkdirp "^0.5.1" + normalize-package-data "^2.4.0" + npm-package-arg "^6.1.0" + npm-packlist "^1.1.10" + npm-pick-manifest "^2.1.0" + osenv "^0.1.5" + promise-inflight "^1.0.1" + promise-retry "^1.1.1" + protoduck "^5.0.0" + rimraf "^2.6.2" + safe-buffer "^5.1.2" + semver "^5.5.0" + ssri "^6.0.0" + tar "^4.4.3" + unique-filename "^1.1.0" + which "^1.3.0" + pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" @@ -7651,13 +8574,17 @@ parse-bmfont-binary@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz#d038b476d3e9dd9db1e11a0b0e53a22792b69006" -parse-bmfont-xml@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.3.tgz#d6b66a371afd39c5007d9f0eeb262a4f2cce7b7c" +parse-bmfont-xml@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz#015319797e3e12f9e739c4d513872cd2fa35f389" dependencies: xml-parse-from-string "^1.0.0" xml2js "^0.4.5" +parse-github-url@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-github-url/-/parse-github-url-1.0.2.tgz#242d3b65cbcdda14bb50439e3242acf6971db395" + parse-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" @@ -7680,6 +8607,17 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-ms@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-1.0.1.tgz#56346d4749d78f23430ca0c713850aef91aa361d" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -7690,11 +8628,16 @@ parse-png@^1.0.0, parse-png@^1.1.1: dependencies: pngjs "^3.2.0" -parsejson@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/parsejson/-/parsejson-0.0.3.tgz#ab7e3759f209ece99437973f7d0f1f64ae0e64ab" +parse-url@^1.3.0: + version "1.3.11" + resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-1.3.11.tgz#57c15428ab8a892b1f43869645c711d0e144b554" dependencies: - better-assert "~1.0.0" + is-ssh "^1.3.0" + protocols "^1.4.0" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" parseqs@0.0.5: version "0.0.5" @@ -7708,9 +8651,9 @@ parseuri@0.0.5: dependencies: better-assert "~1.0.0" -parseurl@~1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" pascalcase@^0.1.1: version "0.1.1" @@ -7730,10 +8673,6 @@ path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" -path-exists@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-1.0.0.tgz#d5a8998eb71ef37a74c34eb0d9eba6e878eea081" - path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -7748,17 +8687,17 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-is-inside@^1.0.1, path-is-inside@^1.0.2: +path-is-inside@^1.0.1, path-is-inside@^1.0.2, path-is-inside@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" -path-key@^2.0.0: +path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" path-posix@^1.0.0: version "1.0.0" @@ -7782,6 +8721,12 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + pbkdf2@^3.0.3: version "3.0.16" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c" @@ -7796,28 +8741,36 @@ pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" -performance-now@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" phantomjs-prebuilt@^2.1.10: - version "2.1.14" - resolved "https://registry.yarnpkg.com/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.14.tgz#d53d311fcfb7d1d08ddb24014558f1188c516da0" + version "2.1.16" + resolved "https://registry.yarnpkg.com/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz#efd212a4a3966d3647684ea8ba788549be2aefef" dependencies: - es6-promise "~4.0.3" - extract-zip "~1.5.0" - fs-extra "~1.0.0" - hasha "~2.2.0" - kew "~0.7.0" - progress "~1.1.8" - request "~2.79.0" - request-progress "~2.0.1" - which "~1.2.10" + es6-promise "^4.0.3" + extract-zip "^1.6.5" + fs-extra "^1.0.0" + hasha "^2.2.0" + kew "^0.7.0" + progress "^1.1.8" + request "^2.81.0" + request-progress "^2.0.1" + which "^1.2.10" -pify@^2.0.0, pify@^2.3.0: +phin@^2.9.1: + version "2.9.2" + resolved "https://registry.yarnpkg.com/phin/-/phin-2.9.2.tgz#0a82d5b6dd75552b665f371f8060689c1af7336e" + +pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" @@ -7834,6 +8787,13 @@ pixelmatch@^4.0.0: dependencies: pngjs "^3.0.0" +pkg-conf@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.1.0.tgz#2126514ca6f2abfebd168596df18ba57867f0058" + dependencies: + find-up "^2.0.0" + load-json-file "^4.0.0" + pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -7846,25 +8806,21 @@ pkg-up@^2.0.0: dependencies: find-up "^2.1.0" -pluralize@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" -pluralize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-4.0.0.tgz#59b708c1c0190a2f692f1c7618c446b052fd1762" - -pn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.0.0.tgz#1cf5a30b0d806cd18f88fc41a6b5d4ad615b3ba9" +pn@^1.0.0, pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" pngjs@^3.0.0, pngjs@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.2.0.tgz#fc9fcea1a8a375da54a51148019d5abd41dbabde" + version "3.3.3" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.3.3.tgz#85173703bde3edac8998757b96e5821d0966a21b" -portfinder@^1.0.7: - version "1.0.13" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" +portfinder@^1.0.15: + version "1.0.17" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.17.tgz#a8a1691143e46c4735edefcf4fbcccedad26456a" dependencies: async "^1.5.2" debug "^2.2.0" @@ -7879,46 +8835,43 @@ postcss-value-parser@^3.2.3: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15" postcss@^6.0.1, postcss@^6.0.17: - version "6.0.21" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.21.tgz#8265662694eddf9e9a5960db6da33c39e4cd069d" + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" dependencies: - chalk "^2.3.2" + chalk "^2.4.1" source-map "^0.6.1" - supports-color "^5.3.0" + supports-color "^5.4.0" prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -pretender@^1.1.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pretender/-/pretender-1.5.1.tgz#bd9098c03d39c3bc7dcb84a28ee27e096e2e32b8" - dependencies: - fake-xml-http-request "^1.6.0" - route-recognizer "^0.3.3" - -pretender@^1.6.1: +pretender@^1.4.2, pretender@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/pretender/-/pretender-1.6.1.tgz#77d1e42ac8c6b298f5cd43534a87645df035db8c" dependencies: fake-xml-http-request "^1.6.0" route-recognizer "^0.3.3" -prettier-eslint-cli@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/prettier-eslint-cli/-/prettier-eslint-cli-4.2.1.tgz#7a36dd4c8e2243f077f30c266ea6c90c616a09e8" +prettier-eslint-cli@^4.7.1: + version "4.7.1" + resolved "https://registry.yarnpkg.com/prettier-eslint-cli/-/prettier-eslint-cli-4.7.1.tgz#3d103c494baa4e80b99ad53e2b9db7620101859f" dependencies: arrify "^1.0.1" babel-runtime "^6.23.0" boolify "^1.0.0" camelcase-keys "^4.1.0" - chalk "^1.1.3" + chalk "2.3.0" common-tags "^1.4.0" - eslint "^3.19.0" + eslint "^4.5.0" find-up "^2.1.0" get-stdin "^5.0.1" glob "^7.1.1" @@ -7927,51 +8880,57 @@ prettier-eslint-cli@^4.2.1: lodash.memoize "^4.1.2" loglevel-colored-level-prefix "^1.0.0" messageformat "^1.0.2" - prettier-eslint "^6.0.0" + prettier-eslint "^8.5.0" rxjs "^5.3.0" - yargs "^7.1.0" + yargs "10.0.3" -prettier-eslint@^6.0.0: - version "6.4.2" - resolved "https://registry.yarnpkg.com/prettier-eslint/-/prettier-eslint-6.4.2.tgz#9bafd9549e0827396c75848e8dbeb65525b9096e" +prettier-eslint@^8.5.0: + version "8.8.2" + resolved "https://registry.yarnpkg.com/prettier-eslint/-/prettier-eslint-8.8.2.tgz#fcb29a48ab4524e234680797fe70e9d136ccaf0b" dependencies: + babel-runtime "^6.26.0" common-tags "^1.4.0" dlv "^1.1.0" - eslint "^3.19.0" - indent-string "^3.1.0" + eslint "^4.0.0" + indent-string "^3.2.0" lodash.merge "^4.6.0" loglevel-colored-level-prefix "^1.0.0" - prettier "^1.5.0" - pretty-format "^20.0.3" + prettier "^1.7.0" + pretty-format "^23.0.1" require-relative "^0.8.7" + typescript "^2.5.1" + typescript-eslint-parser "^16.0.0" + vue-eslint-parser "^2.0.2" -prettier@^1.5.0, prettier@^1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.5.3.tgz#59dadc683345ec6b88f88b94ed4ae7e1da394bfe" +prettier@^1.14.3: + version "1.14.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895" -pretty-format@^20.0.3: - version "20.0.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-20.0.3.tgz#020e350a560a1fe1a98dc3beb6ccffb386de8b14" +prettier@^1.7.0: + version "1.14.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.2.tgz#0ac1c6e1a90baa22a62925f41963c841983282f9" + +pretty-format@^23.0.1: + version "23.5.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.5.0.tgz#0f9601ad9da70fe690a269cd3efca732c210687c" dependencies: - ansi-regex "^2.1.1" - ansi-styles "^3.0.0" + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" -printf@^0.2.3: - version "0.2.5" - resolved "https://registry.yarnpkg.com/printf/-/printf-0.2.5.tgz#c438ca2ca33e3927671db4ab69c0e52f936a4f0f" +pretty-ms@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-3.2.0.tgz#87a8feaf27fc18414d75441467d411d6e6098a25" + dependencies: + parse-ms "^1.0.0" -private@^0.1.6, private@~0.1.5: - version "0.1.7" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" +printf@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/printf/-/printf-0.5.1.tgz#e0466788260859ed153006dc6867f09ddf240cf3" -private@^0.1.8: +private@^0.1.6, private@^0.1.8, private@~0.1.5: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" -process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" @@ -7990,7 +8949,7 @@ process@~0.5.1: version "0.5.2" resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" -progress@^1.1.8, progress@~1.1.8: +progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" @@ -7998,26 +8957,53 @@ progress@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" -promise-inflight@^1.0.1: +promise-inflight@^1.0.1, promise-inflight@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" -promise-map-series@^0.2.1: +promise-map-series@^0.2.1, promise-map-series@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/promise-map-series/-/promise-map-series-0.2.3.tgz#c2d377afc93253f6bd03dbb77755eb88ab20a847" dependencies: rsvp "^3.0.14" +promise-retry@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" + dependencies: + err-code "^1.0.0" + retry "^0.10.0" + promised-io@*: version "0.3.5" resolved "https://registry.yarnpkg.com/promised-io/-/promised-io-0.3.5.tgz#4ad217bb3658bcaae9946b17a8668ecd851e1356" -proxy-addr@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.4.tgz#27e545f6960a44a627d9b44467e35c1b6b4ce2f3" +promzard@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" dependencies: - forwarded "~0.1.0" - ipaddr.js "1.3.0" + read "1" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + +protocols@^1.1.0, protocols@^1.4.0: + version "1.4.6" + resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.6.tgz#f8bb263ea1b5fd7a7604d26b8be39bd77678bf8a" + +protoduck@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.0.tgz#752145e6be0ad834cb25716f670a713c860dce70" + dependencies: + genfun "^4.0.1" + +proxy-addr@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.8.0" prr@~1.0.1: version "1.0.1" @@ -8027,6 +9013,10 @@ pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" +psl@^1.1.24: + version "1.1.29" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" + public-encrypt@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.2.tgz#46eb9107206bf73489f8b85b69d91334c6610994" @@ -8044,6 +9034,13 @@ pump@^2.0.0, pump@^2.0.1: end-of-stream "^1.1.0" once "^1.3.1" +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + pumpify@^1.3.3: version "1.5.1" resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" @@ -8064,21 +9061,28 @@ punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" -q@^1.1.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" +q@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" -qs@6.4.0, qs@^6.4.0, qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" +qrcode-terminal@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" qs@6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" -qs@~6.3.0: - version "6.3.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" +qs@6.5.2, qs@^6.2.0, qs@^6.4.0, qs@~6.5.1, qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + +query-string@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.1.0.tgz#01e7d69f6a0940dac67a937d6c6325647aa4532a" + dependencies: + decode-uri-component "^0.2.0" + strict-uri-encode "^2.0.0" querystring-es3@^0.2.0: version "0.2.1" @@ -8100,35 +9104,36 @@ quick-temp@^0.1.0, quick-temp@^0.1.2, quick-temp@^0.1.3, quick-temp@^0.1.5, quic rimraf "^2.5.4" underscore.string "~3.3.4" -qunit-dom@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/qunit-dom/-/qunit-dom-0.6.2.tgz#0b37012cbbc838f09eba760b3d39924ad5ccbccb" +qunit-dom@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/qunit-dom/-/qunit-dom-0.7.1.tgz#2e6ad4a6453c034f88ef415250b37e82572460b9" dependencies: broccoli-funnel "^2.0.0" broccoli-merge-trees "^2.0.0" -qunit-notifications@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/qunit-notifications/-/qunit-notifications-0.1.1.tgz#3001afc6a6a77dfbd962ccbcddde12dec5286c09" - -qunitjs@^2.0.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/qunitjs/-/qunitjs-2.4.0.tgz#58f3a81e846687f2e7f637c5bedc9c267f887261" +qunit@^2.5.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/qunit/-/qunit-2.6.2.tgz#551210c5cf857258a4fe39a7fe15d9e14dfef22c" dependencies: - chokidar "1.6.1" - commander "2.9.0" + commander "2.12.2" exists-stat "1.0.0" - findup-sync "0.4.3" - js-reporters "1.2.0" - resolve "1.3.2" - walk-sync "0.3.1" + findup-sync "2.0.0" + js-reporters "1.2.1" + resolve "1.5.0" + sane "^2.5.2" + walk-sync "0.3.2" -randomatic@^1.1.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" +qw@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/qw/-/qw-1.0.1.tgz#efbfdc740f9ad054304426acb183412cc8b996d4" + +randomatic@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.0.tgz#36f2ca708e9e567f5ed2ec01949026d50aa10116" dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.0.6" @@ -8156,6 +9161,15 @@ raw-body@2.3.2: iconv-lite "0.4.19" unpipe "1.0.0" +raw-body@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + raw-body@~1.1.0: version "1.1.7" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-1.1.7.tgz#1d027c2bfa116acc6623bca8f00016572a87d425" @@ -8163,16 +9177,7 @@ raw-body@~1.1.0: bytes "1" string_decoder "0.10" -rc@^1.1.7: - version "1.2.1" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" - dependencies: - deep-extend "~0.4.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -rc@^1.2.7: +rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" dependencies: @@ -8185,6 +9190,46 @@ read-chunk@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194" +read-cmd-shim@^1.0.1, read-cmd-shim@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" + dependencies: + graceful-fs "^4.1.2" + +read-installed@~4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" + dependencies: + debuglog "^1.0.1" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + semver "2 || 3 || 4 || 5" + slide "~1.1.3" + util-extend "^1.0.1" + optionalDependencies: + graceful-fs "^4.1.2" + +"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.13.tgz#2e82ebd9f613baa6d2ebe3aa72cefe3f68e41f4a" + dependencies: + glob "^7.1.1" + json-parse-better-errors "^1.0.1" + normalize-package-data "^2.0.0" + slash "^1.0.0" + optionalDependencies: + graceful-fs "^4.1.2" + +read-package-tree@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.2.1.tgz#6218b187d6fac82289ce4387bbbaf8eef536ad63" + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + once "^1.3.0" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -8192,6 +9237,20 @@ read-pkg-up@^1.0.1: find-up "^1.0.0" read-pkg "^1.0.0" +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" @@ -8200,7 +9259,29 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.4, readable-stream@^2.3.3, readable-stream@^2.3.6: +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +read-pkg@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" + dependencies: + normalize-package-data "^2.3.2" + parse-json "^4.0.0" + pify "^3.0.0" + +read@1, read@~1.0.1, read@~1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + dependencies: + mute-stream "~0.0.4" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: @@ -8221,18 +9302,6 @@ readable-stream@1.1: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - safe-buffer "~5.1.1" - string_decoder "~1.0.3" - util-deprecate "~1.0.1" - readable-stream@~1.0.2: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" @@ -8242,16 +9311,23 @@ readable-stream@~1.0.2: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@~2.0.0: - version "2.0.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" +readable-stream@~1.1.10: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" dependencies: core-util-is "~1.0.0" inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" + isarray "0.0.1" string_decoder "~0.10.x" - util-deprecate "~1.0.1" + +readdir-scoped-modules@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + graceful-fs "^4.1.2" + once "^1.3.0" readdirp@^2.0.0: version "2.1.0" @@ -8262,24 +9338,7 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" -readline2@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - mute-stream "0.0.5" - -recast@0.10.33, recast@^0.10.10: - version "0.10.33" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.33.tgz#942808f7aa016f1fa7142c461d7e5704aaa8d697" - dependencies: - ast-types "0.8.12" - esprima-fb "~15001.1001.0-dev-harmony-fb" - private "~0.1.5" - source-map "~0.5.0" - -recast@^0.11.17, recast@^0.11.3: +recast@^0.11.3: version "0.11.23" resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" dependencies: @@ -8288,12 +9347,6 @@ recast@^0.11.17, recast@^0.11.3: private "~0.1.5" source-map "~0.5.0" -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - dependencies: - resolve "^1.1.6" - redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" @@ -8301,17 +9354,30 @@ redent@^1.0.0: indent-string "^2.1.0" strip-indent "^1.0.1" +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + redeyed@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-1.0.1.tgz#e96c193b40c0816b00aec842698e61185e55498a" dependencies: esprima "~3.0.0" -regenerate@^1.2.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" +redeyed@~2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-2.1.1.tgz#8984b5815d99cb220469c99eeeffe38913e6cc0b" + dependencies: + esprima "~4.0.0" -regenerator-runtime@^0.10.0, regenerator-runtime@^0.10.5: +regenerate@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + +regenerator-runtime@^0.10.5: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" @@ -8323,31 +9389,19 @@ regenerator-runtime@^0.9.5: version "0.9.6" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" -regenerator-transform@0.9.11: - version "0.9.11" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283" +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" dependencies: babel-runtime "^6.18.0" babel-types "^6.19.0" private "^0.1.6" -regenerator@0.8.40: - version "0.8.40" - resolved "https://registry.yarnpkg.com/regenerator/-/regenerator-0.8.40.tgz#a0e457c58ebdbae575c9f8cd75127e93756435d8" - dependencies: - commoner "~0.10.3" - defs "~1.1.0" - esprima-fb "~15001.1001.0-dev-harmony-fb" - private "~0.1.5" - recast "0.10.33" - through "~2.3.8" - regex-cache@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" dependencies: is-equal-shallow "^0.1.3" - is-primitive "^2.0.0" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" @@ -8356,6 +9410,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpp@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + regexpu-core@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" @@ -8364,15 +9422,18 @@ regexpu-core@^2.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" -regexpu@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexpu/-/regexpu-1.3.0.tgz#e534dc991a9e5846050c98de6d7dd4a55c9ea16d" +registry-auth-token@^3.0.1, registry-auth-token@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" dependencies: - esprima "^2.6.0" - recast "^0.10.10" - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + dependencies: + rc "^1.0.1" regjsgen@^0.2.0: version "0.2.0" @@ -8385,23 +9446,17 @@ regjsparser@^0.1.4: jsesc "~0.5.0" remove-trailing-separator@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz#69b062d978727ad14dc6b56ba4ab772fd8d70511" + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" -repeating@^1.1.0, repeating@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac" - dependencies: - is-finite "^1.0.0" - repeating@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" @@ -8412,63 +9467,75 @@ replace-ext@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" -request-progress@~2.0.1: +request-progress@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-2.0.1.tgz#5d36bb57961c673aa5b788dbc8141fdf23b44e08" dependencies: throttleit "^1.0.0" -request@2, request@^2.65.0, request@^2.81.0: - version "2.81.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" + lodash "^4.13.1" + +request-promise-native@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + dependencies: + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request@2.87.0: + version "2.87.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" caseless "~0.12.0" combined-stream "~1.0.5" - extend "~3.0.0" + extend "~3.0.1" forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~4.2.1" - hawk "~3.1.3" - http-signature "~1.1.0" + form-data "~2.3.1" + har-validator "~5.0.3" + http-signature "~1.2.0" is-typedarray "~1.0.0" isstream "~0.1.2" json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - performance-now "^0.2.0" - qs "~6.4.0" - safe-buffer "^5.0.1" - stringstream "~0.0.4" - tough-cookie "~2.3.0" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + tough-cookie "~2.3.3" tunnel-agent "^0.6.0" - uuid "^3.0.0" + uuid "^3.1.0" -request@~2.79.0: - version "2.79.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" +request@^2.65.0, request@^2.74.0, request@^2.81.0, request@^2.87.0, request@^2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.11.0" - combined-stream "~1.0.5" - extend "~3.0.0" + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~2.0.6" - hawk "~3.1.3" - http-signature "~1.1.0" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" is-typedarray "~1.0.0" isstream "~0.1.2" json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - qs "~6.3.0" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "~0.4.1" - uuid "^3.0.0" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" require-directory@^2.1.1: version "2.1.1" @@ -8482,18 +9549,18 @@ require-relative@^0.8.7: version "0.8.7" resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de" -require-uncached@^1.0.2, require-uncached@^1.0.3: +require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" dependencies: caller-path "^0.1.0" resolve-from "^1.0.0" -requires-port@1.x.x: +requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" -reserved-words@^0.1.1: +reserved-words@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.2.tgz#00a0940f98cd501aeaaac316411d9adc52b31ab1" @@ -8508,40 +9575,36 @@ resize-img@^1.1.0: jpeg-js "^0.1.1" parse-png "^1.1.1" -resolve-dir@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" dependencies: - expand-tilde "^1.2.2" - global-modules "^0.2.3" + expand-tilde "^2.0.0" + global-modules "^1.0.0" resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" -resolve@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235" +resolve@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" dependencies: path-parse "^1.0.5" -resolve@^1.1.2, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.0, resolve@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" - dependencies: - path-parse "^1.0.5" - -resolve@^1.4.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3" - dependencies: - path-parse "^1.0.5" - -resolve@^1.7.1: +resolve@^1.1.3, resolve@^1.1.7, resolve@^1.2.0, resolve@^1.3.3, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.7.1, resolve@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" dependencies: @@ -8565,19 +9628,15 @@ ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" +retry@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" -rimraf@2, rimraf@^2.2.8, rimraf@^2.3.2, rimraf@^2.3.4, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@^2.5.1, rimraf@^2.5.3, rimraf@^2.5.4, rimraf@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" - dependencies: - glob "^7.0.5" +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" -rimraf@^2.6.2: +rimraf@2, rimraf@^2.2.8, rimraf@^2.3.4, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@^2.5.2, rimraf@^2.5.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: @@ -8585,7 +9644,7 @@ rimraf@^2.6.2: rimraf@~2.2.6: version "2.2.8" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + resolved "http://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" @@ -8594,44 +9653,49 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +rollup-pluginutils@^2.0.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.3.1.tgz#760d185ccc237dedc12d7ae48c6bcd127b4892d0" + dependencies: + estree-walker "^0.5.2" + micromatch "^2.3.11" + +rollup@^0.57.1: + version "0.57.1" + resolved "http://registry.npmjs.org/rollup/-/rollup-0.57.1.tgz#0bb28be6151d253f67cf4a00fea48fb823c74027" + dependencies: + "@types/acorn" "^4.0.3" + acorn "^5.5.3" + acorn-dynamic-import "^3.0.0" + date-time "^2.1.0" + is-reference "^1.1.0" + locate-character "^2.0.5" + pretty-ms "^3.1.0" + require-relative "^0.8.7" + rollup-pluginutils "^2.0.1" + signal-exit "^3.0.2" + sourcemap-codec "^1.4.1" + route-recognizer@^0.2.3: version "0.2.10" resolved "https://registry.yarnpkg.com/route-recognizer/-/route-recognizer-0.2.10.tgz#024b2283c2e68d13a7c7f5173a5924645e8902df" route-recognizer@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/route-recognizer/-/route-recognizer-0.3.3.tgz#1d365e27fa6995e091675f7dc940a8c00353bd29" + version "0.3.4" + resolved "https://registry.yarnpkg.com/route-recognizer/-/route-recognizer-0.3.4.tgz#39ab1ffbce1c59e6d2bdca416f0932611e4f3ca3" -rsvp@^3.0.14, rsvp@^3.0.16, rsvp@^3.0.17, rsvp@^3.0.18, rsvp@^3.0.21, rsvp@^3.0.6, rsvp@^3.1.0, rsvp@^3.2.1, rsvp@^3.3.3, rsvp@^3.5.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.1.tgz#34f4a7ac2859f7bacc8f49789c5604f1e26ae702" - -rsvp@^3.6.0: +rsvp@^3.0.14, rsvp@^3.0.16, rsvp@^3.0.17, rsvp@^3.0.18, rsvp@^3.0.21, rsvp@^3.0.6, rsvp@^3.1.0, rsvp@^3.3.3: version "3.6.2" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" -rsvp@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.7.0.tgz#dc1b0b1a536f7dec9d2be45e0a12ad4197c9fd96" - -rsvp@^4.8.2: - version "4.8.2" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.2.tgz#9d5647108735784eb13418cdddb56f75b919d722" - -rsvp@~3.0.6: - version "3.0.21" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.0.21.tgz#49c588fe18ef293bcd0ab9f4e6756e6ac433359f" +rsvp@^4.6.1, rsvp@^4.7.0, rsvp@^4.8.2, rsvp@^4.8.3: + version "4.8.3" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.3.tgz#25d4b9fdd0f95e216eb5884d9b3767d3fbfbe2cd" rsvp@~3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.2.1.tgz#07cb4a5df25add9e826ebc67dcc9fd89db27d84a" -run-async@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" - dependencies: - once "^1.3.0" - run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -8654,25 +9718,21 @@ rx-lite@*, rx-lite@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" -rx-lite@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" - rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" rxjs@^5.3.0: - version "5.4.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.4.3.tgz#0758cddee6033d68e0fd53676f0f3596ce3d483f" + version "5.5.12" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" dependencies: - symbol-observable "^1.0.1" + symbol-observable "1.0.1" -safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" -safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -8686,25 +9746,43 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" -samsam@1.x, samsam@^1.1.3: +samsam@1.3.0, samsam@1.x, samsam@^1.1.3: version "1.3.0" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" -sane@^1.1.1, sane@^1.6.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-1.7.0.tgz#b3579bccb45c94cf20355cc81124990dfd346e30" +sane@^2.4.1, sane@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa" dependencies: - anymatch "^1.3.0" + anymatch "^2.0.0" + capture-exit "^1.2.0" exec-sh "^0.2.0" fb-watchman "^2.0.0" - minimatch "^3.0.2" + micromatch "^3.1.4" minimist "^1.1.1" walker "~1.0.5" - watch "~0.10.0" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.2.3" + +sane@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-3.0.0.tgz#32e88d110b32dcd0ae3b88bdc58d8e4762cdf49a" + dependencies: + anymatch "^2.0.0" + capture-exit "^1.2.0" + exec-sh "^0.2.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.2.3" sass-graph@^2.2.4: version "2.2.4" @@ -8724,8 +9802,8 @@ sax@>=0.6.0, sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" schema-utils@^0.4.4, schema-utils@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e" + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" dependencies: ajv "^6.1.0" ajv-keywords "^3.1.0" @@ -8741,48 +9819,90 @@ select@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" -"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.1.1, semver@^5.3.0, semver@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" +semantic-release@^15.9.12: + version "15.9.14" + resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-15.9.14.tgz#108fa88649e318b85f728adc9375b12d68075726" + dependencies: + "@semantic-release/commit-analyzer" "^6.0.0" + "@semantic-release/error" "^2.2.0" + "@semantic-release/github" "^5.0.0" + "@semantic-release/npm" "^5.0.1" + "@semantic-release/release-notes-generator" "^7.0.0" + aggregate-error "^1.0.0" + cosmiconfig "^5.0.1" + debug "^3.1.0" + env-ci "^2.4.0" + execa "^1.0.0" + figures "^2.0.0" + find-versions "^2.0.0" + get-stream "^4.0.0" + git-log-parser "^1.2.0" + git-url-parse "^10.0.1" + hook-std "^1.1.0" + hosted-git-info "^2.7.1" + lodash "^4.17.4" + marked "^0.5.0" + marked-terminal "^3.0.0" + p-locate "^3.0.0" + p-reduce "^1.0.0" + read-pkg-up "^4.0.0" + resolve-from "^4.0.0" + semver "^5.4.1" + signale "^1.2.1" + yargs "^12.0.0" -semver@^4.1.0: - version "4.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + dependencies: + semver "^5.0.3" -semver@^5.4.1, semver@^5.5.0: +semver-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-1.0.0.tgz#92a4969065f9c70c694753d55248fc68f8f652c9" + +"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: + version "5.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" + +semver@5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" -send@0.15.3: - version "0.15.3" - resolved "https://registry.yarnpkg.com/send/-/send-0.15.3.tgz#5013f9f99023df50d1bd9892c19e3defd1d53309" +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" dependencies: - debug "2.6.7" - depd "~1.1.0" + debug "2.6.9" + depd "~1.1.2" destroy "~1.0.4" - encodeurl "~1.0.1" + encodeurl "~1.0.2" escape-html "~1.0.3" - etag "~1.8.0" - fresh "0.5.0" - http-errors "~1.6.1" - mime "1.3.4" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" ms "2.0.0" on-finished "~2.3.0" range-parser "~1.2.0" - statuses "~1.3.1" + statuses "~1.4.0" serialize-javascript@^1.4.0: version "1.5.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" -serve-static@1.12.3: - version "1.12.3" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.3.tgz#9f4ba19e2f3030c547f8af99107838ec38d5b1e2" +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" dependencies: - encodeurl "~1.0.1" + encodeurl "~1.0.2" escape-html "~1.0.3" - parseurl "~1.3.1" - send "0.15.3" + parseurl "~1.3.2" + send "0.16.2" set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" @@ -8829,6 +9949,13 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +sha@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sha/-/sha-2.0.1.tgz#6030822fbd2c9823949f8f72ed6411ee5cf25aae" + dependencies: + graceful-fs "^4.1.2" + readable-stream "^2.0.2" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -8839,17 +9966,9 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" -shelljs@^0.7.5: - version "0.7.8" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -shellwords@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.0.tgz#66afd47b6a12932d9071cbfd98a52e785cd0ba14" +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" sigmund@~1.0.0: version "1.0.1" @@ -8859,31 +9978,29 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" +signale@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/signale/-/signale-1.3.0.tgz#1b4917c2c7a8691550adca0ad1da750a662b4497" + dependencies: + chalk "^2.3.2" + figures "^2.0.0" + pkg-conf "^2.1.0" + silent-error@^1.0.0, silent-error@^1.0.1, silent-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/silent-error/-/silent-error-1.1.0.tgz#2209706f1c850a9f1d10d0d840918b46f26e1bc9" dependencies: debug "^2.2.0" -simple-dom@^0.3.0: - version "0.3.2" - resolved "https://registry.yarnpkg.com/simple-dom/-/simple-dom-0.3.2.tgz#0663d10f1556f1500551d518f56e3aba0871371d" +simple-html-tokenizer@^0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/simple-html-tokenizer/-/simple-html-tokenizer-0.5.6.tgz#e1e442b14f5484bf9a7e2924f78f00855e6b3c14" -simple-fmt@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/simple-fmt/-/simple-fmt-0.1.0.tgz#191bf566a59e6530482cb25ab53b4a8dc85c3a6b" - -simple-html-tokenizer@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/simple-html-tokenizer/-/simple-html-tokenizer-0.3.0.tgz#9b8b5559d80e331a544dd13dd59382e5d0d94411" - -simple-html-tokenizer@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/simple-html-tokenizer/-/simple-html-tokenizer-0.4.1.tgz#028988bb7fe8b2e6645676d82052587d440b02d3" - -simple-is@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/simple-is/-/simple-is-0.2.0.tgz#2abb75aade39deb5cc815ce10e6191164850baf0" +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + dependencies: + is-arrayish "^0.3.1" sinon@^3.2.1: version "3.3.0" @@ -8905,14 +10022,30 @@ slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" -slice-ansi@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + dependencies: + is-fullwidth-code-point "^2.0.0" -slide@^1.1.5: +slide@^1.1.3, slide@^1.1.6, slide@~1.1.3, slide@~1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" +smart-buffer@^1.0.13: + version "1.1.15" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16" + +smart-buffer@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.1.tgz#07ea1ca8d4db24eb4cac86537d7d18995221ace3" + +snake-case@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f" + dependencies: + no-case "^2.2.0" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -8940,97 +10073,124 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - dependencies: - hoek "2.x.x" +socket.io-adapter@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b" -socket.io-adapter@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz#cb6d4bb8bec81e1078b99677f9ced0046066bb8b" - dependencies: - debug "2.3.3" - socket.io-parser "2.3.1" - -socket.io-client@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.6.0.tgz#5b668f4f771304dfeed179064708386fa6717853" +socket.io-client@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.1.1.tgz#dcb38103436ab4578ddb026638ae2f21b623671f" dependencies: backo2 "1.0.2" + base64-arraybuffer "0.1.5" component-bind "1.0.0" component-emitter "1.2.1" - debug "2.3.3" - engine.io-client "1.8.0" - has-binary "0.1.7" + debug "~3.1.0" + engine.io-client "~3.2.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" indexof "0.0.1" object-component "0.0.3" + parseqs "0.0.5" parseuri "0.0.5" - socket.io-parser "2.3.1" + socket.io-parser "~3.2.0" to-array "0.1.4" -socket.io-parser@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.3.1.tgz#dd532025103ce429697326befd64005fcfe5b4a0" +socket.io-parser@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077" dependencies: - component-emitter "1.1.2" - debug "2.2.0" - isarray "0.0.1" - json3 "3.3.2" + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" -socket.io@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.6.0.tgz#3e40d932637e6bd923981b25caf7c53e83b6e2e1" +socket.io@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.1.1.tgz#a069c5feabee3e6b214a75b40ce0652e1cfb9980" dependencies: - debug "2.3.3" - engine.io "1.8.0" - has-binary "0.1.7" - object-assign "4.1.0" - socket.io-adapter "0.5.0" - socket.io-client "1.6.0" - socket.io-parser "2.3.1" + debug "~3.1.0" + engine.io "~3.2.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.1.1" + socket.io-parser "~3.2.0" + +socks-proxy-agent@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz#2eae7cf8e2a82d34565761539a7f9718c5617659" + dependencies: + agent-base "^4.1.0" + socks "^1.1.10" + +socks-proxy-agent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz#5936bf8b707a993079c6f37db2091821bffa6473" + dependencies: + agent-base "~4.2.0" + socks "~2.2.0" + +socks@^1.1.10: + version "1.1.10" + resolved "https://registry.yarnpkg.com/socks/-/socks-1.1.10.tgz#5b8b7fc7c8f341c53ed056e929b7bf4de8ba7b5a" + dependencies: + ip "^1.1.4" + smart-buffer "^1.0.13" + +socks@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.2.1.tgz#68ad678b3642fbc5d99c64c165bc561eab0215f9" + dependencies: + ip "^1.1.5" + smart-buffer "^4.0.1" sort-object-keys@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/sort-object-keys/-/sort-object-keys-1.1.2.tgz#d3a6c48dc2ac97e6bc94367696e03f6d09d37952" -sort-package-json@^1.4.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/sort-package-json/-/sort-package-json-1.7.0.tgz#13b362ff6400c5b4eaa9ba220f9ea7c3d6644b5f" +sort-package-json@^1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/sort-package-json/-/sort-package-json-1.15.0.tgz#3c732cc8312eb4aa12f6eccab1bc3dea89b11dff" dependencies: + detect-indent "^5.0.0" sort-object-keys "^1.1.1" +sorted-object@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" + +sorted-union-stream@~2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/sorted-union-stream/-/sorted-union-stream-2.1.3.tgz#c7794c7e077880052ff71a8d4a2dbb4a9a638ac7" + dependencies: + from2 "^1.3.0" + stream-iterate "^1.1.0" + source-list-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" source-map-resolve@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.1.tgz#7ad0f593f2281598e854df80f19aae4b92d7a11a" + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" dependencies: - atob "^2.0.0" + atob "^2.1.1" decode-uri-component "^0.2.0" resolve-url "^0.2.1" source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.2.10: - version "0.2.10" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.2.10.tgz#ea5a3900a1c1cb25096a0ae8cc5c2b4b10ded3dc" - dependencies: - source-map "0.1.32" - source-map-support@^0.4.15: version "0.4.18" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" dependencies: source-map "^0.5.6" -source-map-support@^0.4.2: - version "0.4.15" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" +source-map-support@~0.5.6: + version "0.5.9" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" dependencies: - source-map "^0.5.6" + buffer-from "^1.0.0" + source-map "^0.6.0" source-map-url@^0.3.0: version "0.3.0" @@ -9040,34 +10200,47 @@ source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" -source-map@0.1.32: - version "0.1.32" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266" - dependencies: - amdefine ">=0.0.4" - -source-map@0.4.x, source-map@^0.4.2, source-map@^0.4.4: +source-map@0.4.x, source-map@^0.4.2: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" dependencies: amdefine ">=0.0.4" -source-map@^0.5.0, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - -source-map@^0.5.7: +source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.0: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" -source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" +source-map@~0.1.x: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + +sourcemap-codec@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.1.tgz#c8fd92d91889e902a07aee392bdd2c5863958ba2" + +sourcemap-validator@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/sourcemap-validator/-/sourcemap-validator-1.1.0.tgz#00454547d1682186e1498a7208e022e8dfa8738f" + dependencies: + jsesc "~0.3.x" + lodash.foreach "~2.3.x" + lodash.template "~2.3.x" + source-map "~0.1.x" + spawn-args@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/spawn-args/-/spawn-args-0.2.0.tgz#fb7d0bd1d70fd4316bd9e3dec389e65f9d6361bb" +spawn-error-forwarder@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz#1afd94738e999b0346d7b9fc373be55e07577029" + spawn-sync@^1.0.11, spawn-sync@^1.0.15: version "1.0.15" resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" @@ -9075,19 +10248,27 @@ spawn-sync@^1.0.11, spawn-sync@^1.0.15: concat-stream "^1.4.7" os-shim "^0.1.2" -spdx-correct@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" +spdx-correct@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" dependencies: - spdx-license-ids "^1.0.2" + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" -spdx-expression-parse@~1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" +spdx-exceptions@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" -spdx-license-ids@^1.0.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz#e2a303236cac54b04031fa7a5a79c7e701df852f" split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -9095,7 +10276,29 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" -sprintf-js@^1.0.3, sprintf-js@~1.0.2: +split2@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" + dependencies: + through2 "^2.0.2" + +split2@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-1.0.0.tgz#52e2e221d88c75f9a73f90556e263ff96772b314" + dependencies: + through2 "~2.0.0" + +split@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + dependencies: + through "2" + +sprintf-js@^1.0.3: + version "1.1.1" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c" + +sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -9104,13 +10307,14 @@ sri-toolbox@^0.2.0: resolved "https://registry.yarnpkg.com/sri-toolbox/-/sri-toolbox-0.2.0.tgz#a7fea5c3fde55e675cf1c8c06f3ebb5c2935835e" sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + version "1.14.2" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98" dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" dashdash "^1.12.0" getpass "^0.1.1" + safer-buffer "^2.0.2" optionalDependencies: bcrypt-pbkdf "^1.0.0" ecc-jsbn "~0.1.1" @@ -9123,9 +10327,11 @@ ssri@^5.2.4: dependencies: safe-buffer "^5.1.1" -stable@~0.1.3: - version "0.1.6" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.6.tgz#910f5d2aed7b520c6e777499c1f32e139fdecb10" +ssri@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + dependencies: + figgy-pudding "^3.5.1" stack-trace@0.0.x: version "0.0.10" @@ -9138,20 +10344,24 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.3.1 < 2", statuses@~1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" - -"statuses@>= 1.4.0 < 2": +"statuses@>= 1.3.1 < 2", "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" -stdout-stream@^1.4.0: +statuses@~1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.0.tgz#a2c7c8587e54d9427ea9edb3ac3f2cd522df378b" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + +stdout-stream@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" dependencies: readable-stream "^2.0.1" +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + stream-browserify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" @@ -9159,9 +10369,16 @@ stream-browserify@^2.0.1: inherits "~2.0.1" readable-stream "^2.0.2" +stream-combiner2@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" + dependencies: + duplexer2 "~0.1.0" + readable-stream "^2.0.2" + stream-each@^1.1.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" dependencies: end-of-stream "^1.1.0" stream-shift "^1.0.0" @@ -9176,6 +10393,13 @@ stream-http@^2.7.2: to-arraybuffer "^1.0.0" xtend "^4.0.0" +stream-iterate@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/stream-iterate/-/stream-iterate-1.2.0.tgz#2bd7c77296c1702a46488b8ad41f79865eecd4e1" + dependencies: + readable-stream "^2.1.5" + stream-shift "^1.0.0" + stream-shift@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" @@ -9190,6 +10414,10 @@ stream-to@~0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/stream-to/-/stream-to-0.2.2.tgz#84306098d85fdb990b9fa300b1b3ccf55e8ef01d" +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + string-template@~0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" @@ -9202,9 +10430,9 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0, string-width@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.0.tgz#030664561fc146c9423ec7d978fe2457437fe6d0" +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" @@ -9227,29 +10455,9 @@ string_decoder@^1.0.0, string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -string_decoder@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" - dependencies: - safe-buffer "~5.1.0" - -stringmap@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/stringmap/-/stringmap-0.2.2.tgz#556c137b258f942b8776f5b2ef582aa069d7d1b1" - -stringset@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/stringset/-/stringset-0.2.1.tgz#ef259c4e349344377fcd1c913dd2e848c9c042b5" - -stringstream@~0.0.4: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - -strip-ansi@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220" - dependencies: - ansi-regex "^0.2.1" +stringify-package@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.0.tgz#e02828089333d7d45cd8c287c30aa9a13375081b" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" @@ -9287,6 +10495,10 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -9301,23 +10513,19 @@ sum-up@^1.0.1: dependencies: chalk "^1.0.0" -supports-color@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" supports-color@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.0.tgz#ad986dc7eb2315d009b4d77c8169c2231a684037" + version "4.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" dependencies: has-flag "^2.0.0" -supports-color@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" +supports-color@^5.3.0, supports-color@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" dependencies: has-flag "^3.0.0" @@ -9329,67 +10537,42 @@ svg2png@~3.0.1: pn "^1.0.0" yargs "^3.31.0" -symbol-observable@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" -symlink-or-copy@^1.0.0, symlink-or-copy@^1.0.1, symlink-or-copy@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/symlink-or-copy/-/symlink-or-copy-1.1.8.tgz#cabe61e0010c1c023c173b25ee5108b37f4b4aa3" +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" -symlink-or-copy@^1.2.0: +symlink-or-copy@^1.0.0, symlink-or-copy@^1.0.1, symlink-or-copy@^1.1.8, symlink-or-copy@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/symlink-or-copy/-/symlink-or-copy-1.2.0.tgz#5d49108e2ab824a34069b68974486c290020b393" -table@^3.7.8: - version "3.8.3" - resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" +table@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" dependencies: - ajv "^4.7.0" - ajv-keywords "^1.0.0" - chalk "^1.1.1" - lodash "^4.0.0" - slice-ansi "0.0.4" - string-width "^2.0.0" + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" -table@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.1.tgz#a8116c133fac2c61f4a420ab6cdf5c4d61f0e435" - dependencies: - ajv "^4.7.0" - ajv-keywords "^1.0.0" - chalk "^1.1.1" - lodash "^4.0.0" - slice-ansi "0.0.4" - string-width "^2.0.0" - -tap-parser@^5.1.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/tap-parser/-/tap-parser-5.4.0.tgz#6907e89725d7b7fa6ae41ee2c464c3db43188aec" +tap-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/tap-parser/-/tap-parser-7.0.0.tgz#54db35302fda2c2ccc21954ad3be22b2cba42721" dependencies: events-to-array "^1.0.1" js-yaml "^3.2.7" - optionalDependencies: - readable-stream "^2" + minipass "^2.2.0" tapable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" -tar-pack@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984" - dependencies: - debug "^2.2.0" - fstream "^1.0.10" - fstream-ignore "^1.0.5" - once "^1.3.3" - readable-stream "^2.1.4" - rimraf "^2.5.1" - tar "^2.2.1" - uid-number "^0.0.6" - -tar@^2.0.0, tar@^2.2.1: +tar@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" dependencies: @@ -9397,9 +10580,9 @@ tar@^2.0.0, tar@^2.2.1: fstream "^1.0.2" inherits "2" -tar@^4: - version "4.4.4" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.4.tgz#ec8409fae9f665a4355cc3b4087d0820232bb8cd" +tar@^4, tar@^4.4.3, tar@^4.4.6: + version "4.4.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" dependencies: chownr "^1.0.1" fs-minipass "^1.2.5" @@ -9416,22 +10599,37 @@ temp@0.8.3: os-tmpdir "^1.0.0" rimraf "~2.2.6" -testem@^1.18.0: - version "1.18.4" - resolved "https://registry.yarnpkg.com/testem/-/testem-1.18.4.tgz#e45fed922bec2f54a616c43f11922598ac97eb41" +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + dependencies: + execa "^0.7.0" + +terser@^3.7.5: + version "3.8.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.8.2.tgz#48b880f949f8d038aca4dfd00a37c53d96ecf9fb" + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + source-map-support "~0.5.6" + +testem@^2.9.2: + version "2.11.0" + resolved "https://registry.yarnpkg.com/testem/-/testem-2.11.0.tgz#3e561fc0892ed3df8da94a55bcc2c51688b4c533" dependencies: backbone "^1.1.2" bluebird "^3.4.6" charm "^1.0.0" commander "^2.6.0" - consolidate "^0.14.0" - cross-spawn "^5.1.0" + consolidate "^0.15.1" + execa "^0.11.0" express "^4.10.7" fireworm "^0.7.0" glob "^7.0.4" http-proxy "^1.13.1" js-yaml "^3.2.5" lodash.assignin "^4.1.0" + lodash.castarray "^4.4.0" lodash.clonedeep "^4.4.1" lodash.find "^4.5.1" lodash.uniqby "^4.7.0" @@ -9439,12 +10637,12 @@ testem@^1.18.0: mustache "^2.2.1" node-notifier "^5.0.1" npmlog "^4.0.0" - printf "^0.2.3" + printf "^0.5.1" rimraf "^2.4.4" - socket.io "1.6.0" + socket.io "^2.1.0" spawn-args "^0.2.0" styled_string "0.0.1" - tap-parser "^5.1.0" + tap-parser "^7.0.0" xmldom "^0.1.19" text-encoder-lite@1.0.0: @@ -9455,29 +10653,45 @@ text-encoding@0.6.4, text-encoding@^0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" +text-extensions@^1.0.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.7.0.tgz#faaaba2625ed746d568a23e4d0aacd9bf08a8b39" + +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" "textextensions@1 || 2": - version "2.1.0" - resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.1.0.tgz#1be0dc2a0dc244d44be8a09af6a85afb93c4dbc3" + version "2.2.0" + resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.2.0.tgz#38ac676151285b658654581987a0ce1a4490d286" throttleit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" -through2@^2.0.0: +through2@^2.0.0, through2@^2.0.2, through2@~2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" dependencies: readable-stream "^2.1.5" xtend "~4.0.1" -through@^2.3.6, through@^2.3.8, through@~2.3.8: +through@2, "through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" +time-zone@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/time-zone/-/time-zone-1.0.0.tgz#99c5bf55958966af6d06d83bdf3800dc82faec5d" + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + timers-browserify@^2.0.4: version "2.0.10" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" @@ -9492,17 +10706,21 @@ tiny-emitter@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c" -tiny-lr@^1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-1.0.5.tgz#21f40bf84ebd1f853056680375eef1670c334112" +tiny-lr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-1.1.1.tgz#9fa547412f238fedb068ee295af8b682c98b2aab" dependencies: body "^5.1.0" - debug "~2.6.7" + debug "^3.1.0" faye-websocket "~0.10.0" - livereload-js "^2.2.2" + livereload-js "^2.3.0" object-assign "^4.1.0" qs "^6.4.0" +tiny-relative-date@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07" + tinycolor2@^1.1.2: version "1.4.1" resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" @@ -9519,11 +10737,11 @@ tmp@^0.0.29: dependencies: os-tmpdir "~1.0.1" -tmp@^0.0.31: - version "0.0.31" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" dependencies: - os-tmpdir "~1.0.1" + os-tmpdir "~1.0.2" tmpl@1.0.x: version "1.0.4" @@ -9537,13 +10755,13 @@ to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" -to-fast-properties@^1.0.0, to-fast-properties@^1.0.1, to-fast-properties@^1.0.3: +to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" to-ico@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/to-ico/-/to-ico-1.1.4.tgz#b4c7b4afd2aa9fe65356c38c4bcb62e077de1ca7" + version "1.1.5" + resolved "https://registry.yarnpkg.com/to-ico/-/to-ico-1.1.5.tgz#1d32da5f2c90922edee6b686d610c54527b5a8d5" dependencies: arrify "^1.0.1" buffer-alloc "^1.1.0" @@ -9573,13 +10791,30 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -tough-cookie@~2.3.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" +tough-cookie@>=2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tough-cookie@~2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" dependencies: punycode "^1.4.1" -tree-sync@^1.2.1, tree-sync@^1.2.2: +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + +traverse@~0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" + +tree-sync@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-sync/-/tree-sync-1.2.2.tgz#2cf76b8589f59ffedb58db5a3ac7cb013d0158b7" dependencies: @@ -9593,7 +10828,15 @@ trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" -trim-right@^1.0.0, trim-right@^1.0.1: +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + +trim-off-newlines@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + +trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -9601,23 +10844,15 @@ trim@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" +triple-beam@^1.2.0, triple-beam@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" + "true-case-path@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62" - dependencies: - glob "^6.0.4" - -try-resolve@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/try-resolve/-/try-resolve-1.0.1.tgz#cfde6fabd72d63e5797cfaab873abbe8e700e912" - -tryit@^1.0.1: version "1.0.3" - resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" - -tryor@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/tryor/-/tryor-0.1.2.tgz#8145e4ca7caff40acde3ccf946e8b8bb75b4172b" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" + dependencies: + glob "^7.1.2" tslib@^1.9.0: version "1.9.3" @@ -9633,10 +10868,6 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tunnel-agent@~0.4.1: - version "0.4.3" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" - tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" @@ -9648,23 +10879,34 @@ type-check@~0.3.2: prelude-ls "~1.1.2" type-detect@^4.0.0: - version "4.0.7" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.7.tgz#862bd2cf6058ad92799ff5a5b8cf7b6cec726198" + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" -type-is@~1.6.15: - version "1.6.15" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" +type-is@~1.6.15, type-is@~1.6.16: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" dependencies: media-typer "0.3.0" - mime-types "~2.1.15" + mime-types "~2.1.18" -typedarray@^0.0.6, typedarray@~0.0.5: +typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -uc.micro@^1.0.1, uc.micro@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192" +typescript-eslint-parser@^16.0.0: + version "16.0.1" + resolved "https://registry.yarnpkg.com/typescript-eslint-parser/-/typescript-eslint-parser-16.0.1.tgz#b40681c7043b222b9772748b700a000b241c031b" + dependencies: + lodash.unescape "4.0.1" + semver "5.5.0" + +typescript@^2.5.1: + version "2.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c" + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.5.tgz#0c65f15f815aa08b560a61ce8b4db7ffc3f45376" uglify-es@^3.3.4: version "3.3.9" @@ -9675,24 +10917,18 @@ uglify-es@^3.3.4: uglify-js@1.x: version "1.3.5" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-1.3.5.tgz#4b5bfff9186effbaa888e4c9e94bd9fc4c94929d" + resolved "http://registry.npmjs.org/uglify-js/-/uglify-js-1.3.5.tgz#4b5bfff9186effbaa888e4c9e94bd9fc4c94929d" -uglify-js@^2.6, uglify-js@^2.7.0: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" +uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + commander "~2.17.1" + source-map "~0.6.1" uglifyjs-webpack-plugin@^1.2.4: - version "1.2.7" - resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.7.tgz#57638dd99c853a1ebfe9d97b42160a8a507f9d00" + version "1.3.0" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz#75f548160858163a08643e086d5fefe18a5d67de" dependencies: cacache "^10.0.4" find-cache-dir "^1.0.0" @@ -9703,13 +10939,17 @@ uglifyjs-webpack-plugin@^1.2.4: webpack-sources "^1.1.0" worker-farm "^1.5.2" -uid-number@^0.0.6: +uid-number@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" -ultron@1.0.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + +umask@^1.1.0, umask@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" underscore.string@~3.3.4: version "3.3.4" @@ -9719,8 +10959,8 @@ underscore.string@~3.3.4: util-deprecate "^1.0.2" underscore@>=1.8.3, underscore@^1.8.3: - version "1.8.3" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + version "1.9.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" underscore@~1.6.0: version "1.6.0" @@ -9735,7 +10975,7 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^0.4.3" -unique-filename@^1.1.0: +unique-filename@^1.1.0, unique-filename@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" dependencies: @@ -9754,8 +10994,8 @@ unique-string@^1.0.0: crypto-random-string "^1.0.0" universalify@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.0.tgz#9eb1c4651debcc670cc94f1a75762332bb967778" + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" @@ -9774,11 +11014,30 @@ untildify@^2.1.0: dependencies: os-homedir "^1.0.0" +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + upath@^1.0.5: version "1.1.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" -uri-js@^4.2.1: +update-notifier@^2.3.0, update-notifier@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" dependencies: @@ -9788,12 +11047,26 @@ urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" +url-join@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.0.tgz#4d3340e807d3773bda9991f8305acdcc2a665d2a" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + url-regex@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/url-regex/-/url-regex-3.2.0.tgz#dbad1e0c9e29e105dd0b1f09f6862f7fdb482724" dependencies: ip-regex "^1.0.1" +url-template@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" + url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -9802,20 +11075,8 @@ url@^0.11.0: querystring "0.2.0" use@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544" - dependencies: - kind-of "^6.0.2" - -user-home@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" - -user-home@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" - dependencies: - os-homedir "^1.0.0" + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" user-info@^1.0.0: version "1.0.0" @@ -9839,6 +11100,17 @@ util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" +util-extend@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" + +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -9851,36 +11123,38 @@ util@^0.10.3: dependencies: inherits "2.0.3" -utils-merge@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" -uuid@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" +uuid@^3.1.0, uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" -validate-npm-package-license@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" +validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" dependencies: - spdx-correct "~1.0.0" - spdx-expression-parse "~1.0.0" + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" -validate-npm-package-name@^3.0.0: +validate-npm-package-name@^3.0.0, validate-npm-package-name@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" dependencies: builtins "^1.0.3" -vary@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37" +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" -verror@1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" dependencies: - extsprintf "1.0.2" + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" vinyl@^1.1.0: version "1.2.0" @@ -9896,9 +11170,26 @@ vm-browserify@0.0.4: dependencies: indexof "0.0.1" -walk-sync@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.1.tgz#558a16aeac8c0db59c028b73c66f397684ece465" +vue-eslint-parser@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz#c268c96c6d94cfe3d938a5f7593959b0ca3360d1" + dependencies: + debug "^3.1.0" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.2" + esquery "^1.0.0" + lodash "^4.17.4" + +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + dependencies: + browser-process-hrtime "^0.1.2" + +walk-sync@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.2.tgz#4827280afc42d0e035367c4a4e31eeac0d136f75" dependencies: ensure-posix-path "^1.0.0" matcher-collection "^1.0.0" @@ -9914,9 +11205,9 @@ walk-sync@^0.2.5, walk-sync@^0.2.7: ensure-posix-path "^1.0.0" matcher-collection "^1.0.0" -walk-sync@^0.3.0, walk-sync@^0.3.1, walk-sync@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.2.tgz#4827280afc42d0e035367c4a4e31eeac0d136f75" +walk-sync@^0.3.0, walk-sync@^0.3.1, walk-sync@^0.3.2, walk-sync@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.3.tgz#1e9f12cd4fe6e0e6d4a0715b5cc7e30711d43cd1" dependencies: ensure-posix-path "^1.0.0" matcher-collection "^1.0.0" @@ -9927,9 +11218,22 @@ walker@1.x, walker@~1.0.5: dependencies: makeerror "1.0.x" -watch@~0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/watch/-/watch-0.10.0.tgz#77798b2da0f9910d595f1ace5b0c2258521f21dc" +watch-detector@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/watch-detector/-/watch-detector-0.1.0.tgz#e37b410d149e2a8bf263a4f8b71e2f667633dbf8" + dependencies: + heimdalljs-logger "^0.1.9" + quick-temp "^0.1.8" + rsvp "^4.7.0" + semver "^5.4.1" + silent-error "^1.1.0" + +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" watchpack@^1.5.0: version "1.6.0" @@ -9945,16 +11249,20 @@ wcwidth@^1.0.0, wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -webpack-sources@^1.0.1, webpack-sources@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + +webpack-sources@^1.1.0, webpack-sources@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.2.0.tgz#18181e0d013fce096faf6f8e6d41eeffffdceac2" dependencies: source-list-map "^2.0.0" source-map "~0.6.1" webpack@^4.12.0: - version "4.16.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.16.1.tgz#2c4b89ea648125c3e67bcca6adf49ce2c14b2d31" + version "4.17.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.17.2.tgz#49feb20205bd15f0a5f1fe0a12097d5d9931878d" dependencies: "@webassemblyjs/ast" "1.5.13" "@webassemblyjs/helper-module-context" "1.5.13" @@ -9980,60 +11288,99 @@ webpack@^4.12.0: tapable "^1.0.0" uglifyjs-webpack-plugin "^1.2.4" watchpack "^1.5.0" - webpack-sources "^1.0.1" + webpack-sources "^1.2.0" websocket-driver@>=0.5.1: - version "0.6.5" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" + version "0.7.0" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" dependencies: + http-parser-js ">=0.4.0" websocket-extensions ">=0.1.1" websocket-extensions@>=0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.1.tgz#76899499c184b6ef754377c2dbb0cd6cb55d29e7" + version "0.1.3" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.4.tgz#63fb016b7435b795d9025632c086a5209dbd2621" + dependencies: + iconv-lite "0.4.23" whatwg-fetch@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + +whatwg-mimetype@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz#f0f21d76cbba72362eb609dbed2a30cd17fcc7d4" + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" -which@1, which@^1.2.12, which@^1.2.9, which@~1.2.10: - version "1.2.14" - resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + +which@1, which@^1.2.10, which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" dependencies: isexe "^2.0.0" wide-align@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" dependencies: - string-width "^1.0.2" + string-width "^1.0.2 || 2" -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" +widest-line@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.0.tgz#0142a4e8a243f8882c0233aa0e0281aa76152273" + dependencies: + string-width "^2.1.1" -window-size@^0.1.2, window-size@^0.1.4: +window-size@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" -winston@*: - version "2.4.0" - resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.0.tgz#808050b93d52661ed9fb6c26b3f0c826708b0aee" +winston-transport@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.2.0.tgz#a20be89edf2ea2ca39ba25f3e50344d73e6520e5" dependencies: - async "~1.0.0" - colors "1.0.x" - cycle "1.0.x" - eyes "0.1.x" - isstream "0.1.x" - stack-trace "0.0.x" + readable-stream "^2.3.6" + triple-beam "^1.2.0" -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" +winston@*: + version "3.1.0" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.1.0.tgz#80724376aef164e024f316100d5b178d78ac5331" + dependencies: + async "^2.6.0" + diagnostics "^1.1.1" + is-stream "^1.1.0" + logform "^1.9.1" + one-time "0.0.4" + readable-stream "^2.3.6" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.2.0" wordwrap@~0.0.2: version "0.0.3" @@ -10043,27 +11390,21 @@ wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" -worker-farm@^1.5.2: +worker-farm@^1.5.2, worker-farm@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" dependencies: errno "~0.1.7" -workerpool@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-2.2.2.tgz#1cf53bacafd98ca5d808ff54cc72f3fecb5e1d56" - dependencies: - object-assign "4.1.1" - workerpool@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-2.3.0.tgz#86c5cbe946b55e7dc9d12b1936c8801a6e2d744d" + version "2.3.2" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-2.3.2.tgz#6bb17f31293e6b1e5e8dcdd5c2ad9122f471aaf3" dependencies: object-assign "4.1.1" wrap-ansi@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + resolved "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" @@ -10076,13 +11417,13 @@ wrench@1.3.x: version "1.3.9" resolved "https://registry.yarnpkg.com/wrench/-/wrench-1.3.9.tgz#6f13ec35145317eb292ca5f6531391b244111411" -write-file-atomic@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.1.0.tgz#1769f4b551eedce419f0505deae2e26763542d37" +write-file-atomic@^2.0.0, write-file-atomic@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" dependencies: graceful-fs "^4.1.11" imurmurhash "^0.1.4" - slide "^1.1.5" + signal-exit "^3.0.2" write@^0.2.1: version "0.2.1" @@ -10090,54 +11431,63 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.1.tgz#082ddb6c641e85d4bb451f03d52f06eabdb1f018" +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" dependencies: - options ">=0.0.5" - ultron "1.0.x" + async-limiter "~1.0.0" -wtf-8@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a" +ws@~3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" xhr@^2.0.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.4.0.tgz#e16e66a45f869861eeefab416d5eff722dc40993" + version "2.5.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" dependencies: global "~4.3.0" is-function "^1.0.1" parse-headers "^2.0.0" xtend "^4.0.0" +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + xml-parse-from-string@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" xml2js@>=0.2.4, xml2js@^0.4.5: - version "0.4.17" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.17.tgz#17be93eaae3f3b779359c795b419705a8817e868" + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" dependencies: sax ">=0.6.0" - xmlbuilder "^4.1.0" + xmlbuilder "~9.0.1" -xmlbuilder@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" - dependencies: - lodash "^4.0.0" +xmlbuilder@~9.0.1: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" xmldom@^0.1.19: version "0.1.27" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" -xmlhttprequest-ssl@1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d" +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + +xregexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" xstate@^3.3.3: version "3.3.3" @@ -10151,7 +11501,7 @@ y18n@^3.2.0, y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" -y18n@^4.0.0: +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" @@ -10163,16 +11513,16 @@ yallist@^3.0.0, yallist@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" -yam@0.0.22: - version "0.0.22" - resolved "https://registry.yarnpkg.com/yam/-/yam-0.0.22.tgz#38a76cb79a19284d9206ed49031e359a1340bd06" +yam@^0.0.24: + version "0.0.24" + resolved "https://registry.yarnpkg.com/yam/-/yam-0.0.24.tgz#11e9630444735f66a561d29221407de6d037cd95" dependencies: - fs-extra "^0.30.0" - lodash.merge "^4.4.0" + fs-extra "^4.0.2" + lodash.merge "^4.6.0" -yargs-parser@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.0.0.tgz#c737c93de2567657750cb1f2c00be639fd19c994" +yargs-parser@^10.0.0, yargs-parser@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" dependencies: camelcase "^4.1.0" @@ -10182,9 +11532,72 @@ yargs-parser@^5.0.0: dependencies: camelcase "^3.0.0" +yargs-parser@^8.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" + dependencies: + camelcase "^4.1.0" + +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + dependencies: + camelcase "^4.1.0" + +yargs@10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae" + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^8.0.0" + +yargs@^11.0.0: + version "11.1.0" + resolved "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^9.0.2" + +yargs@^12.0.0: + version "12.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc" + dependencies: + cliui "^4.0.0" + decamelize "^2.0.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^10.1.0" + yargs@^3.31.0: version "3.32.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" + resolved "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" dependencies: camelcase "^2.0.1" cliui "^3.0.3" @@ -10194,7 +11607,7 @@ yargs@^3.31.0: window-size "^0.1.4" y18n "^3.2.0" -yargs@^7.0.0, yargs@^7.1.0: +yargs@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" dependencies: @@ -10212,26 +11625,6 @@ yargs@^7.0.0, yargs@^7.1.0: y18n "^3.2.1" yargs-parser "^5.0.0" -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" - -yargs@~3.27.0: - version "3.27.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.27.0.tgz#21205469316e939131d59f2da0c6d7f98221ea40" - dependencies: - camelcase "^1.2.1" - cliui "^2.1.0" - decamelize "^1.0.0" - os-locale "^1.4.0" - window-size "^0.1.2" - y18n "^3.2.0" - yauzl@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005"