diff --git a/.eslintrc.js b/.eslintrc.js index 393d7668f45..73a80c91254 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,48 +1,48 @@ module.exports = { - root: true, - parserOptions: { - ecmaVersion: 2017, - sourceType: 'module', - ecmaFeatures: { - experimentalObjectRestSpread: true, - }, + root: true, + parserOptions: { + ecmaVersion: 2017, + sourceType: 'module', + ecmaFeatures: { + experimentalObjectRestSpread: true, }, - plugins: ['ember', 'prettier'], - extends: ['eslint:recommended', 'plugin:ember/recommended', 'plugin:prettier/recommended'], - env: { - browser: true, - }, - rules: { - 'prettier/prettier': 'error', + }, + plugins: ['ember', 'prettier'], + extends: ['eslint:recommended', 'plugin:ember/recommended', 'plugin:prettier/recommended'], + env: { + browser: true, + }, + rules: { + 'prettier/prettier': 'error', - 'arrow-parens': 'off', - 'brace-style': 'off', - camelcase: 'off', - 'comma-dangle': 'off', - 'dot-notation': 'off', - 'operator-linebreak': 'off', + 'arrow-parens': 'off', + 'brace-style': 'off', + camelcase: 'off', + 'comma-dangle': 'off', + 'dot-notation': 'off', + 'operator-linebreak': 'off', + }, + overrides: [ + // node files + { + files: [ + '.eslintrc.js', + '.template-lintrc.js', + 'ember-cli-build.js', + 'testem.js', + 'blueprints/*/index.js', + 'config/**/*.js', + 'lib/*/index.js', + 'server/**/*.js', + ], + parserOptions: { + sourceType: 'script', + ecmaVersion: 2015, + }, + env: { + browser: false, + node: true, + }, }, - overrides: [ - // node files - { - files: [ - '.eslintrc.js', - '.template-lintrc.js', - 'ember-cli-build.js', - 'testem.js', - 'blueprints/*/index.js', - 'config/**/*.js', - 'lib/*/index.js', - 'server/**/*.js', - ], - parserOptions: { - sourceType: 'script', - ecmaVersion: 2015, - }, - env: { - browser: false, - node: true, - }, - }, - ], + ], }; diff --git a/.template-lintrc.js b/.template-lintrc.js index e5d16f8327a..1691cf83d5b 100644 --- a/.template-lintrc.js +++ b/.template-lintrc.js @@ -3,11 +3,11 @@ /* eslint-env node */ module.exports = { - extends: 'recommended', + extends: 'recommended', - rules: { - 'block-indentation': false, - 'img-alt-attributes': false, - 'triple-curlies': false, - }, + rules: { + 'img-alt-attributes': false, + 'triple-curlies': false, + 'html-comments': false, + }, }; diff --git a/.travis.yml b/.travis.yml index 4b41efa0acd..6c4a4797e32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,6 +59,7 @@ matrix: - npm ci before_script: skip script: + - npm run lint:hbs - npm run lint:js - npm run lint:deps - npm test diff --git a/app/adapters/api-token.js b/app/adapters/api-token.js index f956848b701..1c7e6f33e4e 100644 --- a/app/adapters/api-token.js +++ b/app/adapters/api-token.js @@ -1,17 +1,17 @@ import DS from 'ember-data'; export default DS.RESTAdapter.extend({ - namespace: 'api/v1/me', - pathForType() { - return 'tokens'; - }, - createRecord(store, type, snapshot) { - let data = {}; - let serializer = store.serializerFor(type.modelName); - let url = this.buildURL(type.modelName, null, snapshot, 'createRecord'); + namespace: 'api/v1/me', + pathForType() { + return 'tokens'; + }, + createRecord(store, type, snapshot) { + let data = {}; + let serializer = store.serializerFor(type.modelName); + let url = this.buildURL(type.modelName, null, snapshot, 'createRecord'); - serializer.serializeIntoHash(data, type, snapshot, { includeId: true }); + serializer.serializeIntoHash(data, type, snapshot, { includeId: true }); - return this.ajax(url, 'PUT', { data }); - }, + return this.ajax(url, 'PUT', { data }); + }, }); diff --git a/app/adapters/application.js b/app/adapters/application.js index 6858d92982c..7940faa0966 100644 --- a/app/adapters/application.js +++ b/app/adapters/application.js @@ -2,5 +2,5 @@ import DS from 'ember-data'; import AdapterFetch from 'ember-fetch/mixins/adapter-fetch'; export default DS.RESTAdapter.extend(AdapterFetch, { - namespace: 'api/v1', + namespace: 'api/v1', }); diff --git a/app/adapters/category-slug.js b/app/adapters/category-slug.js index cf88cff590c..2d55e5e32aa 100644 --- a/app/adapters/category-slug.js +++ b/app/adapters/category-slug.js @@ -4,8 +4,8 @@ import { underscore, decamelize } from '@ember/string'; import ApplicationAdapter from './application'; export default ApplicationAdapter.extend({ - pathForType(modelName) { - let decamelized = underscore(decamelize(modelName)); - return pluralize(decamelized); - }, + pathForType(modelName) { + let decamelized = underscore(decamelize(modelName)); + return pluralize(decamelized); + }, }); diff --git a/app/adapters/crate-owner-invite.js b/app/adapters/crate-owner-invite.js index 582f4eb1e25..ad99112db29 100644 --- a/app/adapters/crate-owner-invite.js +++ b/app/adapters/crate-owner-invite.js @@ -1,8 +1,8 @@ import DS from 'ember-data'; export default DS.RESTAdapter.extend({ - namespace: 'api/v1/me', - pathForType() { - return 'crate_owner_invitations'; - }, + namespace: 'api/v1/me', + pathForType() { + return 'crate_owner_invitations'; + }, }); diff --git a/app/adapters/crate.js b/app/adapters/crate.js index 20504968b1d..3e0f8cd9dfb 100644 --- a/app/adapters/crate.js +++ b/app/adapters/crate.js @@ -1,35 +1,35 @@ import ApplicationAdapter from './application'; export default ApplicationAdapter.extend({ - follow(id) { - return this.ajax(this.urlForFollowAction(id), 'PUT'); - }, + follow(id) { + return this.ajax(this.urlForFollowAction(id), 'PUT'); + }, - inviteOwner(id, username) { - return this.ajax(this.urlForOwnerAction(id), 'PUT', { - data: { - owners: [username], - }, - }); - }, + inviteOwner(id, username) { + return this.ajax(this.urlForOwnerAction(id), 'PUT', { + data: { + owners: [username], + }, + }); + }, - removeOwner(id, username) { - return this.ajax(this.urlForOwnerAction(id), 'DELETE', { - data: { - owners: [username], - }, - }); - }, + removeOwner(id, username) { + return this.ajax(this.urlForOwnerAction(id), 'DELETE', { + data: { + owners: [username], + }, + }); + }, - unfollow(id) { - return this.ajax(this.urlForFollowAction(id), 'DELETE'); - }, + unfollow(id) { + return this.ajax(this.urlForFollowAction(id), 'DELETE'); + }, - urlForFollowAction(id) { - return `${this.buildURL('crate', id)}/follow`; - }, + urlForFollowAction(id) { + return `${this.buildURL('crate', id)}/follow`; + }, - urlForOwnerAction(id) { - return `${this.buildURL('crate', id)}/owners`; - }, + urlForOwnerAction(id) { + return `${this.buildURL('crate', id)}/owners`; + }, }); diff --git a/app/adapters/dependency.js b/app/adapters/dependency.js index bf6c5db25af..9e2d5a086ed 100644 --- a/app/adapters/dependency.js +++ b/app/adapters/dependency.js @@ -1,13 +1,13 @@ import ApplicationAdapter from './application'; export default ApplicationAdapter.extend({ - query(store, type, query) { - if (!query.reverse) { - return this._super(...arguments); - } - delete query.reverse; - let { crate } = query; - delete query.crate; - return this.ajax(`/${this.urlPrefix()}/crates/${crate.get('id')}/reverse_dependencies`, 'GET', { data: query }); - }, + query(store, type, query) { + if (!query.reverse) { + return this._super(...arguments); + } + delete query.reverse; + let { crate } = query; + delete query.crate; + return this.ajax(`/${this.urlPrefix()}/crates/${crate.get('id')}/reverse_dependencies`, 'GET', { data: query }); + }, }); diff --git a/app/adapters/team.js b/app/adapters/team.js index 8f4738e298b..e92de43a614 100644 --- a/app/adapters/team.js +++ b/app/adapters/team.js @@ -1,8 +1,8 @@ import ApplicationAdapter from './application'; export default ApplicationAdapter.extend({ - queryRecord(store, type, query) { - let url = this.urlForFindRecord(query.team_id, 'team'); - return this.ajax(url, 'GET'); - }, + queryRecord(store, type, query) { + let url = this.urlForFindRecord(query.team_id, 'team'); + return this.ajax(url, 'GET'); + }, }); diff --git a/app/adapters/user.js b/app/adapters/user.js index ba343fc4cfd..0517c69951d 100644 --- a/app/adapters/user.js +++ b/app/adapters/user.js @@ -1,16 +1,16 @@ import ApplicationAdapter from './application'; export default ApplicationAdapter.extend({ - stats(id) { - return this.ajax(this.urlForStatsAction(id), 'GET'); - }, + stats(id) { + return this.ajax(this.urlForStatsAction(id), 'GET'); + }, - urlForStatsAction(id) { - return `${this.buildURL('user', id)}/stats`; - }, + urlForStatsAction(id) { + return `${this.buildURL('user', id)}/stats`; + }, - queryRecord(store, type, query) { - let url = this.urlForFindRecord(query.user_id, 'user'); - return this.ajax(url, 'GET'); - }, + queryRecord(store, type, query) { + let url = this.urlForFindRecord(query.user_id, 'user'); + return this.ajax(url, 'GET'); + }, }); diff --git a/app/app.js b/app/app.js index ffb39911076..ddd13a0ff68 100644 --- a/app/app.js +++ b/app/app.js @@ -5,9 +5,9 @@ import loadInitializers from 'ember-load-initializers'; import config from './config/environment'; const App = Application.extend({ - modulePrefix: config.modulePrefix, - podModulePrefix: config.podModulePrefix, - Resolver, + modulePrefix: config.modulePrefix, + podModulePrefix: config.podModulePrefix, + Resolver, }); loadInitializers(App, config.modulePrefix); diff --git a/app/components/api-token-row.js b/app/components/api-token-row.js index 5a8066ceea9..eb8255a63ef 100644 --- a/app/components/api-token-row.js +++ b/app/components/api-token-row.js @@ -2,44 +2,44 @@ import Component from '@ember/component'; import { empty, or } from '@ember/object/computed'; export default Component.extend({ - emptyName: empty('api_token.name'), - disableCreate: or('api_token.isSaving', 'emptyName'), - serverError: null, + emptyName: empty('api_token.name'), + disableCreate: or('api_token.isSaving', 'emptyName'), + serverError: null, - didInsertElement() { - if (this.get('api_token.isNew')) { - this.$('input').focus(); + didInsertElement() { + if (this.get('api_token.isNew')) { + this.$('input').focus(); + } + }, + + actions: { + async saveToken() { + try { + await this.api_token.save(); + this.set('serverError', null); + } catch (err) { + let msg; + if (err.errors && err.errors[0] && err.errors[0].detail) { + msg = `An error occurred while saving this token, ${err.errors[0].detail}`; + } else { + msg = 'An unknown error occurred while saving this token'; } + this.set('serverError', msg); + } }, - actions: { - async saveToken() { - try { - await this.api_token.save(); - this.set('serverError', null); - } catch (err) { - let msg; - if (err.errors && err.errors[0] && err.errors[0].detail) { - msg = `An error occurred while saving this token, ${err.errors[0].detail}`; - } else { - msg = 'An unknown error occurred while saving this token'; - } - this.set('serverError', msg); - } - }, - - async revokeToken() { - try { - await this.api_token.destroyRecord(); - } catch (err) { - let msg; - if (err.errors && err.errors[0] && err.errors[0].detail) { - msg = `An error occurred while revoking this token, ${err.errors[0].detail}`; - } else { - msg = 'An unknown error occurred while revoking this token'; - } - this.set('serverError', msg); - } - }, + async revokeToken() { + try { + await this.api_token.destroyRecord(); + } catch (err) { + let msg; + if (err.errors && err.errors[0] && err.errors[0].detail) { + msg = `An error occurred while revoking this token, ${err.errors[0].detail}`; + } else { + msg = 'An unknown error occurred while revoking this token'; + } + this.set('serverError', msg); + } }, + }, }); diff --git a/app/components/badge-appveyor.js b/app/components/badge-appveyor.js index fc25c203810..72e52f54162 100644 --- a/app/components/badge-appveyor.js +++ b/app/components/badge-appveyor.js @@ -3,40 +3,38 @@ import { computed } from '@ember/object'; import { alias } from '@ember/object/computed'; export default Component.extend({ - tagName: 'span', - classNames: ['badge'], - - id: alias('badge.attributes.id'), - repository: alias('badge.attributes.repository'), - - imageUrl: computed('badge.attributes.id', function() { - let id = this.get('badge.attributes.id'); - let branch = this.branch; - if (id !== undefined && id !== null) { - return `https://ci.appveyor.com/api/projects/status/${id}/branch/${branch}?svg=true`; - } else { - let service = this.service; - let repository = this.repository; - - return `https://ci.appveyor.com/api/projects/status/${service}/${repository}?svg=true&branch=${branch}`; - } - }), - - branch: computed('badge.attributes.branch', function() { - return this.get('badge.attributes.branch') || 'master'; - }), - - projectName: computed('badge.attributes.project_name', function() { - return ( - this.get('badge.attributes.project_name') || this.get('badge.attributes.repository').replace(/[_.]/g, '-') - ); - }), - - service: computed('badge.attributes.service', function() { - return this.get('badge.attributes.service') || 'github'; - }), - - text: computed('badge', function() { - return `Appveyor build status for the ${this.branch} branch`; - }), + tagName: 'span', + classNames: ['badge'], + + id: alias('badge.attributes.id'), + repository: alias('badge.attributes.repository'), + + imageUrl: computed('badge.attributes.id', function() { + let id = this.get('badge.attributes.id'); + let branch = this.branch; + if (id !== undefined && id !== null) { + return `https://ci.appveyor.com/api/projects/status/${id}/branch/${branch}?svg=true`; + } else { + let service = this.service; + let repository = this.repository; + + return `https://ci.appveyor.com/api/projects/status/${service}/${repository}?svg=true&branch=${branch}`; + } + }), + + branch: computed('badge.attributes.branch', function() { + return this.get('badge.attributes.branch') || 'master'; + }), + + projectName: computed('badge.attributes.project_name', function() { + return this.get('badge.attributes.project_name') || this.get('badge.attributes.repository').replace(/[_.]/g, '-'); + }), + + service: computed('badge.attributes.service', function() { + return this.get('badge.attributes.service') || 'github'; + }), + + text: computed('badge', function() { + return `Appveyor build status for the ${this.branch} branch`; + }), }); diff --git a/app/components/badge-azure-devops.js b/app/components/badge-azure-devops.js index 89335afd9f1..16dd7b1a3e6 100644 --- a/app/components/badge-azure-devops.js +++ b/app/components/badge-azure-devops.js @@ -3,14 +3,14 @@ import { computed } from '@ember/object'; import { alias } from '@ember/object/computed'; export default Component.extend({ - tagName: 'span', - classNames: ['badge'], - project: alias('badge.attributes.project'), - pipeline: alias('badge.attributes.pipeline'), - build: computed('badge.attributes.build', function() { - return this.get('badge.attributes.build') || '1'; - }), - text: computed('pipeline', function() { - return `Azure Devops build status for the ${this.pipeline} pipeline`; - }), + tagName: 'span', + classNames: ['badge'], + project: alias('badge.attributes.project'), + pipeline: alias('badge.attributes.pipeline'), + build: computed('badge.attributes.build', function() { + return this.get('badge.attributes.build') || '1'; + }), + text: computed('pipeline', function() { + return `Azure Devops build status for the ${this.pipeline} pipeline`; + }), }); diff --git a/app/components/badge-circle-ci.js b/app/components/badge-circle-ci.js index 0af66e4acb9..f3d40695892 100644 --- a/app/components/badge-circle-ci.js +++ b/app/components/badge-circle-ci.js @@ -3,13 +3,13 @@ import { alias } from '@ember/object/computed'; import Component from '@ember/component'; export default Component.extend({ - tagName: 'span', - classNames: ['badge'], - repository: alias('badge.attributes.repository'), - branch: computed('badge.attributes.branch', function() { - return encodeURIComponent(this.get('badge.attributes.branch') || 'master'); - }), - text: computed('branch', function() { - return `Circle CI build status for the ${this.branch} branch`; - }), + tagName: 'span', + classNames: ['badge'], + repository: alias('badge.attributes.repository'), + branch: computed('badge.attributes.branch', function() { + return encodeURIComponent(this.get('badge.attributes.branch') || 'master'); + }), + text: computed('branch', function() { + return `Circle CI build status for the ${this.branch} branch`; + }), }); diff --git a/app/components/badge-cirrus-ci.js b/app/components/badge-cirrus-ci.js index 62a3db4e328..93229669396 100644 --- a/app/components/badge-cirrus-ci.js +++ b/app/components/badge-cirrus-ci.js @@ -3,13 +3,13 @@ import { alias } from '@ember/object/computed'; import Component from '@ember/component'; export default Component.extend({ - tagName: 'span', - classNames: ['badge'], - repository: alias('badge.attributes.repository'), - branch: computed('badge.attributes.branch', function() { - return encodeURIComponent(this.get('badge.attributes.branch') || 'master'); - }), - text: computed('branch', function() { - return `Cirrus CI build status for the ${this.branch} branch`; - }), + tagName: 'span', + classNames: ['badge'], + repository: alias('badge.attributes.repository'), + branch: computed('badge.attributes.branch', function() { + return encodeURIComponent(this.get('badge.attributes.branch') || 'master'); + }), + text: computed('branch', function() { + return `Cirrus CI build status for the ${this.branch} branch`; + }), }); diff --git a/app/components/badge-codecov.js b/app/components/badge-codecov.js index caa3429194a..90f30bb6201 100644 --- a/app/components/badge-codecov.js +++ b/app/components/badge-codecov.js @@ -3,16 +3,16 @@ import { computed } from '@ember/object'; import { alias } from '@ember/object/computed'; export default Component.extend({ - tagName: 'span', - classNames: ['badge'], - repository: alias('badge.attributes.repository'), - branch: computed('badge.attributes.branch', function() { - return this.get('badge.attributes.branch') || 'master'; - }), - service: computed('badge.attributes.service', function() { - return this.get('badge.attributes.service') || 'github'; - }), - text: computed('branch', function() { - return `CodeCov coverage status for the ${this.branch} branch`; - }), + tagName: 'span', + classNames: ['badge'], + repository: alias('badge.attributes.repository'), + branch: computed('badge.attributes.branch', function() { + return this.get('badge.attributes.branch') || 'master'; + }), + service: computed('badge.attributes.service', function() { + return this.get('badge.attributes.service') || 'github'; + }), + text: computed('branch', function() { + return `CodeCov coverage status for the ${this.branch} branch`; + }), }); diff --git a/app/components/badge-coveralls.js b/app/components/badge-coveralls.js index 8596f9f77ba..ee4dfaf17e5 100644 --- a/app/components/badge-coveralls.js +++ b/app/components/badge-coveralls.js @@ -3,16 +3,16 @@ import { computed } from '@ember/object'; import { alias } from '@ember/object/computed'; export default Component.extend({ - tagName: 'span', - classNames: ['badge'], - repository: alias('badge.attributes.repository'), - branch: computed('badge.attributes.branch', function() { - return this.get('badge.attributes.branch') || 'master'; - }), - service: computed('badge.attributes.service', function() { - return this.get('badge.attributes.service') || 'github'; - }), - text: computed('branch', function() { - return `Coveralls coverage status for the ${this.branch} branch`; - }), + tagName: 'span', + classNames: ['badge'], + repository: alias('badge.attributes.repository'), + branch: computed('badge.attributes.branch', function() { + return this.get('badge.attributes.branch') || 'master'; + }), + service: computed('badge.attributes.service', function() { + return this.get('badge.attributes.service') || 'github'; + }), + text: computed('branch', function() { + return `Coveralls coverage status for the ${this.branch} branch`; + }), }); diff --git a/app/components/badge-gitlab.js b/app/components/badge-gitlab.js index 98d5f1fae86..e3e00cf27e1 100644 --- a/app/components/badge-gitlab.js +++ b/app/components/badge-gitlab.js @@ -3,13 +3,13 @@ import { computed } from '@ember/object'; import { alias } from '@ember/object/computed'; export default Component.extend({ - tagName: 'span', - classNames: ['badge'], - repository: alias('badge.attributes.repository'), - branch: computed('badge.attributes.branch', function() { - return this.get('badge.attributes.branch') || 'master'; - }), - text: computed('badge', function() { - return `GitLab build status for the ${this.branch} branch`; - }), + tagName: 'span', + classNames: ['badge'], + repository: alias('badge.attributes.repository'), + branch: computed('badge.attributes.branch', function() { + return this.get('badge.attributes.branch') || 'master'; + }), + text: computed('badge', function() { + return `GitLab build status for the ${this.branch} branch`; + }), }); diff --git a/app/components/badge-is-it-maintained-issue-resolution.js b/app/components/badge-is-it-maintained-issue-resolution.js index a131e01868b..67c3b5252ff 100644 --- a/app/components/badge-is-it-maintained-issue-resolution.js +++ b/app/components/badge-is-it-maintained-issue-resolution.js @@ -3,10 +3,10 @@ import { computed } from '@ember/object'; import { alias } from '@ember/object/computed'; export default Component.extend({ - tagName: 'span', - classNames: ['badge'], - repository: alias('badge.attributes.repository'), - text: computed('badge', function() { - return `Is It Maintained average time to resolve an issue`; - }), + tagName: 'span', + classNames: ['badge'], + repository: alias('badge.attributes.repository'), + text: computed('badge', function() { + return `Is It Maintained average time to resolve an issue`; + }), }); diff --git a/app/components/badge-is-it-maintained-open-issues.js b/app/components/badge-is-it-maintained-open-issues.js index 5695dcca856..813a0e60428 100644 --- a/app/components/badge-is-it-maintained-open-issues.js +++ b/app/components/badge-is-it-maintained-open-issues.js @@ -3,10 +3,10 @@ import { computed } from '@ember/object'; import { alias } from '@ember/object/computed'; export default Component.extend({ - tagName: 'span', - classNames: ['badge'], - repository: alias('badge.attributes.repository'), - text: computed('badge', function() { - return `Is It Maintained percentage of issues still open`; - }), + tagName: 'span', + classNames: ['badge'], + repository: alias('badge.attributes.repository'), + text: computed('badge', function() { + return `Is It Maintained percentage of issues still open`; + }), }); diff --git a/app/components/badge-maintenance.js b/app/components/badge-maintenance.js index 70473376ae0..327b0bd769b 100644 --- a/app/components/badge-maintenance.js +++ b/app/components/badge-maintenance.js @@ -3,30 +3,30 @@ import { computed } from '@ember/object'; import { alias } from '@ember/object/computed'; export default Component.extend({ - tagName: 'span', - classNames: ['badge'], - escapedStatus: computed('badge', function() { - return this.get('badge.attributes.status').replace(/-/g, '--'); - }), - none: computed('badge', function() { - return this.get('badge.attributes.status') === 'none' || !this.get('badge.attributes.status'); - }), - status: alias('badge.attributes.status'), - color: computed('badge', function() { - switch (this.get('badge.attributes.status')) { - case 'actively-developed': - return 'brightgreen'; - case 'passively-maintained': - return 'yellowgreen'; - case 'as-is': - return 'yellow'; - case 'experimental': - return 'blue'; - case 'looking-for-maintainer': - return 'orange'; - case 'deprecated': - return 'red'; - } - }), - text: 'Maintenance intention for this crate', + tagName: 'span', + classNames: ['badge'], + escapedStatus: computed('badge', function() { + return this.get('badge.attributes.status').replace(/-/g, '--'); + }), + none: computed('badge', function() { + return this.get('badge.attributes.status') === 'none' || !this.get('badge.attributes.status'); + }), + status: alias('badge.attributes.status'), + color: computed('badge', function() { + switch (this.get('badge.attributes.status')) { + case 'actively-developed': + return 'brightgreen'; + case 'passively-maintained': + return 'yellowgreen'; + case 'as-is': + return 'yellow'; + case 'experimental': + return 'blue'; + case 'looking-for-maintainer': + return 'orange'; + case 'deprecated': + return 'red'; + } + }), + text: 'Maintenance intention for this crate', }); diff --git a/app/components/badge-travis-ci.js b/app/components/badge-travis-ci.js index a4562265e16..3650c7951b0 100644 --- a/app/components/badge-travis-ci.js +++ b/app/components/badge-travis-ci.js @@ -3,13 +3,13 @@ import { computed } from '@ember/object'; import { alias } from '@ember/object/computed'; export default Component.extend({ - tagName: 'span', - classNames: ['badge'], - repository: alias('badge.attributes.repository'), - branch: computed('badge.attributes.branch', function() { - return this.get('badge.attributes.branch') || 'master'; - }), - text: computed('branch', function() { - return `Travis CI build status for the ${this.branch} branch`; - }), + tagName: 'span', + classNames: ['badge'], + repository: alias('badge.attributes.repository'), + branch: computed('badge.attributes.branch', function() { + return this.get('badge.attributes.branch') || 'master'; + }), + text: computed('branch', function() { + return `Travis CI build status for the ${this.branch} branch`; + }), }); diff --git a/app/components/crate-badge.js b/app/components/crate-badge.js index 7b1f8feaafb..30e30257d65 100644 --- a/app/components/crate-badge.js +++ b/app/components/crate-badge.js @@ -2,19 +2,19 @@ import Component from '@ember/component'; import { computed } from '@ember/object'; export default Component.extend({ - classNames: ['vers'], + classNames: ['vers'], - tagName: 'span', + tagName: 'span', - version: computed('crate.max_version', function() { - return this.get('crate.max_version').replace('-', '--'); - }), + version: computed('crate.max_version', function() { + return this.get('crate.max_version').replace('-', '--'); + }), - color: computed('crate.max_version', function() { - if (this.get('crate.max_version')[0] == '0') { - return 'orange'; - } else { - return 'blue'; - } - }), + color: computed('crate.max_version', function() { + if (this.get('crate.max_version')[0] == '0') { + return 'orange'; + } else { + return 'blue'; + } + }), }); diff --git a/app/components/crate-readme.js b/app/components/crate-readme.js index 9aa88e6ab7f..513647ec05a 100644 --- a/app/components/crate-readme.js +++ b/app/components/crate-readme.js @@ -1,11 +1,11 @@ import Component from '@ember/component'; export default Component.extend({ - rendered: '', - didRender() { - this._super(...arguments); - this.$('pre > code').each(function() { - window.Prism.highlightElement(this); - }); - }, + rendered: '', + didRender() { + this._super(...arguments); + this.$('pre > code').each(function() { + window.Prism.highlightElement(this); + }); + }, }); diff --git a/app/components/crate-row.js b/app/components/crate-row.js index e395f9f98e3..84b9ce752bc 100644 --- a/app/components/crate-row.js +++ b/app/components/crate-row.js @@ -1,7 +1,7 @@ import Component from '@ember/component'; export default Component.extend({ - classNames: ['crate', 'row'], + classNames: ['crate', 'row'], - 'data-test-crate-row': true, + 'data-test-crate-row': true, }); diff --git a/app/components/download-graph.js b/app/components/download-graph.js index 56c1bf2f7f0..3682d29e246 100644 --- a/app/components/download-graph.js +++ b/app/components/download-graph.js @@ -4,174 +4,174 @@ import Component from '@ember/component'; const COLORS = ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#92c5de', '#4393c3', '#2166ac', '#053061']; export default Component.extend({ - classNames: 'graph-data', - resizeHandler: undefined, - - didInsertElement() { - this._super(...arguments); - - this.resizeHandler = () => this.rerender(); - window.addEventListener('resize', this.resizeHandler, false); - document.addEventListener('googleChartsLoaded', this.resizeHandler, false); - }, - - willDestroyElement() { - window.removeEventListener('resize', this.resizeHandler); - document.removeEventListener('googleChartsLoaded', this.resizeHandler); - }, - - didRender() { - this._super(...arguments); - - let data = this.data; - - let subarray_length = (data[1] || []).length; - - // Start at 1 to skip the date element in the 0th - // location in the array. - for (let k = 1; k < subarray_length; k++) { - let on = false; - - // Start at 1 because the 0th entry in the array - // is an array of version numbers. - // - // End before the last element is reached because we never - // want to change the last element. - for (let i = 1; i < data.length - 1; i++) { - // k + 1 because the first entry in the array is the date - let value = data[i][k]; - - // If we are "off" and are looking at a zero - // replace the data at this point with `null`. - // - // Null tells google.visualization to stop drawing - // the line altogether. - if (!on && value === 0) { - data[i][k] = null; - } - - // If we are off and the value is not zero, we - // need to turn back on. (keep the value the same though) - else if (!on && value !== 0) { - on = true; - - // We previously wrote a null into data[i - 1][k + 1], - // so to make the graph look pretty, we'll switch it back - // to the zero that it was before. - if (i >= 2) { - data[i - 1][k] = 0; - } - } - // If we are on and the value is zero, turn off - // but keep the zero in the array - else if (on && value === 0) { - on = false; - } - } + classNames: 'graph-data', + resizeHandler: undefined, + + didInsertElement() { + this._super(...arguments); + + this.resizeHandler = () => this.rerender(); + window.addEventListener('resize', this.resizeHandler, false); + document.addEventListener('googleChartsLoaded', this.resizeHandler, false); + }, + + willDestroyElement() { + window.removeEventListener('resize', this.resizeHandler); + document.removeEventListener('googleChartsLoaded', this.resizeHandler); + }, + + didRender() { + this._super(...arguments); + + let data = this.data; + + let subarray_length = (data[1] || []).length; + + // Start at 1 to skip the date element in the 0th + // location in the array. + for (let k = 1; k < subarray_length; k++) { + let on = false; + + // Start at 1 because the 0th entry in the array + // is an array of version numbers. + // + // End before the last element is reached because we never + // want to change the last element. + for (let i = 1; i < data.length - 1; i++) { + // k + 1 because the first entry in the array is the date + let value = data[i][k]; + + // If we are "off" and are looking at a zero + // replace the data at this point with `null`. + // + // Null tells google.visualization to stop drawing + // the line altogether. + if (!on && value === 0) { + data[i][k] = null; } - let show = data && window.google && window.googleChartsLoaded; - this.element.style.display = show ? '' : 'none'; - if (!show) { - return; + // If we are off and the value is not zero, we + // need to turn back on. (keep the value the same though) + else if (!on && value !== 0) { + on = true; + + // We previously wrote a null into data[i - 1][k + 1], + // so to make the graph look pretty, we'll switch it back + // to the zero that it was before. + if (i >= 2) { + data[i - 1][k] = 0; + } } + // If we are on and the value is zero, turn off + // but keep the zero in the array + else if (on && value === 0) { + on = false; + } + } + } - let myData = window.google.visualization.arrayToDataTable(data); - - let dateFmt = new window.google.visualization.DateFormat({ - pattern: 'LLL d, yyyy', - }); - dateFmt.format(myData, 0); - - // Create a formatter to use for daily download numbers - let numberFormatWhole = new window.google.visualization.NumberFormat({ - pattern: '#,##0', - }); - - // Create a formatter to use for 7-day average numbers - let numberFormatDecimal = new window.google.visualization.NumberFormat({ - pattern: '#,##0.0', - }); - - // use a DataView to calculate an x-day moving average - let days = 7; - let view = new window.google.visualization.DataView(myData); - let moving_avg_func_for_col = function(col) { - return function(dt, row) { - // For the last rows (the *first* days, remember, the dataset is - // backwards), we cannot calculate the avg. of previous days. - if (row >= dt.getNumberOfRows() - days) { - return null; - } - - let total = 0; - for (let i = days; i > 0; i--) { - total += dt.getValue(row + i, col); - } - let avg = total / days; - return { - v: avg, - f: numberFormatDecimal.formatValue(avg), - }; - }; - }; + let show = data && window.google && window.googleChartsLoaded; + this.element.style.display = show ? '' : 'none'; + if (!show) { + return; + } - let columns = [0]; // 0 = datetime - let seriesOption = {}; - let [headers] = data; - // Walk over the headers/colums in reverse order, as the newest version - // is at the end, but in the UI we want it at the top of the chart legend. - - range(headers.length - 1, 0, -1).forEach((dataCol, i) => { - // Set the number format for the colum in the data table. - numberFormatWhole.format(myData, dataCol); - columns.push(dataCol); // add the column itself - columns.push({ - // add a 'calculated' column, the moving average - type: 'number', - label: `${headers[dataCol]} ${days}-day avg.`, - calc: moving_avg_func_for_col(dataCol), - }); - // Note: while the columns start with index 1 (because 0 is the time - // axis), the series configuration starts with index 0. - seriesOption[i * 2] = { - type: 'scatter', - color: COLORS[i % COLORS.length], - pointSize: 3, - pointShape: 'square', - }; - seriesOption[i * 2 + 1] = { - type: 'area', - color: COLORS[i % COLORS.length], - lineWidth: 2, - curveType: 'function', - visibleInLegend: false, - }; - }); - view.setColumns(columns); - - let chart = new window.google.visualization.ComboChart(this.element); - chart.draw(view, { - chartArea: { left: 85, width: '77%', height: '80%' }, - hAxis: { - minorGridlines: { count: 8 }, - }, - vAxis: { - minorGridlines: { count: 5 }, - viewWindow: { min: 0 }, - }, - isStacked: true, - focusTarget: 'category', - seriesType: 'scatter', - series: seriesOption, - }); - }, + let myData = window.google.visualization.arrayToDataTable(data); + + let dateFmt = new window.google.visualization.DateFormat({ + pattern: 'LLL d, yyyy', + }); + dateFmt.format(myData, 0); + + // Create a formatter to use for daily download numbers + let numberFormatWhole = new window.google.visualization.NumberFormat({ + pattern: '#,##0', + }); + + // Create a formatter to use for 7-day average numbers + let numberFormatDecimal = new window.google.visualization.NumberFormat({ + pattern: '#,##0.0', + }); + + // use a DataView to calculate an x-day moving average + let days = 7; + let view = new window.google.visualization.DataView(myData); + let moving_avg_func_for_col = function(col) { + return function(dt, row) { + // For the last rows (the *first* days, remember, the dataset is + // backwards), we cannot calculate the avg. of previous days. + if (row >= dt.getNumberOfRows() - days) { + return null; + } + + let total = 0; + for (let i = days; i > 0; i--) { + total += dt.getValue(row + i, col); + } + let avg = total / days; + return { + v: avg, + f: numberFormatDecimal.formatValue(avg), + }; + }; + }; + + let columns = [0]; // 0 = datetime + let seriesOption = {}; + let [headers] = data; + // Walk over the headers/colums in reverse order, as the newest version + // is at the end, but in the UI we want it at the top of the chart legend. + + range(headers.length - 1, 0, -1).forEach((dataCol, i) => { + // Set the number format for the colum in the data table. + numberFormatWhole.format(myData, dataCol); + columns.push(dataCol); // add the column itself + columns.push({ + // add a 'calculated' column, the moving average + type: 'number', + label: `${headers[dataCol]} ${days}-day avg.`, + calc: moving_avg_func_for_col(dataCol), + }); + // Note: while the columns start with index 1 (because 0 is the time + // axis), the series configuration starts with index 0. + seriesOption[i * 2] = { + type: 'scatter', + color: COLORS[i % COLORS.length], + pointSize: 3, + pointShape: 'square', + }; + seriesOption[i * 2 + 1] = { + type: 'area', + color: COLORS[i % COLORS.length], + lineWidth: 2, + curveType: 'function', + visibleInLegend: false, + }; + }); + view.setColumns(columns); + + let chart = new window.google.visualization.ComboChart(this.element); + chart.draw(view, { + chartArea: { left: 85, width: '77%', height: '80%' }, + hAxis: { + minorGridlines: { count: 8 }, + }, + vAxis: { + minorGridlines: { count: 5 }, + viewWindow: { min: 0 }, + }, + isStacked: true, + focusTarget: 'category', + seriesType: 'scatter', + series: seriesOption, + }); + }, }); function range(start, end, step) { - let array = []; - for (let i = start; i !== end; i += step) { - array.push(i); - } - return array; + let array = []; + for (let i = start; i !== end; i += step) { + array.push(i); + } + return array; } diff --git a/app/components/email-input.js b/app/components/email-input.js index 0c95afdae2e..641f6434c8b 100644 --- a/app/components/email-input.js +++ b/app/components/email-input.js @@ -5,108 +5,109 @@ import { inject as service } from '@ember/service'; import ajax from 'ember-fetch/ajax'; export default Component.extend({ - flashMessages: service(), + flashMessages: service(), - type: '', - value: '', - isEditing: false, - user: null, - disableSave: empty('user.email'), - notValidEmail: false, - prevEmail: '', - emailIsNull: computed('user.email', function() { - let email = this.get('user.email'); - return email == null; - }), - emailNotVerified: computed('user.{email,email_verified}', function() { - let email = this.get('user.email'); - let verified = this.get('user.email_verified'); + type: '', + value: '', + isEditing: false, + user: null, + disableSave: empty('user.email'), + notValidEmail: false, + prevEmail: '', + emailIsNull: computed('user.email', function() { + let email = this.get('user.email'); + return email == null; + }), + emailNotVerified: computed('user.{email,email_verified}', function() { + let email = this.get('user.email'); + let verified = this.get('user.email_verified'); - return email != null && !verified; - }), - isError: false, - emailError: '', - disableResend: false, - resendButtonText: computed('disableResend', 'user.email_verification_sent', function() { - if (this.disableResend) { - return 'Sent!'; - } else if (this.get('user.email_verification_sent')) { - return 'Resend'; - } else { - return 'Send verification email'; - } - }), + return email != null && !verified; + }), + isError: false, + emailError: '', + disableResend: false, + resendButtonText: computed('disableResend', 'user.email_verification_sent', function() { + if (this.disableResend) { + return 'Sent!'; + } else if (this.get('user.email_verification_sent')) { + return 'Resend'; + } else { + return 'Send verification email'; + } + }), - actions: { - editEmail() { - let email = this.value; - let isEmailNull = function(email) { - return email == null; - }; + actions: { + editEmail() { + let email = this.value; + let isEmailNull = function(email) { + return email == null; + }; - this.set('emailIsNull', isEmailNull(email)); - this.set('isEditing', true); - this.set('prevEmail', this.value); - }, + this.set('emailIsNull', isEmailNull(email)); + this.set('isEditing', true); + this.set('prevEmail', this.value); + }, - saveEmail() { - let userEmail = this.value; - let user = this.user; + saveEmail() { + let userEmail = this.value; + let user = this.user; - let emailIsProperFormat = function(userEmail) { - let regExp = /^\S+@\S+\.\S+$/; - return regExp.test(userEmail); - }; + let emailIsProperFormat = function(userEmail) { + let regExp = /^\S+@\S+\.\S+$/; + return regExp.test(userEmail); + }; - if (!emailIsProperFormat(userEmail)) { - this.set('notValidEmail', true); - return; - } + if (!emailIsProperFormat(userEmail)) { + this.set('notValidEmail', true); + return; + } - user.set('email', userEmail); - user.save() - .then(() => { - this.set('serverError', null); - this.set('user.email_verification_sent', true); - this.set('user.email_verified', false); - }) - .catch(err => { - let msg; - if (err.errors && err.errors[0] && err.errors[0].detail) { - msg = `An error occurred while saving this email, ${err.errors[0].detail}`; - } else { - msg = 'An unknown error occurred while saving this email.'; - } - this.set('serverError', msg); - this.set('isError', true); - this.set('emailError', `Error in saving email: ${msg}`); - }); + user.set('email', userEmail); + user + .save() + .then(() => { + this.set('serverError', null); + this.set('user.email_verification_sent', true); + this.set('user.email_verified', false); + }) + .catch(err => { + let msg; + if (err.errors && err.errors[0] && err.errors[0].detail) { + msg = `An error occurred while saving this email, ${err.errors[0].detail}`; + } else { + msg = 'An unknown error occurred while saving this email.'; + } + this.set('serverError', msg); + this.set('isError', true); + this.set('emailError', `Error in saving email: ${msg}`); + }); - this.set('isEditing', false); - this.set('notValidEmail', false); - this.set('disableResend', false); - }, + this.set('isEditing', false); + this.set('notValidEmail', false); + this.set('disableResend', false); + }, - cancelEdit() { - this.set('isEditing', false); - this.set('value', this.prevEmail); - }, + cancelEdit() { + this.set('isEditing', false); + this.set('value', this.prevEmail); + }, - async resendEmail() { - let user = this.user; + async resendEmail() { + let user = this.user; - try { - await ajax(`/api/v1/users/${user.id}/resend`, { method: 'PUT' }); - this.set('disableResend', true); - } catch (error) { - if (error.payload) { - this.set('isError', true); - this.set('emailError', `Error in resending message: ${error.payload.errors[0].detail}`); - } else { - this.set('isError', true); - this.set('emailError', 'Unknown error in resending message'); - } - } - }, + try { + await ajax(`/api/v1/users/${user.id}/resend`, { method: 'PUT' }); + this.set('disableResend', true); + } catch (error) { + if (error.payload) { + this.set('isError', true); + this.set('emailError', `Error in resending message: ${error.payload.errors[0].detail}`); + } else { + this.set('isError', true); + this.set('emailError', 'Unknown error in resending message'); + } + } }, + }, }); diff --git a/app/components/flash-message.js b/app/components/flash-message.js index 27567632a98..ef807af025a 100644 --- a/app/components/flash-message.js +++ b/app/components/flash-message.js @@ -3,10 +3,10 @@ import { readOnly } from '@ember/object/computed'; import { inject as service } from '@ember/service'; export default Component.extend({ - flashMessages: service(), - message: readOnly('flashMessages.message'), + flashMessages: service(), + message: readOnly('flashMessages.message'), - elementId: 'flash', - tagName: 'p', - classNameBindings: ['message:shown'], + elementId: 'flash', + tagName: 'p', + classNameBindings: ['message:shown'], }); diff --git a/app/components/google-jsapi.js b/app/components/google-jsapi.js index db35067b8ab..50feacf7e41 100644 --- a/app/components/google-jsapi.js +++ b/app/components/google-jsapi.js @@ -1,26 +1,26 @@ import Component from '@ember/component'; function createEvent(name) { - let event = document.createEvent('Event'); - event.initEvent(name, true, true); - return event; + let event = document.createEvent('Event'); + event.initEvent(name, true, true); + return event; } export default Component.extend({ - tagName: '', + tagName: '', - didInsertElement() { - let script = document.createElement('script'); - script.onload = () => { - window.google.load('visualization', '1.0', { - packages: ['corechart'], - callback() { - window.googleChartsLoaded = true; - document.dispatchEvent(createEvent('googleChartsLoaded')); - }, - }); - }; - document.body.appendChild(script); - script.src = 'https://www.google.com/jsapi'; - }, + didInsertElement() { + let script = document.createElement('script'); + script.onload = () => { + window.google.load('visualization', '1.0', { + packages: ['corechart'], + callback() { + window.googleChartsLoaded = true; + document.dispatchEvent(createEvent('googleChartsLoaded')); + }, + }); + }; + document.body.appendChild(script); + script.src = 'https://www.google.com/jsapi'; + }, }); diff --git a/app/components/pending-owner-invite-row.js b/app/components/pending-owner-invite-row.js index c330822d0b3..0fe78fc1cfa 100644 --- a/app/components/pending-owner-invite-row.js +++ b/app/components/pending-owner-invite-row.js @@ -1,42 +1,42 @@ import Component from '@ember/component'; export default Component.extend({ - isAccepted: false, - isDeclined: false, - isError: false, - inviteError: 'default error message', + isAccepted: false, + isDeclined: false, + isError: false, + inviteError: 'default error message', - actions: { - async acceptInvitation(invite) { - invite.set('accepted', true); + actions: { + async acceptInvitation(invite) { + invite.set('accepted', true); - try { - await invite.save(); - this.set('isAccepted', true); - } catch (error) { - this.set('isError', true); - if (error.payload) { - this.set('inviteError', `Error in accepting invite: ${error.payload.errors[0].detail}`); - } else { - this.set('inviteError', 'Error in accepting invite'); - } - } - }, + try { + await invite.save(); + this.set('isAccepted', true); + } catch (error) { + this.set('isError', true); + if (error.payload) { + this.set('inviteError', `Error in accepting invite: ${error.payload.errors[0].detail}`); + } else { + this.set('inviteError', 'Error in accepting invite'); + } + } + }, - async declineInvitation(invite) { - invite.set('accepted', false); + async declineInvitation(invite) { + invite.set('accepted', false); - try { - await invite.save(); - this.set('isDeclined', true); - } catch (error) { - this.set('isError', true); - if (error.payload) { - this.set('inviteError', `Error in declining invite: ${error.payload.errors[0].detail}`); - } else { - this.set('inviteError', 'Error in declining invite'); - } - } - }, + try { + await invite.save(); + this.set('isDeclined', true); + } catch (error) { + this.set('isError', true); + if (error.payload) { + this.set('inviteError', `Error in declining invite: ${error.payload.errors[0].detail}`); + } else { + this.set('inviteError', 'Error in declining invite'); + } + } }, + }, }); diff --git a/app/components/rl-dropdown-container.js b/app/components/rl-dropdown-container.js index e12592c5384..909d64a8b78 100644 --- a/app/components/rl-dropdown-container.js +++ b/app/components/rl-dropdown-container.js @@ -3,5 +3,5 @@ import Component from '@ember/component'; import DropdownComponentMixin from '../mixins/rl-dropdown-component'; export default Component.extend(DropdownComponentMixin, { - classNameBindings: ['dropdownExpanded'], + classNameBindings: ['dropdownExpanded'], }); diff --git a/app/components/rl-dropdown-toggle.js b/app/components/rl-dropdown-toggle.js index 049f3f4235c..380db2f7846 100644 --- a/app/components/rl-dropdown-toggle.js +++ b/app/components/rl-dropdown-toggle.js @@ -4,39 +4,39 @@ import { computed } from '@ember/object'; import RlDropdownContainer from './rl-dropdown-container'; export default Component.extend({ - classNames: ['rl-dropdown-toggle'], + classNames: ['rl-dropdown-toggle'], - tagName: 'button', + tagName: 'button', - attributeBindings: ['type', 'role', 'disabled'], + attributeBindings: ['type', 'role', 'disabled'], - type: computed('tagName', function() { - return this.tagName === 'button' ? 'button' : null; - }), + type: computed('tagName', function() { + return this.tagName === 'button' ? 'button' : null; + }), - role: computed('tagName', function() { - return this.tagName === 'a' ? 'button' : null; - }), + role: computed('tagName', function() { + return this.tagName === 'a' ? 'button' : null; + }), - dropdownContainer: computed(function() { - return this.nearestOfType(RlDropdownContainer); - }), + dropdownContainer: computed(function() { + return this.nearestOfType(RlDropdownContainer); + }), - action: 'toggleDropdown', + action: 'toggleDropdown', - propagateClicks: true, + propagateClicks: true, - disabled: false, + disabled: false, - click(event) { - if (!this.disabled) { - let propagateClicks = this.propagateClicks; + click(event) { + if (!this.disabled) { + let propagateClicks = this.propagateClicks; - this.dropdownContainer.send(this.action); + this.dropdownContainer.send(this.action); - if (propagateClicks === false || propagateClicks === 'false') { - event.stopPropagation(); - } - } - }, + if (propagateClicks === false || propagateClicks === 'false') { + event.stopPropagation(); + } + } + }, }); diff --git a/app/components/rl-dropdown.js b/app/components/rl-dropdown.js index 2c6934290b3..be9b398f7a7 100644 --- a/app/components/rl-dropdown.js +++ b/app/components/rl-dropdown.js @@ -6,35 +6,35 @@ import $ from 'jquery'; import RlDropdownContainer from './rl-dropdown-container'; export default Component.extend({ - classNames: ['rl-dropdown'], - classNameBindings: ['isExpanded:open'], + classNames: ['rl-dropdown'], + classNameBindings: ['isExpanded:open'], - dropdownContainer: computed(function() { - return this.nearestOfType(RlDropdownContainer); - }), + dropdownContainer: computed(function() { + return this.nearestOfType(RlDropdownContainer); + }), - isExpanded: alias('dropdownContainer.dropdownExpanded'), + isExpanded: alias('dropdownContainer.dropdownExpanded'), - closeOnChildClick: false, + closeOnChildClick: false, - propagateClicks: true, + propagateClicks: true, - click(event) { - let closeOnChildClick = this.closeOnChildClick; - let propagateClicks = this.propagateClicks; - let $target = $(event.target); - let $c = this.$(); + click(event) { + let closeOnChildClick = this.closeOnChildClick; + let propagateClicks = this.propagateClicks; + let $target = $(event.target); + let $c = this.$(); - if ($target !== $c) { - if ((closeOnChildClick === true || closeOnChildClick === 'true') && $target.closest($c).length) { - this.set('isExpanded', false); - } else if (closeOnChildClick && $target.closest(closeOnChildClick, $c).length) { - this.set('isExpanded', false); - } - } + if ($target !== $c) { + if ((closeOnChildClick === true || closeOnChildClick === 'true') && $target.closest($c).length) { + this.set('isExpanded', false); + } else if (closeOnChildClick && $target.closest(closeOnChildClick, $c).length) { + this.set('isExpanded', false); + } + } - if (propagateClicks === false || propagateClicks === 'false') { - event.stopPropagation(); - } - }, + if (propagateClicks === false || propagateClicks === 'false') { + event.stopPropagation(); + } + }, }); diff --git a/app/components/user-avatar.js b/app/components/user-avatar.js index ee6b8249b56..ef98e9af231 100644 --- a/app/components/user-avatar.js +++ b/app/components/user-avatar.js @@ -3,28 +3,28 @@ import Component from '@ember/component'; import { computed } from '@ember/object'; export default Component.extend({ - size: 'small', - user: null, - attributeBindings: ['src', 'width', 'height', 'alt'], - tagName: 'img', + size: 'small', + user: null, + attributeBindings: ['src', 'width', 'height', 'alt'], + tagName: 'img', - width: computed('size', function() { - if (this.size === 'small') { - return 22; - } else if (this.size === 'medium-small') { - return 32; - } else { - return 85; // medium - } - }), + width: computed('size', function() { + if (this.size === 'small') { + return 22; + } else if (this.size === 'medium-small') { + return 32; + } else { + return 85; // medium + } + }), - height: readOnly('width'), + height: readOnly('width'), - alt: computed('user', function() { - return `${this.get('user.name')} (${this.get('user.login')})`; - }), + alt: computed('user', function() { + return `${this.get('user.name')} (${this.get('user.login')})`; + }), - src: computed('size', 'user', function() { - return `${this.get('user.avatar')}&s=${this.width * 2}`; - }), + src: computed('size', 'user', function() { + return `${this.get('user.avatar')}&s=${this.width * 2}`; + }), }); diff --git a/app/components/user-link.js b/app/components/user-link.js index 814fbb7f6f7..37cfd84baea 100644 --- a/app/components/user-link.js +++ b/app/components/user-link.js @@ -2,13 +2,13 @@ import { readOnly } from '@ember/object/computed'; import Component from '@ember/component'; export default Component.extend({ - user: null, - attributeBindings: ['title', 'href'], - tagName: 'a', + user: null, + attributeBindings: ['title', 'href'], + tagName: 'a', - title: readOnly('user.login'), + title: readOnly('user.login'), - // TODO replace this with a link to a native crates.io profile - // page when they exist. - href: readOnly('user.url'), + // TODO replace this with a link to a native crates.io profile + // page when they exist. + href: readOnly('user.url'), }); diff --git a/app/components/validated-input.js b/app/components/validated-input.js index bdea206ce91..f40807b8f63 100644 --- a/app/components/validated-input.js +++ b/app/components/validated-input.js @@ -3,36 +3,36 @@ import Component from '@ember/component'; import { defineProperty } from '@ember/object'; export default Component.extend({ - classNames: ['validated-input'], - classNameBindings: ['showErrorClass:has-error', 'isValid:has-success'], - model: null, - value: null, - type: 'text', - valuePath: '', - placeholder: '', - validation: null, - showValidations: false, - didValidate: false, + classNames: ['validated-input'], + classNameBindings: ['showErrorClass:has-error', 'isValid:has-success'], + model: null, + value: null, + type: 'text', + valuePath: '', + placeholder: '', + validation: null, + showValidations: false, + didValidate: false, - notValidating: not('validation.isValidating').readOnly(), - hasContent: notEmpty('value').readOnly(), - hasWarnings: notEmpty('validation.warnings').readOnly(), - isValid: and('hasContent', 'validation.isTruelyValid').readOnly(), - shouldDisplayValidations: or('showValidations', 'didValidate', 'hasContent').readOnly(), + notValidating: not('validation.isValidating').readOnly(), + hasContent: notEmpty('value').readOnly(), + hasWarnings: notEmpty('validation.warnings').readOnly(), + isValid: and('hasContent', 'validation.isTruelyValid').readOnly(), + shouldDisplayValidations: or('showValidations', 'didValidate', 'hasContent').readOnly(), - showErrorClass: and('notValidating', 'showErrorMessage', 'hasContent', 'validation').readOnly(), - showErrorMessage: and('shouldDisplayValidations', 'validation.isInvalid').readOnly(), + showErrorClass: and('notValidating', 'showErrorMessage', 'hasContent', 'validation').readOnly(), + showErrorMessage: and('shouldDisplayValidations', 'validation.isInvalid').readOnly(), - init() { - this._super(...arguments); - let valuePath = this.valuePath; + init() { + this._super(...arguments); + let valuePath = this.valuePath; - defineProperty(this, 'validation', readOnly(`model.validations.attrs.${valuePath}`)); - defineProperty(this, 'value', alias(`model.${valuePath}`)); - }, + defineProperty(this, 'validation', readOnly(`model.validations.attrs.${valuePath}`)); + defineProperty(this, 'value', alias(`model.${valuePath}`)); + }, - focusOut() { - this._super(...arguments); - this.set('showValidations', true); - }, + focusOut() { + this._super(...arguments); + this.set('showValidations', true); + }, }); diff --git a/app/controllers/application.js b/app/controllers/application.js index f7ccf93eaf4..8d8216d7424 100644 --- a/app/controllers/application.js +++ b/app/controllers/application.js @@ -5,31 +5,31 @@ import { EKMixin, keyDown, keyPress } from 'ember-keyboard'; import { on } from '@ember/object/evented'; export default Controller.extend(EKMixin, { - search: service(), - searchQuery: oneWay('search.q'), - session: service(), + search: service(), + searchQuery: oneWay('search.q'), + session: service(), - keyboardActivated: true, + keyboardActivated: true, - focusSearch: on(keyDown('KeyS'), keyPress('KeyS'), keyDown('shift+KeyS'), function(event) { - if (event.ctrlKey || event.altKey || event.metaKey) { - return; - } + focusSearch: on(keyDown('KeyS'), keyPress('KeyS'), keyDown('shift+KeyS'), function(event) { + if (event.ctrlKey || event.altKey || event.metaKey) { + return; + } - if (document.activeElement === document.body) { - event.preventDefault(); - document.querySelector('#cargo-desktop-search').focus(); - } - }), + if (document.activeElement === document.body) { + event.preventDefault(); + document.querySelector('#cargo-desktop-search').focus(); + } + }), - actions: { - search() { - this.transitionToRoute('search', { - queryParams: { - q: this.searchQuery, - page: 1, - }, - }); + actions: { + search() { + this.transitionToRoute('search', { + queryParams: { + q: this.searchQuery, + page: 1, }, + }); }, + }, }); diff --git a/app/controllers/catch-all.js b/app/controllers/catch-all.js index 4e5ecb1f2b9..2005430f146 100644 --- a/app/controllers/catch-all.js +++ b/app/controllers/catch-all.js @@ -1,9 +1,9 @@ import Controller from '@ember/controller'; export default Controller.extend({ - actions: { - search(query) { - return this.transitionToRoute('search', { queryParams: { q: query } }); - }, + actions: { + search(query) { + return this.transitionToRoute('search', { queryParams: { q: query } }); }, + }, }); diff --git a/app/controllers/categories.js b/app/controllers/categories.js index 56ce1b6feb2..625c2e9529d 100644 --- a/app/controllers/categories.js +++ b/app/controllers/categories.js @@ -5,14 +5,14 @@ import { computed } from '@ember/object'; import PaginationMixin from '../mixins/pagination'; export default Controller.extend(PaginationMixin, { - queryParams: ['page', 'per_page', 'sort'], - page: '1', - per_page: 100, - sort: 'alpha', + queryParams: ['page', 'per_page', 'sort'], + page: '1', + per_page: 100, + sort: 'alpha', - totalItems: readOnly('model.meta.total'), + totalItems: readOnly('model.meta.total'), - currentSortBy: computed('sort', function() { - return this.sort === 'crates' ? '# Crates' : 'Alphabetical'; - }), + currentSortBy: computed('sort', function() { + return this.sort === 'crates' ? '# Crates' : 'Alphabetical'; + }), }); diff --git a/app/controllers/category/index.js b/app/controllers/category/index.js index 2e4d091ac1a..b74e744555b 100644 --- a/app/controllers/category/index.js +++ b/app/controllers/category/index.js @@ -5,24 +5,24 @@ import { computed } from '@ember/object'; import PaginationMixin from '../../mixins/pagination'; export default Controller.extend(PaginationMixin, { - queryParams: ['page', 'per_page', 'sort'], - page: '1', - per_page: 10, - sort: 'recent-downloads', + queryParams: ['page', 'per_page', 'sort'], + page: '1', + per_page: 10, + sort: 'recent-downloads', - totalItems: readOnly('model.meta.total'), + totalItems: readOnly('model.meta.total'), - category: null, + category: null, - currentSortBy: computed('sort', function() { - if (this.sort === 'downloads') { - return 'All-Time Downloads'; - } else if (this.sort === 'alpha') { - return 'Alphabetical'; - } else if (this.get('sort') === 'recent-updates') { - return 'Recent Updates'; - } else { - return 'Recent Downloads'; - } - }), + currentSortBy: computed('sort', function() { + if (this.sort === 'downloads') { + return 'All-Time Downloads'; + } else if (this.sort === 'alpha') { + return 'Alphabetical'; + } else if (this.get('sort') === 'recent-updates') { + return 'Recent Updates'; + } else { + return 'Recent Downloads'; + } + }), }); diff --git a/app/controllers/crate/owners.js b/app/controllers/crate/owners.js index bfdab8da2c6..3f56a4d472f 100644 --- a/app/controllers/crate/owners.js +++ b/app/controllers/crate/owners.js @@ -1,51 +1,51 @@ import Controller from '@ember/controller'; export default Controller.extend({ - crate: null, - error: false, - invited: false, - removed: false, - username: '', - - actions: { - async addOwner() { - this.set('error', false); - this.set('invited', false); - - const username = this.username; - - if (!username) { - this.set('error', 'Please enter a username'); - return false; - } - - try { - await this.crate.inviteOwner(username); - this.set('invited', `An invite has been sent to ${username}`); - } catch (error) { - if (error.payload) { - this.set('error', `Error sending invite: ${error.payload.errors[0].detail}`); - } else { - this.set('error', 'Error sending invite'); - } - } - }, - - async removeOwner(user) { - this.set('removed', false); - - try { - await this.crate.removeOwner(user.get('login')); - this.set('removed', `User ${user.get('login')} removed as crate owner`); - - this.get('crate.owner_user').removeObject(user); - } catch (error) { - if (error.payload) { - this.set('removed', `Error removing owner: ${error.payload.errors[0].detail}`); - } else { - this.set('removed', 'Error removing owner'); - } - } - }, + crate: null, + error: false, + invited: false, + removed: false, + username: '', + + actions: { + async addOwner() { + this.set('error', false); + this.set('invited', false); + + const username = this.username; + + if (!username) { + this.set('error', 'Please enter a username'); + return false; + } + + try { + await this.crate.inviteOwner(username); + this.set('invited', `An invite has been sent to ${username}`); + } catch (error) { + if (error.payload) { + this.set('error', `Error sending invite: ${error.payload.errors[0].detail}`); + } else { + this.set('error', 'Error sending invite'); + } + } }, + + async removeOwner(user) { + this.set('removed', false); + + try { + await this.crate.removeOwner(user.get('login')); + this.set('removed', `User ${user.get('login')} removed as crate owner`); + + this.get('crate.owner_user').removeObject(user); + } catch (error) { + if (error.payload) { + this.set('removed', `Error removing owner: ${error.payload.errors[0].detail}`); + } else { + this.set('removed', 'Error removing owner'); + } + } + }, + }, }); diff --git a/app/controllers/crate/reverse-dependencies.js b/app/controllers/crate/reverse-dependencies.js index cc668f1f0ef..ab3aafb5a9c 100644 --- a/app/controllers/crate/reverse-dependencies.js +++ b/app/controllers/crate/reverse-dependencies.js @@ -4,10 +4,10 @@ import { readOnly } from '@ember/object/computed'; import PaginationMixin from '../../mixins/pagination'; export default Controller.extend(PaginationMixin, { - queryParams: ['page', 'per_page'], - page: '1', - per_page: 10, - crate: null, + queryParams: ['page', 'per_page'], + page: '1', + per_page: 10, + crate: null, - totalItems: readOnly('model.meta.total'), + totalItems: readOnly('model.meta.total'), }); diff --git a/app/controllers/crate/version.js b/app/controllers/crate/version.js index 5aefab120dc..685cd18110c 100644 --- a/app/controllers/crate/version.js +++ b/app/controllers/crate/version.js @@ -12,190 +12,188 @@ const NUM_VERSIONS = 5; const PromiseArray = ArrayProxy.extend(PromiseProxyMixin); export default Controller.extend({ - session: service(), - - isDownloading: false, - - downloadsContext: computed('requestedVersion', 'model', 'crate', function() { - return this.requestedVersion ? this.model : this.crate; - }), - downloads: alias('downloadsContext.version_downloads'), - extraDownloads: alias('downloads.content.meta.extra_downloads'), - - fetchingFollowing: true, - following: false, - currentVersion: alias('model'), - requestedVersion: null, - keywords: alias('crate.keywords'), - categories: alias('crate.categories'), - badges: alias('crate.badges'), - isOwner: computed('crate.owner_user', 'session.currentUser.id', function() { - return this.get('crate.owner_user').findBy('id', this.get('session.currentUser.id')); - }), - notYankedOrIsOwner: computed('model', 'crate.owner_user', 'session.currentUser.id', function() { - return ( - !this.get('model').yanked || this.get('crate.owner_user').findBy('id', this.get('session.currentUser.id')) - ); - }), - - sortedVersions: readOnly('crate.versions'), - - smallSortedVersions: computed('sortedVersions', function() { - return this.sortedVersions.slice(0, NUM_VERSIONS); - }), - - hasMoreVersions: gt('sortedVersions.length', NUM_VERSIONS), - - displayedAuthors: computed('currentVersion.authors.[]', function() { - return PromiseArray.create({ - promise: this.get('currentVersion.authors').then(authors => { - let ret = authors.slice(); - let others = authors.get('meta'); - for (let i = 0; i < others.names.length; i++) { - ret.push({ name: others.names[i] }); - } - return ret; - }), - }); - }), - - anyKeywords: gt('keywords.length', 0), - anyCategories: gt('categories.length', 0), - - currentDependencies: computed('currentVersion.dependencies', function() { - let deps = this.get('currentVersion.dependencies'); - - if (deps === null) { - return []; + session: service(), + + isDownloading: false, + + downloadsContext: computed('requestedVersion', 'model', 'crate', function() { + return this.requestedVersion ? this.model : this.crate; + }), + downloads: alias('downloadsContext.version_downloads'), + extraDownloads: alias('downloads.content.meta.extra_downloads'), + + fetchingFollowing: true, + following: false, + currentVersion: alias('model'), + requestedVersion: null, + keywords: alias('crate.keywords'), + categories: alias('crate.categories'), + badges: alias('crate.badges'), + isOwner: computed('crate.owner_user', 'session.currentUser.id', function() { + return this.get('crate.owner_user').findBy('id', this.get('session.currentUser.id')); + }), + notYankedOrIsOwner: computed('model', 'crate.owner_user', 'session.currentUser.id', function() { + return !this.get('model').yanked || this.get('crate.owner_user').findBy('id', this.get('session.currentUser.id')); + }), + + sortedVersions: readOnly('crate.versions'), + + smallSortedVersions: computed('sortedVersions', function() { + return this.sortedVersions.slice(0, NUM_VERSIONS); + }), + + hasMoreVersions: gt('sortedVersions.length', NUM_VERSIONS), + + displayedAuthors: computed('currentVersion.authors.[]', function() { + return PromiseArray.create({ + promise: this.get('currentVersion.authors').then(authors => { + let ret = authors.slice(); + let others = authors.get('meta'); + for (let i = 0; i < others.names.length; i++) { + ret.push({ name: others.names[i] }); } - - return PromiseArray.create({ - promise: deps.then(deps => { - return deps.filter(dep => dep.get('kind') !== 'dev').uniqBy('crate_id'); - }), - }); - }), - - currentDevDependencies: computed('currentVersion.dependencies', function() { - let deps = this.get('currentVersion.dependencies'); - if (deps === null) { - return []; - } - return PromiseArray.create({ - promise: deps.then(deps => { - return deps.filterBy('kind', 'dev'); - }), - }); - }), - - downloadData: computed('downloads', 'extraDownloads', 'requestedVersion', function() { - let downloads = this.downloads; - if (!downloads) { - return; - } - - let extra = this.extraDownloads || []; - - let dates = {}; - let versions = []; - for (let i = 0; i < 90; i++) { - let now = moment().subtract(i, 'days'); - dates[now.format('MMM D')] = { date: now, cnt: {} }; - } - - downloads.forEach(d => { - let version_id = d.get('version.id'); - let key = moment(d.get('date')) - .utc() - .format('MMM D'); - if (dates[key]) { - let prev = dates[key].cnt[version_id] || 0; - dates[key].cnt[version_id] = prev + d.get('downloads'); - } - }); - - extra.forEach(d => { - let key = moment(d.date) - .utc() - .format('MMM D'); - if (dates[key]) { - let prev = dates[key].cnt[null] || 0; - dates[key].cnt[null] = prev + d.downloads; - } - }); - if (this.requestedVersion) { - versions.push(this.model.getProperties('id', 'num')); - } else { - this.smallSortedVersions.forEach(version => { - versions.push(version.getProperties('id', 'num')); - }); - } - if (extra.length > 0) { - versions.push({ - id: null, - num: 'Other', - }); - } - - let headers = ['Date']; - versions.sort(b => b.num).reverse(); - for (let i = 0; i < versions.length; i++) { - headers.push(versions[i].num); - } - let data = [headers]; - for (let date in dates) { - let row = [dates[date].date.toDate()]; - for (let i = 0; i < versions.length; i++) { - row.push(dates[date].cnt[versions[i].id] || 0); - } - data.push(row); - } - - return data; - }), - - toggleClipboardProps(isSuccess) { - this.setProperties({ - showSuccess: isSuccess, - showNotification: true, - }); - later( - this, - () => { - this.set('showNotification', false); - }, - 2000, - ); + return ret; + }), + }); + }), + + anyKeywords: gt('keywords.length', 0), + anyCategories: gt('categories.length', 0), + + currentDependencies: computed('currentVersion.dependencies', function() { + let deps = this.get('currentVersion.dependencies'); + + if (deps === null) { + return []; + } + + return PromiseArray.create({ + promise: deps.then(deps => { + return deps.filter(dep => dep.get('kind') !== 'dev').uniqBy('crate_id'); + }), + }); + }), + + currentDevDependencies: computed('currentVersion.dependencies', function() { + let deps = this.get('currentVersion.dependencies'); + if (deps === null) { + return []; + } + return PromiseArray.create({ + promise: deps.then(deps => { + return deps.filterBy('kind', 'dev'); + }), + }); + }), + + downloadData: computed('downloads', 'extraDownloads', 'requestedVersion', function() { + let downloads = this.downloads; + if (!downloads) { + return; + } + + let extra = this.extraDownloads || []; + + let dates = {}; + let versions = []; + for (let i = 0; i < 90; i++) { + let now = moment().subtract(i, 'days'); + dates[now.format('MMM D')] = { date: now, cnt: {} }; + } + + downloads.forEach(d => { + let version_id = d.get('version.id'); + let key = moment(d.get('date')) + .utc() + .format('MMM D'); + if (dates[key]) { + let prev = dates[key].cnt[version_id] || 0; + dates[key].cnt[version_id] = prev + d.get('downloads'); + } + }); + + extra.forEach(d => { + let key = moment(d.date) + .utc() + .format('MMM D'); + if (dates[key]) { + let prev = dates[key].cnt[null] || 0; + dates[key].cnt[null] = prev + d.downloads; + } + }); + if (this.requestedVersion) { + versions.push(this.model.getProperties('id', 'num')); + } else { + this.smallSortedVersions.forEach(version => { + versions.push(version.getProperties('id', 'num')); + }); + } + if (extra.length > 0) { + versions.push({ + id: null, + num: 'Other', + }); + } + + let headers = ['Date']; + versions.sort(b => b.num).reverse(); + for (let i = 0; i < versions.length; i++) { + headers.push(versions[i].num); + } + let data = [headers]; + for (let date in dates) { + let row = [dates[date].date.toDate()]; + for (let i = 0; i < versions.length; i++) { + row.push(dates[date].cnt[versions[i].id] || 0); + } + data.push(row); + } + + return data; + }), + + toggleClipboardProps(isSuccess) { + this.setProperties({ + showSuccess: isSuccess, + showNotification: true, + }); + later( + this, + () => { + this.set('showNotification', false); + }, + 2000, + ); + }, + + actions: { + copySuccess(event) { + event.clearSelection(); + this.toggleClipboardProps(true); }, - actions: { - copySuccess(event) { - event.clearSelection(); - this.toggleClipboardProps(true); - }, - - copyError() { - this.toggleClipboardProps(false); - }, + copyError() { + this.toggleClipboardProps(false); + }, - toggleFollow() { - this.set('fetchingFollowing', true); + toggleFollow() { + this.set('fetchingFollowing', true); - let crate = this.crate; - let op = this.toggleProperty('following') ? crate.follow() : crate.unfollow(); + let crate = this.crate; + let op = this.toggleProperty('following') ? crate.follow() : crate.unfollow(); - return op.finally(() => this.set('fetchingFollowing', false)); - }, + return op.finally(() => this.set('fetchingFollowing', false)); }, - - report: observer('crate.readme', function() { - if (typeof document === 'undefined') { - return; - } - setTimeout(() => { - let e = document.createEvent('CustomEvent'); - e.initCustomEvent('hashchange', true, true); - window.dispatchEvent(e); - }); - }), + }, + + report: observer('crate.readme', function() { + if (typeof document === 'undefined') { + return; + } + setTimeout(() => { + let e = document.createEvent('CustomEvent'); + e.initCustomEvent('hashchange', true, true); + window.dispatchEvent(e); + }); + }), }); diff --git a/app/controllers/crates.js b/app/controllers/crates.js index dbfc0e8ff74..e07b3662aba 100644 --- a/app/controllers/crates.js +++ b/app/controllers/crates.js @@ -5,24 +5,24 @@ import { computed } from '@ember/object'; import PaginationMixin from '../mixins/pagination'; export default Controller.extend(PaginationMixin, { - queryParams: ['letter', 'page', 'per_page', 'sort'], - letter: null, - page: '1', - per_page: 10, - sort: 'alpha', - alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), + queryParams: ['letter', 'page', 'per_page', 'sort'], + letter: null, + page: '1', + per_page: 10, + sort: 'alpha', + alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), - totalItems: readOnly('model.meta.total'), + totalItems: readOnly('model.meta.total'), - currentSortBy: computed('sort', function() { - if (this.sort === 'downloads') { - return 'All-Time Downloads'; - } else if (this.sort === 'recent-downloads') { - return 'Recent Downloads'; - } else if (this.get('sort') === 'recent-updates') { - return 'Recent Updates'; - } else { - return 'Alphabetical'; - } - }), + currentSortBy: computed('sort', function() { + if (this.sort === 'downloads') { + return 'All-Time Downloads'; + } else if (this.sort === 'recent-downloads') { + return 'Recent Downloads'; + } else if (this.get('sort') === 'recent-updates') { + return 'Recent Updates'; + } else { + return 'Alphabetical'; + } + }), }); diff --git a/app/controllers/dashboard.js b/app/controllers/dashboard.js index 12bc169d9a7..81b6fbfb9b6 100644 --- a/app/controllers/dashboard.js +++ b/app/controllers/dashboard.js @@ -6,51 +6,51 @@ import ajax from 'ember-fetch/ajax'; const TO_SHOW = 5; export default Controller.extend({ - init() { - this._super(...arguments); - - this.loadingMore = false; - this.hasMore = false; - this.myCrates = A(); - this.myFollowing = A(); - this.myFeed = A(); - this.myStats = 0; - }, - - visibleCrates: computed('myCrates.[]', function() { - return this.myCrates.slice(0, TO_SHOW); - }), - - visibleFollowing: computed('myFollowing.[]', function() { - return this.myFollowing.slice(0, TO_SHOW); - }), - - visibleStats: computed('myStats', function() { - return this.myStats; - }), - - hasMoreCrates: computed('myCrates.[]', function() { - return this.get('myCrates.length') > TO_SHOW; - }), - - hasMoreFollowing: computed('myFollowing.[]', function() { - return this.get('myFollowing.length') > TO_SHOW; - }), - - actions: { - async loadMore() { - this.set('loadingMore', true); - let page = this.myFeed.length / 10 + 1; - - try { - let data = await ajax(`/api/v1/me/updates?page=${page}`); - let versions = data.versions.map(version => this.store.push(this.store.normalize('version', version))); - - this.myFeed.pushObjects(versions); - this.set('hasMore', data.meta.more); - } finally { - this.set('loadingMore', false); - } - }, + init() { + this._super(...arguments); + + this.loadingMore = false; + this.hasMore = false; + this.myCrates = A(); + this.myFollowing = A(); + this.myFeed = A(); + this.myStats = 0; + }, + + visibleCrates: computed('myCrates.[]', function() { + return this.myCrates.slice(0, TO_SHOW); + }), + + visibleFollowing: computed('myFollowing.[]', function() { + return this.myFollowing.slice(0, TO_SHOW); + }), + + visibleStats: computed('myStats', function() { + return this.myStats; + }), + + hasMoreCrates: computed('myCrates.[]', function() { + return this.get('myCrates.length') > TO_SHOW; + }), + + hasMoreFollowing: computed('myFollowing.[]', function() { + return this.get('myFollowing.length') > TO_SHOW; + }), + + actions: { + async loadMore() { + this.set('loadingMore', true); + let page = this.myFeed.length / 10 + 1; + + try { + let data = await ajax(`/api/v1/me/updates?page=${page}`); + let versions = data.versions.map(version => this.store.push(this.store.normalize('version', version))); + + this.myFeed.pushObjects(versions); + this.set('hasMore', data.meta.more); + } finally { + this.set('loadingMore', false); + } }, + }, }); diff --git a/app/controllers/index.js b/app/controllers/index.js index fc283920743..6d057737714 100644 --- a/app/controllers/index.js +++ b/app/controllers/index.js @@ -6,26 +6,26 @@ import ajax from 'ember-fetch/ajax'; import { task } from 'ember-concurrency'; export default Controller.extend({ - model: readOnly('dataTask.lastSuccessful.value'), + model: readOnly('dataTask.lastSuccessful.value'), - hasData: computed('dataTask.{lastSuccessful,isRunning}', function() { - return this.get('dataTask.lastSuccessful') || !this.get('dataTask.isRunning'); - }), + hasData: computed('dataTask.{lastSuccessful,isRunning}', function() { + return this.get('dataTask.lastSuccessful') || !this.get('dataTask.isRunning'); + }), - dataTask: task(function*() { - let data = yield ajax('/api/v1/summary'); + dataTask: task(function*() { + let data = yield ajax('/api/v1/summary'); - addCrates(this.store, data.new_crates); - addCrates(this.store, data.most_downloaded); - addCrates(this.store, data.just_updated); - addCrates(this.store, data.most_recently_downloaded); + addCrates(this.store, data.new_crates); + addCrates(this.store, data.most_downloaded); + addCrates(this.store, data.just_updated); + addCrates(this.store, data.most_recently_downloaded); - return data; - }).drop(), + return data; + }).drop(), }); function addCrates(store, crates) { - for (let i = 0; i < crates.length; i++) { - crates[i] = store.push(store.normalize('crate', crates[i])); - } + for (let i = 0; i < crates.length; i++) { + crates[i] = store.push(store.normalize('crate', crates[i])); + } } diff --git a/app/controllers/install.js b/app/controllers/install.js index f57d8814168..7366e369a8f 100644 --- a/app/controllers/install.js +++ b/app/controllers/install.js @@ -1,14 +1,14 @@ import Controller from '@ember/controller'; function link(target) { - return `https://static.rust-lang.org/cargo-dist/cargo-nightly-${target}.tar.gz`; + return `https://static.rust-lang.org/cargo-dist/cargo-nightly-${target}.tar.gz`; } export default Controller.extend({ - linux64: link('x86_64-unknown-linux-gnu'), - linux32: link('i686-unknown-linux-gnu'), - mac64: link('x86_64-apple-darwin'), - mac32: link('i686-apple-darwin'), - win64: link('x86_64-pc-windows-gnu'), - win32: link('i686-pc-windows-gnu'), + linux64: link('x86_64-unknown-linux-gnu'), + linux32: link('i686-unknown-linux-gnu'), + mac64: link('x86_64-apple-darwin'), + mac32: link('i686-apple-darwin'), + win64: link('x86_64-pc-windows-gnu'), + win32: link('i686-pc-windows-gnu'), }); diff --git a/app/controllers/keyword/index.js b/app/controllers/keyword/index.js index aadd8fb66c9..d952fb40812 100644 --- a/app/controllers/keyword/index.js +++ b/app/controllers/keyword/index.js @@ -5,22 +5,22 @@ import { computed } from '@ember/object'; import PaginationMixin from '../../mixins/pagination'; export default Controller.extend(PaginationMixin, { - queryParams: ['page', 'per_page', 'sort'], - page: '1', - per_page: 10, - sort: 'recent-downloads', + queryParams: ['page', 'per_page', 'sort'], + page: '1', + per_page: 10, + sort: 'recent-downloads', - totalItems: readOnly('model.meta.total'), + totalItems: readOnly('model.meta.total'), - currentSortBy: computed('sort', function() { - if (this.sort === 'downloads') { - return 'All-Time Downloads'; - } else if (this.sort === 'alpha') { - return 'Alphabetical'; - } else if (this.get('sort') === 'recent-updates') { - return 'Recent Updates'; - } else { - return 'Recent Downloads'; - } - }), + currentSortBy: computed('sort', function() { + if (this.sort === 'downloads') { + return 'All-Time Downloads'; + } else if (this.sort === 'alpha') { + return 'Alphabetical'; + } else if (this.get('sort') === 'recent-updates') { + return 'Recent Updates'; + } else { + return 'Recent Downloads'; + } + }), }); diff --git a/app/controllers/keywords.js b/app/controllers/keywords.js index a23839aec12..4dec3969e28 100644 --- a/app/controllers/keywords.js +++ b/app/controllers/keywords.js @@ -5,14 +5,14 @@ import { computed } from '@ember/object'; import PaginationMixin from '../mixins/pagination'; export default Controller.extend(PaginationMixin, { - queryParams: ['page', 'per_page', 'sort'], - page: '1', - per_page: 10, - sort: 'crates', + queryParams: ['page', 'per_page', 'sort'], + page: '1', + per_page: 10, + sort: 'crates', - totalItems: readOnly('model.meta.total'), + totalItems: readOnly('model.meta.total'), - currentSortBy: computed('sort', function() { - return this.sort === 'crates' ? '# Crates' : 'Alphabetical'; - }), + currentSortBy: computed('sort', function() { + return this.sort === 'crates' ? '# Crates' : 'Alphabetical'; + }), }); diff --git a/app/controllers/me/crates.js b/app/controllers/me/crates.js index fd9c716d1b8..dc52b917c91 100644 --- a/app/controllers/me/crates.js +++ b/app/controllers/me/crates.js @@ -7,22 +7,22 @@ import PaginationMixin from '../../mixins/pagination'; // TODO: reduce duplicatoin with controllers/crates export default Controller.extend(PaginationMixin, { - queryParams: ['page', 'per_page', 'sort'], - page: '1', - per_page: 10, - sort: 'alpha', + queryParams: ['page', 'per_page', 'sort'], + page: '1', + per_page: 10, + sort: 'alpha', - totalItems: readOnly('model.meta.total'), + totalItems: readOnly('model.meta.total'), - currentSortBy: computed('sort', function() { - if (this.sort === 'downloads') { - return 'All-Time Downloads'; - } else if (this.sort === 'recent-downloads') { - return 'Recent Downloads'; - } else if (this.get('sort') === 'recent-updates') { - return 'Recent Updates'; - } else { - return 'Alphabetical'; - } - }), + currentSortBy: computed('sort', function() { + if (this.sort === 'downloads') { + return 'All-Time Downloads'; + } else if (this.sort === 'recent-downloads') { + return 'Recent Downloads'; + } else if (this.get('sort') === 'recent-updates') { + return 'Recent Updates'; + } else { + return 'Alphabetical'; + } + }), }); diff --git a/app/controllers/me/following.js b/app/controllers/me/following.js index ad74cc201ab..4d97fde6b61 100644 --- a/app/controllers/me/following.js +++ b/app/controllers/me/following.js @@ -7,14 +7,14 @@ import PaginationMixin from '../../mixins/pagination'; // TODO: reduce duplicatoin with controllers/me/crates export default Controller.extend(PaginationMixin, { - queryParams: ['page', 'per_page', 'sort'], - page: '1', - per_page: 10, - sort: 'alpha', + queryParams: ['page', 'per_page', 'sort'], + page: '1', + per_page: 10, + sort: 'alpha', - totalItems: readOnly('model.meta.total'), + totalItems: readOnly('model.meta.total'), - currentSortBy: computed('sort', function() { - return this.sort === 'downloads' ? 'Downloads' : 'Alphabetical'; - }), + currentSortBy: computed('sort', function() { + return this.sort === 'downloads' ? 'Downloads' : 'Alphabetical'; + }), }); diff --git a/app/controllers/me/index.js b/app/controllers/me/index.js index 875806bc5c9..a3edf82124e 100644 --- a/app/controllers/me/index.js +++ b/app/controllers/me/index.js @@ -3,23 +3,23 @@ import { sort, filterBy, notEmpty } from '@ember/object/computed'; import { inject as service } from '@ember/service'; export default Controller.extend({ - // eslint-disable-next-line ember/avoid-leaking-state-in-ember-objects - tokenSort: ['created_at:desc'], + // eslint-disable-next-line ember/avoid-leaking-state-in-ember-objects + tokenSort: ['created_at:desc'], - sortedTokens: sort('model.api_tokens', 'tokenSort'), + sortedTokens: sort('model.api_tokens', 'tokenSort'), - flashMessages: service(), + flashMessages: service(), - isResetting: false, + isResetting: false, - newTokens: filterBy('model.api_tokens', 'isNew', true), - disableCreate: notEmpty('newTokens'), + newTokens: filterBy('model.api_tokens', 'isNew', true), + disableCreate: notEmpty('newTokens'), - actions: { - startNewToken() { - this.store.createRecord('api-token', { - created_at: new Date(Date.now() + 2000), - }); - }, + actions: { + startNewToken() { + this.store.createRecord('api-token', { + created_at: new Date(Date.now() + 2000), + }); }, + }, }); diff --git a/app/controllers/search.js b/app/controllers/search.js index 4fc8564f512..4c08b873454 100644 --- a/app/controllers/search.js +++ b/app/controllers/search.js @@ -8,43 +8,43 @@ import { task } from 'ember-concurrency'; import PaginationMixin from '../mixins/pagination'; export default Controller.extend(PaginationMixin, { - search: service(), - queryParams: ['q', 'page', 'per_page', 'sort'], - q: alias('search.q'), - page: '1', - per_page: 10, - - model: readOnly('dataTask.lastSuccessful.value'), - - hasData: computed('dataTask.{lastSuccessful,isRunning}', function() { - return this.get('dataTask.lastSuccessful') || !this.get('dataTask.isRunning'); - }), - - firstResultPending: computed('dataTask.{lastSuccessful,isRunning}', function() { - return !this.get('dataTask.lastSuccessful') && this.get('dataTask.isRunning'); - }), - - totalItems: readOnly('model.meta.total'), - - currentSortBy: computed('sort', function() { - if (this.sort === 'downloads') { - return 'All-Time Downloads'; - } else if (this.sort === 'recent-downloads') { - return 'Recent Downloads'; - } else if (this.get('sort') === 'recent-updates') { - return 'Recent Updates'; - } else { - return 'Relevance'; - } - }), - - hasItems: bool('totalItems'), - - dataTask: task(function*(params) { - if (params.q !== null) { - params.q = params.q.trim(); - } - - return yield this.store.query('crate', params); - }).drop(), + search: service(), + queryParams: ['q', 'page', 'per_page', 'sort'], + q: alias('search.q'), + page: '1', + per_page: 10, + + model: readOnly('dataTask.lastSuccessful.value'), + + hasData: computed('dataTask.{lastSuccessful,isRunning}', function() { + return this.get('dataTask.lastSuccessful') || !this.get('dataTask.isRunning'); + }), + + firstResultPending: computed('dataTask.{lastSuccessful,isRunning}', function() { + return !this.get('dataTask.lastSuccessful') && this.get('dataTask.isRunning'); + }), + + totalItems: readOnly('model.meta.total'), + + currentSortBy: computed('sort', function() { + if (this.sort === 'downloads') { + return 'All-Time Downloads'; + } else if (this.sort === 'recent-downloads') { + return 'Recent Downloads'; + } else if (this.get('sort') === 'recent-updates') { + return 'Recent Updates'; + } else { + return 'Relevance'; + } + }), + + hasItems: bool('totalItems'), + + dataTask: task(function*(params) { + if (params.q !== null) { + params.q = params.q.trim(); + } + + return yield this.store.query('crate', params); + }).drop(), }); diff --git a/app/controllers/team.js b/app/controllers/team.js index 8d36c2bfe56..96fd125d032 100644 --- a/app/controllers/team.js +++ b/app/controllers/team.js @@ -5,22 +5,22 @@ import { computed } from '@ember/object'; import PaginationMixin from '../mixins/pagination'; export default Controller.extend(PaginationMixin, { - queryParams: ['page', 'per_page', 'sort'], - page: '1', - per_page: 10, - sort: 'alpha', + queryParams: ['page', 'per_page', 'sort'], + page: '1', + per_page: 10, + sort: 'alpha', - totalItems: readOnly('model.crates.meta.total'), + totalItems: readOnly('model.crates.meta.total'), - currentSortBy: computed('sort', function() { - if (this.sort === 'downloads') { - return 'All-Time Downloads'; - } else if (this.sort === 'recent-downloads') { - return 'Recent Downloads'; - } else if (this.get('sort') === 'recent-updates') { - return 'Recent Updates'; - } else { - return 'Alphabetical'; - } - }), + currentSortBy: computed('sort', function() { + if (this.sort === 'downloads') { + return 'All-Time Downloads'; + } else if (this.sort === 'recent-downloads') { + return 'Recent Downloads'; + } else if (this.get('sort') === 'recent-updates') { + return 'Recent Updates'; + } else { + return 'Alphabetical'; + } + }), }); diff --git a/app/controllers/user.js b/app/controllers/user.js index 08b51995c2d..9afafbfc9a2 100644 --- a/app/controllers/user.js +++ b/app/controllers/user.js @@ -6,22 +6,22 @@ import PaginationMixin from '../mixins/pagination'; // TODO: reduce duplication with controllers/crates export default Controller.extend(PaginationMixin, { - queryParams: ['page', 'per_page', 'sort'], - page: '1', - per_page: 10, - sort: 'alpha', + queryParams: ['page', 'per_page', 'sort'], + page: '1', + per_page: 10, + sort: 'alpha', - totalItems: readOnly('model.crates.meta.total'), + totalItems: readOnly('model.crates.meta.total'), - currentSortBy: computed('sort', function() { - if (this.sort === 'downloads') { - return 'All-Time Downloads'; - } else if (this.sort === 'recent-downloads') { - return 'Recent Downloads'; - } else if (this.get('sort') === 'recent-updates') { - return 'Recent Updates'; - } else { - return 'Alphabetical'; - } - }), + currentSortBy: computed('sort', function() { + if (this.sort === 'downloads') { + return 'All-Time Downloads'; + } else if (this.sort === 'recent-downloads') { + return 'Recent Downloads'; + } else if (this.get('sort') === 'recent-updates') { + return 'Recent Updates'; + } else { + return 'Alphabetical'; + } + }), }); diff --git a/app/helpers/format-crate-size.js b/app/helpers/format-crate-size.js index 2f8beb53809..f0103c11d44 100644 --- a/app/helpers/format-crate-size.js +++ b/app/helpers/format-crate-size.js @@ -1,11 +1,11 @@ import { helper } from '@ember/component/helper'; export function formatCrateSize(sizeInBytes) { - if (sizeInBytes < 100000) { - return +(sizeInBytes / 1000).toFixed(2) + ' kB'; - } else { - return +(sizeInBytes / 1000000).toFixed(2) + ' MB'; - } + if (sizeInBytes < 100000) { + return +(sizeInBytes / 1000).toFixed(2) + ' kB'; + } else { + return +(sizeInBytes / 1000000).toFixed(2) + ' MB'; + } } export default helper(formatCrateSize); diff --git a/app/helpers/format-email.js b/app/helpers/format-email.js index 11ff4b1b1a6..4852ab98ee1 100644 --- a/app/helpers/format-email.js +++ b/app/helpers/format-email.js @@ -5,16 +5,16 @@ import Ember from 'ember'; const escape = Ember.Handlebars.Utils.escapeExpression; export function formatEmail(email) { - let formatted = email.match(/^(.*?)\s*(?:<(.*)>)?$/); - let ret = ''; + let formatted = email.match(/^(.*?)\s*(?:<(.*)>)?$/); + let ret = ''; - ret += escape(formatted[1]); + ret += escape(formatted[1]); - if (formatted[2]) { - ret = `${ret}`; - } + if (formatted[2]) { + ret = `${ret}`; + } - return htmlSafe(ret); + return htmlSafe(ret); } export default helper(params => formatEmail(params[0])); diff --git a/app/helpers/format-num.js b/app/helpers/format-num.js index a5f3e4589d8..54fff2d67cd 100644 --- a/app/helpers/format-num.js +++ b/app/helpers/format-num.js @@ -1,22 +1,22 @@ import { helper } from '@ember/component/helper'; export function formatNum(value) { - if (value === 0) { - return '0'; - } + if (value === 0) { + return '0'; + } - let ret = ''; - let cnt = 0; - while (value > 0) { - if (cnt > 0 && cnt % 3 === 0) { - ret = `,${ret}`; - cnt = 0; - } - ret = (value % 10) + ret; - cnt += 1; - value = Math.floor(value / 10); + let ret = ''; + let cnt = 0; + while (value > 0) { + if (cnt > 0 && cnt % 3 === 0) { + ret = `,${ret}`; + cnt = 0; } - return ret; + ret = (value % 10) + ret; + cnt += 1; + value = Math.floor(value / 10); + } + return ret; } export default helper(params => formatNum(params[0])); diff --git a/app/helpers/format-req.js b/app/helpers/format-req.js index 22e79f9b492..2e3740ea71a 100644 --- a/app/helpers/format-req.js +++ b/app/helpers/format-req.js @@ -1,6 +1,6 @@ import { helper } from '@ember/component/helper'; export default helper(function(params) { - let [req] = params; - return req === '*' ? '' : req; + let [req] = params; + return req === '*' ? '' : req; }); diff --git a/app/helpers/truncate-text.js b/app/helpers/truncate-text.js index b42feaa0714..029dde80fbe 100644 --- a/app/helpers/truncate-text.js +++ b/app/helpers/truncate-text.js @@ -1,12 +1,12 @@ import { helper } from '@ember/component/helper'; export default helper(function(params) { - let [value] = params; - if (!value) { - return value; - } - if (value.length > 200) { - return `${value.slice(0, 200)} ...`; - } + let [value] = params; + if (!value) { return value; + } + if (value.length > 200) { + return `${value.slice(0, 200)} ...`; + } + return value; }); diff --git a/app/initializers/hashchange.js b/app/initializers/hashchange.js index d852ecf7f0a..13c14f5ac0d 100644 --- a/app/initializers/hashchange.js +++ b/app/initializers/hashchange.js @@ -1,55 +1,55 @@ function decodeFragmentValue(hash) { - try { - return decodeURIComponent(hash.slice(1)); - } catch (_) { - return ''; - } + try { + return decodeURIComponent(hash.slice(1)); + } catch (_) { + return ''; + } } function findElementByFragmentName(document, name) { - if (name === '') { - return; - } + if (name === '') { + return; + } - return document.getElementById(name) || document.getElementsByName(name)[0]; + return document.getElementById(name) || document.getElementsByName(name)[0]; } function hashchange() { - if (document.querySelector(':target')) { - return; - } + if (document.querySelector(':target')) { + return; + } - const hash = decodeFragmentValue(location.hash); - const target = findElementByFragmentName(document, `user-content-${hash}`); - if (target) { - target.scrollIntoView(); - } + const hash = decodeFragmentValue(location.hash); + const target = findElementByFragmentName(document, `user-content-${hash}`); + if (target) { + target.scrollIntoView(); + } } export function initialize() { - if (typeof window === 'undefined' || typeof window.addEventListener === 'undefined') { - // Don't run this initializer under FastBoot - return; - } - window.addEventListener('hashchange', hashchange); + if (typeof window === 'undefined' || typeof window.addEventListener === 'undefined') { + // Don't run this initializer under FastBoot + return; + } + window.addEventListener('hashchange', hashchange); - // If clicking on a link to the same fragment as currently in the address bar, - // hashchange won't be fired, so we need to manually trigger rescroll. - document.addEventListener('click', function(event) { - if (event.target.tagName !== 'A') { - return; - } - if (this.href === location.href && location.hash.length > 1) { - setTimeout(function() { - if (!event.defaultPrevented) { - hashchange(); - } - }); + // If clicking on a link to the same fragment as currently in the address bar, + // hashchange won't be fired, so we need to manually trigger rescroll. + document.addEventListener('click', function(event) { + if (event.target.tagName !== 'A') { + return; + } + if (this.href === location.href && location.hash.length > 1) { + setTimeout(function() { + if (!event.defaultPrevented) { + hashchange(); } - }); + }); + } + }); } export default { - name: 'app.hashchange', - initialize, + name: 'app.hashchange', + initialize, }; diff --git a/app/initializers/set-global-promise.js b/app/initializers/set-global-promise.js index 972f5dad550..20a20415742 100644 --- a/app/initializers/set-global-promise.js +++ b/app/initializers/set-global-promise.js @@ -1,9 +1,9 @@ import RSVP from 'rsvp'; export function initialize() { - // async/await is using window.Promise by default and we want async/await to - // use RSVP instead which is properly integrated with Ember's runloop - window.Promise = RSVP.Promise; + // async/await is using window.Promise by default and we want async/await to + // use RSVP instead which is properly integrated with Ember's runloop + window.Promise = RSVP.Promise; } export default { initialize }; diff --git a/app/mixins/authenticated-route.js b/app/mixins/authenticated-route.js index ffa174be15b..d599c648495 100644 --- a/app/mixins/authenticated-route.js +++ b/app/mixins/authenticated-route.js @@ -2,12 +2,12 @@ import Mixin from '@ember/object/mixin'; import { inject as service } from '@ember/service'; export default Mixin.create({ - flashMessages: service(), - session: service(), + flashMessages: service(), + session: service(), - beforeModel(transition) { - return this.session.checkCurrentUser(transition, () => { - this.flashMessages.queue('Please log in to proceed'); - }); - }, + beforeModel(transition) { + return this.session.checkCurrentUser(transition, () => { + this.flashMessages.queue('Please log in to proceed'); + }); + }, }); diff --git a/app/mixins/pagination.js b/app/mixins/pagination.js index fd271e11ada..70706b51421 100644 --- a/app/mixins/pagination.js +++ b/app/mixins/pagination.js @@ -5,71 +5,71 @@ import { computed } from '@ember/object'; const VIEWABLE_PAGES = 9; export default Mixin.create({ - // Gives page numbers to the surrounding 9 pages. - pages: computed('currentPage', 'availablePages', function() { - let pages = []; - let currentPage = this.currentPage; - let availablePages = this.availablePages; - let lowerBound = 0; - let upperBound = 0; + // Gives page numbers to the surrounding 9 pages. + pages: computed('currentPage', 'availablePages', function() { + let pages = []; + let currentPage = this.currentPage; + let availablePages = this.availablePages; + let lowerBound = 0; + let upperBound = 0; - // Always show the same number of pages even if we're - // at the beginning or at the end of the list. - if (availablePages - currentPage < Math.ceil(VIEWABLE_PAGES / 2)) { - lowerBound = Math.max(0, availablePages - VIEWABLE_PAGES); - upperBound = availablePages; - } else if (currentPage <= Math.ceil(VIEWABLE_PAGES / 2)) { - lowerBound = 0; - upperBound = Math.min(availablePages, VIEWABLE_PAGES); - } else { - lowerBound = currentPage - Math.ceil(VIEWABLE_PAGES / 2); - upperBound = currentPage + Math.floor(VIEWABLE_PAGES / 2); - } - for (let i = lowerBound; i < upperBound; i++) { - pages.push(i + 1); - } - return pages; - }), + // Always show the same number of pages even if we're + // at the beginning or at the end of the list. + if (availablePages - currentPage < Math.ceil(VIEWABLE_PAGES / 2)) { + lowerBound = Math.max(0, availablePages - VIEWABLE_PAGES); + upperBound = availablePages; + } else if (currentPage <= Math.ceil(VIEWABLE_PAGES / 2)) { + lowerBound = 0; + upperBound = Math.min(availablePages, VIEWABLE_PAGES); + } else { + lowerBound = currentPage - Math.ceil(VIEWABLE_PAGES / 2); + upperBound = currentPage + Math.floor(VIEWABLE_PAGES / 2); + } + for (let i = lowerBound; i < upperBound; i++) { + pages.push(i + 1); + } + return pages; + }), - currentPage: computed('selectedPage', function() { - return parseInt(this.selectedPage, 10) || 1; - }), + currentPage: computed('selectedPage', function() { + return parseInt(this.selectedPage, 10) || 1; + }), - currentPageStart: computed('currentPage', 'itemsPerPage', 'totalItems', function() { - if (this.totalItems === 0) { - return 0; - } - return (this.currentPage - 1) * this.itemsPerPage + 1; - }), + currentPageStart: computed('currentPage', 'itemsPerPage', 'totalItems', function() { + if (this.totalItems === 0) { + return 0; + } + return (this.currentPage - 1) * this.itemsPerPage + 1; + }), - currentPageEnd: computed('currentPage', 'itemsPerPage', 'totalItems', function() { - return Math.min(this.currentPage * this.itemsPerPage, this.totalItems); - }), + currentPageEnd: computed('currentPage', 'itemsPerPage', 'totalItems', function() { + return Math.min(this.currentPage * this.itemsPerPage, this.totalItems); + }), - nextPage: computed('currentPage', 'availablePages', function() { - let nextPage = this.currentPage + 1; - let availablePages = this.availablePages; - if (nextPage <= availablePages) { - return nextPage; - } else { - return this.currentPage; - } - }), + nextPage: computed('currentPage', 'availablePages', function() { + let nextPage = this.currentPage + 1; + let availablePages = this.availablePages; + if (nextPage <= availablePages) { + return nextPage; + } else { + return this.currentPage; + } + }), - prevPage: computed('currentPage', function() { - let prevPage = this.currentPage - 1; - if (prevPage > 0) { - return prevPage; - } else { - return this.currentPage; - } - }), + prevPage: computed('currentPage', function() { + let prevPage = this.currentPage - 1; + if (prevPage > 0) { + return prevPage; + } else { + return this.currentPage; + } + }), - availablePages: computed('totalItems', 'itemsPerPage', function() { - return Math.ceil(this.totalItems / this.itemsPerPage || 1); - }), + availablePages: computed('totalItems', 'itemsPerPage', function() { + return Math.ceil(this.totalItems / this.itemsPerPage || 1); + }), - // wire up these ember-style variables to the expected query parameters - itemsPerPage: readOnly('per_page'), - selectedPage: readOnly('page'), + // wire up these ember-style variables to the expected query parameters + itemsPerPage: readOnly('per_page'), + selectedPage: readOnly('page'), }); diff --git a/app/mixins/rl-dropdown-component.js b/app/mixins/rl-dropdown-component.js index 677c7bee5cb..1d9adf352d5 100644 --- a/app/mixins/rl-dropdown-component.js +++ b/app/mixins/rl-dropdown-component.js @@ -5,97 +5,97 @@ import { bind, later } from '@ember/runloop'; import $ from 'jquery'; export default Mixin.create({ - init() { - this._super(...arguments); + init() { + this._super(...arguments); - this.set('boundClickoutHandler', bind(this, this.clickoutHandler)); - this.set('boundEscapeHandler', bind(this, this.escapeHandler)); - }, - - onOpen() {}, - onClose() {}, + this.set('boundClickoutHandler', bind(this, this.clickoutHandler)); + this.set('boundEscapeHandler', bind(this, this.escapeHandler)); + }, - dropdownExpanded: false, + onOpen() {}, + onClose() {}, - dropdownToggleSelector: '.rl-dropdown-toggle', + dropdownExpanded: false, - dropdownSelector: '.rl-dropdown', + dropdownToggleSelector: '.rl-dropdown-toggle', - closingEventNamespace: 'rl-dropdown', + dropdownSelector: '.rl-dropdown', - closeOnEscape: true, + closingEventNamespace: 'rl-dropdown', - actions: { - toggleDropdown() { - this.toggleProperty('dropdownExpanded'); + closeOnEscape: true, - if (this.dropdownExpanded) { - this.onOpen(); - } else { - this.onClose(); - } - }, + actions: { + toggleDropdown() { + this.toggleProperty('dropdownExpanded'); - openDropdown() { - this.set('dropdownExpanded', true); - this.onOpen(); - }, + if (this.dropdownExpanded) { + this.onOpen(); + } else { + this.onClose(); + } + }, - closeDropdown() { - this.set('dropdownExpanded', false); - this.onClose(); - }, + openDropdown() { + this.set('dropdownExpanded', true); + this.onOpen(); }, - manageClosingEvents: on( - 'didInsertElement', - observer('dropdownExpanded', function() { - let namespace = this.closingEventNamespace; - let clickEventName = `click.${namespace}`; - let focusEventName = `focusin.${namespace}`; - let touchEventName = `touchstart.${namespace}`; - let escapeEventName = `keydown.${namespace}`; - let component = this; - let $document = $(document); - - if (this.dropdownExpanded) { - /* Add clickout handler with 1ms delay, to allow opening the dropdown + closeDropdown() { + this.set('dropdownExpanded', false); + this.onClose(); + }, + }, + + manageClosingEvents: on( + 'didInsertElement', + observer('dropdownExpanded', function() { + let namespace = this.closingEventNamespace; + let clickEventName = `click.${namespace}`; + let focusEventName = `focusin.${namespace}`; + let touchEventName = `touchstart.${namespace}`; + let escapeEventName = `keydown.${namespace}`; + let component = this; + let $document = $(document); + + if (this.dropdownExpanded) { + /* Add clickout handler with 1ms delay, to allow opening the dropdown * by clicking e.g. a checkbox and binding to dropdownExpanded, without * having the handler close the dropdown immediately. */ - later(() => { - $document.bind(clickEventName, { component }, component.boundClickoutHandler); - $document.bind(focusEventName, { component }, component.boundClickoutHandler); - $document.bind(touchEventName, { component }, component.boundClickoutHandler); - }, 1); - - if (this.closeOnEscape) { - $document.bind(escapeEventName, { component }, component.boundEscapeHandler); - } - } else { - $document.unbind(clickEventName, component.boundClickoutHandler); - $document.unbind(focusEventName, component.boundClickoutHandler); - $document.unbind(touchEventName, component.boundClickoutHandler); - $document.unbind(escapeEventName, component.boundEscapeHandler); - } - }), - ), - - unbindClosingEvents: on('willDestroyElement', function() { - let namespace = this.closingEventNamespace; - let $document = $(document); - - $document.unbind(`click.${namespace}`, this.boundClickoutHandler); - $document.unbind(`focusin.${namespace}`, this.boundClickoutHandler); - $document.unbind(`touchstart.${namespace}`, this.boundClickoutHandler); - $document.unbind(`keydown.${namespace}`, this.boundEscapeHandler); + later(() => { + $document.bind(clickEventName, { component }, component.boundClickoutHandler); + $document.bind(focusEventName, { component }, component.boundClickoutHandler); + $document.bind(touchEventName, { component }, component.boundClickoutHandler); + }, 1); + + if (this.closeOnEscape) { + $document.bind(escapeEventName, { component }, component.boundEscapeHandler); + } + } else { + $document.unbind(clickEventName, component.boundClickoutHandler); + $document.unbind(focusEventName, component.boundClickoutHandler); + $document.unbind(touchEventName, component.boundClickoutHandler); + $document.unbind(escapeEventName, component.boundEscapeHandler); + } }), + ), + + unbindClosingEvents: on('willDestroyElement', function() { + let namespace = this.closingEventNamespace; + let $document = $(document); - clickoutHandler(event) { - let { component } = event.data; - let $c = component.$(); - let $target = $(event.target); + $document.unbind(`click.${namespace}`, this.boundClickoutHandler); + $document.unbind(`focusin.${namespace}`, this.boundClickoutHandler); + $document.unbind(`touchstart.${namespace}`, this.boundClickoutHandler); + $document.unbind(`keydown.${namespace}`, this.boundEscapeHandler); + }), - /* There is an issue when the click triggered a dom change in the + clickoutHandler(event) { + let { component } = event.data; + let $c = component.$(); + let $target = $(event.target); + + /* There is an issue when the click triggered a dom change in the * dropdown that unloaded the target element. The ancestry of the target * can no longer be determined. We can check if html is still an ancestor * to determine if this has happened. The safe option then seems to be to @@ -103,21 +103,21 @@ export default Mixin.create({ * should have closed, seems to be less bad for usability than occasionaly * closing the dropdown when it should not have closed. */ - if ( - component.get('dropdownExpanded') && - $target.closest('html').length && - !( - $target.closest($c.find(component.get('dropdownToggleSelector'))).length || - $target.closest($c.find(component.get('dropdownSelector'))).length - ) - ) { - component.send('closeDropdown'); - } - }, - - escapeHandler(event) { - if (event.keyCode === 27) { - event.data.component.send('closeDropdown'); - } - }, + if ( + component.get('dropdownExpanded') && + $target.closest('html').length && + !( + $target.closest($c.find(component.get('dropdownToggleSelector'))).length || + $target.closest($c.find(component.get('dropdownSelector'))).length + ) + ) { + component.send('closeDropdown'); + } + }, + + escapeHandler(event) { + if (event.keyCode === 27) { + event.data.component.send('closeDropdown'); + } + }, }); diff --git a/app/models/api-token.js b/app/models/api-token.js index 2d9e01ca6d6..b4f95ea61ec 100644 --- a/app/models/api-token.js +++ b/app/models/api-token.js @@ -1,8 +1,8 @@ import DS from 'ember-data'; export default DS.Model.extend({ - name: DS.attr('string'), - token: DS.attr('string'), - created_at: DS.attr('date'), - last_used_at: DS.attr('date'), + name: DS.attr('string'), + token: DS.attr('string'), + created_at: DS.attr('date'), + last_used_at: DS.attr('date'), }); diff --git a/app/models/category-slug.js b/app/models/category-slug.js index ee38d510b21..100f88069c0 100644 --- a/app/models/category-slug.js +++ b/app/models/category-slug.js @@ -1,6 +1,6 @@ import DS from 'ember-data'; export default DS.Model.extend({ - slug: DS.attr('string'), - description: DS.attr('string'), + slug: DS.attr('string'), + description: DS.attr('string'), }); diff --git a/app/models/category.js b/app/models/category.js index 235eb0ad27b..cfc787f806c 100644 --- a/app/models/category.js +++ b/app/models/category.js @@ -1,14 +1,14 @@ import DS from 'ember-data'; export default DS.Model.extend({ - category: DS.attr('string'), - slug: DS.attr('string'), - description: DS.attr('string'), - created_at: DS.attr('date'), - crates_cnt: DS.attr('number'), + category: DS.attr('string'), + slug: DS.attr('string'), + description: DS.attr('string'), + created_at: DS.attr('date'), + crates_cnt: DS.attr('number'), - subcategories: DS.attr(), - parent_categories: DS.attr(), + subcategories: DS.attr(), + parent_categories: DS.attr(), - crates: DS.hasMany('crate', { async: true }), + crates: DS.hasMany('crate', { async: true }), }); diff --git a/app/models/crate-owner-invite.js b/app/models/crate-owner-invite.js index b17385aacda..d1fb018f7dd 100644 --- a/app/models/crate-owner-invite.js +++ b/app/models/crate-owner-invite.js @@ -1,9 +1,9 @@ import DS from 'ember-data'; export default DS.Model.extend({ - invited_by_username: DS.attr('string'), - crate_name: DS.attr('string'), - crate_id: DS.attr('number'), - created_at: DS.attr('date'), - accepted: DS.attr('boolean', { defaultValue: false }), + invited_by_username: DS.attr('string'), + crate_name: DS.attr('string'), + crate_id: DS.attr('number'), + created_at: DS.attr('date'), + accepted: DS.attr('boolean', { defaultValue: false }), }); diff --git a/app/models/crate.js b/app/models/crate.js index f020f19355a..19c057c4c46 100644 --- a/app/models/crate.js +++ b/app/models/crate.js @@ -2,54 +2,54 @@ import { map, sort } from '@ember/object/computed'; import DS from 'ember-data'; export default DS.Model.extend({ - name: DS.attr('string'), - downloads: DS.attr('number'), - recent_downloads: DS.attr('number'), - created_at: DS.attr('date'), - updated_at: DS.attr('date'), - max_version: DS.attr('string'), - - description: DS.attr('string'), - homepage: DS.attr('string'), - wiki: DS.attr('string'), - mailing_list: DS.attr('string'), - issues: DS.attr('string'), - documentation: DS.attr('string'), - repository: DS.attr('string'), - exact_match: DS.attr('boolean'), - - versions: DS.hasMany('versions', { async: true }), - badges: DS.attr(), - enhanced_badges: map('badges', badge => ({ - ...badge, - component_name: `badge-${badge.badge_type}`, - })), - - // eslint-disable-next-line ember/avoid-leaking-state-in-ember-objects - badge_sort: ['badge_type'], - annotated_badges: sort('enhanced_badges', 'badge_sort'), - - owners: DS.hasMany('users', { async: true }), - owner_team: DS.hasMany('teams', { async: true }), - owner_user: DS.hasMany('users', { async: true }), - version_downloads: DS.hasMany('version-download', { async: true }), - keywords: DS.hasMany('keywords', { async: true }), - categories: DS.hasMany('categories', { async: true }), - reverse_dependencies: DS.hasMany('dependency', { async: true }), - - follow() { - return this.store.adapterFor('crate').follow(this.id); - }, - - inviteOwner(username) { - return this.store.adapterFor('crate').inviteOwner(this.id, username); - }, - - removeOwner(username) { - return this.store.adapterFor('crate').removeOwner(this.id, username); - }, - - unfollow() { - return this.store.adapterFor('crate').unfollow(this.id); - }, + name: DS.attr('string'), + downloads: DS.attr('number'), + recent_downloads: DS.attr('number'), + created_at: DS.attr('date'), + updated_at: DS.attr('date'), + max_version: DS.attr('string'), + + description: DS.attr('string'), + homepage: DS.attr('string'), + wiki: DS.attr('string'), + mailing_list: DS.attr('string'), + issues: DS.attr('string'), + documentation: DS.attr('string'), + repository: DS.attr('string'), + exact_match: DS.attr('boolean'), + + versions: DS.hasMany('versions', { async: true }), + badges: DS.attr(), + enhanced_badges: map('badges', badge => ({ + ...badge, + component_name: `badge-${badge.badge_type}`, + })), + + // eslint-disable-next-line ember/avoid-leaking-state-in-ember-objects + badge_sort: ['badge_type'], + annotated_badges: sort('enhanced_badges', 'badge_sort'), + + owners: DS.hasMany('users', { async: true }), + owner_team: DS.hasMany('teams', { async: true }), + owner_user: DS.hasMany('users', { async: true }), + version_downloads: DS.hasMany('version-download', { async: true }), + keywords: DS.hasMany('keywords', { async: true }), + categories: DS.hasMany('categories', { async: true }), + reverse_dependencies: DS.hasMany('dependency', { async: true }), + + follow() { + return this.store.adapterFor('crate').follow(this.id); + }, + + inviteOwner(username) { + return this.store.adapterFor('crate').inviteOwner(this.id, username); + }, + + removeOwner(username) { + return this.store.adapterFor('crate').removeOwner(this.id, username); + }, + + unfollow() { + return this.store.adapterFor('crate').unfollow(this.id); + }, }); diff --git a/app/models/dependency.js b/app/models/dependency.js index add3fbc0efe..9cccd5d7d54 100644 --- a/app/models/dependency.js +++ b/app/models/dependency.js @@ -4,14 +4,14 @@ import Inflector from 'ember-inflector'; Inflector.inflector.irregular('dependency', 'dependencies'); export default DS.Model.extend({ - version: DS.belongsTo('version', { - async: false, - }), - crate_id: DS.attr('string'), - req: DS.attr('string'), - optional: DS.attr('boolean'), - default_features: DS.attr('boolean'), - features: DS.attr({ defaultValue: () => [] }), - kind: DS.attr('string'), - downloads: DS.attr('number'), + version: DS.belongsTo('version', { + async: false, + }), + crate_id: DS.attr('string'), + req: DS.attr('string'), + optional: DS.attr('boolean'), + default_features: DS.attr('boolean'), + features: DS.attr({ defaultValue: () => [] }), + kind: DS.attr('string'), + downloads: DS.attr('number'), }); diff --git a/app/models/keyword.js b/app/models/keyword.js index d32a54d8983..a55b15bca86 100644 --- a/app/models/keyword.js +++ b/app/models/keyword.js @@ -1,9 +1,9 @@ import DS from 'ember-data'; export default DS.Model.extend({ - keyword: DS.attr('string'), - created_at: DS.attr('date'), - crates_cnt: DS.attr('number'), + keyword: DS.attr('string'), + created_at: DS.attr('date'), + crates_cnt: DS.attr('number'), - crates: DS.hasMany('crate', { async: true }), + crates: DS.hasMany('crate', { async: true }), }); diff --git a/app/models/team.js b/app/models/team.js index a993e5b42e5..80b4a6bb782 100644 --- a/app/models/team.js +++ b/app/models/team.js @@ -2,16 +2,16 @@ import { computed } from '@ember/object'; import DS from 'ember-data'; export default DS.Model.extend({ - email: DS.attr('string'), - name: DS.attr('string'), - login: DS.attr('string'), - api_token: DS.attr('string'), - avatar: DS.attr('string'), - url: DS.attr('string'), - kind: DS.attr('string'), - org_name: computed('login', function() { - let login = this.login; - let login_split = login.split(':'); - return login_split[1]; - }), + email: DS.attr('string'), + name: DS.attr('string'), + login: DS.attr('string'), + api_token: DS.attr('string'), + avatar: DS.attr('string'), + url: DS.attr('string'), + kind: DS.attr('string'), + org_name: computed('login', function() { + let login = this.login; + let login_split = login.split(':'); + return login_split[1]; + }), }); diff --git a/app/models/user.js b/app/models/user.js index 9bab18b285d..0bcbdcbce71 100644 --- a/app/models/user.js +++ b/app/models/user.js @@ -1,16 +1,16 @@ import DS from 'ember-data'; export default DS.Model.extend({ - email: DS.attr('string'), - email_verified: DS.attr('boolean'), - email_verification_sent: DS.attr('boolean'), - name: DS.attr('string'), - login: DS.attr('string'), - avatar: DS.attr('string'), - url: DS.attr('string'), - kind: DS.attr('string'), + email: DS.attr('string'), + email_verified: DS.attr('boolean'), + email_verification_sent: DS.attr('boolean'), + name: DS.attr('string'), + login: DS.attr('string'), + avatar: DS.attr('string'), + url: DS.attr('string'), + kind: DS.attr('string'), - stats() { - return this.store.adapterFor('user').stats(this.id); - }, + stats() { + return this.store.adapterFor('user').stats(this.id); + }, }); diff --git a/app/models/version-download.js b/app/models/version-download.js index a8f0c25f1e5..fc15938974c 100644 --- a/app/models/version-download.js +++ b/app/models/version-download.js @@ -1,9 +1,9 @@ import DS from 'ember-data'; export default DS.Model.extend({ - version: DS.belongsTo('version', { - async: false, - }), - downloads: DS.attr('number'), - date: DS.attr('date'), + version: DS.belongsTo('version', { + async: false, + }), + downloads: DS.attr('number'), + date: DS.attr('date'), }); diff --git a/app/models/version.js b/app/models/version.js index e5888831c48..504ba240d93 100644 --- a/app/models/version.js +++ b/app/models/version.js @@ -2,24 +2,24 @@ import { computed } from '@ember/object'; import DS from 'ember-data'; export default DS.Model.extend({ - num: DS.attr('string'), - dl_path: DS.attr('string'), - readme_path: DS.attr('string'), - created_at: DS.attr('date'), - updated_at: DS.attr('date'), - downloads: DS.attr('number'), - yanked: DS.attr('boolean'), - license: DS.attr('string'), + num: DS.attr('string'), + dl_path: DS.attr('string'), + readme_path: DS.attr('string'), + created_at: DS.attr('date'), + updated_at: DS.attr('date'), + downloads: DS.attr('number'), + yanked: DS.attr('boolean'), + license: DS.attr('string'), - crate: DS.belongsTo('crate', { - async: false, - }), - authors: DS.hasMany('users', { async: true }), - dependencies: DS.hasMany('dependency', { async: true }), - version_downloads: DS.hasMany('version-download', { async: true }), + crate: DS.belongsTo('crate', { + async: false, + }), + authors: DS.hasMany('users', { async: true }), + dependencies: DS.hasMany('dependency', { async: true }), + version_downloads: DS.hasMany('version-download', { async: true }), - crateName: computed('crate', function() { - return this.belongsTo('crate').id(); - }), - crate_size: DS.attr('number'), + crateName: computed('crate', function() { + return this.belongsTo('crate').id(); + }), + crate_size: DS.attr('number'), }); diff --git a/app/router.js b/app/router.js index 01eb2bbeace..969fbfc156b 100644 --- a/app/router.js +++ b/app/router.js @@ -3,52 +3,52 @@ import config from './config/environment'; import RouterScroll from 'ember-router-scroll'; const Router = EmberRouter.extend(RouterScroll, { - location: config.locationType, - rootURL: config.rootURL, + location: config.locationType, + rootURL: config.rootURL, }); Router.map(function() { - this.route('logout'); - this.route('login'); - this.route('github-login', { path: 'github_login' }); - this.route('github-authorize', { path: '/authorize/github' }); - this.route('crates'); - this.route('crate', { path: '/crates/:crate_id' }, function() { - this.route('download'); - this.route('versions'); - this.route('version', { path: '/:version_num' }); + this.route('logout'); + this.route('login'); + this.route('github-login', { path: 'github_login' }); + this.route('github-authorize', { path: '/authorize/github' }); + this.route('crates'); + this.route('crate', { path: '/crates/:crate_id' }, function() { + this.route('download'); + this.route('versions'); + this.route('version', { path: '/:version_num' }); - this.route('reverse-dependencies', { path: 'reverse_dependencies' }); + this.route('reverse-dependencies', { path: 'reverse_dependencies' }); - this.route('owners'); + this.route('owners'); - // Well-known routes - this.route('docs'); - this.route('repo'); - }); - this.route('me', function() { - this.route('crates'); - this.route('following'); - this.route('pending-invites'); - }); - this.route('user', { path: '/users/:user_id' }); - this.route('install'); - this.route('search'); - this.route('dashboard'); - this.route('keywords'); - this.route('keyword', { path: '/keywords/:keyword_id' }, function() { - this.route('index', { path: '/' }); - }); - this.route('categories'); - this.route('category', { path: '/categories/:category_id' }, function() { - this.route('index', { path: '/' }); - }); - this.route('category-slugs', { path: 'category_slugs' }); - this.route('team', { path: '/teams/:team_id' }); - this.route('policies'); - this.route('confirm', { path: '/confirm/:email_token' }); + // Well-known routes + this.route('docs'); + this.route('repo'); + }); + this.route('me', function() { + this.route('crates'); + this.route('following'); + this.route('pending-invites'); + }); + this.route('user', { path: '/users/:user_id' }); + this.route('install'); + this.route('search'); + this.route('dashboard'); + this.route('keywords'); + this.route('keyword', { path: '/keywords/:keyword_id' }, function() { + this.route('index', { path: '/' }); + }); + this.route('categories'); + this.route('category', { path: '/categories/:category_id' }, function() { + this.route('index', { path: '/' }); + }); + this.route('category-slugs', { path: 'category_slugs' }); + this.route('team', { path: '/teams/:team_id' }); + this.route('policies'); + this.route('confirm', { path: '/confirm/:email_token' }); - this.route('catch-all', { path: '*path' }); + this.route('catch-all', { path: '*path' }); }); export default Router; diff --git a/app/routes/application.js b/app/routes/application.js index 61cc50b7307..b295f018340 100644 --- a/app/routes/application.js +++ b/app/routes/application.js @@ -2,16 +2,16 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; export default Route.extend({ - flashMessages: service(), - session: service(), + flashMessages: service(), + session: service(), - beforeModel() { - this.session.loadUser(); - }, + beforeModel() { + this.session.loadUser(); + }, - actions: { - didTransition() { - this.flashMessages.step(); - }, + actions: { + didTransition() { + this.flashMessages.step(); }, + }, }); diff --git a/app/routes/categories.js b/app/routes/categories.js index 99a581cdfe8..9e21dfc5809 100644 --- a/app/routes/categories.js +++ b/app/routes/categories.js @@ -1,12 +1,12 @@ import Route from '@ember/routing/route'; export default Route.extend({ - queryParams: { - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, + queryParams: { + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, - model(params) { - return this.store.query('category', params); - }, + model(params) { + return this.store.query('category', params); + }, }); diff --git a/app/routes/category-slugs.js b/app/routes/category-slugs.js index ea695cfe049..ab314b37f43 100644 --- a/app/routes/category-slugs.js +++ b/app/routes/category-slugs.js @@ -1,12 +1,12 @@ import Route from '@ember/routing/route'; export default Route.extend({ - queryParams: { - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, + queryParams: { + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, - model(params) { - return this.store.query('category-slug', params); - }, + model(params) { + return this.store.query('category-slug', params); + }, }); diff --git a/app/routes/category.js b/app/routes/category.js index f36246439e6..bd106c48fb9 100644 --- a/app/routes/category.js +++ b/app/routes/category.js @@ -2,14 +2,14 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; export default Route.extend({ - flashMessages: service(), + flashMessages: service(), - model(params) { - return this.store.find('category', params.category_id).catch(e => { - if (e.errors.some(e => e.detail === 'Not Found')) { - this.flashMessages.queue(`Category '${params.category_id}' does not exist`); - return this.replaceWith('index'); - } - }); - }, + model(params) { + return this.store.find('category', params.category_id).catch(e => { + if (e.errors.some(e => e.detail === 'Not Found')) { + this.flashMessages.queue(`Category '${params.category_id}' does not exist`); + return this.replaceWith('index'); + } + }); + }, }); diff --git a/app/routes/category/index.js b/app/routes/category/index.js index c1bc4378f8d..1b347b13303 100644 --- a/app/routes/category/index.js +++ b/app/routes/category/index.js @@ -1,19 +1,19 @@ import Route from '@ember/routing/route'; export default Route.extend({ - queryParams: { - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, + queryParams: { + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, - model(params) { - params.category = this.paramsFor('category').category_id; - return this.store.query('crate', params); - }, + model(params) { + params.category = this.paramsFor('category').category_id; + return this.store.query('crate', params); + }, - setupController(controller) { - this._super(...arguments); - let category = this.modelFor('category'); - controller.set('category', category); - }, + setupController(controller) { + this._super(...arguments); + let category = this.modelFor('category'); + controller.set('category', category); + }, }); diff --git a/app/routes/confirm.js b/app/routes/confirm.js index 9280e88d483..67405995bb9 100644 --- a/app/routes/confirm.js +++ b/app/routes/confirm.js @@ -3,14 +3,14 @@ import { inject as service } from '@ember/service'; import ajax from 'ember-fetch/ajax'; export default Route.extend({ - flashMessages: service(), - session: service(), + flashMessages: service(), + session: service(), - async model(params) { - try { - await ajax(`/api/v1/confirm/${params.email_token}`, { method: 'PUT', body: '{}' }); + async model(params) { + try { + await ajax(`/api/v1/confirm/${params.email_token}`, { method: 'PUT', body: '{}' }); - /* We need this block to reload the user model from the database, + /* We need this block to reload the user model from the database, without which if we haven't submitted another GET /me after clicking the link and before checking their account info page, the user will still see that their email has not yet been @@ -20,19 +20,19 @@ export default Route.extend({ Suggestions of a more ideomatic way to fix/test this are welcome! */ - if (this.get('session.isLoggedIn')) { - ajax('/api/v1/me').then(response => { - this.session.set('currentUser', this.store.push(this.store.normalize('user', response.user))); - }); - } - } catch (error) { - if (error.payload) { - this.flashMessages.queue(`Error in email confirmation: ${error.payload.errors[0].detail}`); - return this.replaceWith('index'); - } else { - this.flashMessages.queue(`Unknown error in email confirmation`); - return this.replaceWith('index'); - } - } - }, + if (this.get('session.isLoggedIn')) { + ajax('/api/v1/me').then(response => { + this.session.set('currentUser', this.store.push(this.store.normalize('user', response.user))); + }); + } + } catch (error) { + if (error.payload) { + this.flashMessages.queue(`Error in email confirmation: ${error.payload.errors[0].detail}`); + return this.replaceWith('index'); + } else { + this.flashMessages.queue(`Unknown error in email confirmation`); + return this.replaceWith('index'); + } + } + }, }); diff --git a/app/routes/crate.js b/app/routes/crate.js index f3ca47726d7..145f005e13d 100644 --- a/app/routes/crate.js +++ b/app/routes/crate.js @@ -2,35 +2,35 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; export default Route.extend({ - flashMessages: service(), + flashMessages: service(), - model(params) { - return this.store.find('crate', params.crate_id).catch(e => { - if (e.errors.some(e => e.detail === 'Not Found')) { - this.flashMessages.show(`Crate '${params.crate_id}' does not exist`); - return; - } - }); - }, + model(params) { + return this.store.find('crate', params.crate_id).catch(e => { + if (e.errors.some(e => e.detail === 'Not Found')) { + this.flashMessages.show(`Crate '${params.crate_id}' does not exist`); + return; + } + }); + }, - afterModel(model) { - if (model && typeof model.get === 'function') { - this.setHeadTags(model); - } - }, + afterModel(model) { + if (model && typeof model.get === 'function') { + this.setHeadTags(model); + } + }, - setHeadTags(model) { - let headTags = [ - { - type: 'meta', - tagId: 'meta-description-tag', - attrs: { - name: 'description', - content: model.get('description') || 'A package for Rust.', - }, - }, - ]; + setHeadTags(model) { + let headTags = [ + { + type: 'meta', + tagId: 'meta-description-tag', + attrs: { + name: 'description', + content: model.get('description') || 'A package for Rust.', + }, + }, + ]; - this.set('headTags', headTags); - }, + this.set('headTags', headTags); + }, }); diff --git a/app/routes/crate/docs.js b/app/routes/crate/docs.js index 7bceb06433e..2579eb95e9e 100644 --- a/app/routes/crate/docs.js +++ b/app/routes/crate/docs.js @@ -2,20 +2,20 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; export default Route.extend({ - flashMessages: service(), + flashMessages: service(), - redirect() { - let crate = this.modelFor('crate'); + redirect() { + let crate = this.modelFor('crate'); - let documentation = crate.get('documentation'); - if (documentation) { - window.location = documentation; - } else { - // Redirect to the crate's main page and show a flash error if - // no documentation is found - let message = 'Crate does not supply a documentation URL'; - this.flashMessages.queue(message); - this.replaceWith('crate', crate); - } - }, + let documentation = crate.get('documentation'); + if (documentation) { + window.location = documentation; + } else { + // Redirect to the crate's main page and show a flash error if + // no documentation is found + let message = 'Crate does not supply a documentation URL'; + this.flashMessages.queue(message); + this.replaceWith('crate', crate); + } + }, }); diff --git a/app/routes/crate/index.js b/app/routes/crate/index.js index fdf2da0a21f..18fdbb182b1 100644 --- a/app/routes/crate/index.js +++ b/app/routes/crate/index.js @@ -1,6 +1,6 @@ import VersionRoute from './version'; export default VersionRoute.extend({ - controllerName: 'crate.version', - templateName: 'crate/version', + controllerName: 'crate.version', + templateName: 'crate/version', }); diff --git a/app/routes/crate/owners.js b/app/routes/crate/owners.js index ac698aa6eb3..3809c391aa6 100644 --- a/app/routes/crate/owners.js +++ b/app/routes/crate/owners.js @@ -1,9 +1,9 @@ import Route from '@ember/routing/route'; export default Route.extend({ - setupController(controller) { - this._super(...arguments); - let crate = this.modelFor('crate'); - controller.set('crate', crate); - }, + setupController(controller) { + this._super(...arguments); + let crate = this.modelFor('crate'); + controller.set('crate', crate); + }, }); diff --git a/app/routes/crate/repo.js b/app/routes/crate/repo.js index 2a340521387..8ff337aadf5 100644 --- a/app/routes/crate/repo.js +++ b/app/routes/crate/repo.js @@ -2,20 +2,20 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; export default Route.extend({ - flashMessages: service(), + flashMessages: service(), - redirect() { - let crate = this.modelFor('crate'); + redirect() { + let crate = this.modelFor('crate'); - let repository = crate.get('repository'); - if (repository) { - window.location = repository; - } else { - // Redirect to the crate's main page and show a flash error if - // no repository is found - let message = 'Crate does not supply a repository URL'; - this.flashMessages.queue(message); - this.replaceWith('crate', crate); - } - }, + let repository = crate.get('repository'); + if (repository) { + window.location = repository; + } else { + // Redirect to the crate's main page and show a flash error if + // no repository is found + let message = 'Crate does not supply a repository URL'; + this.flashMessages.queue(message); + this.replaceWith('crate', crate); + } + }, }); diff --git a/app/routes/crate/reverse-dependencies.js b/app/routes/crate/reverse-dependencies.js index 0f869a2569e..4a2c6d059f5 100644 --- a/app/routes/crate/reverse-dependencies.js +++ b/app/routes/crate/reverse-dependencies.js @@ -1,20 +1,20 @@ import Route from '@ember/routing/route'; export default Route.extend({ - queryParams: { - page: { refreshModel: true }, - }, + queryParams: { + page: { refreshModel: true }, + }, - model(params) { - params.reverse = true; - params.crate = this.modelFor('crate'); + model(params) { + params.reverse = true; + params.crate = this.modelFor('crate'); - return this.store.query('dependency', params); - }, + return this.store.query('dependency', params); + }, - setupController(controller) { - this._super(...arguments); - let crate = this.modelFor('crate'); - controller.set('crate', crate); - }, + setupController(controller) { + this._super(...arguments); + let crate = this.modelFor('crate'); + controller.set('crate', crate); + }, }); diff --git a/app/routes/crate/version.js b/app/routes/crate/version.js index b46a57fb226..86a6acf9395 100644 --- a/app/routes/crate/version.js +++ b/app/routes/crate/version.js @@ -6,122 +6,122 @@ import fetch from 'fetch'; import ajax from 'ember-fetch/ajax'; export default Route.extend({ - session: service(), + session: service(), - flashMessages: service(), + flashMessages: service(), - refreshAfterLogin: observer('session.isLoggedIn', function() { - this.refresh(); - }), + refreshAfterLogin: observer('session.isLoggedIn', function() { + this.refresh(); + }), - async model(params) { - const requestedVersion = params.version_num === 'all' ? '' : params.version_num; - const crate = this.modelFor('crate'); - const controller = this.controllerFor(this.routeName); - const maxVersion = crate.get('max_version'); + async model(params) { + const requestedVersion = params.version_num === 'all' ? '' : params.version_num; + const crate = this.modelFor('crate'); + const controller = this.controllerFor(this.routeName); + const maxVersion = crate.get('max_version'); - const isUnstableVersion = version => { - const versionLen = version.length; - let majorMinorPatchChars = 0; - let result = false; + const isUnstableVersion = version => { + const versionLen = version.length; + let majorMinorPatchChars = 0; + let result = false; - for (let i = 0; i < versionLen; i++) { - const char = version.charAt(i); + for (let i = 0; i < versionLen; i++) { + const char = version.charAt(i); - if (!isNaN(parseInt(char)) || char === '.') { - majorMinorPatchChars++; - } else { - break; - } - } - - if (versionLen !== majorMinorPatchChars) { - result = true; - } - - return result; - }; - - const fetchCrateDocumentation = () => { - if (!crate.get('documentation') || crate.get('documentation').substr(0, 16) === 'https://docs.rs/') { - let crateName = crate.get('name'); - let crateVersion = params.version_num; - ajax(`https://docs.rs/crate/${crateName}/${crateVersion}/builds.json`, { mode: 'cors' }).then(r => { - if (r.length > 0 && r[0].build_status === true) { - crate.set('documentation', `https://docs.rs/${crateName}/${crateVersion}/`); - } - }); - } - }; - - // Fallback to the crate's last stable version - // If `max_version` is `0.0.0` then all versions have been yanked - if (!requestedVersion && maxVersion !== '0.0.0') { - if (isUnstableVersion(maxVersion)) { - crate - .get('versions') - .then(versions => { - const latestStableVersion = versions.find(version => { - if (!isUnstableVersion(version.get('num')) && !version.get('yanked')) { - return version; - } - }); - - if (latestStableVersion == null) { - // If no stable version exists, fallback to `maxVersion` - params.version_num = maxVersion; - } else { - params.version_num = latestStableVersion.get('num'); - } - }) - .then(fetchCrateDocumentation); - } else { - params.version_num = maxVersion; - fetchCrateDocumentation(); - } + if (!isNaN(parseInt(char)) || char === '.') { + majorMinorPatchChars++; } else { - fetchCrateDocumentation(); - } - - controller.set('crate', crate); - controller.set('requestedVersion', requestedVersion); - controller.set('fetchingFollowing', true); - - if (this.get('session.currentUser')) { - ajax(`/api/v1/crates/${crate.get('name')}/following`) - .then(d => controller.set('following', d.following)) - .finally(() => controller.set('fetchingFollowing', false)); + break; } - - // Find version model - let versions = await crate.get('versions'); - - const version = versions.find(version => version.get('num') === params.version_num); - if (params.version_num && !version) { - this.flashMessages.queue(`Version '${params.version_num}' of crate '${crate.get('name')}' does not exist`); - } - - const result = version || versions.find(version => version.get('num') === maxVersion) || versions.objectAt(0); - - if (result.get('readme_path')) { - fetch(result.get('readme_path')) - .then(async r => { - if (r.ok) { - crate.set('readme', await r.text()); - } else { - crate.set('readme', null); - } - }) - .catch(() => { - crate.set('readme', null); - }); - } - - return result; - }, - - serialize(model) { - let version_num = model.get('num'); - return { version_num }; - }, + } + + if (versionLen !== majorMinorPatchChars) { + result = true; + } + + return result; + }; + + const fetchCrateDocumentation = () => { + if (!crate.get('documentation') || crate.get('documentation').substr(0, 16) === 'https://docs.rs/') { + let crateName = crate.get('name'); + let crateVersion = params.version_num; + ajax(`https://docs.rs/crate/${crateName}/${crateVersion}/builds.json`, { mode: 'cors' }).then(r => { + if (r.length > 0 && r[0].build_status === true) { + crate.set('documentation', `https://docs.rs/${crateName}/${crateVersion}/`); + } + }); + } + }; + + // Fallback to the crate's last stable version + // If `max_version` is `0.0.0` then all versions have been yanked + if (!requestedVersion && maxVersion !== '0.0.0') { + if (isUnstableVersion(maxVersion)) { + crate + .get('versions') + .then(versions => { + const latestStableVersion = versions.find(version => { + if (!isUnstableVersion(version.get('num')) && !version.get('yanked')) { + return version; + } + }); + + if (latestStableVersion == null) { + // If no stable version exists, fallback to `maxVersion` + params.version_num = maxVersion; + } else { + params.version_num = latestStableVersion.get('num'); + } + }) + .then(fetchCrateDocumentation); + } else { + params.version_num = maxVersion; + fetchCrateDocumentation(); + } + } else { + fetchCrateDocumentation(); + } + + controller.set('crate', crate); + controller.set('requestedVersion', requestedVersion); + controller.set('fetchingFollowing', true); + + if (this.get('session.currentUser')) { + ajax(`/api/v1/crates/${crate.get('name')}/following`) + .then(d => controller.set('following', d.following)) + .finally(() => controller.set('fetchingFollowing', false)); + } + + // Find version model + let versions = await crate.get('versions'); + + const version = versions.find(version => version.get('num') === params.version_num); + if (params.version_num && !version) { + this.flashMessages.queue(`Version '${params.version_num}' of crate '${crate.get('name')}' does not exist`); + } + + const result = version || versions.find(version => version.get('num') === maxVersion) || versions.objectAt(0); + + if (result.get('readme_path')) { + fetch(result.get('readme_path')) + .then(async r => { + if (r.ok) { + crate.set('readme', await r.text()); + } else { + crate.set('readme', null); + } + }) + .catch(() => { + crate.set('readme', null); + }); + } + + return result; + }, + + serialize(model) { + let version_num = model.get('num'); + return { version_num }; + }, }); diff --git a/app/routes/crates.js b/app/routes/crates.js index 17f7362a51f..b0968c8e54a 100644 --- a/app/routes/crates.js +++ b/app/routes/crates.js @@ -1,19 +1,19 @@ import Route from '@ember/routing/route'; export default Route.extend({ - queryParams: { - letter: { refreshModel: true }, - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, + queryParams: { + letter: { refreshModel: true }, + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, - model(params) { - // The backend throws an error if the letter param is - // empty or null. - if (!params.letter) { - delete params.letter; - } + model(params) { + // The backend throws an error if the letter param is + // empty or null. + if (!params.letter) { + delete params.letter; + } - return this.store.query('crate', params); - }, + return this.store.query('crate', params); + }, }); diff --git a/app/routes/dashboard.js b/app/routes/dashboard.js index 8e13703b0c7..2883935b16e 100644 --- a/app/routes/dashboard.js +++ b/app/routes/dashboard.js @@ -5,34 +5,34 @@ import RSVP from 'rsvp'; import AuthenticatedRoute from '../mixins/authenticated-route'; export default Route.extend(AuthenticatedRoute, { - setupController(controller) { - this._super(...arguments); + setupController(controller) { + this._super(...arguments); - controller.set('myCrates', this.get('data.myCrates')); - controller.set('myFollowing', this.get('data.myFollowing')); - controller.set('myStats', this.get('data.myStats')); + controller.set('myCrates', this.get('data.myCrates')); + controller.set('myFollowing', this.get('data.myFollowing')); + controller.set('myStats', this.get('data.myStats')); - if (!controller.loadingMore) { - controller.set('myFeed', A()); - controller.send('loadMore'); - } - }, + if (!controller.loadingMore) { + controller.set('myFeed', A()); + controller.send('loadMore'); + } + }, - model() { - return this.get('session.currentUser'); - }, + model() { + return this.get('session.currentUser'); + }, - async afterModel(user) { - let myCrates = this.store.query('crate', { - user_id: user.get('id'), - }); + async afterModel(user) { + let myCrates = this.store.query('crate', { + user_id: user.get('id'), + }); - let myFollowing = this.store.query('crate', { - following: 1, - }); + let myFollowing = this.store.query('crate', { + following: 1, + }); - let myStats = user.stats(); + let myStats = user.stats(); - this.set('data', await RSVP.hash({ myCrates, myFollowing, myStats })); - }, + this.set('data', await RSVP.hash({ myCrates, myFollowing, myStats })); + }, }); diff --git a/app/routes/github-authorize.js b/app/routes/github-authorize.js index 0fcc44e5d58..4ee10cd9a18 100644 --- a/app/routes/github-authorize.js +++ b/app/routes/github-authorize.js @@ -16,22 +16,22 @@ import { serializeQueryParams } from 'ember-fetch/utils/serialize-query-params'; * @see `/login` route */ export default Route.extend({ - async beforeModel(transition) { - try { - let queryParams = serializeQueryParams(transition.queryParams); - let resp = await fetch(`/authorize?${queryParams}`); - let json = await resp.json(); - let item = JSON.stringify({ ok: resp.ok, data: json }); - if (window.opener) { - window.opener.github_response = item; - } - } catch (d) { - let item = JSON.stringify({ ok: false, data: d }); - if (window.opener) { - window.opener.github_response = item; - } - } finally { - window.close(); - } - }, + async beforeModel(transition) { + try { + let queryParams = serializeQueryParams(transition.queryParams); + let resp = await fetch(`/authorize?${queryParams}`); + let json = await resp.json(); + let item = JSON.stringify({ ok: resp.ok, data: json }); + if (window.opener) { + window.opener.github_response = item; + } + } catch (d) { + let item = JSON.stringify({ ok: false, data: d }); + if (window.opener) { + window.opener.github_response = item; + } + } finally { + window.close(); + } + }, }); diff --git a/app/routes/github-login.js b/app/routes/github-login.js index 8386a59318f..904e386725b 100644 --- a/app/routes/github-login.js +++ b/app/routes/github-login.js @@ -15,8 +15,8 @@ import ajax from 'ember-fetch/ajax'; * @see `github-authorize` route */ export default Route.extend({ - async beforeModel() { - let url = await ajax(`/authorize_url`); - window.location = url.url; - }, + async beforeModel() { + let url = await ajax(`/authorize_url`); + window.location = url.url; + }, }); diff --git a/app/routes/index.js b/app/routes/index.js index 44a52edf53a..f3502da44d8 100644 --- a/app/routes/index.js +++ b/app/routes/index.js @@ -1,19 +1,19 @@ import Route from '@ember/routing/route'; export default Route.extend({ - headTags() { - return [ - { - type: 'meta', - attrs: { - name: 'description', - content: 'cargo is the package manager and crate host for rust', - }, - }, - ]; - }, + headTags() { + return [ + { + type: 'meta', + attrs: { + name: 'description', + content: 'cargo is the package manager and crate host for rust', + }, + }, + ]; + }, - setupController(controller) { - controller.dataTask.perform(); - }, + setupController(controller) { + controller.dataTask.perform(); + }, }); diff --git a/app/routes/install.js b/app/routes/install.js index 006e9fece36..7c52f9ce3da 100644 --- a/app/routes/install.js +++ b/app/routes/install.js @@ -1,7 +1,7 @@ import Route from '@ember/routing/route'; export default Route.extend({ - redirect() { - window.location = 'https://doc.rust-lang.org/cargo/getting-started/installation.html'; - }, + redirect() { + window.location = 'https://doc.rust-lang.org/cargo/getting-started/installation.html'; + }, }); diff --git a/app/routes/keyword.js b/app/routes/keyword.js index 49056de679f..cc5dfa1dba0 100644 --- a/app/routes/keyword.js +++ b/app/routes/keyword.js @@ -2,14 +2,14 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; export default Route.extend({ - flashMessages: service(), + flashMessages: service(), - model({ keyword_id }) { - return this.store.find('keyword', keyword_id).catch(e => { - if (e.errors.some(e => e.detail === 'Not Found')) { - this.flashMessages.queue(`Keyword '${keyword_id}' does not exist`); - return this.replaceWith('index'); - } - }); - }, + model({ keyword_id }) { + return this.store.find('keyword', keyword_id).catch(e => { + if (e.errors.some(e => e.detail === 'Not Found')) { + this.flashMessages.queue(`Keyword '${keyword_id}' does not exist`); + return this.replaceWith('index'); + } + }); + }, }); diff --git a/app/routes/keyword/index.js b/app/routes/keyword/index.js index 9f8bcb5ba10..48f0e56588e 100644 --- a/app/routes/keyword/index.js +++ b/app/routes/keyword/index.js @@ -1,18 +1,18 @@ import Route from '@ember/routing/route'; export default Route.extend({ - queryParams: { - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, + queryParams: { + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, - model(params) { - params.keyword = this.modelFor('keyword').id; - return this.store.query('crate', params); - }, + model(params) { + params.keyword = this.modelFor('keyword').id; + return this.store.query('crate', params); + }, - setupController(controller) { - controller.set('keyword', this.modelFor('keyword')); - this._super(...arguments); - }, + setupController(controller) { + controller.set('keyword', this.modelFor('keyword')); + this._super(...arguments); + }, }); diff --git a/app/routes/keywords.js b/app/routes/keywords.js index 3f450f138c7..1027b4ac4f5 100644 --- a/app/routes/keywords.js +++ b/app/routes/keywords.js @@ -1,12 +1,12 @@ import Route from '@ember/routing/route'; export default Route.extend({ - queryParams: { - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, + queryParams: { + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, - model(params) { - return this.store.query('keyword', params); - }, + model(params) { + return this.store.query('keyword', params); + }, }); diff --git a/app/routes/login.js b/app/routes/login.js index 07ddf3fdab7..bed6ee39b3e 100644 --- a/app/routes/login.js +++ b/app/routes/login.js @@ -9,69 +9,69 @@ import { inject as service } from '@ember/service'; * @see `github-authorize` route */ export default Route.extend({ - flashMessages: service(), - session: service(), + flashMessages: service(), + session: service(), - beforeModel(transition) { - try { - localStorage.removeItem('github_response'); - } catch (e) { - // ignore error - } + beforeModel(transition) { + try { + localStorage.removeItem('github_response'); + } catch (e) { + // ignore error + } - window.github_response = undefined; - let windowDimensions = [ - 'width=1000', - 'height=450', - 'toolbar=0', - 'scrollbars=1', - 'status=1', - 'resizable=1', - 'location=1', - 'menuBar=0', - ].join(','); + window.github_response = undefined; + let windowDimensions = [ + 'width=1000', + 'height=450', + 'toolbar=0', + 'scrollbars=1', + 'status=1', + 'resizable=1', + 'location=1', + 'menuBar=0', + ].join(','); - let win = window.open('/github_login', 'Authorization', windowDimensions); - if (!win) { - return; - } + let win = window.open('/github_login', 'Authorization', windowDimensions); + if (!win) { + return; + } - // For the life of me I cannot figure out how to do this other than - // polling - let oauthInterval = window.setInterval(() => { - if (!win.closed) { - return; - } - window.clearInterval(oauthInterval); - let json = window.github_response; - window.github_response = undefined; - if (!json) { - return; - } + // For the life of me I cannot figure out how to do this other than + // polling + let oauthInterval = window.setInterval(() => { + if (!win.closed) { + return; + } + window.clearInterval(oauthInterval); + let json = window.github_response; + window.github_response = undefined; + if (!json) { + return; + } - let response = JSON.parse(json); - if (!response) { - return; - } + let response = JSON.parse(json); + if (!response) { + return; + } - let { data } = response; - if (data && data.errors) { - let error = `Failed to log in: ${data.errors[0].detail}`; - this.flashMessages.show(error); - return; - } else if (!response.ok) { - this.flashMessages.show('Failed to log in'); - return; - } + let { data } = response; + if (data && data.errors) { + let error = `Failed to log in: ${data.errors[0].detail}`; + this.flashMessages.show(error); + return; + } else if (!response.ok) { + this.flashMessages.show('Failed to log in'); + return; + } - let user = this.store.push(this.store.normalize('user', data.user)); - let transition = this.get('session.savedTransition'); - this.session.loginUser(user); - if (transition) { - transition.retry(); - } - }, 200); + let user = this.store.push(this.store.normalize('user', data.user)); + let transition = this.get('session.savedTransition'); + this.session.loginUser(user); + if (transition) { + transition.retry(); + } + }, 200); - transition.abort(); - }, + transition.abort(); + }, }); diff --git a/app/routes/logout.js b/app/routes/logout.js index f5e3e90c556..7fc5fd7bb30 100644 --- a/app/routes/logout.js +++ b/app/routes/logout.js @@ -4,13 +4,13 @@ import { inject as service } from '@ember/service'; import ajax from 'ember-fetch/ajax'; export default Route.extend({ - session: service(), + session: service(), - async activate() { - await ajax(`/logout`, { method: 'DELETE' }); - run(() => { - this.session.logoutUser(); - this.transitionTo('index'); - }); - }, + async activate() { + await ajax(`/logout`, { method: 'DELETE' }); + run(() => { + this.session.logoutUser(); + this.transitionTo('index'); + }); + }, }); diff --git a/app/routes/me/crates.js b/app/routes/me/crates.js index a793a754055..9d302af0c46 100644 --- a/app/routes/me/crates.js +++ b/app/routes/me/crates.js @@ -3,13 +3,13 @@ import Route from '@ember/routing/route'; import AuthenticatedRoute from '../../mixins/authenticated-route'; export default Route.extend(AuthenticatedRoute, { - queryParams: { - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, + queryParams: { + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, - model(params) { - params.user_id = this.get('session.currentUser.id'); - return this.store.query('crate', params); - }, + model(params) { + params.user_id = this.get('session.currentUser.id'); + return this.store.query('crate', params); + }, }); diff --git a/app/routes/me/following.js b/app/routes/me/following.js index 31966532829..3843fc2d622 100644 --- a/app/routes/me/following.js +++ b/app/routes/me/following.js @@ -3,13 +3,13 @@ import Route from '@ember/routing/route'; import AuthenticatedRoute from '../../mixins/authenticated-route'; export default Route.extend(AuthenticatedRoute, { - queryParams: { - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, + queryParams: { + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, - model(params) { - params.following = 1; - return this.store.query('crate', params); - }, + model(params) { + params.following = 1; + return this.store.query('crate', params); + }, }); diff --git a/app/routes/me/index.js b/app/routes/me/index.js index b205f67453d..7e0fb31bcbe 100644 --- a/app/routes/me/index.js +++ b/app/routes/me/index.js @@ -3,10 +3,10 @@ import Route from '@ember/routing/route'; import AuthenticatedRoute from '../../mixins/authenticated-route'; export default Route.extend(AuthenticatedRoute, { - model() { - return { - user: this.get('session.currentUser'), - api_tokens: this.store.findAll('api-token'), - }; - }, + model() { + return { + user: this.get('session.currentUser'), + api_tokens: this.store.findAll('api-token'), + }; + }, }); diff --git a/app/routes/me/pending-invites.js b/app/routes/me/pending-invites.js index 318ce3b8fe4..d8a5e77de76 100644 --- a/app/routes/me/pending-invites.js +++ b/app/routes/me/pending-invites.js @@ -3,7 +3,7 @@ import Route from '@ember/routing/route'; import AuthenticatedRoute from '../../mixins/authenticated-route'; export default Route.extend(AuthenticatedRoute, { - model() { - return this.store.findAll('crate-owner-invite'); - }, + model() { + return this.store.findAll('crate-owner-invite'); + }, }); diff --git a/app/routes/search.js b/app/routes/search.js index 8132c7235fc..62a8325e11d 100644 --- a/app/routes/search.js +++ b/app/routes/search.js @@ -1,19 +1,19 @@ import Route from '@ember/routing/route'; export default Route.extend({ - queryParams: { - q: { refreshModel: true }, - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, + queryParams: { + q: { refreshModel: true }, + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, - model(params) { - // we need a model() implementation that changes, otherwise the setupController() hook - // is not called and we won't reload the results if a new query string is used - return params; - }, + model(params) { + // we need a model() implementation that changes, otherwise the setupController() hook + // is not called and we won't reload the results if a new query string is used + return params; + }, - setupController(controller, params) { - controller.dataTask.perform(params); - }, + setupController(controller, params) { + controller.dataTask.perform(params); + }, }); diff --git a/app/routes/team.js b/app/routes/team.js index a0c539e2157..48706381ad2 100644 --- a/app/routes/team.js +++ b/app/routes/team.js @@ -3,31 +3,31 @@ import { inject as service } from '@ember/service'; import RSVP from 'rsvp'; export default Route.extend({ - flashMessages: service(), + flashMessages: service(), - queryParams: { - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, + queryParams: { + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, - model(params) { - const { team_id } = params; + model(params) { + const { team_id } = params; - return this.store.queryRecord('team', { team_id }).then( - team => { - params.team_id = team.get('id'); - params.include_yanked = 'n'; - return RSVP.hash({ - crates: this.store.query('crate', params), - team, - }); - }, - e => { - if (e.errors.some(e => e.detail === 'Not Found')) { - this.flashMessages.queue(`Team '${params.team_id}' does not exist`); - return this.replaceWith('index'); - } - }, - ); - }, + return this.store.queryRecord('team', { team_id }).then( + team => { + params.team_id = team.get('id'); + params.include_yanked = 'n'; + return RSVP.hash({ + crates: this.store.query('crate', params), + team, + }); + }, + e => { + if (e.errors.some(e => e.detail === 'Not Found')) { + this.flashMessages.queue(`Team '${params.team_id}' does not exist`); + return this.replaceWith('index'); + } + }, + ); + }, }); diff --git a/app/routes/user.js b/app/routes/user.js index a47e3b258c8..10bbe8b292e 100644 --- a/app/routes/user.js +++ b/app/routes/user.js @@ -3,30 +3,30 @@ import { inject as service } from '@ember/service'; import RSVP from 'rsvp'; export default Route.extend({ - flashMessages: service(), + flashMessages: service(), - queryParams: { - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, + queryParams: { + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, - model(params) { - const { user_id } = params; - return this.store.queryRecord('user', { user_id }).then( - user => { - params.user_id = user.get('id'); - params.include_yanked = 'n'; - return RSVP.hash({ - crates: this.store.query('crate', params), - user, - }); - }, - e => { - if (e.errors.some(e => e.detail === 'Not Found')) { - this.flashMessages.queue(`User '${params.user_id}' does not exist`); - return this.replaceWith('index'); - } - }, - ); - }, + model(params) { + const { user_id } = params; + return this.store.queryRecord('user', { user_id }).then( + user => { + params.user_id = user.get('id'); + params.include_yanked = 'n'; + return RSVP.hash({ + crates: this.store.query('crate', params), + user, + }); + }, + e => { + if (e.errors.some(e => e.detail === 'Not Found')) { + this.flashMessages.queue(`User '${params.user_id}' does not exist`); + return this.replaceWith('index'); + } + }, + ); + }, }); diff --git a/app/serializers/api-token.js b/app/serializers/api-token.js index 52a9a49e870..449579d7e4c 100644 --- a/app/serializers/api-token.js +++ b/app/serializers/api-token.js @@ -1,7 +1,7 @@ import DS from 'ember-data'; export default DS.RESTSerializer.extend({ - payloadKeyFromModelName() { - return 'api_token'; - }, + payloadKeyFromModelName() { + return 'api_token'; + }, }); diff --git a/app/serializers/crate-owner-invite.js b/app/serializers/crate-owner-invite.js index 65bcb7e7cfe..724732be8b9 100644 --- a/app/serializers/crate-owner-invite.js +++ b/app/serializers/crate-owner-invite.js @@ -1,11 +1,11 @@ import DS from 'ember-data'; export default DS.RESTSerializer.extend({ - primaryKey: 'crate_id', - modelNameFromPayloadKey() { - return 'crate-owner-invite'; - }, - payloadKeyFromModelName() { - return 'crate_owner_invite'; - }, + primaryKey: 'crate_id', + modelNameFromPayloadKey() { + return 'crate-owner-invite'; + }, + payloadKeyFromModelName() { + return 'crate_owner_invite'; + }, }); diff --git a/app/serializers/crate.js b/app/serializers/crate.js index b8b9500e2d8..cde8d51c725 100644 --- a/app/serializers/crate.js +++ b/app/serializers/crate.js @@ -1,13 +1,13 @@ import DS from 'ember-data'; export default DS.RESTSerializer.extend({ - isNewSerializerAPI: true, + isNewSerializerAPI: true, - extractRelationships(modelClass, resourceHash) { - if (resourceHash.versions == null) { - delete resourceHash.versions; - } + extractRelationships(modelClass, resourceHash) { + if (resourceHash.versions == null) { + delete resourceHash.versions; + } - return this._super(...arguments); - }, + return this._super(...arguments); + }, }); diff --git a/app/serializers/dependency.js b/app/serializers/dependency.js index 865e3a63a4e..e03395aed0b 100644 --- a/app/serializers/dependency.js +++ b/app/serializers/dependency.js @@ -1,7 +1,7 @@ import DS from 'ember-data'; export default DS.RESTSerializer.extend({ - attrs: { - version: 'version_id', - }, + attrs: { + version: 'version_id', + }, }); diff --git a/app/serializers/version-download.js b/app/serializers/version-download.js index 48c5589a423..830917e2b9e 100644 --- a/app/serializers/version-download.js +++ b/app/serializers/version-download.js @@ -1,7 +1,7 @@ import DS from 'ember-data'; export default DS.RESTSerializer.extend({ - extractId(modelClass, resourceHash) { - return `${resourceHash.date}-${resourceHash.version}`; - }, + extractId(modelClass, resourceHash) { + return `${resourceHash.date}-${resourceHash.version}`; + }, }); diff --git a/app/services/flash-messages.js b/app/services/flash-messages.js index 62ff4826e35..e8f2568fe54 100644 --- a/app/services/flash-messages.js +++ b/app/services/flash-messages.js @@ -1,19 +1,19 @@ import Service from '@ember/service'; export default Service.extend({ - message: null, - _nextMessage: null, + message: null, + _nextMessage: null, - show(message) { - this.set('message', message); - }, + show(message) { + this.set('message', message); + }, - queue(message) { - this.set('_nextMessage', message); - }, + queue(message) { + this.set('_nextMessage', message); + }, - step() { - this.set('message', this._nextMessage); - this.set('_nextMessage', null); - }, + step() { + this.set('message', this._nextMessage); + this.set('_nextMessage', null); + }, }); diff --git a/app/services/search.js b/app/services/search.js index 47ff25937ce..89fb6aa8d73 100644 --- a/app/services/search.js +++ b/app/services/search.js @@ -1,5 +1,5 @@ import Service from '@ember/service'; export default Service.extend({ - q: null, + q: null, }); diff --git a/app/services/session.js b/app/services/session.js index 2eb60002234..9b9903f38b8 100644 --- a/app/services/session.js +++ b/app/services/session.js @@ -2,91 +2,91 @@ import Service, { inject as service } from '@ember/service'; import ajax from 'ember-fetch/ajax'; export default Service.extend({ - savedTransition: null, - abortedTransition: null, - isLoggedIn: false, - currentUser: null, - currentUserDetected: false, + savedTransition: null, + abortedTransition: null, + isLoggedIn: false, + currentUser: null, + currentUserDetected: false, - store: service(), - router: service(), + store: service(), + router: service(), - init() { - this._super(...arguments); - let isLoggedIn; - try { - isLoggedIn = localStorage.getItem('isLoggedIn') === '1'; - } catch (e) { - isLoggedIn = false; - } - this.set('isLoggedIn', isLoggedIn); - this.set('currentUser', null); - }, + init() { + this._super(...arguments); + let isLoggedIn; + try { + isLoggedIn = localStorage.getItem('isLoggedIn') === '1'; + } catch (e) { + isLoggedIn = false; + } + this.set('isLoggedIn', isLoggedIn); + this.set('currentUser', null); + }, - loginUser(user) { - this.set('isLoggedIn', true); - this.set('currentUser', user); - try { - localStorage.setItem('isLoggedIn', '1'); - } catch (e) { - // ignore error - } - }, + loginUser(user) { + this.set('isLoggedIn', true); + this.set('currentUser', user); + try { + localStorage.setItem('isLoggedIn', '1'); + } catch (e) { + // ignore error + } + }, - logoutUser() { - this.set('savedTransition', null); - this.set('abortedTransition', null); - this.set('isLoggedIn', null); - this.set('currentUser', null); + logoutUser() { + this.set('savedTransition', null); + this.set('abortedTransition', null); + this.set('isLoggedIn', null); + this.set('currentUser', null); - try { - localStorage.removeItem('isLoggedIn'); - } catch (e) { - // ignore error - } - }, + try { + localStorage.removeItem('isLoggedIn'); + } catch (e) { + // ignore error + } + }, - loadUser() { - if (this.isLoggedIn && !this.currentUser) { - this.fetchUser() - .catch(() => this.logoutUser()) - .finally(() => { - this.set('currentUserDetected', true); - let transition = this.abortedTransition; - if (transition) { - transition.retry(); - this.set('abortedTransition', null); - } - }); - } else { - this.set('currentUserDetected', true); - } - }, - - fetchUser() { - return ajax('/api/v1/me').then(response => { - this.set('currentUser', this.store.push(this.store.normalize('user', response.user))); + loadUser() { + if (this.isLoggedIn && !this.currentUser) { + this.fetchUser() + .catch(() => this.logoutUser()) + .finally(() => { + this.set('currentUserDetected', true); + let transition = this.abortedTransition; + if (transition) { + transition.retry(); + this.set('abortedTransition', null); + } }); - }, + } else { + this.set('currentUserDetected', true); + } + }, + + fetchUser() { + return ajax('/api/v1/me').then(response => { + this.set('currentUser', this.store.push(this.store.normalize('user', response.user))); + }); + }, - checkCurrentUser(transition, beforeRedirect) { - if (this.currentUser) { - return; - } + checkCurrentUser(transition, beforeRedirect) { + if (this.currentUser) { + return; + } - // The current user is loaded asynchronously, so if we haven't actually - // loaded the current user yet then we need to wait for it to be loaded. - // Once we've done that we can retry the transition and start the whole - // process over again! - if (!this.currentUserDetected) { - transition.abort(); - this.set('abortedTransition', transition); - } else { - this.set('savedTransition', transition); - if (beforeRedirect) { - beforeRedirect(); - } - return this.router.transitionTo('index'); - } - }, + // The current user is loaded asynchronously, so if we haven't actually + // loaded the current user yet then we need to wait for it to be loaded. + // Once we've done that we can retry the transition and start the whole + // process over again! + if (!this.currentUserDetected) { + transition.abort(); + this.set('abortedTransition', transition); + } else { + this.set('savedTransition', transition); + if (beforeRedirect) { + beforeRedirect(); + } + return this.router.transitionTo('index'); + } + }, }); diff --git a/app/templates/application.hbs b/app/templates/application.hbs index 883a6ea4d31..3cffa08ef8d 100644 --- a/app/templates/application.hbs +++ b/app/templates/application.hbs @@ -4,133 +4,133 @@ {{google-jsapi}}
- {{flash-message}} + {{flash-message}} - {{outlet}} + {{outlet}}
diff --git a/app/templates/catch-all.hbs b/app/templates/catch-all.hbs index e86dc64dd16..c4a01a5a5e6 100644 --- a/app/templates/catch-all.hbs +++ b/app/templates/catch-all.hbs @@ -1,11 +1,11 @@

Oops, that route doesn't exist!

- Perhaps a search of the site may help? + Perhaps a search of the site may help? - {{input type="text" class="search" - placeholder="Search" - value=search - enter="search" - required=true}} + {{input type="text" class="search" + placeholder="Search" + value=search + enter="search" + required=true}}

diff --git a/app/templates/categories.hbs b/app/templates/categories.hbs index f59c02996bb..b3ae63b6e5e 100644 --- a/app/templates/categories.hbs +++ b/app/templates/categories.hbs @@ -1,72 +1,72 @@ {{ title 'Categories' }}
- {{svg-jar "crate"}} -

All Categories

+ {{svg-jar "crate"}} +

All Categories

- + -
- Sort by - {{#rl-dropdown-container class="dropdown-container"}} - {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} - {{svg-jar "sort"}} - {{ currentSortBy }} - - {{/rl-dropdown-toggle}} +
+ Sort by + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} + {{svg-jar "sort"}} + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} - {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to (query-params sort="alpha")}} - Alphabetical - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="crates")}} - # Crates - {{/link-to}} -
  • - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params sort="alpha")}} + Alphabetical + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="crates")}} + # Crates + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    - {{#each model as |category|}} -
    -
    -
    - {{link-to category.category "category" category.slug}} - - {{ pluralize (format-num category.crates_cnt) "crate" }} - -
    -
    - - {{ category.description }} - -
    -
    + {{#each model as |category|}} +
    +
    +
    + {{link-to category.category "category" category.slug}} + + {{ pluralize (format-num category.crates_cnt) "crate" }} +
    - {{/each}} +
    + + {{ category.description }} + +
    +
    +
    + {{/each}}
    diff --git a/app/templates/category-slugs.hbs b/app/templates/category-slugs.hbs index 8644b50d134..5adf0881bae 100644 --- a/app/templates/category-slugs.hbs +++ b/app/templates/category-slugs.hbs @@ -1,17 +1,17 @@ {{ title 'Category Slugs' }}
    -
    - {{svg-jar "crate"}} -

    All Valid Category Slugs

    -
    +
    + {{svg-jar "crate"}} +

    All Valid Category Slugs

    +
    -
    -
    - {{#each model as |category|}} -
    {{category.slug}}
    -
    {{category.description}}
    - {{/each}} -
    -
    +
    +
    + {{#each model as |category|}} +
    {{category.slug}}
    +
    {{category.description}}
    + {{/each}} +
    +
    diff --git a/app/templates/category/index.hbs b/app/templates/category/index.hbs index a54d5ea9cdd..537ce8c60d8 100644 --- a/app/templates/category/index.hbs +++ b/app/templates/category/index.hbs @@ -1,101 +1,101 @@ {{ title category.category ' - Categories' }}
    - {{#link-to "categories" (html-attributes aria-label="Categories")}}{{svg-jar "crate"}}{{/link-to}} -

    - {{#each category.parent_categories as |parent|}}{{link-to parent.category "category" parent.slug}}::{{/each}} - {{~ category.category }} -

    + {{#link-to "categories" (html-attributes aria-label="Categories")}}{{svg-jar "crate"}}{{/link-to}} +

    + {{#each category.parent_categories as |parent|}}{{link-to parent.category "category" parent.slug}}::{{/each}} + {{~ category.category }} +

    -

    {{ category.description }}

    +

    {{ category.description }}

    {{#if category.subcategories }}
    -

    Subcategories

    -
    - {{#each category.subcategories as |subcategory| }} -
    -
    -
    - {{link-to subcategory.category "category" subcategory.slug}} - - {{ pluralize (format-num subcategory.crates_cnt) "crate" }} - -
    -
    - - {{ subcategory.description }} - -
    -
    -
    - {{/each}} -
    +

    Subcategories

    +
    + {{#each category.subcategories as |subcategory| }} +
    +
    +
    + {{link-to subcategory.category "category" subcategory.slug}} + + {{ pluralize (format-num subcategory.crates_cnt) "crate" }} + +
    +
    + + {{ subcategory.description }} + +
    +
    +
    + {{/each}} +
    {{/if}}

    Crates

    - + -
    - Sort by - {{#rl-dropdown-container class="dropdown-container"}} - {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} - {{svg-jar "sort"}} - {{ currentSortBy }} - - {{/rl-dropdown-toggle}} +
    + Sort by + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} + {{svg-jar "sort"}} + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} - {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to (query-params sort="alpha")}} - Alphabetical - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="downloads")}} - All-Time Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="recent-downloads")}} - Recent Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="recent-updates")}} - Recent Updates - {{/link-to}} -
  • - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params sort="alpha")}} + Alphabetical + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="downloads")}} + All-Time Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="recent-downloads")}} + Recent Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="recent-updates")}} + Recent Updates + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    - {{#each model as |crate|}} - {{crate-row crate=crate}} - {{/each}} + {{#each model as |crate|}} + {{crate-row crate=crate}} + {{/each}}
    diff --git a/app/templates/components/api-token-row.hbs b/app/templates/components/api-token-row.hbs index 83d5f331463..8eeaf0a4dfa 100644 --- a/app/templates/components/api-token-row.hbs +++ b/app/templates/components/api-token-row.hbs @@ -1,74 +1,78 @@
    -
    - {{#if api_token.isNew}} - {{input - type="text" - placeholder="New token name" - disabled=api_token.isSaving - value=api_token.name - autofocus=true - enter="saveToken"}} - {{else}} - {{ api_token.name }} - {{/if}} -
    +
    + {{#if api_token.isNew}} + {{input + type="text" + placeholder="New token name" + disabled=api_token.isSaving + value=api_token.name + autofocus=true + enter="saveToken"}} + {{else}} + {{ api_token.name }} + {{/if}} +
    -
    +
    - {{#unless api_token.isNew}} -
    -
    - - Created {{moment-from-now api_token.created_at}} - -
    - {{#if api_token.last_used_at}} -
    - - Last used {{moment-from-now api_token.last_used_at}} - -
    - {{else}} -
    - Never used -
    - {{/if}} + {{#unless api_token.isNew}} +
    +
    + + Created {{moment-from-now api_token.created_at}} + +
    + {{#if api_token.last_used_at}} +
    + + Last used {{moment-from-now api_token.last_used_at}} +
    - {{/unless}} - -
    - {{#if api_token.isNew}} - - {{else}} - - {{/if}} - {{#if api_token.isSaving}} - - {{/if}} + {{else}} +
    + Never used +
    + {{/if}}
    + {{/unless}} + +
    + {{#if api_token.isNew}} + + {{else}} + + {{/if}} + {{#if api_token.isSaving}} + + {{/if}} +
    {{#if serverError}} -
    -
    - {{ serverError }} -
    +
    +
    + {{ serverError }}
    +
    {{/if}} {{#if api_token.token}} -
    -
    - Please record this token somewhere, you cannot retrieve - its value again. For use on the command line you can save it to ~/.cargo/credentials - with: +
    +
    + Please record this token somewhere, you cannot retrieve + its value again. For use on the command line you can save it to ~/.cargo/credentials + with: -
    cargo login {{ api_token.token }}
    -
    +
    cargo login {{ api_token.token }}
    +
    {{/if}} diff --git a/app/templates/components/badge-appveyor.hbs b/app/templates/components/badge-appveyor.hbs index 7f4fc26fa9f..7c6cc34c8a2 100644 --- a/app/templates/components/badge-appveyor.hbs +++ b/app/templates/components/badge-appveyor.hbs @@ -1,8 +1,8 @@
    - {{ text }} + {{ text }} diff --git a/app/templates/components/badge-azure-devops.hbs b/app/templates/components/badge-azure-devops.hbs index 8b39bac3ccd..b58e9721f46 100644 --- a/app/templates/components/badge-azure-devops.hbs +++ b/app/templates/components/badge-azure-devops.hbs @@ -1,3 +1,3 @@ - {{ text }} + {{ text }} diff --git a/app/templates/components/badge-circle-ci.hbs b/app/templates/components/badge-circle-ci.hbs index 8dbc73a8e08..c26dc67f844 100644 --- a/app/templates/components/badge-circle-ci.hbs +++ b/app/templates/components/badge-circle-ci.hbs @@ -1,6 +1,6 @@ - {{ text }} + {{ text }} diff --git a/app/templates/components/badge-cirrus-ci.hbs b/app/templates/components/badge-cirrus-ci.hbs index 67a23242528..33afc52d760 100644 --- a/app/templates/components/badge-cirrus-ci.hbs +++ b/app/templates/components/badge-cirrus-ci.hbs @@ -1,6 +1,6 @@ - {{ text }} + {{ text }} diff --git a/app/templates/components/badge-codecov.hbs b/app/templates/components/badge-codecov.hbs index 87143b29349..b411913e4a5 100644 --- a/app/templates/components/badge-codecov.hbs +++ b/app/templates/components/badge-codecov.hbs @@ -1,6 +1,6 @@ - {{ text }} - \ No newline at end of file + {{ text }} + diff --git a/app/templates/components/badge-coveralls.hbs b/app/templates/components/badge-coveralls.hbs index 220d1051815..3beeeaeae84 100644 --- a/app/templates/components/badge-coveralls.hbs +++ b/app/templates/components/badge-coveralls.hbs @@ -1,6 +1,6 @@ - {{ text }} - \ No newline at end of file + {{ text }} + diff --git a/app/templates/components/badge-gitlab.hbs b/app/templates/components/badge-gitlab.hbs index 97abe5a7c31..20446090887 100644 --- a/app/templates/components/badge-gitlab.hbs +++ b/app/templates/components/badge-gitlab.hbs @@ -1,6 +1,6 @@ - {{ text }} + {{ text }} diff --git a/app/templates/components/badge-is-it-maintained-issue-resolution.hbs b/app/templates/components/badge-is-it-maintained-issue-resolution.hbs index c74a632f527..604b2d128df 100644 --- a/app/templates/components/badge-is-it-maintained-issue-resolution.hbs +++ b/app/templates/components/badge-is-it-maintained-issue-resolution.hbs @@ -1,6 +1,6 @@ - {{ text }} + {{ text }} diff --git a/app/templates/components/badge-is-it-maintained-open-issues.hbs b/app/templates/components/badge-is-it-maintained-open-issues.hbs index fb9c47c9908..7034e257d96 100644 --- a/app/templates/components/badge-is-it-maintained-open-issues.hbs +++ b/app/templates/components/badge-is-it-maintained-open-issues.hbs @@ -1,6 +1,6 @@ - {{ text }} + {{ text }} diff --git a/app/templates/components/badge-maintenance.hbs b/app/templates/components/badge-maintenance.hbs index 5210f1189d5..c1fe446056e 100644 --- a/app/templates/components/badge-maintenance.hbs +++ b/app/templates/components/badge-maintenance.hbs @@ -1,6 +1,6 @@ {{#unless none}} - {{text}} + {{text}} {{/unless}} diff --git a/app/templates/components/badge-travis-ci.hbs b/app/templates/components/badge-travis-ci.hbs index c5dbc330b31..c61c2e6d64d 100644 --- a/app/templates/components/badge-travis-ci.hbs +++ b/app/templates/components/badge-travis-ci.hbs @@ -1,6 +1,6 @@ - {{ text }} + {{ text }} diff --git a/app/templates/components/category-list.hbs b/app/templates/components/category-list.hbs index 172406d6ce4..d1c092b2c6d 100644 --- a/app/templates/components/category-list.hbs +++ b/app/templates/components/category-list.hbs @@ -1,12 +1,12 @@
      - {{#each categories as |category|}} -
    • - {{#link-to 'category' category.slug class='name'}} - {{ category.category }} ({{ format-num category.crates_cnt }}) -
      - {{svg-jar "right-arrow"}} -
      - {{/link-to}} -
    • - {{/each}} + {{#each categories as |category|}} +
    • + {{#link-to 'category' category.slug class='name'}} + {{ category.category }} ({{ format-num category.crates_cnt }}) +
      + {{svg-jar "right-arrow"}} +
      + {{/link-to}} +
    • + {{/each}}
    diff --git a/app/templates/components/crate-downloads-list.hbs b/app/templates/components/crate-downloads-list.hbs index 9fa90c936f9..69f7341e952 100644 --- a/app/templates/components/crate-downloads-list.hbs +++ b/app/templates/components/crate-downloads-list.hbs @@ -1,13 +1,13 @@
      - {{#each crates as |crate|}} -
    • - {{#link-to 'crate' crate.id class='name'}} - {{ crate.name }} ({{ crate.max_version }}) -
      - {{svg-jar "download-clear-back"}} - {{ format-num crate.downloads }} -
      - {{/link-to}} -
    • - {{/each}} + {{#each crates as |crate|}} +
    • + {{#link-to 'crate' crate.id class='name'}} + {{ crate.name }} ({{ crate.max_version }}) +
      + {{svg-jar "download-clear-back"}} + {{ format-num crate.downloads }} +
      + {{/link-to}} +
    • + {{/each}}
    diff --git a/app/templates/components/crate-list.hbs b/app/templates/components/crate-list.hbs index f13d4061ffb..50a474d7210 100644 --- a/app/templates/components/crate-list.hbs +++ b/app/templates/components/crate-list.hbs @@ -1,12 +1,12 @@
      - {{#each crates as |crate index|}} -
    1. - {{#link-to 'crate' crate.id class='name' data-test-crate-link=index}} - {{ crate.name }} ({{ crate.max_version }}) -
      - {{svg-jar "right-arrow"}} -
      - {{/link-to}} -
    2. - {{/each}} + {{#each crates as |crate index|}} +
    3. + {{#link-to 'crate' crate.id class='name' data-test-crate-link=index}} + {{ crate.name }} ({{ crate.max_version }}) +
      + {{svg-jar "right-arrow"}} +
      + {{/link-to}} +
    4. + {{/each}}
    diff --git a/app/templates/components/crate-row.hbs b/app/templates/components/crate-row.hbs index 2111cbc0c8a..f61dddfef4a 100644 --- a/app/templates/components/crate-row.hbs +++ b/app/templates/components/crate-row.hbs @@ -1,37 +1,37 @@
    -
    - {{#link-to 'crate' crate.id data-test-crate-link}}{{ crate.name }}{{/link-to}} - {{crate-badge crate=crate}} - {{#each crate.annotated_badges as |badge|}} - {{component badge.component_name badge=badge data-test-badge=badge.badge_type}} - {{/each}} -
    -
    - - {{ truncate-text crate.description }} - -
    +
    + {{#link-to 'crate' crate.id data-test-crate-link}}{{ crate.name }}{{/link-to}} + {{crate-badge crate=crate}} + {{#each crate.annotated_badges as |badge|}} + {{component badge.component_name badge=badge data-test-badge=badge.badge_type}} + {{/each}} +
    +
    + + {{ truncate-text crate.description }} + +
    -
    - {{svg-jar "download"}} - All-Time: {{ format-num crate.downloads }} -
    -
    - {{svg-jar "download"}} - Recent: {{ format-num crate.recent_downloads }} -
    +
    + {{svg-jar "download"}} + All-Time: {{ format-num crate.downloads }} +
    +
    + {{svg-jar "download"}} + Recent: {{ format-num crate.recent_downloads }} +
    diff --git a/app/templates/components/email-input.hbs b/app/templates/components/email-input.hbs index 25b8952cdbd..8944bd52397 100644 --- a/app/templates/components/email-input.hbs +++ b/app/templates/components/email-input.hbs @@ -1,64 +1,65 @@ {{#if emailIsNull }} -
    -

    Please add your email address. We will only use - it to contact you about your account. We promise we'll never share it! -

    -
    +
    +

    + Please add your email address. We will only use + it to contact you about your account. We promise we'll never share it! +

    +
    {{/if}} {{#if isEditing }} -
    -
    -
    Email
    -
    - +
    +
    +
    Email
    + +
    {{else}} +
    +
    +
    Email
    +
    + +
    + +
    +
    + {{#if emailNotVerified }}
    -
    -
    Email
    -
    - -
    - -
    +
    + {{#if user.email_verification_sent}} +

    We have sent a verification email to your address.

    + {{/if}} +

    Your email has not yet been verified.

    +
    +
    + +
    - {{#if emailNotVerified }} -
    -
    - {{#if user.email_verification_sent}} -

    We have sent a verification email to your address.

    - {{/if}} -

    Your email has not yet been verified.

    -
    -
    - -
    -
    - {{/if}} - {{#if isError}} -
    -
    -

    {{emailError}}

    -
    -
    - {{/if}} + {{/if}} + {{#if isError}} +
    +
    +

    {{emailError}}

    +
    +
    + {{/if}} {{/if}} diff --git a/app/templates/components/keyword-list.hbs b/app/templates/components/keyword-list.hbs index 171350fb160..aa9d91a5b5b 100644 --- a/app/templates/components/keyword-list.hbs +++ b/app/templates/components/keyword-list.hbs @@ -1,12 +1,12 @@
      - {{#each keywords as |keyword|}} -
    • - {{#link-to 'keyword' keyword class='name'}} - {{ keyword.id }} ({{ format-num keyword.crates_cnt }}) -
      - {{svg-jar "right-arrow"}} -
      - {{/link-to}} -
    • - {{/each}} + {{#each keywords as |keyword|}} +
    • + {{#link-to 'keyword' keyword class='name'}} + {{ keyword.id }} ({{ format-num keyword.crates_cnt }}) +
      + {{svg-jar "right-arrow"}} +
      + {{/link-to}} +
    • + {{/each}}
    diff --git a/app/templates/components/link-to-dep.hbs b/app/templates/components/link-to-dep.hbs index e5768f42c24..641b6f4a445 100644 --- a/app/templates/components/link-to-dep.hbs +++ b/app/templates/components/link-to-dep.hbs @@ -1,6 +1,6 @@ {{#link-to 'crate' dep.crate_id}} - {{ dep.crate_id }} {{ format-req dep.req }} + {{ dep.crate_id }} {{ format-req dep.req }} {{/link-to}} {{#if dep.optional}} - optional + optional {{/if}} diff --git a/app/templates/components/pending-owner-invite-row.hbs b/app/templates/components/pending-owner-invite-row.hbs index ba4f86fc883..10ec86830ed 100644 --- a/app/templates/components/pending-owner-invite-row.hbs +++ b/app/templates/components/pending-owner-invite-row.hbs @@ -1,40 +1,43 @@
    - {{#if isAccepted }} -

    Success! You've been added as an owner of crate - {{#link-to 'crate' invite.crate_name}}{{invite.crate_name}}{{/link-to}}. -

    - {{else if isDeclined}} -

    Declined. You have not been added as an owner of crate - {{#link-to 'crate' invite.crate_name}}{{invite.crate_name}}{{/link-to}}. -

    - {{else}} + {{#if isAccepted }} +

    + Success! You've been added as an owner of crate + {{#link-to 'crate' invite.crate_name}}{{invite.crate_name}}{{/link-to}}. +

    + {{else if isDeclined}} +

    + Declined. You have not been added as an owner of crate + {{#link-to 'crate' invite.crate_name}}{{invite.crate_name}}{{/link-to}}. +

    + {{else}}
    -
    -

    - {{#link-to 'crate' invite.crate_name}} - {{invite.crate_name}} - {{/link-to}} -

    -
    -
    -

    Invited by: - {{#link-to 'user' invite.invited_by_username}} - {{invite.invited_by_username}} - {{/link-to}} -

    -
    -
    - {{moment-from-now invite.created_at}} -
    -
    - - +
    +

    + {{#link-to 'crate' invite.crate_name}} + {{invite.crate_name}} + {{/link-to}} +

    +
    +
    +

    + Invited by: + {{#link-to 'user' invite.invited_by_username}} + {{invite.invited_by_username}} + {{/link-to}} +

    +
    +
    + {{moment-from-now invite.created_at}} +
    +
    + + +
    + {{#if isError}} +
    +

    {{inviteError}}

    - {{#if isError}} -
    -

    {{inviteError}}

    -
    - {{/if}} + {{/if}}
    - {{/if}} + {{/if}}
    diff --git a/app/templates/components/validated-input.hbs b/app/templates/components/validated-input.hbs index 08d90f7cdce..592e8f4887a 100644 --- a/app/templates/components/validated-input.hbs +++ b/app/templates/components/validated-input.hbs @@ -1,14 +1,14 @@
    - {{input type=type value=value placeholder=placeholder class='form-control' name=valuePath}} - {{#if isValid}} - - {{/if}} + {{input type=type value=value placeholder=placeholder class='form-control' name=valuePath}} + {{#if isValid}} + + {{/if}} -
    - {{#if showErrorMessage}} -
    - {{v-get model valuePath 'message'}} -
    - {{/if}} -
    +
    + {{#if showErrorMessage}} +
    + {{v-get model valuePath 'message'}} +
    + {{/if}} +
    diff --git a/app/templates/crate/docs.hbs b/app/templates/crate/docs.hbs index da179b2fe65..82d4d5c6612 100644 --- a/app/templates/crate/docs.hbs +++ b/app/templates/crate/docs.hbs @@ -1,8 +1,8 @@
    - {{svg-jar "circle-with-i"}} -

    Documentation for {{model.name}}

    + {{svg-jar "circle-with-i"}} +

    Documentation for {{model.name}}

    - Redirecting you to {{model.documentation}}… + Redirecting you to {{model.documentation}}

    diff --git a/app/templates/crate/owners.hbs b/app/templates/crate/owners.hbs index 0dd1218b443..bd30b32f252 100644 --- a/app/templates/crate/owners.hbs +++ b/app/templates/crate/owners.hbs @@ -1,67 +1,67 @@ {{ title 'Manage Crate Owners' }}
    - {{svg-jar "gear"}} -

    Manage Crate Owners

    -

    {{ crate.name }}

    + {{svg-jar "gear"}} +

    Manage Crate Owners

    +

    {{ crate.name }}

    -

    Add Owner

    +

    Add Owner

    -
    - +
    + +
    + +

    Owners

    {{#if removed}} -
    +

    {{removed}}

    -
    +
    {{/if}}
    - {{#each crate.owner_user as |user|}} -
    -
    - {{#link-to user.kind user.login}} - {{user-avatar user=user size='medium-small'}} - {{/link-to}} -
    -
    - {{#link-to user.kind user.login}} - {{ user.name }} - {{/link-to}} -
    -
    - {{{ if user.email user.email " " }}} -
    -
    - -
    -
    - {{/each}} -
    \ No newline at end of file + {{#each crate.owner_user as |user|}} +
    +
    + {{#link-to user.kind user.login}} + {{user-avatar user=user size='medium-small'}} + {{/link-to}} +
    +
    + {{#link-to user.kind user.login}} + {{ user.name }} + {{/link-to}} +
    +
    + {{{ if user.email user.email " " }}} +
    +
    + +
    +
    + {{/each}} +
    diff --git a/app/templates/crate/reverse-dependencies.hbs b/app/templates/crate/reverse-dependencies.hbs index 210216be197..157cbdfbf5d 100644 --- a/app/templates/crate/reverse-dependencies.hbs +++ b/app/templates/crate/reverse-dependencies.hbs @@ -1,42 +1,42 @@
    - {{#link-to 'crate' crate.id}}⬅ Back to {{ crate.name }}{{/link-to}} + {{#link-to 'crate' crate.id}}⬅ Back to {{ crate.name }}{{/link-to}}
    - +
    - {{#each model as |dependency|}} -
    -
    - {{#link-to 'crate' dependency.version.crateName}}{{dependency.version.crateName}}{{/link-to}} requires {{dependency.req}} -
    -
    - {{svg-jar "download-clear-back"}} - {{ format-num dependency.downloads }} -
    -
    - {{/each}} + {{#each model as |dependency|}} +
    +
    + {{#link-to 'crate' dependency.version.crateName}}{{dependency.version.crateName}}{{/link-to}} requires {{dependency.req}} +
    +
    + {{svg-jar "download-clear-back"}} + {{ format-num dependency.downloads }} +
    +
    + {{/each}}
    diff --git a/app/templates/crate/version.hbs b/app/templates/crate/version.hbs index 468747ddc07..b9d00aa94be 100644 --- a/app/templates/crate/version.hbs +++ b/app/templates/crate/version.hbs @@ -1,296 +1,296 @@ {{title crate.name}}
    -
    -
    - {{svg-jar "crate" class='crate-icon'}} -

    {{ crate.name }}

    -

    {{ currentVersion.num }}

    -
    +
    +
    + {{svg-jar "crate" class='crate-icon'}} +

    {{ crate.name }}

    +

    {{ currentVersion.num }}

    +
    -
    - {{#if session.currentUser}} - +
    + {{#if session.currentUser}} +
    + {{/if}} + + {{/if}}
    +
    -
    -
    - {{#if currentVersion.yanked}} -

    - This crate has been yanked, but it is still available for download for other crates that - may be depending on it. -

    -

    - You may wish to {{#link-to 'crate.versions' crate}}view all versions{{/link-to}} to find - one that has not been yanked. -

    - {{else}} -
    -
    Cargo.toml
    - {{ crate.name }} = "{{ currentVersion.num }}" - {{#if (is-clipboard-supported)}} - {{#copy-button clipboardTarget="#crate-toml" success=(action 'copySuccess') error=(action 'copyError') title="Copy to clipboard"}} - {{svg-jar "copy" alt="Copy to clipboard"}} - {{/copy-button}} - {{/if}} -
    -
    - - {{#if showNotification}} - {{#if showSuccess}} - Copied! - {{else}} - An error occured. Please use CTRL+C. - {{/if}} - {{/if}} - -
    - {{#if crate.readme}} -
    - {{crate-readme rendered=crate.readme}} -
    +
    + {{#if currentVersion.yanked}} +

    + This crate has been yanked, but it is still available for download for other crates that + may be depending on it. +

    +

    + You may wish to {{#link-to 'crate.versions' crate}}view all versions{{/link-to}} to find + one that has not been yanked. +

    + {{else}} +
    +
    Cargo.toml
    + {{ crate.name }} = "{{ currentVersion.num }}" + {{#if (is-clipboard-supported)}} + {{#copy-button clipboardTarget="#crate-toml" success=(action 'copySuccess') error=(action 'copyError') title="Copy to clipboard"}} + {{svg-jar "copy" alt="Copy to clipboard"}} + {{/copy-button}} + {{/if}} +
    +
    + + {{#if showNotification}} + {{#if showSuccess}} + Copied! {{else}} - {{#if crate.description}} -
    -

    About This Package

    -

    {{ crate.description }}

    -
    - {{/if}} + An error occured. Please use CTRL+C. {{/if}} + {{/if}} +
    +
    + {{#if crate.readme}} +
    + {{crate-readme rendered=crate.readme}} +
    + {{else}} + {{#if crate.description}} +
    +

    About This Package

    +

    {{ crate.description }}

    +
    {{/if}} -
    - {{#if notYankedOrIsOwner}} -
    -
    -
    -
    Last Updated
    -
    {{moment-from-now crate.updated_at}}
    - {{#each crate.annotated_badges as |badge|}} -

    - {{component badge.component_name badge=badge}} -

    - {{/each}} -
    + {{/if}} + {{/if}} +
    + {{#if notYankedOrIsOwner}} +
    +
    +
    +
    Last Updated
    +
    {{moment-from-now crate.updated_at}}
    + {{#each crate.annotated_badges as |badge|}} +

    + {{component badge.component_name badge=badge}} +

    + {{/each}} +
    - {{#if currentVersion.crate_size}} -
    -
    Crate Size
    -
    {{format-crate-size currentVersion.crate_size}}
    -
    - {{/if}} + {{#if currentVersion.crate_size}} +
    +
    Crate Size
    +
    {{format-crate-size currentVersion.crate_size}}
    +
    + {{/if}} -
    -

    Authors

    -
      - {{#each displayedAuthors as |author|}} -
    • {{ format-email author.name }}
    • - {{/each}} -
    -
    -
    +
    +

    Authors

    +
      + {{#each displayedAuthors as |author|}} +
    • {{ format-email author.name }}
    • + {{/each}} +
    +
    +
    -
    - {{#if currentVersion.license}} -
    -

    License

    -

    {{ currentVersion.license }}

    -
    - {{/if}} +
    + {{#if currentVersion.license}} +
    +

    License

    +

    {{ currentVersion.license }}

    +
    + {{/if}} - {{#unless crate.keywords.isPending}} - {{#if anyKeywords}} -
    -

    Keywords

    -
      - {{#each keywords as |keyword|}} -
    • {{link-to keyword.id 'keyword' keyword}}
    • - {{/each}} -
    -
    - {{/if}} - {{/unless}} + {{#unless crate.keywords.isPending}} + {{#if anyKeywords}} +
    +

    Keywords

    +
      + {{#each keywords as |keyword|}} +
    • {{link-to keyword.id 'keyword' keyword}}
    • + {{/each}} +
    +
    + {{/if}} + {{/unless}} - {{#unless crate.categories.isPending}} - {{#if anyCategories}} -
    -

    Categories

    -
      - {{#each categories as |category|}} -
    • {{link-to category.category 'category' category.slug}}
    • - {{/each}} -
    -
    - {{/if}} - {{/unless}} + {{#unless crate.categories.isPending}} + {{#if anyCategories}} +
    +

    Categories

    +
      + {{#each categories as |category|}} +
    • {{link-to category.category 'category' category.slug}}
    • + {{/each}} +
    +
    + {{/if}} + {{/unless}} -
    -

    Owners

    +
    +

    Owners

    - {{#if isOwner}} -

    - {{#link-to 'crate.owners' crate}} - Manage owners - {{/link-to}} -

    - {{/if}} + {{#if isOwner}} +

    + {{#link-to 'crate.owners' crate}} + Manage owners + {{/link-to}} +

    + {{/if}} -
      - {{#each crate.owner_team as |team|}} -
    • - {{#link-to team.kind team.login data-test-team-link=team.login}} - {{user-avatar user=team size='medium-small'}} - {{/link-to}} -
    • - {{/each}} +
        + {{#each crate.owner_team as |team|}} +
      • + {{#link-to team.kind team.login data-test-team-link=team.login}} + {{user-avatar user=team size='medium-small'}} + {{/link-to}} +
      • + {{/each}} - {{#each crate.owner_user as |user|}} -
      • - {{#link-to user.kind user.login data-test-user-link=user.login}} - {{user-avatar user=user size='medium-small'}} - {{/link-to}} -
      • - {{/each}} -
      -
    + {{#each crate.owner_user as |user|}} +
  • + {{#link-to user.kind user.login data-test-user-link=user.login}} + {{user-avatar user=user size='medium-small'}} + {{/link-to}} +
  • + {{/each}} + +
    -
    -

    Versions

    -
      - {{#each smallSortedVersions as |version|}} -
    • - {{#link-to 'crate.version' version.num data-test-version-link=version.num}} - {{ version.num }} - {{/link-to}} - {{moment-format version.created_at 'll'}} - {{#if version.yanked}} - yanked - {{/if}} -
    • - {{/each}} -
    - - {{#if hasMoreVersions}} - {{#link-to 'crate.versions' crate data-test-all-versions-link=true}} - show all {{ crate.versions.length }} versions - {{/link-to}} - {{/if}} - -
    +
    +

    Versions

    +
      + {{#each smallSortedVersions as |version|}} +
    • + {{#link-to 'crate.version' version.num data-test-version-link=version.num}} + {{ version.num }} + {{/link-to}} + {{moment-format version.created_at 'll'}} + {{#if version.yanked}} + yanked + {{/if}} +
    • + {{/each}} +
    + + {{#if hasMoreVersions}} + {{#link-to 'crate.versions' crate data-test-all-versions-link=true}} + show all {{ crate.versions.length }} versions + {{/link-to}} + {{/if}} + +
    -
    -

    Dependencies

    -
      - {{#each currentDependencies as |dep|}} - {{link-to-dep tagName="li" dep=dep}} - {{else}} -
    • None
    • - {{/each}} -
    -
    +
    +

    Dependencies

    +
      + {{#each currentDependencies as |dep|}} + {{link-to-dep tagName="li" dep=dep}} + {{else}} +
    • None
    • + {{/each}} +
    +
    - {{#if currentDevDependencies}} -
    -

    Dev-Dependencies

    -
      - {{#each currentDevDependencies as |dep|}} - {{link-to-dep tagName="li" dep=dep}} - {{/each}} -
    -
    - {{/if}} -
    - - {{/if}} + {{#if currentDevDependencies}} +
    +

    Dev-Dependencies

    +
      + {{#each currentDevDependencies as |dep|}} + {{link-to-dep tagName="li" dep=dep}} + {{/each}} +
    +
    + {{/if}} +
    + + {{/if}}
    {{#unless currentVersion.yanked}} -
    -
    -

    Stats Overview

    -
    - - {{svg-jar "download"}} - {{ format-num downloadsContext.downloads }} - - Downloads all time -
    -
    - - {{svg-jar "crate"}} - {{ crate.versions.length }} - - Versions published -
    -
    +
    +
    +

    Stats Overview

    +
    + + {{svg-jar "download"}} + {{ format-num downloadsContext.downloads }} + + Downloads all time +
    +
    + + {{svg-jar "crate"}} + {{ crate.versions.length }} + + Versions published +
    +
    -
    - Showing stats for +
    + Showing stats for - {{#rl-dropdown-container class="button-holder"}} - {{#rl-dropdown-toggle class="tan-button dropdown"}} - {{#if requestedVersion}} - {{ requestedVersion }} - {{else}} - All Versions - {{/if}} - - {{/rl-dropdown-toggle}} + {{#rl-dropdown-container class="button-holder"}} + {{#rl-dropdown-toggle class="tan-button dropdown"}} + {{#if requestedVersion}} + {{ requestedVersion }} + {{else}} + All Versions + {{/if}} + + {{/rl-dropdown-toggle}} - {{#rl-dropdown id="all-versions" tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to 'crate.version' 'all'}}All Versions{{/link-to}} -
  • - {{#each smallSortedVersions as |version|}} -
  • - {{#link-to 'crate.version' version.num}} - {{ version.num }} - {{/link-to}} -
  • - {{/each}} - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    -
    -

    Downloads over the last 90 days

    - {{download-graph data=downloadData}} -
    + {{#rl-dropdown id="all-versions" tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to 'crate.version' 'all'}}All Versions{{/link-to}} +
  • + {{#each smallSortedVersions as |version|}} +
  • + {{#link-to 'crate.version' version.num}} + {{ version.num }} + {{/link-to}} +
  • + {{/each}} + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    +
    +

    Downloads over the last 90 days

    + {{download-graph data=downloadData}}
    +
    {{/unless}} diff --git a/app/templates/crate/versions.hbs b/app/templates/crate/versions.hbs index 1873d57b651..fa35bc571d3 100644 --- a/app/templates/crate/versions.hbs +++ b/app/templates/crate/versions.hbs @@ -1,29 +1,29 @@
    - {{#link-to 'crate' model}}⬅ Back to Main Page{{/link-to}} + {{#link-to 'crate' model}}⬅ Back to Main Page{{/link-to}}
    - - All {{ model.versions.length }} - versions of {{ model.name }} since - {{moment-format model.created_at 'LL'}} - + + All {{ model.versions.length }} + versions of {{ model.name }} since + {{moment-format model.created_at 'LL'}} +
    - {{#each model.versions as |version|}} -
    -
    - {{#link-to 'crate.version' version.num}}{{ version.num }}{{/link-to}} + {{#each model.versions as |version|}} +
    +
    + {{#link-to 'crate.version' version.num}}{{ version.num }}{{/link-to}} - {{moment-format version.created_at 'LL'}} - {{#if version.yanked}} - yanked - {{/if}} -
    - {{#link-to 'crate.version' version.num class='arrow'}} - {{svg-jar "right-arrow"}} - {{/link-to}} -
    - {{/each}} + {{moment-format version.created_at 'LL'}} + {{#if version.yanked}} + yanked + {{/if}} +
    + {{#link-to 'crate.version' version.num class='arrow'}} + {{svg-jar "right-arrow"}} + {{/link-to}} +
    + {{/each}}
    diff --git a/app/templates/crates.hbs b/app/templates/crates.hbs index 1b63ff233ff..bca965170e6 100644 --- a/app/templates/crates.hbs +++ b/app/templates/crates.hbs @@ -1,95 +1,95 @@ {{ title 'Crates' }}
    -
    - {{svg-jar "crate"}} -

    All Crates

    -
    - {{#if letter}} -

    starting with '{{ letter }}'

    - {{/if}} +
    + {{svg-jar "crate"}} +

    All Crates

    +
    + {{#if letter}} +

    starting with '{{ letter }}'

    + {{/if}}
    + {{#each alphabet as |letter|}} + {{#link-to (query-params letter=letter page=1)}} + {{ letter }} + {{/link-to}} + {{/each}} + + {{#x-select value=letter action=(action (mut letter)) as |xs|}} + {{#each alphabet as |letter|}} - {{#link-to (query-params letter=letter page=1)}} - {{ letter }} - {{/link-to}} + {{#xs.option value=letter}}{{ letter }}{{/xs.option}} {{/each}} - - {{#x-select value=letter action=(action (mut letter)) as |xs|}} - - {{#each alphabet as |letter|}} - {{#xs.option value=letter}}{{ letter }}{{/xs.option}} - {{/each}} - {{/x-select}} + {{/x-select}}
    - + -
    - Sort by +
    + Sort by - {{#rl-dropdown-container class="dropdown-container"}} - {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} - {{svg-jar "sort"}} - {{ currentSortBy }} - - {{/rl-dropdown-toggle}} + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} + {{svg-jar "sort"}} + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} - {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to (query-params page=1 sort="alpha")}} - Alphabetical - {{/link-to}} -
  • -
  • - {{#link-to (query-params page=1 sort="downloads")}} - All-Time Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params page=1 sort="recent-downloads")}} - Recent Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params page=1 sort="recent-updates")}} - Recent Updates - {{/link-to}} -
  • - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params page=1 sort="alpha")}} + Alphabetical + {{/link-to}} +
  • +
  • + {{#link-to (query-params page=1 sort="downloads")}} + All-Time Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params page=1 sort="recent-downloads")}} + Recent Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params page=1 sort="recent-updates")}} + Recent Updates + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    - {{#each model as |crate index|}} - {{crate-row crate=crate data-test-crate-row=index}} - {{/each}} + {{#each model as |crate index|}} + {{crate-row crate=crate data-test-crate-row=index}} + {{/each}}
    diff --git a/app/templates/dashboard.hbs b/app/templates/dashboard.hbs index 7a414332d7f..5264b55cd83 100644 --- a/app/templates/dashboard.hbs +++ b/app/templates/dashboard.hbs @@ -1,84 +1,84 @@ {{ title 'Dashboard' }}
    - {{svg-jar "dashboard"}} -

    My Dashboard

    -
    -
    - - {{format-num visibleStats.total_downloads}} - Total Downloads -
    + {{svg-jar "dashboard"}} +

    My Dashboard

    +
    +
    + + {{format-num visibleStats.total_downloads}} + Total Downloads
    +
    -
    -
    -
    -

    - {{svg-jar "my-packages"}} - My Crates -

    - - {{#if hasMoreCrates}} - - {{link-to 'Show all' 'me.crates'}} - - {{/if}} -
    - {{crate-downloads-list crates=visibleCrates}} -
    -
    -
    -

    - {{svg-jar "following"}} - Following -

    +
    +
    +
    +

    + {{svg-jar "my-packages"}} + My Crates +

    - {{#if hasMoreFollowing}} - - {{link-to 'Show all' 'me.following'}} - - {{/if}} -
    - {{crate-downloads-list crates=visibleFollowing}} -
    + {{#if hasMoreCrates}} + + {{link-to 'Show all' 'me.crates'}} + + {{/if}} +
    + {{crate-downloads-list crates=visibleCrates}}
    - -
    +
    +

    - {{svg-jar "latest-updates"}} - Latest Updates + {{svg-jar "following"}} + Following

    -
    - {{#each myFeed as |version|}} -
    -
    - {{#link-to 'crate.version' version.crateName version.num}} - {{ version.crateName }} - {{ version.num }} - {{/link-to}} - - {{moment-from-now version.created_at}} - -
    -
    - {{/each}} + {{#if hasMoreFollowing}} + + {{link-to 'Show all' 'me.following'}} + + {{/if}} +
    + {{crate-downloads-list crates=visibleFollowing}} +
    +
    - {{#if loadingMore}} - - - - {{else}} - {{#if hasMore}} - - {{/if}} - {{/if}} +
    +

    + {{svg-jar "latest-updates"}} + Latest Updates +

    + +
    + {{#each myFeed as |version|}} +
    +
    + {{#link-to 'crate.version' version.crateName version.num}} + {{ version.crateName }} + {{ version.num }} + {{/link-to}} + + {{moment-from-now version.created_at}} + +
    + {{/each}} + + {{#if loadingMore}} + + + + {{else}} + {{#if hasMore}} + + {{/if}} + {{/if}}
    +
    diff --git a/app/templates/error.hbs b/app/templates/error.hbs index 32e95e8eeff..95e6ededdb7 100644 --- a/app/templates/error.hbs +++ b/app/templates/error.hbs @@ -1,5 +1,5 @@

    Something Went Wrong!

    {{model.message}}
    -    {{model.stack}}
    +  {{model.stack}}
     
    diff --git a/app/templates/index.hbs b/app/templates/index.hbs index 03c86a5ee81..c11be7b8882 100644 --- a/app/templates/index.hbs +++ b/app/templates/index.hbs @@ -1,63 +1,63 @@
    -

    The Rust community’s crate registry

    +

    The Rust community’s crate registry

    -
    -
    - Instantly publish your crates and install them. Use the API to - interact and find out more information about available crates. Become - a contributor and enhance the site with your work. -
    +
    + Instantly publish your crates and install them. Use the API to + interact and find out more information about available crates. Become + a contributor and enhance the site with your work. +
    -
    -
    - {{svg-jar "download"}} - {{if hasData (format-num model.num_downloads) "---,---,---"}} - Downloads -
    -
    - {{svg-jar "crate"}} - {{if hasData (format-num model.num_crates) "---,---"}} - Crates in stock -
    +
    +
    + {{svg-jar "download"}} + {{if hasData (format-num model.num_downloads) "---,---,---"}} + Downloads +
    +
    + {{svg-jar "crate"}} + {{if hasData (format-num model.num_crates) "---,---"}} + Crates in stock
    +
    -
    -

    New Crates

    - {{crate-list crates=model.new_crates}} -
    -
    -

    Most Downloaded

    - {{crate-list crates=model.most_downloaded}} -
    -
    -

    Just Updated

    - {{crate-list crates=model.just_updated}} -
    -
    -

    Most Recent Downloads

    - {{crate-list crates=model.most_recently_downloaded}} -
    -
    -

    Popular Keywords {{#link-to 'keywords'}}(see all){{/link-to}}

    - {{keyword-list keywords=model.popular_keywords}} -
    -
    -

    Popular Categories {{#link-to 'categories'}}(see all){{/link-to}}

    - {{category-list categories=model.popular_categories}} -
    +
    +

    New Crates

    + {{crate-list crates=model.new_crates}} +
    +
    +

    Most Downloaded

    + {{crate-list crates=model.most_downloaded}} +
    +
    +

    Just Updated

    + {{crate-list crates=model.just_updated}} +
    +
    +

    Most Recent Downloads

    + {{crate-list crates=model.most_recently_downloaded}} +
    +
    +

    Popular Keywords {{#link-to 'keywords'}}(see all){{/link-to}}

    + {{keyword-list keywords=model.popular_keywords}} +
    +
    +

    Popular Categories {{#link-to 'categories'}}(see all){{/link-to}}

    + {{category-list categories=model.popular_categories}} +
    diff --git a/app/templates/install.hbs b/app/templates/install.hbs index 4f4ec760ec1..3c8e8493067 100644 --- a/app/templates/install.hbs +++ b/app/templates/install.hbs @@ -1,8 +1,8 @@
    - {{svg-jar "download"}} -

    Install Cargo

    + {{svg-jar "download"}} +

    Install Cargo

    - Redirecting you to https://doc.rust-lang.org/cargo/getting-started/installation.html… + Redirecting you to https://doc.rust-lang.org/cargo/getting-started/installation.html

    diff --git a/app/templates/keyword/index.hbs b/app/templates/keyword/index.hbs index d187261ea60..dccefc5fe28 100644 --- a/app/templates/keyword/index.hbs +++ b/app/templates/keyword/index.hbs @@ -1,69 +1,69 @@ {{ title keyword.keyword ' - Keywords' }}
    - {{svg-jar "crate"}} -

    All Crates

    -

    for keyword '{{ keyword.keyword }}'

    + {{svg-jar "crate"}} +

    All Crates

    +

    for keyword '{{ keyword.keyword }}'

    - + -
    - Sort by - {{#rl-dropdown-container class="dropdown-container"}} - {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} - {{svg-jar "sort"}} - {{ currentSortBy }} - - {{/rl-dropdown-toggle}} +
    + Sort by + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} + {{svg-jar "sort"}} + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} - {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to (query-params sort="alpha")}} - Alphabetical - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="downloads")}} - All-Time Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="recent-downloads")}} - Recent Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="recent-updates")}} - Recent Updates - {{/link-to}} -
  • - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params sort="alpha")}} + Alphabetical + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="downloads")}} + All-Time Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="recent-downloads")}} + Recent Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="recent-updates")}} + Recent Updates + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    - {{#each model as |crate|}} - {{crate-row crate=crate}} - {{/each}} + {{#each model as |crate|}} + {{crate-row crate=crate}} + {{/each}}
    diff --git a/app/templates/keywords.hbs b/app/templates/keywords.hbs index 48c6b57f21e..10751d85297 100644 --- a/app/templates/keywords.hbs +++ b/app/templates/keywords.hbs @@ -1,65 +1,65 @@ {{ title 'Keywords' }}
    - {{svg-jar "crate"}} -

    All Keywords

    + {{svg-jar "crate"}} +

    All Keywords

    - + -
    - Sort by - {{#rl-dropdown-container class="dropdown-container"}} - {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} - {{svg-jar "sort"}} - {{ currentSortBy }} - - {{/rl-dropdown-toggle}} +
    + Sort by + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} + {{svg-jar "sort"}} + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} - {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to (query-params sort="alpha")}} - Alphabetical - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="crates")}} - # Crates - {{/link-to}} -
  • - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params sort="alpha")}} + Alphabetical + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="crates")}} + # Crates + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    - {{#each model as |keyword|}} -
    -
    - {{link-to keyword.id "keyword" keyword}} - - {{ pluralize (format-num keyword.crates_cnt) "crate" }} - -
    -
    - {{/each}} + {{#each model as |keyword|}} +
    +
    + {{link-to keyword.id "keyword" keyword}} + + {{ pluralize (format-num keyword.crates_cnt) "crate" }} + +
    +
    + {{/each}}
    diff --git a/app/templates/me/crates.hbs b/app/templates/me/crates.hbs index fc3303e1683..c5dfd9e7041 100644 --- a/app/templates/me/crates.hbs +++ b/app/templates/me/crates.hbs @@ -1,70 +1,70 @@ {{ title 'My Crates' }}
    - {{svg-jar "crate"}} -

    My Crates

    + {{svg-jar "crate"}} +

    My Crates

    {{! TODO: reduce duplication with templates/crates.hbs }}
    - + -
    - Sort by - {{#rl-dropdown-container class="dropdown-container"}} - {{#rl-dropdown-toggle tagName="a" class="dropdown"}} - {{svg-jar "sort"}} - {{ currentSortBy }} - - {{/rl-dropdown-toggle}} +
    + Sort by + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown"}} + {{svg-jar "sort"}} + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} - {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to (query-params sort="alpha")}} - Alphabetical - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="downloads")}} - All-Time Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="recent-downloads")}} - Recent Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="recent-updates")}} - Recent Updates - {{/link-to}} -
  • - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params sort="alpha")}} + Alphabetical + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="downloads")}} + All-Time Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="recent-downloads")}} + Recent Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="recent-updates")}} + Recent Updates + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    - {{#each model as |crate|}} - {{crate-row crate=crate}} - {{/each}} + {{#each model as |crate|}} + {{crate-row crate=crate}} + {{/each}}
    diff --git a/app/templates/me/following.hbs b/app/templates/me/following.hbs index 6c68deb3d69..de3047b1a8e 100644 --- a/app/templates/me/following.hbs +++ b/app/templates/me/following.hbs @@ -1,58 +1,58 @@
    - {{svg-jar "crate"}} -

    My Crates

    + {{svg-jar "crate"}} +

    My Crates

    {{! TODO: reduce duplication with templates/me/crates.hbs }}
    - + -
    - Sort by - {{#rl-dropdown-container class="dropdown-container"}} - {{#rl-dropdown-toggle tagName="a" class="dropdown"}} - {{svg-jar "sort"}} - {{ currentSortBy }} - - {{/rl-dropdown-toggle}} +
    + Sort by + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown"}} + {{svg-jar "sort"}} + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} - {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to (query-params sort="alpha")}} - Alphabetical - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="downloads")}} - Downloads - {{/link-to}} -
  • - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params sort="alpha")}} + Alphabetical + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="downloads")}} + Downloads + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    - {{#each model as |crate|}} - {{crate-row crate=crate}} - {{/each}} + {{#each model as |crate|}} + {{crate-row crate=crate}} + {{/each}}
    diff --git a/app/templates/me/index.hbs b/app/templates/me/index.hbs index ffe434749d4..04a720f8c1f 100644 --- a/app/templates/me/index.hbs +++ b/app/templates/me/index.hbs @@ -1,51 +1,51 @@ {{ title 'Settings' }}
    - {{svg-jar "gear"}} -

    Account Settings

    + {{svg-jar "gear"}} +

    Account Settings

    -

    Profile Information

    - -
    - {{#user-link user=model.user }} {{user-avatar user=model.user size='medium'}} {{/user-link}} - -
    -
    Name
    -
    {{ model.user.name }}
    -
    GitHub Account
    -
    {{ model.user.login }}
    -
    -
    +

    Profile Information

    + +
    + {{#user-link user=model.user }} {{user-avatar user=model.user size='medium'}} {{/user-link}} + +
    +
    Name
    +
    {{ model.user.name }}
    +
    GitHub Account
    +
    {{ model.user.login }}
    +
    +
    -

    User Email

    - {{email-input type='email' value=model.user.email user=model.user}} +

    User Email

    + {{email-input type='email' value=model.user.email user=model.user}}
    -
    -

    API Access

    -
    - -
    -
    - -

    - If you want to use package commands from the command line, you will need to - login with cargo login (token) using one of the tokens listed below. -

    -

    - When working in shared environments, supplying the token on the command line could - expose it to prying eyes. To avoid this, enter cargo login and supply your - token when prompted. -

    - -
    - {{#each sortedTokens as |api_token|}} - {{api-token-row api_token=api_token}} - {{/each}} +
    +

    API Access

    +
    +
    +
    + +

    + If you want to use package commands from the command line, you will need to + login with cargo login (token) using one of the tokens listed below. +

    +

    + When working in shared environments, supplying the token on the command line could + expose it to prying eyes. To avoid this, enter cargo login and supply your + token when prompted. +

    + +
    + {{#each sortedTokens as |api_token|}} + {{api-token-row api_token=api_token}} + {{/each}} +
    diff --git a/app/templates/me/pending-invites.hbs b/app/templates/me/pending-invites.hbs index f20ef3d15a2..dd30d42cb98 100644 --- a/app/templates/me/pending-invites.hbs +++ b/app/templates/me/pending-invites.hbs @@ -1,16 +1,16 @@ {{ title 'Pending Invites' }}
    - {{svg-jar "gear"}} -

    Pending Owner Invites

    + {{svg-jar "gear"}} +

    Pending Owner Invites

    -
    - {{#each model as |invite|}} - {{pending-owner-invite-row invite=invite}} - {{else}} -

    You don't seem to have any pending invitations.

    - {{/each}} -
    +
    + {{#each model as |invite|}} + {{pending-owner-invite-row invite=invite}} + {{else}} +

    You don't seem to have any pending invitations.

    + {{/each}} +
    diff --git a/app/templates/policies.hbs b/app/templates/policies.hbs index c6025d666af..3e99e6d441a 100644 --- a/app/templates/policies.hbs +++ b/app/templates/policies.hbs @@ -1,152 +1,154 @@
    - {{svg-jar 'circle-with-i'}} -

    Crates.io Package Policies

    + {{svg-jar 'circle-with-i'}} +

    Crates.io Package Policies

    -In general, these policies are guidelines. Problems are often contextual, and -exceptional circumstances sometimes require exceptional measures. We plan to -continue to clarify and expand these rules over time as new circumstances -arise. If your problem is not described below, consider sending us an email. + In general, these policies are guidelines. Problems are often contextual, and + exceptional circumstances sometimes require exceptional measures. We plan to + continue to clarify and expand these rules over time as new circumstances + arise. If your problem is not described below, consider + sending us an email.

    Package Ownership

    -We have a first-come, first-served policy on crate names. Upon publishing a -package, the publisher will be made owner of the package on Crates.io. + We have a first-come, first-served policy on crate names. Upon publishing a + package, the publisher will be made owner of the package on Crates.io.

    -If someone wants to take over a package, and the previous owner agrees, the -existing maintainer can add them as an owner, and the new maintainer can remove -them. If necessary, the team may reach out to inactive maintainers and help -mediate the process of ownership transfer. + If someone wants to take over a package, and the previous owner agrees, the + existing maintainer can add them as an owner, and the new maintainer can remove + them. If necessary, the team may reach out to inactive maintainers and help + mediate the process of ownership transfer.

    -Using an automated tool to claim ownership of a large number of package names -is not permitted. We reserve the right to block traffic or revoke ownership -of any package we determine to have been claimed by an automated tool. + Using an automated tool to claim ownership of a large number of package names + is not permitted. We reserve the right to block traffic or revoke ownership + of any package we determine to have been claimed by an automated tool.

    Removal

    -Many questions are specialized instances of a more general form: “Under what -circumstances can a package be removed from Crates.io?” + Many questions are specialized instances of a more general form: “Under what + circumstances can a package be removed from Crates.io?”

    -The short version is that packages are first-come, first-served, and we won’t -attempt to get into policing what exactly makes a legitimate package. We will -do what the law requires us to do, and address flagrant violations of the Rust -Code of Conduct. + The short version is that packages are first-come, first-served, and we won’t + attempt to get into policing what exactly makes a legitimate package. We will + do what the law requires us to do, and address flagrant violations of the Rust + Code of Conduct.

    Squatting

    -We do not have any policies to define 'squatting', and so will not hand over -ownership of a package for that reason. + We do not have any policies to define 'squatting', and so will not hand over + ownership of a package for that reason.

    The Law

    -For issues such as DMCA violations, trademark and copyright infringement, -Crates.io will respect Mozilla Legal’s decisions with regards to content that -is hosted. + For issues such as DMCA violations, trademark and copyright infringement, + Crates.io will respect Mozilla Legal’s decisions with regards to content that + is hosted.

    Code of Conduct

    -The Rust project has a Code -of Conduct which governs appropriate conduct for the Rust community. In -general, any content on Crates.io that violates the Code of Conduct may be -removed. Here, content can refer to but is not limited to: + The Rust project has a + Code of Conduct + which governs appropriate conduct for the Rust community. In + general, any content on Crates.io that violates the Code of Conduct may be + removed. Here, content can refer to but is not limited to:

      -
    • Package Name
    • -
    • Package Metadata
    • -
    • Documentation
    • -
    • Code
    • +
    • Package Name
    • +
    • Package Metadata
    • +
    • Documentation
    • +
    • Code

    -There are two important, related aspects: + There are two important, related aspects:

      -
    • +
    • We will not be pro-actively monitoring the site for these kinds of violations, but relying on the community to draw them to our attention. -
    • + -
    • +
    • “Does this violate the Code of Conduct” is a contextual question that cannot be directly answered in the hypothetical sense. All of the details must be taken into consideration in these kinds of situations. -
    • +

    Security

    -Cargo and crates.io are projects that are governed by the Rust Programming -Language Team. Safety is one of the core principles of Rust, and to that end, -we would like to ensure that cargo and crates.io have secure implementations. -To learn more about disclosing security vulnerabilities, please reference the -Rust Security policy for -more details. + Cargo and crates.io are projects that are governed by the Rust Programming + Language Team. Safety is one of the core principles of Rust, and to that end, + we would like to ensure that cargo and crates.io have secure implementations. + To learn more about disclosing security vulnerabilities, please reference the + Rust Security policy for + more details.

    -Thank you for taking the time to responsibly disclose any issues you find. + Thank you for taking the time to responsibly disclose any issues you find.

    Crawlers

    -Before resorting to crawling crates.io, you should first see if you are able to -gather the information you need from the -crates.io index, which is a public git repository containing the majority -of the information availble through our API. + Before resorting to crawling crates.io, you should first see if you are able to + gather the information you need from the + crates.io index, + which is a public git repository containing the majority + of the information availble through our API. -If the index does not have the information you need, we're also happy to -discuss solutions to your needs that don't require you to crawl the registry. -You can email us at help@crates.io. + If the index does not have the information you need, we're also happy to + discuss solutions to your needs that don't require you to crawl the registry. + You can email us at help@crates.io.

    -We allow our API and website to be crawled by commercial crawlers such as -GoogleBot. At our discretion, we may choose to allow access to experimental -crawlers, as long as they limit their request rate to 1 request per second or -less. + We allow our API and website to be crawled by commercial crawlers such as + GoogleBot. At our discretion, we may choose to allow access to experimental + crawlers, as long as they limit their request rate to 1 request per second or + less.

    -We also require all crawlers to provide a user-agent header that allows us to -uniquely identify your bot. This allows us to more accurately monitor any -impact your bot may have on our service. Providing a user agent that only -identifies your HTTP client library (such as "request/0.9.1") increases the -likelihood that we will block your traffic. + We also require all crawlers to provide a user-agent header that allows us to + uniquely identify your bot. This allows us to more accurately monitor any + impact your bot may have on our service. Providing a user agent that only + identifies your HTTP client library (such as "request/0.9.1") increases the + likelihood that we will block your traffic. -It is recommended, but not required, to include contact information in your user -agent. This allows us to contact you if we would like a change in your bot's -behavior without having to block your traffic. + It is recommended, but not required, to include contact information in your user + agent. This allows us to contact you if we would like a change in your bot's + behavior without having to block your traffic.

    -Bad: "User-Agent: reqwest/0.9.1"
    -Better: "User-Agent: my_bot"
    -Best: "User-Agent: my_bot (my_bot.com/info)" or "User-Agent: my_bot (help@my_bot.com)" + Bad: "User-Agent: reqwest/0.9.1"
    + Better: "User-Agent: my_bot"
    + Best: "User-Agent: my_bot (my_bot.com/info)" or "User-Agent: my_bot (help@my_bot.com)"

    -We reserve the right to block traffic from any bot that we determine to be in -violation of this policy or causing an impact on the integrity of our service. + We reserve the right to block traffic from any bot that we determine to be in + violation of this policy or causing an impact on the integrity of our service.

    diff --git a/app/templates/search.hbs b/app/templates/search.hbs index f261201d7e0..89282b73454 100644 --- a/app/templates/search.hbs +++ b/app/templates/search.hbs @@ -1,97 +1,97 @@ {{title (concat "Search Results for '" q "'")}} {{#if firstResultPending}} -
    -

    Loading search results...

    -
    +
    +

    Loading search results...

    +
    {{else if hasItems}} -
    - +
    + -
    - Sort by +
    + Sort by - {{#rl-dropdown-container class="dropdown-container"}} - {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} - {{svg-jar "sort"}} - {{ currentSortBy }} - - {{/rl-dropdown-toggle}} + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown" data-test-current-order=true}} + {{svg-jar "sort"}} + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} - {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to (query-params page=1 sort="relevance")}} - Relevance - {{/link-to}} -
  • -
  • - {{#link-to (query-params page=1 sort="downloads")}} - All-Time Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params page=1 sort="recent-downloads")}} - Recent Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params page=1 sort="recent-updates")}} - Recent Updates - {{/link-to}} -
  • - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params page=1 sort="relevance")}} + Relevance + {{/link-to}} +
  • +
  • + {{#link-to (query-params page=1 sort="downloads")}} + All-Time Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params page=1 sort="recent-downloads")}} + Recent Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params page=1 sort="recent-updates")}} + Recent Updates + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}}
    +
    -
    - {{#each model as |crate index|}} - {{#if crate.exact_match}} -
    - {{#link-to "crate" crate}} -

    Exact Match

    - {{/link-to}} - {{crate-row crate=crate data-test-crate-row=index}} -
    - {{else}} -
    - {{crate-row crate=crate data-test-crate-row=index}} -
    - {{/if}} - {{/each}} -
    +
    + {{#each model as |crate index|}} + {{#if crate.exact_match}} +
    + {{#link-to "crate" crate}} +

    Exact Match

    + {{/link-to}} + {{crate-row crate=crate data-test-crate-row=index}} +
    + {{else}} +
    + {{crate-row crate=crate data-test-crate-row=index}} +
    + {{/if}} + {{/each}} +
    - + {{else}} -
    -

    0 crates found. Get started and create your own.

    -
    +
    +

    0 crates found. Get started and create your own.

    +
    {{/if}} diff --git a/app/templates/team.hbs b/app/templates/team.hbs index a0481e6e521..d0821752c04 100644 --- a/app/templates/team.hbs +++ b/app/templates/team.hbs @@ -1,86 +1,86 @@
    -
    -
    - {{user-avatar user=model.team size='medium' data-test-avatar=true}} -
    -

    - {{ model.team.org_name }} -

    -

    - {{ model.team.name }} -

    -
    - {{#user-link user=model.team data-test-github-link=true}} - GitHub profile - {{/user-link}} -
    +
    +
    + {{user-avatar user=model.team size='medium' data-test-avatar=true}} +
    +

    + {{ model.team.org_name }} +

    +

    + {{ model.team.name }} +

    +
    + {{#user-link user=model.team data-test-github-link=true}} + GitHub profile + {{/user-link}}
    +
    -
    - {{! TODO: reduce duplication with templates/crates.hbs }} +
    + {{! TODO: reduce duplication with templates/crates.hbs }} -
    - +
    + -
    - Sort by - {{#rl-dropdown-container class="dropdown-container"}} - {{#rl-dropdown-toggle tagName="a" class="dropdown"}} - {{svg-jar "sort"}} - {{ currentSortBy }} - - {{/rl-dropdown-toggle}} +
    + Sort by + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown"}} + {{svg-jar "sort"}} + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} - {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to (query-params sort="alpha")}} - Alphabetical - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="downloads")}} - All-Time Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="recent-downloads")}} - Recent Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="recent-updates")}} - Recent Updates - {{/link-to}} -
  • - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    -
    + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params sort="alpha")}} + Alphabetical + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="downloads")}} + All-Time Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="recent-downloads")}} + Recent Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="recent-updates")}} + Recent Updates + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    +
    -
    - {{#each model.crates as |crate|}} - {{crate-row crate=crate}} - {{/each}} -
    +
    + {{#each model.crates as |crate|}} + {{crate-row crate=crate}} + {{/each}} +
    - + +
    diff --git a/app/templates/user.hbs b/app/templates/user.hbs index 69ce4ce34da..be98992d829 100644 --- a/app/templates/user.hbs +++ b/app/templates/user.hbs @@ -1,77 +1,77 @@
    - {{user-avatar user=model.user size='medium' data-test-avatar=true}} -

    - {{ model.user.login }} -

    - {{#user-link user=model.user data-test-user-link=true}} - GitHub profile - {{/user-link}} + {{user-avatar user=model.user size='medium' data-test-avatar=true}} +

    + {{ model.user.login }} +

    + {{#user-link user=model.user data-test-user-link=true}} + GitHub profile + {{/user-link}}
    -
    - {{! TODO: reduce duplication with templates/crates.hbs }} +
    + {{! TODO: reduce duplication with templates/crates.hbs }} -
    - +
    + -
    - Sort by - {{#rl-dropdown-container class="dropdown-container"}} - {{#rl-dropdown-toggle tagName="a" class="dropdown"}} - {{svg-jar "sort"}} - {{ currentSortBy }} - - {{/rl-dropdown-toggle}} +
    + Sort by + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown"}} + {{svg-jar "sort"}} + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} - {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to (query-params sort="alpha")}} - Alphabetical - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="downloads")}} - All-Time Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="recent-downloads")}} - Recent Downloads - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="recent-updates")}} - Recent Updates - {{/link-to}} -
  • - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    -
    + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params sort="alpha")}} + Alphabetical + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="downloads")}} + All-Time Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="recent-downloads")}} + Recent Downloads + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="recent-updates")}} + Recent Updates + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    +
    -
    - {{#each model.crates as |crate|}} - {{crate-row crate=crate}} - {{/each}} -
    +
    + {{#each model.crates as |crate|}} + {{crate-row crate=crate}} + {{/each}} +
    - + +
    diff --git a/config/coverage.js b/config/coverage.js index 133a5c502b1..01fca3c604a 100644 --- a/config/coverage.js +++ b/config/coverage.js @@ -1,4 +1,4 @@ module.exports = { - parallel: true, - reporters: ['json', 'lcov'], + parallel: true, + reporters: ['json', 'lcov'], }; diff --git a/config/environment.js b/config/environment.js index 55a356a27c2..7681acac190 100644 --- a/config/environment.js +++ b/config/environment.js @@ -1,63 +1,63 @@ 'use strict'; module.exports = function(environment) { - let ENV = { - modulePrefix: 'cargo', - environment, - rootURL: '/', - locationType: 'router-scroll', - historySupportMiddleware: true, - EmberENV: { - FEATURES: { - // Here you can enable experimental features on an ember canary build - // e.g. 'with-controller': true - }, - EXTEND_PROTOTYPES: { - // Prevent Ember Data from overriding Date.parse. - Date: false, - }, - }, - - APP: { - // Here you can pass flags/options to your application instance - // when it is created - }, + let ENV = { + modulePrefix: 'cargo', + environment, + rootURL: '/', + locationType: 'router-scroll', + historySupportMiddleware: true, + EmberENV: { + FEATURES: { + // Here you can enable experimental features on an ember canary build + // e.g. 'with-controller': true + }, + EXTEND_PROTOTYPES: { + // Prevent Ember Data from overriding Date.parse. + Date: false, + }, + }, + + APP: { + // Here you can pass flags/options to your application instance + // when it is created + }, + }; + + if (environment === 'development') { + // ENV.APP.LOG_RESOLVER = true; + // ENV.APP.LOG_ACTIVE_GENERATION = true; + // ENV.APP.LOG_TRANSITIONS = true; + // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; + // ENV.APP.LOG_VIEW_LOOKUPS = true; + ENV['ember-a11y-testing'] = { + componentOptions: { + turnAuditOff: true, + }, }; + } - if (environment === 'development') { - // ENV.APP.LOG_RESOLVER = true; - // ENV.APP.LOG_ACTIVE_GENERATION = true; - // ENV.APP.LOG_TRANSITIONS = true; - // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; - // ENV.APP.LOG_VIEW_LOOKUPS = true; - ENV['ember-a11y-testing'] = { - componentOptions: { - turnAuditOff: true, - }, - }; - } - - if (environment === 'test') { - // Testem prefers this... - ENV.locationType = 'none'; + if (environment === 'test') { + // Testem prefers this... + ENV.locationType = 'none'; - // keep test console output quieter - ENV.APP.LOG_ACTIVE_GENERATION = false; - ENV.APP.LOG_VIEW_LOOKUPS = false; + // keep test console output quieter + ENV.APP.LOG_ACTIVE_GENERATION = false; + ENV.APP.LOG_VIEW_LOOKUPS = false; - ENV.APP.rootElement = '#ember-testing'; - ENV.APP.autoboot = false; - } + ENV.APP.rootElement = '#ember-testing'; + ENV.APP.autoboot = false; + } - if (environment === 'production') { - // here you can enable a production-specific feature + if (environment === 'production') { + // here you can enable a production-specific feature - // Heroku Git Hash support - if (process.env.SOURCE_VERSION) { - let hash = process.env.SOURCE_VERSION.substr(0, 7); - ENV['ember-cli-app-version'] = { version: hash }; - } + // Heroku Git Hash support + if (process.env.SOURCE_VERSION) { + let hash = process.env.SOURCE_VERSION.substr(0, 7); + ENV['ember-cli-app-version'] = { version: hash }; } + } - return ENV; + return ENV; }; diff --git a/config/manifest.js b/config/manifest.js index c3a8e22882f..157de48b459 100644 --- a/config/manifest.js +++ b/config/manifest.js @@ -1,23 +1,23 @@ 'use strict'; module.exports = function(/* environment, appConfig */) { - return { - name: 'crates.io: Rust Package Registry', - short_name: 'crates.io', - description: 'crates.io is the default crate host for Rust.', - start_url: '/', - display: 'standalone', - background_color: '#3b6837', - theme_color: '#f9f7ec', - icons: [ - { - src: 'cargo.png', - sizes: '227x227', - type: 'image/png', - }, - ], - ms: { - tileColor: '#3b6837', - }, - }; + return { + name: 'crates.io: Rust Package Registry', + short_name: 'crates.io', + description: 'crates.io is the default crate host for Rust.', + start_url: '/', + display: 'standalone', + background_color: '#3b6837', + theme_color: '#f9f7ec', + icons: [ + { + src: 'cargo.png', + sizes: '227x227', + type: 'image/png', + }, + ], + ms: { + tileColor: '#3b6837', + }, + }; }; diff --git a/config/targets.js b/config/targets.js index f78c1e9dae9..dcde5b9d7d9 100644 --- a/config/targets.js +++ b/config/targets.js @@ -1,12 +1,12 @@ module.exports = { - browsers: [ - // These are the browsers we actually are attempting to support: - 'last 2 Chrome versions', - 'last 1 Firefox version', - 'Firefox ESR', - 'last 1 Safari version', - 'last 1 iOS version', - 'last 1 Edge version', - 'last 1 UCAndroid version', - ], + browsers: [ + // These are the browsers we actually are attempting to support: + 'last 2 Chrome versions', + 'last 1 Firefox version', + 'Firefox ESR', + 'last 1 Safari version', + 'last 1 iOS version', + 'last 1 Edge version', + 'last 1 UCAndroid version', + ], }; diff --git a/ember-cli-build.js b/ember-cli-build.js index 53551c2c1b6..1361574be20 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -3,54 +3,54 @@ const EmberApp = require('ember-cli/lib/broccoli/ember-app'); module.exports = function(defaults) { - const highlightedLanguages = [ - 'bash', - 'clike', - 'glsl', - 'go', - 'ini', - 'javascript', - 'json', - 'markup', - 'protobuf', - 'ruby', - 'rust', - 'scss', - 'sql', - 'yaml', - ]; + const highlightedLanguages = [ + 'bash', + 'clike', + 'glsl', + 'go', + 'ini', + 'javascript', + 'json', + 'markup', + 'protobuf', + 'ruby', + 'rust', + 'scss', + 'sql', + 'yaml', + ]; - let app = new EmberApp(defaults, { - babel6: { - plugins: ['transform-object-rest-spread'], - }, - 'ember-prism': { - theme: 'twilight', - components: highlightedLanguages, - }, - sassOptions: { - includePaths: ['node_modules/normalize.css'], - }, - fingerprint: { - extensions: ['js', 'css', 'png', 'jpg', 'gif', 'map', 'svg', 'ttf', 'woff', 'woff2'], - }, - }); + let app = new EmberApp(defaults, { + babel6: { + plugins: ['transform-object-rest-spread'], + }, + 'ember-prism': { + theme: 'twilight', + components: highlightedLanguages, + }, + sassOptions: { + includePaths: ['node_modules/normalize.css'], + }, + fingerprint: { + extensions: ['js', 'css', 'png', 'jpg', 'gif', 'map', 'svg', 'ttf', 'woff', 'woff2'], + }, + }); - // Use `app.import` to add additional libraries to the generated - // output files. - // - // If you need to use different assets in different - // environments, specify an object as the first parameter. That - // object's keys should be the environment name and the values - // should be the asset to use in that environment. - // - // If the library that you are including contains AMD or ES6 - // modules that you would like to import into your application - // please specify an object with the list of modules as keys - // along with the exports of each module as its value. - app.import('node_modules/timekeeper/lib/timekeeper.js', { - using: [{ transformation: 'cjs', as: 'timekeeper' }], - }); + // Use `app.import` to add additional libraries to the generated + // output files. + // + // If you need to use different assets in different + // environments, specify an object as the first parameter. That + // object's keys should be the environment name and the values + // should be the asset to use in that environment. + // + // If the library that you are including contains AMD or ES6 + // modules that you would like to import into your application + // please specify an object with the list of modules as keys + // along with the exports of each module as its value. + app.import('node_modules/timekeeper/lib/timekeeper.js', { + using: [{ transformation: 'cjs', as: 'timekeeper' }], + }); - return app.toTree(); + return app.toTree(); }; diff --git a/mirage/config.js b/mirage/config.js index b638593a4c6..1dea65e0aff 100644 --- a/mirage/config.js +++ b/mirage/config.js @@ -1,309 +1,307 @@ import Response from 'ember-cli-mirage/response'; export default function() { - // Used by ember-cli-code-coverage - this.passthrough('/write-coverage'); - - this.namespace = '/api/v1'; - - this.get('/summary', function(schema) { - let crates = schema.crates.all(); - - let just_updated = crates.sort((a, b) => compareIsoDates(b.updated_at, a.updated_at)).slice(0, 10); - let most_downloaded = crates.sort((a, b) => b.downloads - a.downloads).slice(0, 10); - let new_crates = crates.sort((a, b) => compareIsoDates(b.created_at, a.created_at)).slice(0, 10); - let most_recently_downloaded = crates.sort((a, b) => b.recent_downloads - a.recent_downloads).slice(0, 10); - - let num_crates = crates.length; - let num_downloads = crates.models.reduce((sum, crate) => sum + crate.downloads, 0); - - let popular_categories = schema.categories - .all() - .sort((a, b) => b.crates_cnt - a.crates_cnt) - .slice(0, 10); - let popular_keywords = schema.keywords - .all() - .sort((a, b) => b.crates_cnt - a.crates_cnt) - .slice(0, 10); - - return { - just_updated: this.serialize(just_updated).crates.map(it => ({ ...it, versions: null })), - most_downloaded: this.serialize(most_downloaded).crates.map(it => ({ ...it, versions: null })), - new_crates: this.serialize(new_crates).crates.map(it => ({ ...it, versions: null })), - most_recently_downloaded: this.serialize(most_recently_downloaded).crates.map(it => ({ - ...it, - versions: null, - })), - num_crates, - num_downloads, - popular_categories: this.serialize(popular_categories).categories, - popular_keywords: this.serialize(popular_keywords).keywords, - }; + // Used by ember-cli-code-coverage + this.passthrough('/write-coverage'); + + this.namespace = '/api/v1'; + + this.get('/summary', function(schema) { + let crates = schema.crates.all(); + + let just_updated = crates.sort((a, b) => compareIsoDates(b.updated_at, a.updated_at)).slice(0, 10); + let most_downloaded = crates.sort((a, b) => b.downloads - a.downloads).slice(0, 10); + let new_crates = crates.sort((a, b) => compareIsoDates(b.created_at, a.created_at)).slice(0, 10); + let most_recently_downloaded = crates.sort((a, b) => b.recent_downloads - a.recent_downloads).slice(0, 10); + + let num_crates = crates.length; + let num_downloads = crates.models.reduce((sum, crate) => sum + crate.downloads, 0); + + let popular_categories = schema.categories + .all() + .sort((a, b) => b.crates_cnt - a.crates_cnt) + .slice(0, 10); + let popular_keywords = schema.keywords + .all() + .sort((a, b) => b.crates_cnt - a.crates_cnt) + .slice(0, 10); + + return { + just_updated: this.serialize(just_updated).crates.map(it => ({ ...it, versions: null })), + most_downloaded: this.serialize(most_downloaded).crates.map(it => ({ ...it, versions: null })), + new_crates: this.serialize(new_crates).crates.map(it => ({ ...it, versions: null })), + most_recently_downloaded: this.serialize(most_recently_downloaded).crates.map(it => ({ + ...it, + versions: null, + })), + num_crates, + num_downloads, + popular_categories: this.serialize(popular_categories).categories, + popular_keywords: this.serialize(popular_keywords).keywords, + }; + }); + + this.get('/crates', function(schema, request) { + const { start, end } = pageParams(request); + + let crates = schema.crates.all(); + + if (request.queryParams.letter) { + let letter = request.queryParams.letter.toLowerCase(); + crates = crates.filter(crate => crate.id[0].toLowerCase() === letter); + } + + if (request.queryParams.q) { + let q = request.queryParams.q.toLowerCase(); + crates = crates.filter(crate => crate.id.toLowerCase().indexOf(q) !== -1); + } + + if (request.queryParams.user_id) { + let userId = parseInt(request.queryParams.user_id, 10); + crates = crates.filter(crate => (crate._owner_users || []).indexOf(userId) !== -1); + } + + if (request.queryParams.team_id) { + let teamId = parseInt(request.queryParams.team_id, 10); + crates = crates.filter(crate => (crate._owner_teams || []).indexOf(teamId) !== -1); + } + + if (request.queryParams.sort === 'alpha') { + crates = crates.sort((a, b) => compareStrings(a.id.toLowerCase(), b.id.toLowerCase())); + } + + return withMeta(this.serialize(crates.slice(start, end)), { total: crates.length }); + }); + + this.get('/crates/:crate_id', function(schema, request) { + let crateId = request.params.crate_id; + let crate = schema.crates.find(crateId); + let categories = schema.categories.all().filter(category => (crate.categories || []).indexOf(category.id) !== -1); + let keywords = schema.keywords.all().filter(keyword => (crate.keywords || []).indexOf(keyword.id) !== -1); + let versions = schema.versions + .all() + .filter(version => (crate.versions || []).indexOf(parseInt(version.id, 10)) !== -1); + + return { + ...this.serialize(crate), + ...this.serialize(categories), + ...this.serialize(keywords), + ...this.serialize(versions), + }; + }); + + this.get('/crates/:crate_id/following', (/* schema, request */) => { + // TODO + }); + + this.get('/crates/:crate_id/versions', (schema, request) => { + let crate = request.params.crate_id; + return schema.versions.where({ crate }).sort((a, b) => compareIsoDates(b.created_at, a.created_at)); + }); + + this.get('/crates/:crate_id/:version_num/authors', (schema, request) => { + let crate = request.params.crate_id; + let num = request.params.version_num; + let version = schema.versions.findBy({ crate, num }); + return { meta: { names: version._authors }, users: [] }; + }); + + this.get('/crates/:crate_id/:version_num/dependencies', (schema, request) => { + let crate = request.params.crate_id; + let num = request.params.version_num; + let version_id = schema.versions.findBy({ crate, num }).id; + return schema.dependencies.where({ version_id }); + }); + + this.get('/crates/:crate_id/:version_num/downloads', function(schema, request) { + let crateId = request.params.crate_id; + let versionNum = request.params.version_num; + let versionId = schema.versions.findBy({ crate: crateId, num: versionNum }).id; + return schema.versionDownloads.where({ version: versionId }); + }); + + this.get('/crates/:crate_id/owner_user', function(schema, request) { + let crateId = request.params.crate_id; + let crate = schema.crates.find(crateId); + let users = schema.users.find(crate._owner_users); + + let response = this.serialize(users); + + response.users.forEach(user => { + user.kind = 'user'; }); - this.get('/crates', function(schema, request) { - const { start, end } = pageParams(request); - - let crates = schema.crates.all(); - - if (request.queryParams.letter) { - let letter = request.queryParams.letter.toLowerCase(); - crates = crates.filter(crate => crate.id[0].toLowerCase() === letter); - } - - if (request.queryParams.q) { - let q = request.queryParams.q.toLowerCase(); - crates = crates.filter(crate => crate.id.toLowerCase().indexOf(q) !== -1); - } - - if (request.queryParams.user_id) { - let userId = parseInt(request.queryParams.user_id, 10); - crates = crates.filter(crate => (crate._owner_users || []).indexOf(userId) !== -1); - } - - if (request.queryParams.team_id) { - let teamId = parseInt(request.queryParams.team_id, 10); - crates = crates.filter(crate => (crate._owner_teams || []).indexOf(teamId) !== -1); - } - - if (request.queryParams.sort === 'alpha') { - crates = crates.sort((a, b) => compareStrings(a.id.toLowerCase(), b.id.toLowerCase())); - } - - return withMeta(this.serialize(crates.slice(start, end)), { total: crates.length }); - }); - - this.get('/crates/:crate_id', function(schema, request) { - let crateId = request.params.crate_id; - let crate = schema.crates.find(crateId); - let categories = schema.categories - .all() - .filter(category => (crate.categories || []).indexOf(category.id) !== -1); - let keywords = schema.keywords.all().filter(keyword => (crate.keywords || []).indexOf(keyword.id) !== -1); - let versions = schema.versions - .all() - .filter(version => (crate.versions || []).indexOf(parseInt(version.id, 10)) !== -1); - - return { - ...this.serialize(crate), - ...this.serialize(categories), - ...this.serialize(keywords), - ...this.serialize(versions), - }; - }); - - this.get('/crates/:crate_id/following', (/* schema, request */) => { - // TODO - }); - - this.get('/crates/:crate_id/versions', (schema, request) => { - let crate = request.params.crate_id; - return schema.versions.where({ crate }).sort((a, b) => compareIsoDates(b.created_at, a.created_at)); - }); - - this.get('/crates/:crate_id/:version_num/authors', (schema, request) => { - let crate = request.params.crate_id; - let num = request.params.version_num; - let version = schema.versions.findBy({ crate, num }); - return { meta: { names: version._authors }, users: [] }; - }); - - this.get('/crates/:crate_id/:version_num/dependencies', (schema, request) => { - let crate = request.params.crate_id; - let num = request.params.version_num; - let version_id = schema.versions.findBy({ crate, num }).id; - return schema.dependencies.where({ version_id }); - }); - - this.get('/crates/:crate_id/:version_num/downloads', function(schema, request) { - let crateId = request.params.crate_id; - let versionNum = request.params.version_num; - let versionId = schema.versions.findBy({ crate: crateId, num: versionNum }).id; - return schema.versionDownloads.where({ version: versionId }); - }); - - this.get('/crates/:crate_id/owner_user', function(schema, request) { - let crateId = request.params.crate_id; - let crate = schema.crates.find(crateId); - let users = schema.users.find(crate._owner_users); - - let response = this.serialize(users); - - response.users.forEach(user => { - user.kind = 'user'; - }); - - return response; - }); - - this.get('/crates/:crate_id/owner_team', function(schema, request) { - let crateId = request.params.crate_id; - let crate = schema.crates.find(crateId); - let teams = schema.teams.find(crate._owner_teams); - - let response = this.serialize(teams); - - response.teams.forEach(team => { - team.kind = 'team'; - }); - - return response; - }); - - this.get('/crates/:crate_id/reverse_dependencies', function(schema, request) { - let { start, end } = pageParams(request); - - let crate = request.params.crate_id; - let allDependencies = schema.dependencies.where({ crate_id: crate }); - let dependencies = allDependencies.slice(start, end); - let total = allDependencies.length; - - let versions = schema.versions.find(dependencies.models.map(it => it.version_id)); - - return { - ...this.serialize(dependencies), - ...this.serialize(versions), - meta: { total }, - }; - }); - - this.get('/crates/:crate_id/downloads', function(schema, request) { - let crateId = request.params.crate_id; - let crate = schema.crates.find(crateId); - let versionDownloads = schema.versionDownloads - .all() - .filter(it => crate.versions.indexOf(parseInt(it.version, 10)) !== -1); - - return withMeta(this.serialize(versionDownloads), { extra_downloads: crate._extra_downloads }); - }); - - this.get('/categories', function(schema, request) { - let { start, end } = pageParams(request); - - let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category)); - let categories = allCategories.slice(start, end); - let total = allCategories.length; - - return withMeta(this.serialize(categories), { total }); - }); - - this.get('/categories/:category_id', function(schema, request) { - let catId = request.params.category_id; - let category = schema.categories.find(catId); - return category ? category : notFound(); - }); - - this.get('/category_slugs', function(schema) { - let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category)); - return { - category_slugs: this.serialize(allCategories).categories.map(cat => ({ - id: cat.id, - slug: cat.slug, - description: cat.description, - })), - }; - }); - - this.get('/keywords', function(schema, request) { - let { start, end } = pageParams(request); - - let allKeywords = schema.keywords.all().sort((a, b) => a.crates_cnt - b.crates_cnt); - let keywords = allKeywords.slice(start, end); - let total = allKeywords.length; - - return withMeta(this.serialize(keywords), { total }); - }); - - this.get('/keywords/:keyword_id', (schema, request) => { - let keywordId = request.params.keyword_id; - let keyword = schema.keywords.find(keywordId); - return keyword ? keyword : notFound(); - }); - - this.get('/teams/:team_id', (schema, request) => { - let login = request.params.team_id; - let team = schema.teams.findBy({ login }); - return team ? team : notFound(); - }); - - this.get('/users/:user_id', (schema, request) => { - let login = request.params.user_id; - let user = schema.users.findBy({ login }); - return user ? user : notFound(); - }); - - this.put('/crates/:crate_id/owners', (schema, request) => { - const crateId = request.params.crate_id; - const crate = schema.crates.find(crateId); - - if (!crate) { - return notFound(); - } + return response; + }); - const body = JSON.parse(request.requestBody); - const [ownerId] = body.owners; - const user = schema.users.findBy({ login: ownerId }); + this.get('/crates/:crate_id/owner_team', function(schema, request) { + let crateId = request.params.crate_id; + let crate = schema.crates.find(crateId); + let teams = schema.teams.find(crate._owner_teams); - if (!user) { - return notFound(); - } + let response = this.serialize(teams); - return { ok: true }; + response.teams.forEach(team => { + team.kind = 'team'; }); - this.delete('/crates/:crate_id/owners', (schema, request) => { - const crateId = request.params.crate_id; - const crate = schema.crates.find(crateId); - - if (!crate) { - return notFound(); - } - - const body = JSON.parse(request.requestBody); - const [ownerId] = body.owners; - const user = schema.users.findBy({ login: ownerId }); - - if (!user) { - return notFound(); - } - - return {}; - }); + return response; + }); + + this.get('/crates/:crate_id/reverse_dependencies', function(schema, request) { + let { start, end } = pageParams(request); + + let crate = request.params.crate_id; + let allDependencies = schema.dependencies.where({ crate_id: crate }); + let dependencies = allDependencies.slice(start, end); + let total = allDependencies.length; + + let versions = schema.versions.find(dependencies.models.map(it => it.version_id)); + + return { + ...this.serialize(dependencies), + ...this.serialize(versions), + meta: { total }, + }; + }); + + this.get('/crates/:crate_id/downloads', function(schema, request) { + let crateId = request.params.crate_id; + let crate = schema.crates.find(crateId); + let versionDownloads = schema.versionDownloads + .all() + .filter(it => crate.versions.indexOf(parseInt(it.version, 10)) !== -1); + + return withMeta(this.serialize(versionDownloads), { extra_downloads: crate._extra_downloads }); + }); + + this.get('/categories', function(schema, request) { + let { start, end } = pageParams(request); + + let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category)); + let categories = allCategories.slice(start, end); + let total = allCategories.length; + + return withMeta(this.serialize(categories), { total }); + }); + + this.get('/categories/:category_id', function(schema, request) { + let catId = request.params.category_id; + let category = schema.categories.find(catId); + return category ? category : notFound(); + }); + + this.get('/category_slugs', function(schema) { + let allCategories = schema.categories.all().sort((a, b) => compareStrings(a.category, b.category)); + return { + category_slugs: this.serialize(allCategories).categories.map(cat => ({ + id: cat.id, + slug: cat.slug, + description: cat.description, + })), + }; + }); + + this.get('/keywords', function(schema, request) { + let { start, end } = pageParams(request); + + let allKeywords = schema.keywords.all().sort((a, b) => a.crates_cnt - b.crates_cnt); + let keywords = allKeywords.slice(start, end); + let total = allKeywords.length; + + return withMeta(this.serialize(keywords), { total }); + }); + + this.get('/keywords/:keyword_id', (schema, request) => { + let keywordId = request.params.keyword_id; + let keyword = schema.keywords.find(keywordId); + return keyword ? keyword : notFound(); + }); + + this.get('/teams/:team_id', (schema, request) => { + let login = request.params.team_id; + let team = schema.teams.findBy({ login }); + return team ? team : notFound(); + }); + + this.get('/users/:user_id', (schema, request) => { + let login = request.params.user_id; + let user = schema.users.findBy({ login }); + return user ? user : notFound(); + }); + + this.put('/crates/:crate_id/owners', (schema, request) => { + const crateId = request.params.crate_id; + const crate = schema.crates.find(crateId); + + if (!crate) { + return notFound(); + } + + const body = JSON.parse(request.requestBody); + const [ownerId] = body.owners; + const user = schema.users.findBy({ login: ownerId }); + + if (!user) { + return notFound(); + } + + return { ok: true }; + }); + + this.delete('/crates/:crate_id/owners', (schema, request) => { + const crateId = request.params.crate_id; + const crate = schema.crates.find(crateId); + + if (!crate) { + return notFound(); + } + + const body = JSON.parse(request.requestBody); + const [ownerId] = body.owners; + const user = schema.users.findBy({ login: ownerId }); + + if (!user) { + return notFound(); + } + + return {}; + }); } function notFound() { - return new Response( - 404, - { 'Content-Type': 'application/json' }, - { - errors: [{ detail: 'Not Found' }], - }, - ); + return new Response( + 404, + { 'Content-Type': 'application/json' }, + { + errors: [{ detail: 'Not Found' }], + }, + ); } function pageParams(request) { - const { queryParams } = request; + const { queryParams } = request; - const page = parseInt(queryParams.page || '1'); - const perPage = parseInt(queryParams.per_page || '10'); + const page = parseInt(queryParams.page || '1'); + const perPage = parseInt(queryParams.per_page || '10'); - const start = (page - 1) * perPage; - const end = start + perPage; + const start = (page - 1) * perPage; + const end = start + perPage; - return { page, perPage, start, end }; + return { page, perPage, start, end }; } function withMeta(response, meta) { - response.meta = meta; - return response; + response.meta = meta; + return response; } function compareStrings(a, b) { - return a < b ? -1 : a > b ? 1 : 0; + return a < b ? -1 : a > b ? 1 : 0; } function compareIsoDates(a, b) { - let aDate = new Date(a); - let bDate = new Date(b); - return aDate < bDate ? -1 : aDate > bDate ? 1 : 0; + let aDate = new Date(a); + let bDate = new Date(b); + return aDate < bDate ? -1 : aDate > bDate ? 1 : 0; } diff --git a/mirage/factories/category.js b/mirage/factories/category.js index 5dc4cb902b3..c2f55a0f545 100644 --- a/mirage/factories/category.js +++ b/mirage/factories/category.js @@ -2,19 +2,19 @@ import { Factory, faker } from 'ember-cli-mirage'; import { dasherize } from '@ember/string'; export default Factory.extend({ - category(i) { - return `Category ${i}`; - }, + category(i) { + return `Category ${i}`; + }, - id() { - return dasherize(this.category); - }, + id() { + return dasherize(this.category); + }, - slug() { - return dasherize(this.category); - }, + slug() { + return dasherize(this.category); + }, - description: () => faker.lorem.sentence(), - created_at: () => faker.date.past(), - crates_cnt: () => faker.random.number({ max: 5000 }), + description: () => faker.lorem.sentence(), + created_at: () => faker.date.past(), + crates_cnt: () => faker.random.number({ max: 5000 }), }); diff --git a/mirage/factories/crate.js b/mirage/factories/crate.js index bbf5ef41436..8d8b2c6a1d9 100644 --- a/mirage/factories/crate.js +++ b/mirage/factories/crate.js @@ -1,37 +1,37 @@ import { Factory, trait, faker } from 'ember-cli-mirage'; export default Factory.extend({ - id(i) { - return `crate-${i}`; - }, + id(i) { + return `crate-${i}`; + }, - name() { - return this.id; - }, + name() { + return this.id; + }, - description: () => faker.lorem.sentence(), - downloads: () => faker.random.number({ max: 10000 }), - documentation: () => faker.internet.url(), - homepage: () => faker.internet.url(), - repository: () => faker.internet.url(), - max_version: () => faker.system.semver(), + description: () => faker.lorem.sentence(), + downloads: () => faker.random.number({ max: 10000 }), + documentation: () => faker.internet.url(), + homepage: () => faker.internet.url(), + repository: () => faker.internet.url(), + max_version: () => faker.system.semver(), - created_at: () => faker.date.past(), - updated_at() { - return faker.date.between(this.created_at, new Date()); - }, + created_at: () => faker.date.past(), + updated_at() { + return faker.date.between(this.created_at, new Date()); + }, - badges: () => [], - categories: () => [], - keywords: () => [], - versions: () => [], - _extra_downloads: () => [], - _owner_teams: () => [], - _owner_users: () => [], + badges: () => [], + categories: () => [], + keywords: () => [], + versions: () => [], + _extra_downloads: () => [], + _owner_teams: () => [], + _owner_users: () => [], - withVersion: trait({ - afterCreate(crate, server) { - server.create('version', { crate: crate.id }); - }, - }), + withVersion: trait({ + afterCreate(crate, server) { + server.create('version', { crate: crate.id }); + }, + }), }); diff --git a/mirage/factories/version.js b/mirage/factories/version.js index 781c6e57abb..e1cdbd6db5b 100644 --- a/mirage/factories/version.js +++ b/mirage/factories/version.js @@ -1,31 +1,31 @@ import { Factory, faker } from 'ember-cli-mirage'; export default Factory.extend({ - id: i => i, + id: i => i, - // crate: '...', + // crate: '...', - num: () => faker.system.semver(), + num: () => faker.system.semver(), - created_at: () => faker.date.past(), - updated_at() { - return faker.date.between(this.created_at, new Date()); - }, + created_at: () => faker.date.past(), + updated_at() { + return faker.date.between(this.created_at, new Date()); + }, - yanked: false, - license: () => faker.hacker.abbreviation(), + yanked: false, + license: () => faker.hacker.abbreviation(), - dl_path() { - return `/api/v1/crates/${this.crate}/${this.num}/download`; - }, + dl_path() { + return `/api/v1/crates/${this.crate}/${this.num}/download`; + }, - downloads: () => faker.random.number({ max: 10000 }), - features: () => {}, - _authors: () => [], + downloads: () => faker.random.number({ max: 10000 }), + features: () => {}, + _authors: () => [], - afterCreate(version, server) { - let crate = server.schema.crates.find(version.crate); - crate.update({ versions: crate.versions.concat(parseInt(version.id, 10)) }); - }, - crate_size: () => faker.random.number({ max: 10000000 }), + afterCreate(version, server) { + let crate = server.schema.crates.find(version.crate); + crate.update({ versions: crate.versions.concat(parseInt(version.id, 10)) }); + }, + crate_size: () => faker.random.number({ max: 10000000 }), }); diff --git a/mirage/fixtures/categories.js b/mirage/fixtures/categories.js index 6e6433a28db..c2f62272f5a 100644 --- a/mirage/fixtures/categories.js +++ b/mirage/fixtures/categories.js @@ -1,29 +1,29 @@ /* eslint-disable quotes */ export default [ - { - category: 'API bindings', - crates_cnt: 0, - created_at: '2017-01-20T14:51:49Z', - description: - 'Idiomatic wrappers of specific APIs for convenient access from Rust. Includes HTTP API wrappers as well. Non-idiomatic or unsafe bindings can be found in External FFI bindings.', - id: 'api-bindings', - slug: 'api-bindings', - }, - { - category: 'Algorithms', - crates_cnt: 1, - created_at: '2017-01-20T14:51:49Z', - description: 'Rust implementations of core algorithms such as hashing, sorting, searching, and more.', - id: 'algorithms', - slug: 'algorithms', - }, - { - category: 'Asynchronous', - crates_cnt: 3910, - created_at: '2017-01-20T14:51:49Z', - description: - 'Crates to help you deal with events independently of the main program flow, using techniques like futures, promises, waiting, or eventing.', - id: 'asynchronous', - slug: 'asynchronous', - }, + { + category: 'API bindings', + crates_cnt: 0, + created_at: '2017-01-20T14:51:49Z', + description: + 'Idiomatic wrappers of specific APIs for convenient access from Rust. Includes HTTP API wrappers as well. Non-idiomatic or unsafe bindings can be found in External FFI bindings.', + id: 'api-bindings', + slug: 'api-bindings', + }, + { + category: 'Algorithms', + crates_cnt: 1, + created_at: '2017-01-20T14:51:49Z', + description: 'Rust implementations of core algorithms such as hashing, sorting, searching, and more.', + id: 'algorithms', + slug: 'algorithms', + }, + { + category: 'Asynchronous', + crates_cnt: 3910, + created_at: '2017-01-20T14:51:49Z', + description: + 'Crates to help you deal with events independently of the main program flow, using techniques like futures, promises, waiting, or eventing.', + id: 'asynchronous', + slug: 'asynchronous', + }, ]; diff --git a/mirage/fixtures/crates.js b/mirage/fixtures/crates.js index e1d009be14f..b2290e9dcee 100644 --- a/mirage/fixtures/crates.js +++ b/mirage/fixtures/crates.js @@ -1,381 +1,380 @@ /* eslint-disable quotes */ export default [ - { - badges: [ - { - badge_type: 'maintenance', - attributes: { - value: 'actively-developed', - }, - }, - ], - categories: [], - created_at: '2014-12-08T02:08:06Z', - description: 'A high-level, Rust idiomatic wrapper around nanomsg.', - documentation: 'https://github.com/thehydroimpulse/nanomsg.rs', - downloads: 3888, - recent_downloads: 800, - homepage: 'https://github.com/thehydroimpulse/nanomsg.rs', - id: 'nanomsg', - keywords: ['network'], - max_version: '0.7.0-alpha', - name: 'nanomsg', - repository: 'https://github.com/thehydroimpulse/nanomsg.rs', - updated_at: '2016-12-28T08:40:00Z', - versions: [40906, 40905, 28431, 21273, 18445, 17384, 13574, 9014, 8236, 7190, 4944, 940, 924], - _extra_downloads: [ - { - date: '2017-02-02', - downloads: 41, - }, - { - date: '2017-02-07', - downloads: 14, - }, - ], - _owner_teams: [1, 303], - _owner_users: [2, 303], - }, - { - created_at: '2015-02-27T11:52:13Z', - description: - 'Yo dawg, use Rust to generate Rust, right in your Rust. (See\n`external_mixin` to use scripting languages.)\n', - documentation: 'https://github.com/huonw/external_mixin#rust_mixin', - downloads: 477, - recent_downloads: 100, - exact_match: true, - homepage: 'https://github.com/huonw/external_mixin', - id: 'rust_mixin', - keywords: ['rust', 'plugin', 'code-generation'], - max_version: '0.0.1', - name: 'rust_mixin', - repository: 'https://github.com/huonw/external_mixin', - updated_at: '2015-02-27T11:52:13Z', - badges: [ - { - attributes: { - project: 'robertohuertasm/github-oss', - pipeline: 'microserver', - build: '2', - }, - badge_type: 'azure-devops', - }, - { - attributes: { - repository: 'huonw/external_mixin', - }, - badge_type: 'appveyor', - }, - { - attributes: { - branch: 'master', - repository: 'huonw/external_mixin', - }, - badge_type: 'travis-ci', - }, - { - attributes: { - branch: 'master', - repository: 'huonw/external_mixin', - }, - badge_type: 'gitlab', - }, - { - attributes: { - repository: 'huonw/external_mixin', - }, - badge_type: 'is-it-maintained-issue-resolution', - }, - { - attributes: { - repository: 'huonw/external_mixin', - }, - badge_type: 'is-it-maintained-open-issues', - }, - { - attributes: { - branch: 'master', - repository: 'huonw/external_mixin', - }, - badge_type: 'codecov', - }, - { - attributes: { - branch: 'master', - repository: 'huonw/external_mixin', - }, - badge_type: 'coveralls', - }, - ], - versions: null, - }, - { - created_at: '2015-02-27T11:51:58Z', - description: - 'Use your favourite interpreted language to generate your Rust, right\nin your Rust. Supports Python, Ruby and shell (`sh`) out of the box,\nwith an extensible macro to support any others. (See `rust_mixin` to\nbe able to use your all-time favourite language to generate your Rust.)\n', - documentation: 'https://github.com/huonw/external_mixin#external_mixin', - downloads: 497, - recent_downloads: 497, - homepage: 'https://github.com/huonw/external_mixin', - id: 'external_mixin', - keywords: ['python', 'ruby', 'shell', 'plugin', 'code-generation'], - max_version: '0.0.1', - name: 'external_mixin', - repository: 'https://github.com/huonw/external_mixin', - updated_at: '2015-02-27T11:51:58Z', - versions: null, - }, - { - created_at: '2015-02-27T11:51:40Z', - description: 'Backing library for `rust_mixin` and `external_mixin` to keep them\nDRY.\n', - documentation: 'https://github.com/huonw/external_mixin#external_mixin_base', - downloads: 989, - recent_downloads: 0, - homepage: 'https://github.com/huonw/external_mixin', - id: 'external_mixin_umbrella', - keywords: ['plugin', 'code-generation'], - max_version: '0.0.2', - name: 'external_mixin_umbrella', - repository: 'https://github.com/huonw/external_mixin', - updated_at: '2015-02-27T11:52:30Z', - versions: null, - }, - { - created_at: '2015-10-10T15:26:24Z', - description: - 'Adds String based inflections for Rust. Snake, kebab, camel, sentence, class, title, upper, and lower cases as well as ordinalize, deordinalize, demodulize, and foreign key are supported as both traits and pure functions acting on String types.\n', - documentation: 'http://whatisinternet.github.io/inflector/doc/inflector/', - downloads: 57, - recent_downloads: 1, - homepage: 'https://github.com/whatisinternet/inflector', - id: 'Inflector', - keywords: ['string', 'case', 'camel', 'snake', 'inflection'], - max_version: '0.1.6', - name: 'Inflector', - repository: 'https://github.com/whatisinternet/inflector', - updated_at: '2015-10-27T01:51:42Z', - versions: null, - }, - { - created_at: '2015-05-21T17:43:38Z', - description: 'Client for the ElasticSearch REST API', - documentation: 'http://benashford.github.io/rs-es/rs_es/index.html', - downloads: 321, - recent_downloads: 21, - homepage: null, - id: 'rs-es', - keywords: ['elasticsearch', 'elastic'], - max_version: '0.1.17', - name: 'rs-es', - repository: 'https://github.com/benashford/rs-es', - updated_at: '2015-09-09T15:34:50Z', - versions: null, - }, - { - created_at: '2014-11-21T05:12:08Z', - description: 'A (mostly) pure-Rust implementation of various common cryptographic algorithms.', - documentation: null, - downloads: 21573, - recent_downloads: 2000, - homepage: 'https://github.com/DaGenix/rust-crypto/', - id: 'rust-crypto', - keywords: ['Crypto', 'MD5', 'Sha1', 'Sha2', 'AES'], - max_version: '0.2.34', - name: 'rust-crypto', - repository: 'https://github.com/DaGenix/rust-crypto/', - updated_at: '2015-10-29T01:16:17Z', - versions: null, - }, - { - created_at: '2015-03-20T13:46:04Z', - description: - 'This library provides HTSlib bindings and a high level Rust API for reading and writing BAM files.', - documentation: null, - downloads: 485, - recent_downloads: 85, - homepage: null, - id: 'rust-htslib', - keywords: ['htslib', 'bam', 'bioinformatics', 'pileup', 'sequencing'], - max_version: '0.5.2', - name: 'rust-htslib', - repository: 'https://github.com/rust-bio/rust-htslib.git', - updated_at: '2015-11-11T00:10:43Z', - versions: null, - }, - { - badges: [ - { - badge_type: 'maintenance', - attributes: { - status: 'actively-developed', - }, - }, - ], - created_at: '2014-11-23T09:01:21Z', - description: 'A Kinetic protocol library written in Rust', - documentation: 'https://icorderi.github.io/kinetic-rust/doc/kinetic/', - downloads: 225, - recent_downloads: 125, - homepage: 'https://icorderi.github.io/icorderi/kinetic-rust', - id: 'kinetic-rust', - keywords: ['Protocol', 'Kinetic', 'Storage'], - max_version: '0.0.16', - name: 'kinetic-rust', - repository: 'https://github.com/icorderi/kinetic-rust/', - updated_at: '2015-04-21T00:15:49Z', - versions: null, - }, - { - created_at: '2014-11-29T17:51:55Z', - description: 'Rustless is a REST-like API micro-framework for Rust.', - documentation: null, - downloads: 554, - recent_downloads: 500, - homepage: 'https://github.com/rustless/rustless', - id: 'rustless', - keywords: ['api', 'web', 'hyper', 'iron', 'rest'], - max_version: '0.8.0', - name: 'rustless', - repository: 'https://crates.io/crates/rustless', - updated_at: '2015-10-31T11:49:29Z', - versions: null, - }, - { - created_at: '2014-12-05T20:20:39Z', - description: 'A generic serialization/deserialization framework', - documentation: 'https://serde-rs.github.io/serde/serde/serde/index.html', - downloads: 50854, - recent_downloads: 854, - homepage: null, - id: 'serde', - keywords: ['serde', 'serialization'], - max_version: '0.6.1', - name: 'serde', - repository: 'https://github.com/serde-rs/serde', - updated_at: '2015-10-18T03:10:21Z', - versions: null, - }, - { - created_at: '2015-08-26T13:50:58Z', - description: 'Send cypher queries to a neo4j database', - documentation: 'http://livioribeiro.github.io/rusted_cypher/rusted_cypher/', - downloads: 156, - recent_downloads: 54, - homepage: 'https://github.com/livioribeiro/rusted-cypher', - id: 'rusted_cypher', - keywords: ['neo4j', 'database', 'query', 'cypher', 'graph'], - max_version: '0.7.1', - name: 'rusted_cypher', - repository: 'https://github.com/livioribeiro/rusted-cypher', - updated_at: '2015-11-07T17:26:55Z', - versions: null, - }, - { - created_at: '2015-01-02T20:54:04Z', - description: - 'An (incomplete) port of zlib to Rust. The decompressor works, but the compressor has not yet been ported.', - documentation: null, - downloads: 223, - recent_downloads: 23, - homepage: null, - id: 'zlib', - keywords: [], - max_version: '0.0.1', - name: 'zlib', - repository: null, - updated_at: '2015-01-02T20:54:04Z', - versions: null, - }, - { - created_at: '2015-05-08T19:34:16Z', - description: - 'A light HTTP framework, with some REST-like features and the ambition of being simple, modular and non-intrusive.', - documentation: 'http://ogeon.github.io/docs/rustful/master/rustful/index.html', - downloads: 576, - recent_downloads: 76, - homepage: null, - id: 'rustful', - keywords: ['web', 'rest', 'framework', 'http', 'routing'], - max_version: '0.5.0', - name: 'rustful', - repository: 'https://github.com/Ogeon/rustful', - updated_at: '2015-09-19T21:10:27Z', - versions: null, - }, - { - created_at: '2014-11-24T02:34:44Z', - description: 'A native PostgreSQL driver', - documentation: 'https://sfackler.github.io/rust-postgres/doc/v0.10.1/postgres', - downloads: 13449, - recent_downloads: 13, - homepage: null, - id: 'postgres', - keywords: ['database', 'sql'], - max_version: '0.10.1', - name: 'postgres', - repository: 'https://github.com/sfackler/rust-postgres', - updated_at: '2015-11-08T00:48:59Z', - versions: null, - }, - { - created_at: '2014-11-21T00:20:47Z', - description: 'Automatic property based testing with shrinking.', - documentation: 'http://burntsushi.net/rustdoc/quickcheck/', - downloads: 19271, - recent_downloads: 143, - homepage: 'https://github.com/BurntSushi/quickcheck', - id: 'quickcheck', - keywords: ['testing', 'quickcheck', 'property', 'shrinking', 'fuzz'], - max_version: '0.2.24', - name: 'quickcheck', - repository: 'https://github.com/BurntSushi/quickcheck', - updated_at: '2015-09-20T21:53:38Z', - versions: null, - }, - { - created_at: '2014-11-21T00:21:04Z', - description: 'A macro attribute for quickcheck.', - documentation: 'http://burntsushi.net/rustdoc/quickcheck/', - downloads: 3796, - recent_downloads: 768, - homepage: 'https://github.com/BurntSushi/quickcheck', - id: 'quickcheck_macros', - keywords: ['testing', 'quickcheck', 'property', 'shrinking', 'fuzz'], - max_version: '0.2.24', - name: 'quickcheck_macros', - repository: 'https://github.com/BurntSushi/quickcheck', - updated_at: '2015-09-20T21:53:57Z', - versions: null, - }, - { - created_at: '2015-08-25T19:15:35Z', - description: - 'Lexical analysers generator for Rust, written in Rust (crate dedicated to rumblebars, divergences written by Nicolas Cherel)', - documentation: null, - downloads: 109, - recent_downloads: 0, - homepage: 'https://github.com/nicolas-cherel/rustlex', - id: 'nc_rustlex', - keywords: ['lexer', 'lexical', 'analyser', 'generator'], - max_version: '0.3.1', - name: 'nc_rustlex', - repository: 'https://github.com/nicolas-cherel/rustlex', - updated_at: '2015-08-25T19:15:35Z', - versions: null, - }, - { - created_at: '2015-01-17T17:47:52Z', - description: 'A byte-oriented, zero-copy, parser combinators library', - documentation: 'http://rust.unhandledexpression.com/nom/', - downloads: 5169, - recent_downloads: 69, - homepage: null, - id: 'nom', - keywords: ['parser', 'parser-combinators', 'parsing', 'streaming', 'bit'], - max_version: '1.0.1', - name: 'nom', - repository: 'https://github.com/Geal/nom', - updated_at: '2015-11-22T22:00:41Z', - versions: null, - }, + { + badges: [ + { + badge_type: 'maintenance', + attributes: { + value: 'actively-developed', + }, + }, + ], + categories: [], + created_at: '2014-12-08T02:08:06Z', + description: 'A high-level, Rust idiomatic wrapper around nanomsg.', + documentation: 'https://github.com/thehydroimpulse/nanomsg.rs', + downloads: 3888, + recent_downloads: 800, + homepage: 'https://github.com/thehydroimpulse/nanomsg.rs', + id: 'nanomsg', + keywords: ['network'], + max_version: '0.7.0-alpha', + name: 'nanomsg', + repository: 'https://github.com/thehydroimpulse/nanomsg.rs', + updated_at: '2016-12-28T08:40:00Z', + versions: [40906, 40905, 28431, 21273, 18445, 17384, 13574, 9014, 8236, 7190, 4944, 940, 924], + _extra_downloads: [ + { + date: '2017-02-02', + downloads: 41, + }, + { + date: '2017-02-07', + downloads: 14, + }, + ], + _owner_teams: [1, 303], + _owner_users: [2, 303], + }, + { + created_at: '2015-02-27T11:52:13Z', + description: + 'Yo dawg, use Rust to generate Rust, right in your Rust. (See\n`external_mixin` to use scripting languages.)\n', + documentation: 'https://github.com/huonw/external_mixin#rust_mixin', + downloads: 477, + recent_downloads: 100, + exact_match: true, + homepage: 'https://github.com/huonw/external_mixin', + id: 'rust_mixin', + keywords: ['rust', 'plugin', 'code-generation'], + max_version: '0.0.1', + name: 'rust_mixin', + repository: 'https://github.com/huonw/external_mixin', + updated_at: '2015-02-27T11:52:13Z', + badges: [ + { + attributes: { + project: 'robertohuertasm/github-oss', + pipeline: 'microserver', + build: '2', + }, + badge_type: 'azure-devops', + }, + { + attributes: { + repository: 'huonw/external_mixin', + }, + badge_type: 'appveyor', + }, + { + attributes: { + branch: 'master', + repository: 'huonw/external_mixin', + }, + badge_type: 'travis-ci', + }, + { + attributes: { + branch: 'master', + repository: 'huonw/external_mixin', + }, + badge_type: 'gitlab', + }, + { + attributes: { + repository: 'huonw/external_mixin', + }, + badge_type: 'is-it-maintained-issue-resolution', + }, + { + attributes: { + repository: 'huonw/external_mixin', + }, + badge_type: 'is-it-maintained-open-issues', + }, + { + attributes: { + branch: 'master', + repository: 'huonw/external_mixin', + }, + badge_type: 'codecov', + }, + { + attributes: { + branch: 'master', + repository: 'huonw/external_mixin', + }, + badge_type: 'coveralls', + }, + ], + versions: null, + }, + { + created_at: '2015-02-27T11:51:58Z', + description: + 'Use your favourite interpreted language to generate your Rust, right\nin your Rust. Supports Python, Ruby and shell (`sh`) out of the box,\nwith an extensible macro to support any others. (See `rust_mixin` to\nbe able to use your all-time favourite language to generate your Rust.)\n', + documentation: 'https://github.com/huonw/external_mixin#external_mixin', + downloads: 497, + recent_downloads: 497, + homepage: 'https://github.com/huonw/external_mixin', + id: 'external_mixin', + keywords: ['python', 'ruby', 'shell', 'plugin', 'code-generation'], + max_version: '0.0.1', + name: 'external_mixin', + repository: 'https://github.com/huonw/external_mixin', + updated_at: '2015-02-27T11:51:58Z', + versions: null, + }, + { + created_at: '2015-02-27T11:51:40Z', + description: 'Backing library for `rust_mixin` and `external_mixin` to keep them\nDRY.\n', + documentation: 'https://github.com/huonw/external_mixin#external_mixin_base', + downloads: 989, + recent_downloads: 0, + homepage: 'https://github.com/huonw/external_mixin', + id: 'external_mixin_umbrella', + keywords: ['plugin', 'code-generation'], + max_version: '0.0.2', + name: 'external_mixin_umbrella', + repository: 'https://github.com/huonw/external_mixin', + updated_at: '2015-02-27T11:52:30Z', + versions: null, + }, + { + created_at: '2015-10-10T15:26:24Z', + description: + 'Adds String based inflections for Rust. Snake, kebab, camel, sentence, class, title, upper, and lower cases as well as ordinalize, deordinalize, demodulize, and foreign key are supported as both traits and pure functions acting on String types.\n', + documentation: 'http://whatisinternet.github.io/inflector/doc/inflector/', + downloads: 57, + recent_downloads: 1, + homepage: 'https://github.com/whatisinternet/inflector', + id: 'Inflector', + keywords: ['string', 'case', 'camel', 'snake', 'inflection'], + max_version: '0.1.6', + name: 'Inflector', + repository: 'https://github.com/whatisinternet/inflector', + updated_at: '2015-10-27T01:51:42Z', + versions: null, + }, + { + created_at: '2015-05-21T17:43:38Z', + description: 'Client for the ElasticSearch REST API', + documentation: 'http://benashford.github.io/rs-es/rs_es/index.html', + downloads: 321, + recent_downloads: 21, + homepage: null, + id: 'rs-es', + keywords: ['elasticsearch', 'elastic'], + max_version: '0.1.17', + name: 'rs-es', + repository: 'https://github.com/benashford/rs-es', + updated_at: '2015-09-09T15:34:50Z', + versions: null, + }, + { + created_at: '2014-11-21T05:12:08Z', + description: 'A (mostly) pure-Rust implementation of various common cryptographic algorithms.', + documentation: null, + downloads: 21573, + recent_downloads: 2000, + homepage: 'https://github.com/DaGenix/rust-crypto/', + id: 'rust-crypto', + keywords: ['Crypto', 'MD5', 'Sha1', 'Sha2', 'AES'], + max_version: '0.2.34', + name: 'rust-crypto', + repository: 'https://github.com/DaGenix/rust-crypto/', + updated_at: '2015-10-29T01:16:17Z', + versions: null, + }, + { + created_at: '2015-03-20T13:46:04Z', + description: 'This library provides HTSlib bindings and a high level Rust API for reading and writing BAM files.', + documentation: null, + downloads: 485, + recent_downloads: 85, + homepage: null, + id: 'rust-htslib', + keywords: ['htslib', 'bam', 'bioinformatics', 'pileup', 'sequencing'], + max_version: '0.5.2', + name: 'rust-htslib', + repository: 'https://github.com/rust-bio/rust-htslib.git', + updated_at: '2015-11-11T00:10:43Z', + versions: null, + }, + { + badges: [ + { + badge_type: 'maintenance', + attributes: { + status: 'actively-developed', + }, + }, + ], + created_at: '2014-11-23T09:01:21Z', + description: 'A Kinetic protocol library written in Rust', + documentation: 'https://icorderi.github.io/kinetic-rust/doc/kinetic/', + downloads: 225, + recent_downloads: 125, + homepage: 'https://icorderi.github.io/icorderi/kinetic-rust', + id: 'kinetic-rust', + keywords: ['Protocol', 'Kinetic', 'Storage'], + max_version: '0.0.16', + name: 'kinetic-rust', + repository: 'https://github.com/icorderi/kinetic-rust/', + updated_at: '2015-04-21T00:15:49Z', + versions: null, + }, + { + created_at: '2014-11-29T17:51:55Z', + description: 'Rustless is a REST-like API micro-framework for Rust.', + documentation: null, + downloads: 554, + recent_downloads: 500, + homepage: 'https://github.com/rustless/rustless', + id: 'rustless', + keywords: ['api', 'web', 'hyper', 'iron', 'rest'], + max_version: '0.8.0', + name: 'rustless', + repository: 'https://crates.io/crates/rustless', + updated_at: '2015-10-31T11:49:29Z', + versions: null, + }, + { + created_at: '2014-12-05T20:20:39Z', + description: 'A generic serialization/deserialization framework', + documentation: 'https://serde-rs.github.io/serde/serde/serde/index.html', + downloads: 50854, + recent_downloads: 854, + homepage: null, + id: 'serde', + keywords: ['serde', 'serialization'], + max_version: '0.6.1', + name: 'serde', + repository: 'https://github.com/serde-rs/serde', + updated_at: '2015-10-18T03:10:21Z', + versions: null, + }, + { + created_at: '2015-08-26T13:50:58Z', + description: 'Send cypher queries to a neo4j database', + documentation: 'http://livioribeiro.github.io/rusted_cypher/rusted_cypher/', + downloads: 156, + recent_downloads: 54, + homepage: 'https://github.com/livioribeiro/rusted-cypher', + id: 'rusted_cypher', + keywords: ['neo4j', 'database', 'query', 'cypher', 'graph'], + max_version: '0.7.1', + name: 'rusted_cypher', + repository: 'https://github.com/livioribeiro/rusted-cypher', + updated_at: '2015-11-07T17:26:55Z', + versions: null, + }, + { + created_at: '2015-01-02T20:54:04Z', + description: + 'An (incomplete) port of zlib to Rust. The decompressor works, but the compressor has not yet been ported.', + documentation: null, + downloads: 223, + recent_downloads: 23, + homepage: null, + id: 'zlib', + keywords: [], + max_version: '0.0.1', + name: 'zlib', + repository: null, + updated_at: '2015-01-02T20:54:04Z', + versions: null, + }, + { + created_at: '2015-05-08T19:34:16Z', + description: + 'A light HTTP framework, with some REST-like features and the ambition of being simple, modular and non-intrusive.', + documentation: 'http://ogeon.github.io/docs/rustful/master/rustful/index.html', + downloads: 576, + recent_downloads: 76, + homepage: null, + id: 'rustful', + keywords: ['web', 'rest', 'framework', 'http', 'routing'], + max_version: '0.5.0', + name: 'rustful', + repository: 'https://github.com/Ogeon/rustful', + updated_at: '2015-09-19T21:10:27Z', + versions: null, + }, + { + created_at: '2014-11-24T02:34:44Z', + description: 'A native PostgreSQL driver', + documentation: 'https://sfackler.github.io/rust-postgres/doc/v0.10.1/postgres', + downloads: 13449, + recent_downloads: 13, + homepage: null, + id: 'postgres', + keywords: ['database', 'sql'], + max_version: '0.10.1', + name: 'postgres', + repository: 'https://github.com/sfackler/rust-postgres', + updated_at: '2015-11-08T00:48:59Z', + versions: null, + }, + { + created_at: '2014-11-21T00:20:47Z', + description: 'Automatic property based testing with shrinking.', + documentation: 'http://burntsushi.net/rustdoc/quickcheck/', + downloads: 19271, + recent_downloads: 143, + homepage: 'https://github.com/BurntSushi/quickcheck', + id: 'quickcheck', + keywords: ['testing', 'quickcheck', 'property', 'shrinking', 'fuzz'], + max_version: '0.2.24', + name: 'quickcheck', + repository: 'https://github.com/BurntSushi/quickcheck', + updated_at: '2015-09-20T21:53:38Z', + versions: null, + }, + { + created_at: '2014-11-21T00:21:04Z', + description: 'A macro attribute for quickcheck.', + documentation: 'http://burntsushi.net/rustdoc/quickcheck/', + downloads: 3796, + recent_downloads: 768, + homepage: 'https://github.com/BurntSushi/quickcheck', + id: 'quickcheck_macros', + keywords: ['testing', 'quickcheck', 'property', 'shrinking', 'fuzz'], + max_version: '0.2.24', + name: 'quickcheck_macros', + repository: 'https://github.com/BurntSushi/quickcheck', + updated_at: '2015-09-20T21:53:57Z', + versions: null, + }, + { + created_at: '2015-08-25T19:15:35Z', + description: + 'Lexical analysers generator for Rust, written in Rust (crate dedicated to rumblebars, divergences written by Nicolas Cherel)', + documentation: null, + downloads: 109, + recent_downloads: 0, + homepage: 'https://github.com/nicolas-cherel/rustlex', + id: 'nc_rustlex', + keywords: ['lexer', 'lexical', 'analyser', 'generator'], + max_version: '0.3.1', + name: 'nc_rustlex', + repository: 'https://github.com/nicolas-cherel/rustlex', + updated_at: '2015-08-25T19:15:35Z', + versions: null, + }, + { + created_at: '2015-01-17T17:47:52Z', + description: 'A byte-oriented, zero-copy, parser combinators library', + documentation: 'http://rust.unhandledexpression.com/nom/', + downloads: 5169, + recent_downloads: 69, + homepage: null, + id: 'nom', + keywords: ['parser', 'parser-combinators', 'parsing', 'streaming', 'bit'], + max_version: '1.0.1', + name: 'nom', + repository: 'https://github.com/Geal/nom', + updated_at: '2015-11-22T22:00:41Z', + versions: null, + }, ]; diff --git a/mirage/fixtures/dependencies.js b/mirage/fixtures/dependencies.js index bd3e7b3e36a..9f7cb4a8390 100644 --- a/mirage/fixtures/dependencies.js +++ b/mirage/fixtures/dependencies.js @@ -1,36 +1,36 @@ /* eslint-disable quotes */ export default [ - { - crate_id: 'libc', - default_features: true, - features: '', - id: 146231, - kind: 'normal', - optional: false, - req: '^0.2.18', - target: null, - version_id: 40905, - }, - { - crate_id: 'nanomsg-sys', - default_features: true, - features: '', - id: 146232, - kind: 'normal', - optional: false, - req: '^0.6.1', - target: null, - version_id: 40905, - }, - { - crate_id: 'nanomsg', - default_features: true, - features: '', - id: 90880, - kind: 'normal', - optional: false, - req: '^0.5.0', - target: null, - version_id: 28674, - }, + { + crate_id: 'libc', + default_features: true, + features: '', + id: 146231, + kind: 'normal', + optional: false, + req: '^0.2.18', + target: null, + version_id: 40905, + }, + { + crate_id: 'nanomsg-sys', + default_features: true, + features: '', + id: 146232, + kind: 'normal', + optional: false, + req: '^0.6.1', + target: null, + version_id: 40905, + }, + { + crate_id: 'nanomsg', + default_features: true, + features: '', + id: 90880, + kind: 'normal', + optional: false, + req: '^0.5.0', + target: null, + version_id: 28674, + }, ]; diff --git a/mirage/fixtures/keywords.js b/mirage/fixtures/keywords.js index 231b818733c..2285b073d4d 100644 --- a/mirage/fixtures/keywords.js +++ b/mirage/fixtures/keywords.js @@ -1,9 +1,9 @@ /* eslint-disable quotes */ export default [ - { - crates_cnt: 38, - created_at: '2014-11-23T06:47:40Z', - id: 'network', - keyword: 'network', - }, + { + crates_cnt: 38, + created_at: '2014-11-23T06:47:40Z', + id: 'network', + keyword: 'network', + }, ]; diff --git a/mirage/fixtures/teams.js b/mirage/fixtures/teams.js index f13fe486a02..aabb1a35ba8 100644 --- a/mirage/fixtures/teams.js +++ b/mirage/fixtures/teams.js @@ -1,17 +1,17 @@ /* eslint-disable quotes */ export default [ - { - avatar: 'https://avatars.githubusercontent.com/u/565790?v=3', - id: 1, - login: 'github:org:thehydroimpulse', - name: 'thehydroimpulseteam', - url: 'https://github.com/org_test', - }, - { - avatar: 'https://avatars.githubusercontent.com/u/9447137?v=3', - id: 303, - login: 'github:org:blabaere', - name: 'Team Benoît Labaere', - url: 'https://github.com/blabaere', - }, + { + avatar: 'https://avatars.githubusercontent.com/u/565790?v=3', + id: 1, + login: 'github:org:thehydroimpulse', + name: 'thehydroimpulseteam', + url: 'https://github.com/org_test', + }, + { + avatar: 'https://avatars.githubusercontent.com/u/9447137?v=3', + id: 303, + login: 'github:org:blabaere', + name: 'Team Benoît Labaere', + url: 'https://github.com/blabaere', + }, ]; diff --git a/mirage/fixtures/users.js b/mirage/fixtures/users.js index 83b1b4365dd..0c57699a959 100644 --- a/mirage/fixtures/users.js +++ b/mirage/fixtures/users.js @@ -1,27 +1,27 @@ /* eslint-disable quotes */ export default [ - { - avatar: 'https://avatars0.githubusercontent.com/u/9447137?v=3', - email: null, - id: 303, - login: 'blabaere', - name: 'Benoît Labaere', - url: 'https://github.com/blabaere', - }, - { - avatar: 'https://avatars.githubusercontent.com/u/565790?v=3', - email: 'dnfagnan@gmail.com', - id: 2, - login: 'thehydroimpulse', - name: 'Daniel Fagnan', - url: 'https://github.com/thehydroimpulse', - }, - { - avatar: 'https://avatars3.githubusercontent.com/u/1179195?v=3', - email: 'iain@fastmail.com', - id: 10982, - login: 'iain8', - name: 'Iain Buchanan', - url: 'https://github.com/iain8', - }, + { + avatar: 'https://avatars0.githubusercontent.com/u/9447137?v=3', + email: null, + id: 303, + login: 'blabaere', + name: 'Benoît Labaere', + url: 'https://github.com/blabaere', + }, + { + avatar: 'https://avatars.githubusercontent.com/u/565790?v=3', + email: 'dnfagnan@gmail.com', + id: 2, + login: 'thehydroimpulse', + name: 'Daniel Fagnan', + url: 'https://github.com/thehydroimpulse', + }, + { + avatar: 'https://avatars3.githubusercontent.com/u/1179195?v=3', + email: 'iain@fastmail.com', + id: 10982, + login: 'iain8', + name: 'Iain Buchanan', + url: 'https://github.com/iain8', + }, ]; diff --git a/mirage/fixtures/version-downloads.js b/mirage/fixtures/version-downloads.js index f7a144d14ae..eaeccc264cf 100644 --- a/mirage/fixtures/version-downloads.js +++ b/mirage/fixtures/version-downloads.js @@ -1,18 +1,18 @@ /* eslint-disable quotes */ export default [ - { - date: '2017-02-10T00:00:00Z', - downloads: 2, - version: 40905, - }, - { - date: '2017-02-10T00:00:00Z', - downloads: 1, - version: 18445, - }, - { - date: '2017-02-11T00:00:00Z', - downloads: 1, - version: 40905, - }, + { + date: '2017-02-10T00:00:00Z', + downloads: 2, + version: 40905, + }, + { + date: '2017-02-10T00:00:00Z', + downloads: 1, + version: 18445, + }, + { + date: '2017-02-11T00:00:00Z', + downloads: 1, + version: 40905, + }, ]; diff --git a/mirage/fixtures/versions.js b/mirage/fixtures/versions.js index 667d44de112..34969b7faf1 100644 --- a/mirage/fixtures/versions.js +++ b/mirage/fixtures/versions.js @@ -1,308 +1,308 @@ /* eslint-disable quotes */ export default [ - { - crate: 'nanomsg', - created_at: '2016-12-27T08:40:00Z', - dl_path: '/api/v1/crates/nanomsg/0.7.0-alpha.1/download', - downloads: 260, - features: { - bundled: ['nanomsg-sys/bundled'], - }, - id: 40906, - num: '0.7.0-alpha.1', - updated_at: '2016-12-27T08:40:00Z', - yanked: false, - license: 'MIT', - crate_size: 912355, - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], + { + crate: 'nanomsg', + created_at: '2016-12-27T08:40:00Z', + dl_path: '/api/v1/crates/nanomsg/0.7.0-alpha.1/download', + downloads: 260, + features: { + bundled: ['nanomsg-sys/bundled'], }, - { - crate: 'nanomsg', - created_at: '2016-12-27T08:40:00Z', - dl_path: '/api/v1/crates/nanomsg/0.6.1/download', - downloads: 260, - features: { - bundled: ['nanomsg-sys/bundled'], - }, - id: 40905, - num: '0.6.1', - crate_size: 8123545, - updated_at: '2016-12-27T08:40:00Z', - yanked: false, - license: 'Apache-2.0', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'nanomsg', - created_at: '2016-06-10T20:03:55Z', - dl_path: '/api/v1/crates/nanomsg/0.6.0/download', - downloads: 904, - features: {}, - id: 28431, - num: '0.6.0', - updated_at: '2016-06-10T20:03:55Z', - yanked: false, - license: 'Apache-2.0', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'nanomsg', - created_at: '2016-01-24T22:07:58Z', - dl_path: '/api/v1/crates/nanomsg/0.5.0/download', - downloads: 1217, - features: {}, - id: 21273, - num: '0.5.0', - updated_at: '2016-01-24T22:07:58Z', - yanked: false, - license: 'MIT/Apache-2.0', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'nanomsg', - created_at: '2015-11-23T12:10:09Z', - dl_path: '/api/v1/crates/nanomsg/0.4.2/download', - downloads: 318, - features: {}, - id: 18445, - num: '0.4.2', - updated_at: '2015-12-16T00:01:56Z', - yanked: false, - license: 'MIT', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'nanomsg', - created_at: '2015-10-29T22:13:45Z', - dl_path: '/api/v1/crates/nanomsg/0.4.1/download', - downloads: 168, - features: {}, - id: 17384, - num: '0.4.1', - updated_at: '2015-12-11T23:54:29Z', - yanked: false, - license: 'MIT', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'nanomsg', - created_at: '2015-07-23T05:54:44Z', - dl_path: '/api/v1/crates/nanomsg/0.4.0/download', - downloads: 311, - features: {}, - id: 13574, - num: '0.4.0', - updated_at: '2015-12-11T23:54:29Z', - yanked: false, - license: 'MIT', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'nanomsg', - created_at: '2015-04-18T20:45:03Z', - dl_path: '/api/v1/crates/nanomsg/0.3.4/download', - downloads: 237, - features: {}, - id: 9014, - num: '0.3.4', - updated_at: '2015-12-15T00:03:39Z', - yanked: false, - license: 'MIT', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'nanomsg', - created_at: '2015-04-06T18:57:47Z', - dl_path: '/api/v1/crates/nanomsg/0.3.3/download', - downloads: 99, - features: {}, - id: 8236, - num: '0.3.3', - updated_at: '2015-12-11T23:54:29Z', - yanked: false, - license: 'MIT', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'nanomsg', - created_at: '2015-03-26T06:51:10Z', - dl_path: '/api/v1/crates/nanomsg/0.3.2/download', - downloads: 98, - features: {}, - id: 7190, - num: '0.3.2', - updated_at: '2015-12-11T23:54:29Z', - yanked: false, - license: 'Apache-2.0', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'nanomsg', - created_at: '2015-02-12T20:20:32Z', - dl_path: '/api/v1/crates/nanomsg/0.3.1/download', - downloads: 95, - features: {}, - id: 4944, - num: '0.3.1', - updated_at: '2015-12-11T23:54:29Z', - yanked: false, - license: 'MIT/Apache-2.0', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'nanomsg', - created_at: '2014-12-08T16:21:01Z', - dl_path: '/api/v1/crates/nanomsg/0.3.0/download', - downloads: 102, - features: {}, - id: 940, - num: '0.3.0', - updated_at: '2015-12-11T23:54:29Z', - yanked: false, - license: 'MIT', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'nanomsg', - created_at: '2014-12-08T02:08:06Z', - dl_path: '/api/v1/crates/nanomsg/0.2.0/download', - downloads: 79, - features: {}, - id: 924, - num: '0.2.0', - updated_at: '2015-12-11T23:54:29Z', - yanked: false, - license: 'MIT', - _authors: [ - 'Daniel Fagnan ', - 'Jason E. Aten', - 'David C. Bishop', - 'Dennis Lawler', - 'Zachary Tong', - 'Dan Burkert', - 'Benoît Labaere ', - 'Chip Collier', - ], - }, - { - crate: 'unicorn-rpc', - created_at: '2014-12-08T02:08:06Z', - dl_path: '/api/v1/crates/unicorn-rpc/0.2.0/download', - downloads: 79, - features: {}, - id: 28674, - num: '0.2.0', - updated_at: '2015-12-11T23:54:29Z', - yanked: false, - license: 'MIT', - _authors: ['David C. Bishop'], + id: 40906, + num: '0.7.0-alpha.1', + updated_at: '2016-12-27T08:40:00Z', + yanked: false, + license: 'MIT', + crate_size: 912355, + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2016-12-27T08:40:00Z', + dl_path: '/api/v1/crates/nanomsg/0.6.1/download', + downloads: 260, + features: { + bundled: ['nanomsg-sys/bundled'], }, + id: 40905, + num: '0.6.1', + crate_size: 8123545, + updated_at: '2016-12-27T08:40:00Z', + yanked: false, + license: 'Apache-2.0', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2016-06-10T20:03:55Z', + dl_path: '/api/v1/crates/nanomsg/0.6.0/download', + downloads: 904, + features: {}, + id: 28431, + num: '0.6.0', + updated_at: '2016-06-10T20:03:55Z', + yanked: false, + license: 'Apache-2.0', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2016-01-24T22:07:58Z', + dl_path: '/api/v1/crates/nanomsg/0.5.0/download', + downloads: 1217, + features: {}, + id: 21273, + num: '0.5.0', + updated_at: '2016-01-24T22:07:58Z', + yanked: false, + license: 'MIT/Apache-2.0', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2015-11-23T12:10:09Z', + dl_path: '/api/v1/crates/nanomsg/0.4.2/download', + downloads: 318, + features: {}, + id: 18445, + num: '0.4.2', + updated_at: '2015-12-16T00:01:56Z', + yanked: false, + license: 'MIT', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2015-10-29T22:13:45Z', + dl_path: '/api/v1/crates/nanomsg/0.4.1/download', + downloads: 168, + features: {}, + id: 17384, + num: '0.4.1', + updated_at: '2015-12-11T23:54:29Z', + yanked: false, + license: 'MIT', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2015-07-23T05:54:44Z', + dl_path: '/api/v1/crates/nanomsg/0.4.0/download', + downloads: 311, + features: {}, + id: 13574, + num: '0.4.0', + updated_at: '2015-12-11T23:54:29Z', + yanked: false, + license: 'MIT', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2015-04-18T20:45:03Z', + dl_path: '/api/v1/crates/nanomsg/0.3.4/download', + downloads: 237, + features: {}, + id: 9014, + num: '0.3.4', + updated_at: '2015-12-15T00:03:39Z', + yanked: false, + license: 'MIT', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2015-04-06T18:57:47Z', + dl_path: '/api/v1/crates/nanomsg/0.3.3/download', + downloads: 99, + features: {}, + id: 8236, + num: '0.3.3', + updated_at: '2015-12-11T23:54:29Z', + yanked: false, + license: 'MIT', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2015-03-26T06:51:10Z', + dl_path: '/api/v1/crates/nanomsg/0.3.2/download', + downloads: 98, + features: {}, + id: 7190, + num: '0.3.2', + updated_at: '2015-12-11T23:54:29Z', + yanked: false, + license: 'Apache-2.0', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2015-02-12T20:20:32Z', + dl_path: '/api/v1/crates/nanomsg/0.3.1/download', + downloads: 95, + features: {}, + id: 4944, + num: '0.3.1', + updated_at: '2015-12-11T23:54:29Z', + yanked: false, + license: 'MIT/Apache-2.0', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2014-12-08T16:21:01Z', + dl_path: '/api/v1/crates/nanomsg/0.3.0/download', + downloads: 102, + features: {}, + id: 940, + num: '0.3.0', + updated_at: '2015-12-11T23:54:29Z', + yanked: false, + license: 'MIT', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'nanomsg', + created_at: '2014-12-08T02:08:06Z', + dl_path: '/api/v1/crates/nanomsg/0.2.0/download', + downloads: 79, + features: {}, + id: 924, + num: '0.2.0', + updated_at: '2015-12-11T23:54:29Z', + yanked: false, + license: 'MIT', + _authors: [ + 'Daniel Fagnan ', + 'Jason E. Aten', + 'David C. Bishop', + 'Dennis Lawler', + 'Zachary Tong', + 'Dan Burkert', + 'Benoît Labaere ', + 'Chip Collier', + ], + }, + { + crate: 'unicorn-rpc', + created_at: '2014-12-08T02:08:06Z', + dl_path: '/api/v1/crates/unicorn-rpc/0.2.0/download', + downloads: 79, + features: {}, + id: 28674, + num: '0.2.0', + updated_at: '2015-12-11T23:54:29Z', + yanked: false, + license: 'MIT', + _authors: ['David C. Bishop'], + }, ]; diff --git a/mirage/scenarios/default.js b/mirage/scenarios/default.js index 6336d953b8c..5031608679b 100644 --- a/mirage/scenarios/default.js +++ b/mirage/scenarios/default.js @@ -1,3 +1,3 @@ export default function(server) { - server.loadFixtures(); + server.loadFixtures(); } diff --git a/mirage/serializers/application.js b/mirage/serializers/application.js index 1a966912efa..29c7196b5e6 100644 --- a/mirage/serializers/application.js +++ b/mirage/serializers/application.js @@ -1,26 +1,26 @@ import { ActiveModelSerializer } from 'ember-cli-mirage'; export default ActiveModelSerializer.extend({ - getHashForResource(resource) { - let isModel = this.isModel(resource); - let hash = ActiveModelSerializer.prototype.getHashForResource.apply(this, arguments); + getHashForResource(resource) { + let isModel = this.isModel(resource); + let hash = ActiveModelSerializer.prototype.getHashForResource.apply(this, arguments); - if (isModel) { - let links = this.links(resource); - if (links) { - hash[0].links = links; - } - } else { - for (let i = 0; i < hash[0].length && i < resource.models.length; i++) { - let links = this.links(resource.models[i]); - if (links) { - hash[0][i].links = links; - } - } + if (isModel) { + let links = this.links(resource); + if (links) { + hash[0].links = links; + } + } else { + for (let i = 0; i < hash[0].length && i < resource.models.length; i++) { + let links = this.links(resource.models[i]); + if (links) { + hash[0][i].links = links; } + } + } - return hash; - }, + return hash; + }, - links() {}, + links() {}, }); diff --git a/mirage/serializers/crate.js b/mirage/serializers/crate.js index 665f66bb37c..940a8f3d27e 100644 --- a/mirage/serializers/crate.js +++ b/mirage/serializers/crate.js @@ -1,32 +1,32 @@ import BaseSerializer from './application'; export default BaseSerializer.extend({ - attrs: [ - 'badges', - 'categories', - 'created_at', - 'description', - 'documentation', - 'downloads', - 'recent_downloads', - 'homepage', - 'id', - 'keywords', - 'links', - 'max_version', - 'name', - 'repository', - 'updated_at', - 'versions', - ], + attrs: [ + 'badges', + 'categories', + 'created_at', + 'description', + 'documentation', + 'downloads', + 'recent_downloads', + 'homepage', + 'id', + 'keywords', + 'links', + 'max_version', + 'name', + 'repository', + 'updated_at', + 'versions', + ], - links(crate) { - return { - owner_user: `/api/v1/crates/${crate.id}/owner_user`, - owner_team: `/api/v1/crates/${crate.id}/owner_team`, - reverse_dependencies: `/api/v1/crates/${crate.id}/reverse_dependencies`, - version_downloads: `/api/v1/crates/${crate.id}/downloads`, - versions: `/api/v1/crates/${crate.id}/versions`, - }; - }, + links(crate) { + return { + owner_user: `/api/v1/crates/${crate.id}/owner_user`, + owner_team: `/api/v1/crates/${crate.id}/owner_team`, + reverse_dependencies: `/api/v1/crates/${crate.id}/reverse_dependencies`, + version_downloads: `/api/v1/crates/${crate.id}/downloads`, + versions: `/api/v1/crates/${crate.id}/versions`, + }; + }, }); diff --git a/mirage/serializers/version.js b/mirage/serializers/version.js index a8cb81f6c89..06f2d158ccc 100644 --- a/mirage/serializers/version.js +++ b/mirage/serializers/version.js @@ -1,26 +1,26 @@ import BaseSerializer from './application'; export default BaseSerializer.extend({ - attrs: [ - 'crate', - 'created_at', - 'dl_path', - 'downloads', - 'features', - 'id', - 'links', - 'num', - 'updated_at', - 'yanked', - 'license', - 'crate_size', - ], + attrs: [ + 'crate', + 'created_at', + 'dl_path', + 'downloads', + 'features', + 'id', + 'links', + 'num', + 'updated_at', + 'yanked', + 'license', + 'crate_size', + ], - links(version) { - return { - authors: `/api/v1/crates/${version.crate}/${version.num}/authors`, - dependencies: `/api/v1/crates/${version.crate}/${version.num}/dependencies`, - version_downloads: `/api/v1/crates/${version.crate}/${version.num}/downloads`, - }; - }, + links(version) { + return { + authors: `/api/v1/crates/${version.crate}/${version.num}/authors`, + dependencies: `/api/v1/crates/${version.crate}/${version.num}/dependencies`, + version_downloads: `/api/v1/crates/${version.crate}/${version.num}/downloads`, + }; + }, }); diff --git a/package.json b/package.json index ce4b06699b1..d9fce801457 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ }, "scripts": { "build": "ember build", + "lint:hbs": "ember-template-lint app/templates", "lint:js": "eslint . --cache", "lint:deps": "ember dependency-lint", "prettier": "prettier --write '{app,tests,mirage}/**/*.js'", @@ -90,7 +91,7 @@ "private": true, "prettier": { "printWidth": 120, - "tabWidth": 4, + "tabWidth": 2, "singleQuote": true, "trailingComma": "all" } diff --git a/testem.js b/testem.js index 97d3c255dd5..6f7073f7dd7 100644 --- a/testem.js +++ b/testem.js @@ -1,15 +1,15 @@ 'use strict'; module.exports = { - test_page: 'tests/index.html?hidepassed', - disable_watching: true, - parallel: -1, - launch_in_ci: ['Chrome'], - launch_in_dev: ['Chrome'], - browser_args: { - Chrome: { - mode: 'ci', - args: ['--disable-gpu', '--headless', '--remote-debugging-port=9222', '--window-size=1440,900'], - }, + test_page: 'tests/index.html?hidepassed', + disable_watching: true, + parallel: -1, + launch_in_ci: ['Chrome'], + launch_in_dev: ['Chrome'], + browser_args: { + Chrome: { + mode: 'ci', + args: ['--disable-gpu', '--headless', '--remote-debugging-port=9222', '--window-size=1440,900'], }, + }, }; diff --git a/tests/acceptance/categories-test.js b/tests/acceptance/categories-test.js index b5c01dc38ca..4c8b34446d3 100644 --- a/tests/acceptance/categories-test.js +++ b/tests/acceptance/categories-test.js @@ -7,62 +7,62 @@ import setupMirage from '../helpers/setup-mirage'; import { percySnapshot } from 'ember-percy'; module('Acceptance | categories', function(hooks) { - setupApplicationTest(hooks); - setupMirage(hooks); + setupApplicationTest(hooks); + setupMirage(hooks); - test('is accessible', async function(assert) { - assert.expect(0); + test('is accessible', async function(assert) { + assert.expect(0); - this.server.create('category', { category: 'API bindings', crates_cnt: 0 }); - this.server.create('category', { category: 'Algorithms', crates_cnt: 1 }); - this.server.create('category', { category: 'Asynchronous', crates_cnt: 3910 }); + this.server.create('category', { category: 'API bindings', crates_cnt: 0 }); + this.server.create('category', { category: 'Algorithms', crates_cnt: 1 }); + this.server.create('category', { category: 'Asynchronous', crates_cnt: 3910 }); - await visit('/categories'); - percySnapshot(assert); + await visit('/categories'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('category/:category_id is accessible', async function(assert) { - assert.expect(0); + test('category/:category_id is accessible', async function(assert) { + assert.expect(0); - this.server.create('category', { category: 'Algorithms', crates_cnt: 1 }); + this.server.create('category', { category: 'Algorithms', crates_cnt: 1 }); - await visit('/categories/algorithms'); - percySnapshot(assert); + await visit('/categories/algorithms'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('listing categories', async function(assert) { - this.server.create('category', { category: 'API bindings', crates_cnt: 0 }); - this.server.create('category', { category: 'Algorithms', crates_cnt: 1 }); - this.server.create('category', { category: 'Asynchronous', crates_cnt: 3910 }); + test('listing categories', async function(assert) { + this.server.create('category', { category: 'API bindings', crates_cnt: 0 }); + this.server.create('category', { category: 'Algorithms', crates_cnt: 1 }); + this.server.create('category', { category: 'Asynchronous', crates_cnt: 3910 }); - await visit('/categories'); + await visit('/categories'); - assert.dom('[data-test-category="api-bindings"] [data-test-crate-count]').hasText('0 crates'); - assert.dom('[data-test-category="algorithms"] [data-test-crate-count]').hasText('1 crate'); - assert.dom('[data-test-category="asynchronous"] [data-test-crate-count]').hasText('3,910 crates'); - }); + assert.dom('[data-test-category="api-bindings"] [data-test-crate-count]').hasText('0 crates'); + assert.dom('[data-test-category="algorithms"] [data-test-crate-count]').hasText('1 crate'); + assert.dom('[data-test-category="asynchronous"] [data-test-crate-count]').hasText('3,910 crates'); + }); - test('category/:category_id index default sort is recent-downloads', async function(assert) { - this.server.create('category', { category: 'Algorithms', crates_cnt: 1 }); + test('category/:category_id index default sort is recent-downloads', async function(assert) { + this.server.create('category', { category: 'Algorithms', crates_cnt: 1 }); - await visit('/categories/algorithms'); + await visit('/categories/algorithms'); - assert.dom('[data-test-category-sort] [data-test-current-order]').hasText('Recent Downloads'); - }); + assert.dom('[data-test-category-sort] [data-test-current-order]').hasText('Recent Downloads'); + }); - test('listing category slugs', async function(assert) { - this.server.create('category', { category: 'Algorithms', description: 'Crates for algorithms' }); - this.server.create('category', { category: 'Asynchronous', description: 'Async crates' }); + test('listing category slugs', async function(assert) { + this.server.create('category', { category: 'Algorithms', description: 'Crates for algorithms' }); + this.server.create('category', { category: 'Asynchronous', description: 'Async crates' }); - await visit('/category_slugs'); + await visit('/category_slugs'); - assert.dom('[data-test-category-slug="algorithms"]').hasText('algorithms'); - assert.dom('[data-test-category-description="algorithms"]').hasText('Crates for algorithms'); - assert.dom('[data-test-category-slug="asynchronous"]').hasText('asynchronous'); - assert.dom('[data-test-category-description="asynchronous"]').hasText('Async crates'); - }); + assert.dom('[data-test-category-slug="algorithms"]').hasText('algorithms'); + assert.dom('[data-test-category-description="algorithms"]').hasText('Crates for algorithms'); + assert.dom('[data-test-category-slug="asynchronous"]').hasText('asynchronous'); + assert.dom('[data-test-category-description="asynchronous"]').hasText('Async crates'); + }); }); diff --git a/tests/acceptance/crate-test.js b/tests/acceptance/crate-test.js index 943c20a96fd..fc49eb0b5f2 100644 --- a/tests/acceptance/crate-test.js +++ b/tests/acceptance/crate-test.js @@ -8,279 +8,279 @@ import setupMirage from '../helpers/setup-mirage'; import { percySnapshot } from 'ember-percy'; module('Acceptance | crate page', function(hooks) { - setupApplicationTest(hooks); - setupMirage(hooks); + setupApplicationTest(hooks); + setupMirage(hooks); - test('is accessible', async function(assert) { - assert.expect(0); + test('is accessible', async function(assert) { + assert.expect(0); - this.server.create('crate', 'withVersion', { id: 'nanomsg' }); + this.server.create('crate', 'withVersion', { id: 'nanomsg' }); - await visit('/'); - percySnapshot(assert); + await visit('/'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('/crates/:crate is accessible', async function(assert) { - assert.expect(0); + test('/crates/:crate is accessible', async function(assert) { + assert.expect(0); - this.server.create('crate', { id: 'nanomsg', max_version: '0.6.1' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); + this.server.create('crate', { id: 'nanomsg', max_version: '0.6.1' }); + this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); + this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); - await visit('/crates/nanomsg'); - percySnapshot(assert); + await visit('/crates/nanomsg'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('/crates/:crate/:version is accessible', async function(assert) { - assert.expect(0); + test('/crates/:crate/:version is accessible', async function(assert) { + assert.expect(0); - this.server.create('crate', { id: 'nanomsg', max_version: '0.6.1' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); + this.server.create('crate', { id: 'nanomsg', max_version: '0.6.1' }); + this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); + this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); - await visit('/crates/nanomsg/0.6.0'); - percySnapshot(assert); + await visit('/crates/nanomsg/0.6.0'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('/crates/:crate/owners is accessible', async function(assert) { - assert.expect(0); + test('/crates/:crate/owners is accessible', async function(assert) { + assert.expect(0); - this.server.loadFixtures(); + this.server.loadFixtures(); - await visit('/crates/nanomsg/owners'); - percySnapshot(assert); + await visit('/crates/nanomsg/owners'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('visiting a crate page from the front page', async function(assert) { - this.server.create('crate', 'withVersion', { id: 'nanomsg' }); + test('visiting a crate page from the front page', async function(assert) { + this.server.create('crate', 'withVersion', { id: 'nanomsg' }); - await visit('/'); - await click('[data-test-just-updated] [data-test-crate-link="0"]'); + await visit('/'); + await click('[data-test-just-updated] [data-test-crate-link="0"]'); - assert.equal(currentURL(), '/crates/nanomsg'); - assert.equal(document.title, 'nanomsg - crates.io: Rust Package Registry'); - }); + assert.equal(currentURL(), '/crates/nanomsg'); + assert.equal(document.title, 'nanomsg - crates.io: Rust Package Registry'); + }); - test('visiting /crates/nanomsg', async function(assert) { - this.server.create('crate', { id: 'nanomsg', max_version: '0.6.1' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); + test('visiting /crates/nanomsg', async function(assert) { + this.server.create('crate', { id: 'nanomsg', max_version: '0.6.1' }); + this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); + this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); - await visit('/crates/nanomsg'); + await visit('/crates/nanomsg'); - assert.equal(currentURL(), '/crates/nanomsg'); - assert.equal(currentRouteName(), 'crate.index'); - assert.equal(document.title, 'nanomsg - crates.io: Rust Package Registry'); + assert.equal(currentURL(), '/crates/nanomsg'); + assert.equal(currentRouteName(), 'crate.index'); + assert.equal(document.title, 'nanomsg - crates.io: Rust Package Registry'); - assert.dom('[data-test-heading] [data-test-crate-name]').hasText('nanomsg'); - assert.dom('[data-test-heading] [data-test-crate-version]').hasText('0.6.1'); - }); + assert.dom('[data-test-heading] [data-test-crate-name]').hasText('nanomsg'); + assert.dom('[data-test-heading] [data-test-crate-version]').hasText('0.6.1'); + }); - test('visiting /crates/nanomsg/', async function(assert) { - this.server.create('crate', { id: 'nanomsg', max_version: '0.6.1' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); + test('visiting /crates/nanomsg/', async function(assert) { + this.server.create('crate', { id: 'nanomsg', max_version: '0.6.1' }); + this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); + this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); - await visit('/crates/nanomsg/'); + await visit('/crates/nanomsg/'); - assert.equal(currentURL(), '/crates/nanomsg/'); - assert.equal(currentRouteName(), 'crate.index'); - assert.equal(document.title, 'nanomsg - crates.io: Rust Package Registry'); + assert.equal(currentURL(), '/crates/nanomsg/'); + assert.equal(currentRouteName(), 'crate.index'); + assert.equal(document.title, 'nanomsg - crates.io: Rust Package Registry'); - assert.dom('[data-test-heading] [data-test-crate-name]').hasText('nanomsg'); - assert.dom('[data-test-heading] [data-test-crate-version]').hasText('0.6.1'); - }); + assert.dom('[data-test-heading] [data-test-crate-name]').hasText('nanomsg'); + assert.dom('[data-test-heading] [data-test-crate-version]').hasText('0.6.1'); + }); - test('visiting /crates/nanomsg/0.6.0', async function(assert) { - this.server.create('crate', { id: 'nanomsg', max_version: '0.6.1' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); - this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); + test('visiting /crates/nanomsg/0.6.0', async function(assert) { + this.server.create('crate', { id: 'nanomsg', max_version: '0.6.1' }); + this.server.create('version', { crate: 'nanomsg', num: '0.6.0' }); + this.server.create('version', { crate: 'nanomsg', num: '0.6.1' }); - await visit('/crates/nanomsg/0.6.0'); + await visit('/crates/nanomsg/0.6.0'); - assert.equal(currentURL(), '/crates/nanomsg/0.6.0'); - assert.equal(currentRouteName(), 'crate.version'); - assert.equal(document.title, 'nanomsg - crates.io: Rust Package Registry'); + assert.equal(currentURL(), '/crates/nanomsg/0.6.0'); + assert.equal(currentRouteName(), 'crate.version'); + assert.equal(document.title, 'nanomsg - crates.io: Rust Package Registry'); - assert.dom('[data-test-heading] [data-test-crate-name]').hasText('nanomsg'); - assert.dom('[data-test-heading] [data-test-crate-version]').hasText('0.6.0'); - }); + assert.dom('[data-test-heading] [data-test-crate-name]').hasText('nanomsg'); + assert.dom('[data-test-heading] [data-test-crate-version]').hasText('0.6.0'); + }); - test('navigating to the all versions page', async function(assert) { - this.server.loadFixtures(); + test('navigating to the all versions page', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg'); - await click('[data-test-all-versions-link]'); + await visit('/crates/nanomsg'); + await click('[data-test-all-versions-link]'); - assert.dom('.info').hasText(/All 13\s+versions of nanomsg since\s+December \d+, 2014/); - }); + assert.dom('.info').hasText(/All 13\s+versions of nanomsg since\s+December \d+, 2014/); + }); - test('navigating to the reverse dependencies page', async function(assert) { - this.server.loadFixtures(); + test('navigating to the reverse dependencies page', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg'); - await click('[data-test-reverse-deps-link]'); + await visit('/crates/nanomsg'); + await click('[data-test-reverse-deps-link]'); - assert.equal(currentURL(), '/crates/nanomsg/reverse_dependencies'); - assert.dom('a[href="/crates/unicorn-rpc"]').hasText('unicorn-rpc'); - }); + assert.equal(currentURL(), '/crates/nanomsg/reverse_dependencies'); + assert.dom('a[href="/crates/unicorn-rpc"]').hasText('unicorn-rpc'); + }); - test('navigating to a user page', async function(assert) { - this.server.loadFixtures(); + test('navigating to a user page', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg'); - await click('[data-test-owners] [data-test-user-link="blabaere"]'); + await visit('/crates/nanomsg'); + await click('[data-test-owners] [data-test-user-link="blabaere"]'); - assert.equal(currentURL(), '/users/blabaere'); - assert.dom('[data-test-heading] [data-test-username]').hasText('blabaere'); - }); + assert.equal(currentURL(), '/users/blabaere'); + assert.dom('[data-test-heading] [data-test-username]').hasText('blabaere'); + }); - test('navigating to a team page', async function(assert) { - this.server.loadFixtures(); + test('navigating to a team page', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg'); - await click('[data-test-owners] [data-test-team-link="github:org:thehydroimpulse"]'); + await visit('/crates/nanomsg'); + await click('[data-test-owners] [data-test-team-link="github:org:thehydroimpulse"]'); - assert.equal(currentURL(), '/teams/github:org:thehydroimpulse'); - assert.dom('[data-test-heading] [data-test-team-name]').hasText('thehydroimpulseteam'); - }); + assert.equal(currentURL(), '/teams/github:org:thehydroimpulse'); + assert.dom('[data-test-heading] [data-test-team-name]').hasText('thehydroimpulseteam'); + }); - test('crates having user-owners', async function(assert) { - this.server.loadFixtures(); + test('crates having user-owners', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg'); + await visit('/crates/nanomsg'); - assert - .dom('[data-test-owners] [data-test-team-link="github:org:thehydroimpulse"] img') - .hasAttribute('src', 'https://avatars.githubusercontent.com/u/565790?v=3&s=64'); + assert + .dom('[data-test-owners] [data-test-team-link="github:org:thehydroimpulse"] img') + .hasAttribute('src', 'https://avatars.githubusercontent.com/u/565790?v=3&s=64'); - assert.dom('[data-test-owners] li').exists({ count: 4 }); - }); + assert.dom('[data-test-owners] li').exists({ count: 4 }); + }); - test('crates having team-owners', async function(assert) { - this.server.loadFixtures(); + test('crates having team-owners', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg'); + await visit('/crates/nanomsg'); - assert.dom('[data-test-owners] [data-test-team-link="github:org:thehydroimpulse"]').exists(); - assert.dom('[data-test-owners] li').exists({ count: 4 }); - }); + assert.dom('[data-test-owners] [data-test-team-link="github:org:thehydroimpulse"]').exists(); + assert.dom('[data-test-owners] li').exists({ count: 4 }); + }); - test('crates license is supplied by version', async function(assert) { - this.server.loadFixtures(); + test('crates license is supplied by version', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg'); - assert.dom('[data-test-license]').hasText('Apache-2.0'); + await visit('/crates/nanomsg'); + assert.dom('[data-test-license]').hasText('Apache-2.0'); - await click('[data-test-version-link="0.5.0"]'); - assert.dom('[data-test-license]').hasText('MIT/Apache-2.0'); - }); + await click('[data-test-version-link="0.5.0"]'); + assert.dom('[data-test-license]').hasText('MIT/Apache-2.0'); + }); - test('navigating to the owners page when not logged in', async function(assert) { - this.server.loadFixtures(); + test('navigating to the owners page when not logged in', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg'); + await visit('/crates/nanomsg'); - assert.dom('#crate-owners p a').doesNotExist(); - }); + assert.dom('#crate-owners p a').doesNotExist(); + }); - test('navigating to the owners page when not an owner', async function(assert) { - this.server.loadFixtures(); + test('navigating to the owners page when not an owner', async function(assert) { + this.server.loadFixtures(); - this.owner.register( - 'service:session', - Service.extend({ - get currentUser() { - return { login: 'iain8' }; - }, - loadUser() {}, - }), - ); + this.owner.register( + 'service:session', + Service.extend({ + get currentUser() { + return { login: 'iain8' }; + }, + loadUser() {}, + }), + ); - await visit('/crates/nanomsg'); + await visit('/crates/nanomsg'); - assert.dom('#crate-owners p a').doesNotExist(); - }); + assert.dom('#crate-owners p a').doesNotExist(); + }); - test('navigating to the owners page', async function(assert) { - this.server.loadFixtures(); + test('navigating to the owners page', async function(assert) { + this.server.loadFixtures(); - this.owner.register( - 'service:session', - Service.extend({ - get currentUser() { - return { login: 'thehydroimpulse', id: '2' }; - }, - loadUser() {}, - }), - ); + this.owner.register( + 'service:session', + Service.extend({ + get currentUser() { + return { login: 'thehydroimpulse', id: '2' }; + }, + loadUser() {}, + }), + ); - await visit('/crates/nanomsg'); - await click('#crate-owners p a'); + await visit('/crates/nanomsg'); + await click('#crate-owners p a'); - assert.dom('#crates-heading h1').hasText('Manage Crate Owners'); - }); + assert.dom('#crates-heading h1').hasText('Manage Crate Owners'); + }); - test('listing crate owners', async function(assert) { - this.server.loadFixtures(); + test('listing crate owners', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg/owners'); + await visit('/crates/nanomsg/owners'); - assert.dom('.owners .row').exists({ count: 2 }); - assert.dom('a[href="/users/thehydroimpulse"]').exists(); - assert.dom('a[href="/users/blabaere"]').exists(); - }); + assert.dom('.owners .row').exists({ count: 2 }); + assert.dom('a[href="/users/thehydroimpulse"]').exists(); + assert.dom('a[href="/users/blabaere"]').exists(); + }); - test('attempting to add owner without username', async function(assert) { - this.server.loadFixtures(); + test('attempting to add owner without username', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg/owners'); - await click('#add-owner'); + await visit('/crates/nanomsg/owners'); + await click('#add-owner'); - assert.dom('.error').exists(); - assert.dom('.error').hasText('Please enter a username'); - assert.dom('.owners .row').exists({ count: 2 }); - }); + assert.dom('.error').exists(); + assert.dom('.error').hasText('Please enter a username'); + assert.dom('.owners .row').exists({ count: 2 }); + }); - test('attempting to add non-existent owner', async function(assert) { - this.server.loadFixtures(); + test('attempting to add non-existent owner', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg/owners'); - await fillIn('input[name="username"]', 'spookyghostboo'); - await click('#add-owner'); + await visit('/crates/nanomsg/owners'); + await fillIn('input[name="username"]', 'spookyghostboo'); + await click('#add-owner'); - assert.dom('.error').exists(); - assert.dom('.error').hasText('Error sending invite'); - assert.dom('.owners .row').exists({ count: 2 }); - }); + assert.dom('.error').exists(); + assert.dom('.error').hasText('Error sending invite'); + assert.dom('.owners .row').exists({ count: 2 }); + }); - test('add a new owner', async function(assert) { - this.server.loadFixtures(); + test('add a new owner', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg/owners'); - await fillIn('input[name="username"]', 'iain8'); - await click('#add-owner'); + await visit('/crates/nanomsg/owners'); + await fillIn('input[name="username"]', 'iain8'); + await click('#add-owner'); - assert.dom('.invited').exists(); - assert.dom('.invited').hasText('An invite has been sent to iain8'); - assert.dom('.owners .row').exists({ count: 2 }); - }); + assert.dom('.invited').exists(); + assert.dom('.invited').hasText('An invite has been sent to iain8'); + assert.dom('.owners .row').exists({ count: 2 }); + }); - test('remove a crate owner', async function(assert) { - this.server.loadFixtures(); + test('remove a crate owner', async function(assert) { + this.server.loadFixtures(); - await visit('/crates/nanomsg/owners'); - await click('.owners .row:first-child .remove-owner'); + await visit('/crates/nanomsg/owners'); + await click('.owners .row:first-child .remove-owner'); - assert.dom('.removed').exists(); - assert.dom('.owners .row').exists({ count: 1 }); - }); + assert.dom('.removed').exists(); + assert.dom('.owners .row').exists({ count: 1 }); + }); }); diff --git a/tests/acceptance/crates-test.js b/tests/acceptance/crates-test.js index 3b37a3ba281..5f6647b5033 100644 --- a/tests/acceptance/crates-test.js +++ b/tests/acceptance/crates-test.js @@ -7,90 +7,90 @@ import setupMirage from '../helpers/setup-mirage'; import { percySnapshot } from 'ember-percy'; module('Acceptance | crates page', function(hooks) { - setupApplicationTest(hooks); - setupMirage(hooks); + setupApplicationTest(hooks); + setupMirage(hooks); - test('is accessible', async function(assert) { - assert.expect(0); + test('is accessible', async function(assert) { + assert.expect(0); - this.server.loadFixtures(); + this.server.loadFixtures(); - await visit('/'); - percySnapshot(assert); + await visit('/'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('/crates is accessible', async function(assert) { - assert.expect(0); + test('/crates is accessible', async function(assert) { + assert.expect(0); - this.server.loadFixtures(); + this.server.loadFixtures(); - await visit('/crates'); - percySnapshot(assert); + await visit('/crates'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('visiting the crates page from the front page', async function(assert) { - this.server.loadFixtures(); + test('visiting the crates page from the front page', async function(assert) { + this.server.loadFixtures(); - await visit('/'); - await click('[data-test-all-crates-link]'); + await visit('/'); + await click('[data-test-all-crates-link]'); - assert.equal(currentURL(), '/crates'); - assert.equal(document.title, 'Crates - crates.io: Rust Package Registry'); - }); + assert.equal(currentURL(), '/crates'); + assert.equal(document.title, 'Crates - crates.io: Rust Package Registry'); + }); - test('visiting the crates page directly', async function(assert) { - this.server.loadFixtures(); + test('visiting the crates page directly', async function(assert) { + this.server.loadFixtures(); - await visit('/crates'); - await click('[data-test-all-crates-link]'); + await visit('/crates'); + await click('[data-test-all-crates-link]'); - assert.equal(currentURL(), '/crates'); - assert.equal(document.title, 'Crates - crates.io: Rust Package Registry'); - }); + assert.equal(currentURL(), '/crates'); + assert.equal(document.title, 'Crates - crates.io: Rust Package Registry'); + }); - test('listing crates', async function(assert) { - this.server.loadFixtures(); + test('listing crates', async function(assert) { + this.server.loadFixtures(); - await visit('/crates'); + await visit('/crates'); - assert.dom('[data-test-crates-nav] [data-test-current-rows]').hasText('1-10'); - assert.dom('[data-test-crates-nav] [data-test-total-rows]').hasText('19'); - }); + assert.dom('[data-test-crates-nav] [data-test-current-rows]').hasText('1-10'); + assert.dom('[data-test-crates-nav] [data-test-total-rows]').hasText('19'); + }); - test('navigating to next page of crates', async function(assert) { - this.server.loadFixtures(); + test('navigating to next page of crates', async function(assert) { + this.server.loadFixtures(); - await visit('/crates'); - await click('[data-test-pagination-next]'); + await visit('/crates'); + await click('[data-test-pagination-next]'); - assert.equal(currentURL(), '/crates?page=2'); - assert.dom('[data-test-crates-nav] [data-test-current-rows]').hasText('11-19'); - assert.dom('[data-test-crates-nav] [data-test-total-rows]').hasText('19'); - }); + assert.equal(currentURL(), '/crates?page=2'); + assert.dom('[data-test-crates-nav] [data-test-current-rows]').hasText('11-19'); + assert.dom('[data-test-crates-nav] [data-test-total-rows]').hasText('19'); + }); - test('crates default sort is alphabetical', async function(assert) { - this.server.loadFixtures(); + test('crates default sort is alphabetical', async function(assert) { + this.server.loadFixtures(); - await visit('/crates'); + await visit('/crates'); - assert.dom('[data-test-crates-sort] [data-test-current-order]').hasText('Alphabetical'); - }); + assert.dom('[data-test-crates-sort] [data-test-current-order]').hasText('Alphabetical'); + }); - test('downloads appears for each crate on crate list', async function(assert) { - this.server.loadFixtures(); + test('downloads appears for each crate on crate list', async function(assert) { + this.server.loadFixtures(); - await visit('/crates'); - assert.dom('[data-test-crate-row="0"] [data-test-downloads]').hasText('All-Time: 497'); - }); + await visit('/crates'); + assert.dom('[data-test-crate-row="0"] [data-test-downloads]').hasText('All-Time: 497'); + }); - test('recent downloads appears for each crate on crate list', async function(assert) { - this.server.loadFixtures(); + test('recent downloads appears for each crate on crate list', async function(assert) { + this.server.loadFixtures(); - await visit('/crates'); - assert.dom('[data-test-crate-row="0"] [data-test-recent-downloads]').hasText('Recent: 497'); - }); + await visit('/crates'); + assert.dom('[data-test-crate-row="0"] [data-test-recent-downloads]').hasText('Recent: 497'); + }); }); diff --git a/tests/acceptance/front-page-test.js b/tests/acceptance/front-page-test.js index cadcfd13d52..173a6d79e6a 100644 --- a/tests/acceptance/front-page-test.js +++ b/tests/acceptance/front-page-test.js @@ -7,42 +7,42 @@ import setupMirage from '../helpers/setup-mirage'; import { percySnapshot } from 'ember-percy'; module('Acceptance | front page', function(hooks) { - setupApplicationTest(hooks); - setupMirage(hooks); + setupApplicationTest(hooks); + setupMirage(hooks); - test('is accessible', async function(assert) { - assert.expect(0); + test('is accessible', async function(assert) { + assert.expect(0); - this.server.loadFixtures(); + this.server.loadFixtures(); - await visit('/'); - await a11yAudit(axeConfig); - }); + await visit('/'); + await a11yAudit(axeConfig); + }); - test('visiting /', async function(assert) { - this.server.loadFixtures(); + test('visiting /', async function(assert) { + this.server.loadFixtures(); - await visit('/'); + await visit('/'); - assert.equal(currentURL(), '/'); - assert.equal(document.title, 'crates.io: Rust Package Registry'); + assert.equal(currentURL(), '/'); + assert.equal(document.title, 'crates.io: Rust Package Registry'); - assert.dom('[data-test-install-cargo-link]').exists(); - assert.dom('[data-test-all-crates-link]').exists(); - assert.dom('[data-test-login-link]').exists(); + assert.dom('[data-test-install-cargo-link]').exists(); + assert.dom('[data-test-all-crates-link]').exists(); + assert.dom('[data-test-login-link]').exists(); - assert.dom('[data-test-total-downloads]').hasText('122,669'); - assert.dom('[data-test-total-crates]').hasText('19'); + assert.dom('[data-test-total-downloads]').hasText('122,669'); + assert.dom('[data-test-total-crates]').hasText('19'); - assert.dom('[data-test-new-crates] [data-test-crate-link="0"]').hasText('Inflector (0.1.6)'); - assert.dom('[data-test-new-crates] [data-test-crate-link="0"]').hasAttribute('href', '/crates/Inflector'); + assert.dom('[data-test-new-crates] [data-test-crate-link="0"]').hasText('Inflector (0.1.6)'); + assert.dom('[data-test-new-crates] [data-test-crate-link="0"]').hasAttribute('href', '/crates/Inflector'); - assert.dom('[data-test-most-downloaded] [data-test-crate-link="0"]').hasText('serde (0.6.1)'); - assert.dom('[data-test-most-downloaded] [data-test-crate-link="0"]').hasAttribute('href', '/crates/serde'); + assert.dom('[data-test-most-downloaded] [data-test-crate-link="0"]').hasText('serde (0.6.1)'); + assert.dom('[data-test-most-downloaded] [data-test-crate-link="0"]').hasAttribute('href', '/crates/serde'); - assert.dom('[data-test-just-updated] [data-test-crate-link="0"]').hasText('nanomsg (0.7.0-alpha)'); - assert.dom('[data-test-just-updated] [data-test-crate-link="0"]').hasAttribute('href', '/crates/nanomsg'); + assert.dom('[data-test-just-updated] [data-test-crate-link="0"]').hasText('nanomsg (0.7.0-alpha)'); + assert.dom('[data-test-just-updated] [data-test-crate-link="0"]').hasAttribute('href', '/crates/nanomsg'); - percySnapshot(assert); - }); + percySnapshot(assert); + }); }); diff --git a/tests/acceptance/keyword-test.js b/tests/acceptance/keyword-test.js index 0e44b5b2464..05ea209fcdd 100644 --- a/tests/acceptance/keyword-test.js +++ b/tests/acceptance/keyword-test.js @@ -7,25 +7,25 @@ import setupMirage from '../helpers/setup-mirage'; import { percySnapshot } from 'ember-percy'; module('Acceptance | keywords', function(hooks) { - setupApplicationTest(hooks); - setupMirage(hooks); + setupApplicationTest(hooks); + setupMirage(hooks); - test('keyword/:keyword_id is accessible', async function(assert) { - assert.expect(0); + test('keyword/:keyword_id is accessible', async function(assert) { + assert.expect(0); - this.server.create('keyword', { id: 'network', keyword: 'network', crates_cnt: 38 }); + this.server.create('keyword', { id: 'network', keyword: 'network', crates_cnt: 38 }); - await visit('keywords/network'); - percySnapshot(assert); + await visit('keywords/network'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('keyword/:keyword_id index default sort is recent-downloads', async function(assert) { - this.server.create('keyword', { id: 'network', keyword: 'network', crates_cnt: 38 }); + test('keyword/:keyword_id index default sort is recent-downloads', async function(assert) { + this.server.create('keyword', { id: 'network', keyword: 'network', crates_cnt: 38 }); - await visit('/keywords/network'); + await visit('/keywords/network'); - assert.dom('[data-test-keyword-sort] [data-test-current-order]').hasText('Recent Downloads'); - }); + assert.dom('[data-test-keyword-sort] [data-test-current-order]').hasText('Recent Downloads'); + }); }); diff --git a/tests/acceptance/search-test.js b/tests/acceptance/search-test.js index d9a93ab9e24..dfe168ba0e5 100644 --- a/tests/acceptance/search-test.js +++ b/tests/acceptance/search-test.js @@ -8,87 +8,87 @@ import setupMirage from '../helpers/setup-mirage'; import { percySnapshot } from 'ember-percy'; module('Acceptance | search', function(hooks) { - setupApplicationTest(hooks); - setupMirage(hooks); + setupApplicationTest(hooks); + setupMirage(hooks); - test('/search?q=rust is accessible', async function(assert) { - assert.expect(0); + test('/search?q=rust is accessible', async function(assert) { + assert.expect(0); - this.server.loadFixtures(); + this.server.loadFixtures(); - await visit('/'); - percySnapshot(assert); + await visit('/'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('searching for "rust"', async function(assert) { - this.server.loadFixtures(); + test('searching for "rust"', async function(assert) { + this.server.loadFixtures(); - await visit('/'); - await fillIn('[data-test-search-input]', 'rust'); - await triggerEvent('[data-test-search-form]', 'submit'); + await visit('/'); + await fillIn('[data-test-search-input]', 'rust'); + await triggerEvent('[data-test-search-form]', 'submit'); - assert.equal(currentURL(), '/search?q=rust'); - assert.equal(document.title, "Search Results for 'rust' - crates.io: Rust Package Registry"); + assert.equal(currentURL(), '/search?q=rust'); + assert.equal(document.title, "Search Results for 'rust' - crates.io: Rust Package Registry"); - assert.dom('[data-test-heading]').hasText("Search Results for 'rust'"); - assert.dom('[data-test-search-nav]').hasText('Displaying 1-8 of 8 total results'); - assert - .dom('[data-test-search-sort]') - .hasText('Sort by Relevance Relevance All-Time Downloads Recent Downloads Recent Updates'); - assert.dom('[data-test-crate-row="0"] [data-test-crate-link]').hasText('kinetic-rust'); - assert.dom('[data-test-crate-row="0"] [data-test-version-badge]').hasAttribute('alt', '0.0.16'); + assert.dom('[data-test-heading]').hasText("Search Results for 'rust'"); + assert.dom('[data-test-search-nav]').hasText('Displaying 1-8 of 8 total results'); + assert + .dom('[data-test-search-sort]') + .hasText('Sort by Relevance Relevance All-Time Downloads Recent Downloads Recent Updates'); + assert.dom('[data-test-crate-row="0"] [data-test-crate-link]').hasText('kinetic-rust'); + assert.dom('[data-test-crate-row="0"] [data-test-version-badge]').hasAttribute('alt', '0.0.16'); - assert - .dom('[data-test-crate-row="0"] [data-test-description]') - .hasText('A Kinetic protocol library written in Rust'); - assert.dom('[data-test-crate-row="0"] [data-test-downloads]').hasText('All-Time: 225'); - assert.dom('[data-test-crate-row="0"] [data-test-badge="maintenance"]').exists(); - }); + assert + .dom('[data-test-crate-row="0"] [data-test-description]') + .hasText('A Kinetic protocol library written in Rust'); + assert.dom('[data-test-crate-row="0"] [data-test-downloads]').hasText('All-Time: 225'); + assert.dom('[data-test-crate-row="0"] [data-test-badge="maintenance"]').exists(); + }); - test('searching for "rust" from query', async function(assert) { - this.server.loadFixtures(); + test('searching for "rust" from query', async function(assert) { + this.server.loadFixtures(); - await visit('/search?q=rust'); + await visit('/search?q=rust'); - assert.equal(currentURL(), '/search?q=rust'); - assert.equal(document.title, "Search Results for 'rust' - crates.io: Rust Package Registry"); + assert.equal(currentURL(), '/search?q=rust'); + assert.equal(document.title, "Search Results for 'rust' - crates.io: Rust Package Registry"); - assert.dom('[data-test-search-input]').hasValue('rust'); - assert.dom('[data-test-heading]').hasText("Search Results for 'rust'"); - assert.dom('[data-test-search-nav]').hasText('Displaying 1-8 of 8 total results'); - }); + assert.dom('[data-test-search-input]').hasValue('rust'); + assert.dom('[data-test-heading]').hasText("Search Results for 'rust'"); + assert.dom('[data-test-search-nav]').hasText('Displaying 1-8 of 8 total results'); + }); - test('pressing S key to focus the search bar', async function(assert) { - this.server.loadFixtures(); + test('pressing S key to focus the search bar', async function(assert) { + this.server.loadFixtures(); - await visit('/'); + await visit('/'); - await blur('[data-test-search-input]'); - await triggerKeyPress('KeyA'); - assert.dom('[data-test-search-input]').isNotFocused(); + await blur('[data-test-search-input]'); + await triggerKeyPress('KeyA'); + assert.dom('[data-test-search-input]').isNotFocused(); - await blur('[data-test-search-input]'); - await triggerKeyPress('KeyS'); - assert.dom('[data-test-search-input]').isFocused(); + await blur('[data-test-search-input]'); + await triggerKeyPress('KeyS'); + assert.dom('[data-test-search-input]').isFocused(); - await blur('[data-test-search-input]'); - await triggerKeyDown('KeyS'); - assert.dom('[data-test-search-input]').isFocused(); + await blur('[data-test-search-input]'); + await triggerKeyDown('KeyS'); + assert.dom('[data-test-search-input]').isFocused(); - await blur('[data-test-search-input]'); - await triggerKeyDown('shift+KeyS'); - assert.dom('[data-test-search-input]').isFocused(); - }); + await blur('[data-test-search-input]'); + await triggerKeyDown('shift+KeyS'); + assert.dom('[data-test-search-input]').isFocused(); + }); - test('check search results are by default displayed by relevance', async function(assert) { - this.server.loadFixtures(); + test('check search results are by default displayed by relevance', async function(assert) { + this.server.loadFixtures(); - await visit('/'); - await fillIn('[data-test-search-input]', 'rust'); - await triggerEvent('[data-test-search-form]', 'submit'); + await visit('/'); + await fillIn('[data-test-search-input]', 'rust'); + await triggerEvent('[data-test-search-form]', 'submit'); - assert.dom('[data-test-search-sort] [data-test-current-order]').hasText('Relevance'); - }); + assert.dom('[data-test-search-sort] [data-test-current-order]').hasText('Relevance'); + }); }); diff --git a/tests/acceptance/team-page-test.js b/tests/acceptance/team-page-test.js index 9f2649242b3..2c0c6625539 100644 --- a/tests/acceptance/team-page-test.js +++ b/tests/acceptance/team-page-test.js @@ -7,52 +7,52 @@ import setupMirage from '../helpers/setup-mirage'; import { percySnapshot } from 'ember-percy'; module('Acceptance | team page', function(hooks) { - setupApplicationTest(hooks); - setupMirage(hooks); + setupApplicationTest(hooks); + setupMirage(hooks); - test('is accessible', async function(assert) { - assert.expect(0); + test('is accessible', async function(assert) { + assert.expect(0); - this.server.loadFixtures(); + this.server.loadFixtures(); - await visit('/teams/github:org:thehydroimpulse'); - percySnapshot(assert); + await visit('/teams/github:org:thehydroimpulse'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('has team organization display', async function(assert) { - this.server.loadFixtures(); + test('has team organization display', async function(assert) { + this.server.loadFixtures(); - await visit('/teams/github:org:thehydroimpulse'); + await visit('/teams/github:org:thehydroimpulse'); - assert.dom('[data-test-heading] [data-test-org-name]').hasText('org'); - assert.dom('[data-test-heading] [data-test-team-name]').hasText('thehydroimpulseteam'); - }); + assert.dom('[data-test-heading] [data-test-org-name]').hasText('org'); + assert.dom('[data-test-heading] [data-test-team-name]').hasText('thehydroimpulseteam'); + }); - test('has link to github in team header', async function(assert) { - this.server.loadFixtures(); + test('has link to github in team header', async function(assert) { + this.server.loadFixtures(); - await visit('/teams/github:org:thehydroimpulse'); + await visit('/teams/github:org:thehydroimpulse'); - assert.dom('[data-test-heading] [data-test-github-link]').hasAttribute('href', 'https://github.com/org_test'); - }); + assert.dom('[data-test-heading] [data-test-github-link]').hasAttribute('href', 'https://github.com/org_test'); + }); - test('github link has image in team header', async function(assert) { - this.server.loadFixtures(); + test('github link has image in team header', async function(assert) { + this.server.loadFixtures(); - await visit('/teams/github:org:thehydroimpulse'); + await visit('/teams/github:org:thehydroimpulse'); - assert.dom('[data-test-heading] [data-test-github-link] img').hasAttribute('src', '/assets/GitHub-Mark.svg'); - }); + assert.dom('[data-test-heading] [data-test-github-link] img').hasAttribute('src', '/assets/GitHub-Mark.svg'); + }); - test('team organization details has github profile icon', async function(assert) { - this.server.loadFixtures(); + test('team organization details has github profile icon', async function(assert) { + this.server.loadFixtures(); - await visit('/teams/github:org:thehydroimpulse'); + await visit('/teams/github:org:thehydroimpulse'); - assert - .dom('[data-test-heading] [data-test-avatar]') - .hasAttribute('src', 'https://avatars.githubusercontent.com/u/565790?v=3&s=170'); - }); + assert + .dom('[data-test-heading] [data-test-avatar]') + .hasAttribute('src', 'https://avatars.githubusercontent.com/u/565790?v=3&s=170'); + }); }); diff --git a/tests/acceptance/user-page-test.js b/tests/acceptance/user-page-test.js index 8241f989cd6..2a05c412aec 100644 --- a/tests/acceptance/user-page-test.js +++ b/tests/acceptance/user-page-test.js @@ -7,53 +7,51 @@ import setupMirage from '../helpers/setup-mirage'; import { percySnapshot } from 'ember-percy'; module('Acceptance | user page', function(hooks) { - setupApplicationTest(hooks); - setupMirage(hooks); + setupApplicationTest(hooks); + setupMirage(hooks); - test('is accessible', async function(assert) { - assert.expect(0); + test('is accessible', async function(assert) { + assert.expect(0); - this.server.loadFixtures(); + this.server.loadFixtures(); - await visit('/users/thehydroimpulse'); - percySnapshot(assert); + await visit('/users/thehydroimpulse'); + percySnapshot(assert); - await a11yAudit(axeConfig); - }); + await a11yAudit(axeConfig); + }); - test('has user display', async function(assert) { - this.server.loadFixtures(); + test('has user display', async function(assert) { + this.server.loadFixtures(); - await visit('/users/thehydroimpulse'); + await visit('/users/thehydroimpulse'); - assert.dom('[data-test-heading] [data-test-username]').hasText('thehydroimpulse'); - }); + assert.dom('[data-test-heading] [data-test-username]').hasText('thehydroimpulse'); + }); - test('has link to github in user header', async function(assert) { - this.server.loadFixtures(); + test('has link to github in user header', async function(assert) { + this.server.loadFixtures(); - await visit('/users/thehydroimpulse'); + await visit('/users/thehydroimpulse'); - assert - .dom('[data-test-heading] [data-test-user-link]') - .hasAttribute('href', 'https://github.com/thehydroimpulse'); - }); + assert.dom('[data-test-heading] [data-test-user-link]').hasAttribute('href', 'https://github.com/thehydroimpulse'); + }); - test('github link has image in user header', async function(assert) { - this.server.loadFixtures(); + test('github link has image in user header', async function(assert) { + this.server.loadFixtures(); - await visit('/users/thehydroimpulse'); + await visit('/users/thehydroimpulse'); - assert.dom('[data-test-heading] [data-test-user-link] img').hasAttribute('src', '/assets/GitHub-Mark.svg'); - }); + assert.dom('[data-test-heading] [data-test-user-link] img').hasAttribute('src', '/assets/GitHub-Mark.svg'); + }); - test('user details has github profile icon', async function(assert) { - this.server.loadFixtures(); + test('user details has github profile icon', async function(assert) { + this.server.loadFixtures(); - await visit('/users/thehydroimpulse'); + await visit('/users/thehydroimpulse'); - assert - .dom('[data-test-heading] [data-test-avatar]') - .hasAttribute('src', 'https://avatars.githubusercontent.com/u/565790?v=3&s=170'); - }); + assert + .dom('[data-test-heading] [data-test-avatar]') + .hasAttribute('src', 'https://avatars.githubusercontent.com/u/565790?v=3&s=170'); + }); }); diff --git a/tests/axe-config.js b/tests/axe-config.js index 19f27f15581..80e95df7ee2 100644 --- a/tests/axe-config.js +++ b/tests/axe-config.js @@ -1,7 +1,7 @@ export default { - rules: { - 'color-contrast': { - enabled: false, - }, + rules: { + 'color-contrast': { + enabled: false, }, + }, }; diff --git a/tests/helpers/setup-mirage.js b/tests/helpers/setup-mirage.js index 4ec913e66fb..ed2cae8c650 100644 --- a/tests/helpers/setup-mirage.js +++ b/tests/helpers/setup-mirage.js @@ -3,15 +3,15 @@ import { faker } from 'ember-cli-mirage'; import timekeeper from 'timekeeper'; export default function(hooks) { - setupMirage(hooks); + setupMirage(hooks); - // To have deterministic visual tests, the seed has to be constant - hooks.beforeEach(function() { - faker.seed(12345); - timekeeper.freeze(new Date('11/20/2017 12:00')); - }); + // To have deterministic visual tests, the seed has to be constant + hooks.beforeEach(function() { + faker.seed(12345); + timekeeper.freeze(new Date('11/20/2017 12:00')); + }); - hooks.afterEach(function() { - timekeeper.reset(); - }); + hooks.afterEach(function() { + timekeeper.reset(); + }); } diff --git a/tests/unit/controllers/crate/version-test.js b/tests/unit/controllers/crate/version-test.js index df75dcffa13..dae6d1b7f5b 100644 --- a/tests/unit/controllers/crate/version-test.js +++ b/tests/unit/controllers/crate/version-test.js @@ -4,32 +4,32 @@ import { A } from '@ember/array'; import Service from '@ember/service'; module('Unit | Controller | crate/version', function(hooks) { - setupTest(hooks); - const userId = 1; - // stub the session service - // https://guides.emberjs.com/release/testing/testing-components/#toc_stubbing-services - const sessionStub = Service.extend(); + setupTest(hooks); + const userId = 1; + // stub the session service + // https://guides.emberjs.com/release/testing/testing-components/#toc_stubbing-services + const sessionStub = Service.extend(); - hooks.beforeEach(function() { - sessionStub.currentUser = { id: userId }; - this.owner.register('service:session', sessionStub); - }); + hooks.beforeEach(function() { + sessionStub.currentUser = { id: userId }; + this.owner.register('service:session', sessionStub); + }); - test('notYankedOrIsOwner is true when conditions fulfilled', function(assert) { - assert.expect(2); - let controller = this.owner.lookup('controller:crate/version'); - controller.model = { yanked: false }; - controller.crate = { owner_user: A([{ id: userId }]) }; - assert.ok(controller); - assert.ok(controller.notYankedOrIsOwner); - }); + test('notYankedOrIsOwner is true when conditions fulfilled', function(assert) { + assert.expect(2); + let controller = this.owner.lookup('controller:crate/version'); + controller.model = { yanked: false }; + controller.crate = { owner_user: A([{ id: userId }]) }; + assert.ok(controller); + assert.ok(controller.notYankedOrIsOwner); + }); - test('notYankedOrIsOwner is false when conditions fulfilled', function(assert) { - assert.expect(2); - let controller = this.owner.lookup('controller:crate/version'); - controller.model = { yanked: true }; - controller.crate = { owner_user: A([{ id: userId }]) }; - assert.ok(controller); - assert.notOk(controller.notYankedOrIsOwner); - }); + test('notYankedOrIsOwner is false when conditions fulfilled', function(assert) { + assert.expect(2); + let controller = this.owner.lookup('controller:crate/version'); + controller.model = { yanked: true }; + controller.crate = { owner_user: A([{ id: userId }]) }; + assert.ok(controller); + assert.notOk(controller.notYankedOrIsOwner); + }); }); diff --git a/tests/unit/helpers/format-crate-size-test.js b/tests/unit/helpers/format-crate-size-test.js index df310d45484..b244ed488aa 100644 --- a/tests/unit/helpers/format-crate-size-test.js +++ b/tests/unit/helpers/format-crate-size-test.js @@ -2,19 +2,19 @@ import { formatCrateSize } from '../../../helpers/format-crate-size'; import { module, test } from 'qunit'; module('Unit | Helper | format-crate-size', function() { - test('Small crate size formats in kB', function(assert) { - assert.equal(formatCrateSize(531), '0.53 kB'); - }); + test('Small crate size formats in kB', function(assert) { + assert.equal(formatCrateSize(531), '0.53 kB'); + }); - test('Small crate size formats in kB without trailing 0', function(assert) { - assert.equal(formatCrateSize(90000), '90 kB'); - }); + test('Small crate size formats in kB without trailing 0', function(assert) { + assert.equal(formatCrateSize(90000), '90 kB'); + }); - test('Large crate size formats in MB', function(assert) { - assert.equal(formatCrateSize(912345), '0.91 MB'); - }); + test('Large crate size formats in MB', function(assert) { + assert.equal(formatCrateSize(912345), '0.91 MB'); + }); - test('Large crate size formats in MB without trailing 0', function(assert) { - assert.equal(formatCrateSize(9100000), '9.1 MB'); - }); + test('Large crate size formats in MB without trailing 0', function(assert) { + assert.equal(formatCrateSize(9100000), '9.1 MB'); + }); }); diff --git a/tests/unit/helpers/format-email-test.js b/tests/unit/helpers/format-email-test.js index 26f26afceaf..20ab0b0eac3 100644 --- a/tests/unit/helpers/format-email-test.js +++ b/tests/unit/helpers/format-email-test.js @@ -2,15 +2,15 @@ import { formatEmail } from '../../../helpers/format-email'; import { module, test } from 'qunit'; module('Unit | Helper | format-email', function() { - // Replace this with your real tests. - test('it works', function(assert) { - assert.equal(formatEmail('foo'), 'foo'); - assert.equal(formatEmail('foo ').toString(), `foo`); - assert.equal( - formatEmail(' ').toString(), - ``, - ); - assert.equal(formatEmail('').toString(), ''); - assert.equal(formatEmail('test ').toString(), `foo`); + assert.equal( + formatEmail(' ').toString(), + ``, + ); + assert.equal(formatEmail('').toString(), ''); + assert.equal(formatEmail('test