diff --git a/.eslintrc.js b/.eslintrc.js
index 6a9d8c4..774659f 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,17 +1,19 @@
module.exports = {
- root: true,
- env: {
- node: true,
- },
- extends: [
- 'plugin:vue/essential',
- '@vue/airbnb',
- ],
- rules: {
- 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
- 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
- },
- parserOptions: {
- parser: 'babel-eslint',
- },
+ root: true,
+ env: {
+ node: true,
+ },
+ extends: [
+ 'plugin:vue/essential',
+ '@vue/airbnb',
+ ],
+ rules: {
+ 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
+ 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
+ indent: ['error', 'tab'],
+ 'no-tabs': 'off',
+ },
+ parserOptions: {
+ parser: 'babel-eslint',
+ },
};
diff --git a/babel.config.js b/babel.config.js
index 91be244..a1daff9 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -1,5 +1,5 @@
module.exports = {
- presets: [
- '@vue/app',
- ],
+ presets: [
+ '@vue/app',
+ ],
};
diff --git a/package.json b/package.json
index b5118b1..93728e6 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,6 @@
{
"name": "dri",
"version": "0.1.0",
- "private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
@@ -19,6 +18,23 @@
"@vue/cli-plugin-eslint": "^3.0.3",
"@vue/cli-service": "^3.0.3",
"@vue/eslint-config-airbnb": "^3.0.3",
- "vue-template-compiler": "^2.5.17"
+ "vue-template-compiler": "^2.5.17",
+ "lint-staged": "^6.0.0"
+ },
+ "gitHooks": {
+ "pre-commit": "lint-staged"
+ },
+ "lint-staged": {
+ "Dockerfile": [
+ "hadolint"
+ ],
+ "*.js": [
+ "vue-cli-service lint",
+ "git add"
+ ],
+ "*.vue": [
+ "vue-cli-service lint",
+ "git add"
+ ]
}
}
diff --git a/postcss.config.js b/postcss.config.js
index a47ef4f..38e0dc8 100644
--- a/postcss.config.js
+++ b/postcss.config.js
@@ -1,5 +1,5 @@
module.exports = {
- plugins: {
- autoprefixer: {},
- },
+ plugins: {
+ autoprefixer: {},
+ },
};
diff --git a/src/api.js b/src/api.js
index c6bb395..0e60b9f 100644
--- a/src/api.js
+++ b/src/api.js
@@ -2,76 +2,163 @@ import parseLink from 'parse-link-header';
import { registryAPI, repositoriesPerPage, tagsPerPage, usePortusExplore } from '@/options';
-async function paginatable(path, n, last = null) {
- const url = new URL(`${await registryAPI()}${path}`);
- if (n) url.searchParams.append('n', n);
- if (last) url.searchParams.append('last', last);
+function parseWWWAuthenticate(text) {
+ const result = {};
+ // extract auth-scheme
+ const schemeParts = text.split(' ');
+ [result.scheme] = schemeParts;
+ // extract auth-params
+ const remain = schemeParts.slice(1).join(' ');
+ const parts = remain.split(/ ?, ?/);
+ parts.forEach((part) => {
+ // parse auth-param
+ const kv = part.split('=');
+ if (kv.length === 2) {
+ const key = kv[0].trim();
+ const value = kv[1].trim();
+ if (value.startsWith('"') && value.endsWith('"')) {
+ result[key] = value.substring(1, value.length - 1);
+ } else {
+ result[key] = value;
+ }
+ } else {
+ result[parts] = true;
+ }
+ });
+ return result;
+}
- const response = await fetch(url);
- let nextLast = null;
- if (response.headers.has('Link')) {
- const links = parseLink(response.headers.get('Link'));
- if (links && links.next) {
- nextLast = links.next.last;
- }
- }
- return Object.assign(await response.json(), { nextLast });
+let cachedToken = null;
+async function doAuth() {
+ if (cachedToken !== null) {
+ return cachedToken;
+ }
+
+ // try accessing registry API
+ const response = await fetch(`${await registryAPI()}/v2/`);
+ if (response.ok) {
+ // token not needed for registry
+ cachedToken = false;
+ return cachedToken;
+ }
+ if (response.status !== 401) {
+ throw new Error(response.statusText);
+ }
+
+ // solve authentication challenge
+ const { headers } = response;
+ if (!headers.has('Www-Authenticate')) {
+ throw new Error('no challenge presented');
+ }
+ const chal = parseWWWAuthenticate(headers.get('Www-Authenticate'));
+ if (chal.scheme !== 'Bearer') {
+ throw new Error('unsupported scheme');
+ }
+
+ const tokURL = new URL(chal.realm);
+ tokURL.searchParams.append('client_id', 'dri-client');
+ tokURL.searchParams.append('service', chal.service);
+ tokURL.searchParams.append('scope', 'repository:pwd/migrate:pull');
+ const tokResponse = await fetch(tokURL);
+ const tok = await tokResponse.json();
+ cachedToken = tok.token;
+ return tok.token;
+}
+
+async function paginatable(path, n, last = null) {
+ const token = await doAuth();
+ const url = new URL(`${await registryAPI()}${path}`);
+ if (n) url.searchParams.append('n', n);
+ if (last) url.searchParams.append('last', last);
+
+ const headers = {};
+ if (token) headers.Authorization = `Bearer ${token}`;
+ const response = await fetch(url, { headers });
+ let nextLast = null;
+ if (response.headers.has('Link')) {
+ const links = parseLink(response.headers.get('Link'));
+ if (links && links.next) {
+ nextLast = links.next.last;
+ }
+ }
+ return Object.assign(await response.json(), { nextLast });
}
async function get(path) {
- const url = new URL(`${await registryAPI()}${path}`);
- const response = await fetch(url);
- return response.json();
+ const token = await doAuth();
+ const url = new URL(`${await registryAPI()}${path}`);
+ const headers = {};
+ if (token) headers.Authorization = `Bearer ${token}`;
+ const response = await fetch(url, { headers });
+ return response.json();
}
async function head(path) {
- const url = new URL(`${await registryAPI()}${path}`);
- const response = await fetch(url, { method: 'HEAD' });
- return response.headers;
+ const token = await doAuth();
+ const url = new URL(`${await registryAPI()}${path}`);
+ const headers = {};
+ if (token) headers.Authorization = `Bearer ${token}`;
+ const response = await fetch(url, { method: 'HEAD', headers });
+ return response.headers;
}
-async function repos(last = null) {
- if (await usePortusExplore()) {
- // TODO: Use the Portus API when it enables anonymous access
- const response = await fetch(`${await registryAPI()}/explore?explore%5Bsearch%5D=`);
- const html = await response.text();
+async function portus() {
+// TODO: Use the Portus API when it enables anonymous access
+ const response = await fetch(`${await registryAPI()}/explore?explore%5Bsearch%5D=`);
+ const html = await response.text();
- // unconventionally parse out JSON from HTML
- const startString = 'window.repositories = ';
- const endString = ';';
- const string = html.substring(
- html.lastIndexOf(startString) + startString.length,
- html.indexOf(endString),
- );
- return JSON.parse(string);
- }
- return paginatable('/v2/_catalog', await repositoriesPerPage(), last);
+ // unconventionally parse out JSON from HTML
+ const startString = 'window.repositories = ';
+ const endString = ';';
+ const string = html.substring(
+ html.lastIndexOf(startString) + startString.length,
+ html.indexOf(endString),
+ );
+ const object = JSON.parse(string);
+ return object;
+}
+
+async function repos(last = null) {
+ if (await usePortusExplore()) {
+ const p = await portus();
+ return {
+ repositories: p.map(r => r.full_name),
+ };
+ }
+ return paginatable('/v2/_catalog', await repositoriesPerPage(), last);
}
async function repo(name) {
- return get(`/v2/${name}`);
+ return get(`/v2/${name}`);
}
async function tags(name, last = null) {
- return paginatable(`/v2/${name}/tags/list`, await tagsPerPage(), last);
+ if (await usePortusExplore()) {
+ const p = await portus();
+ return {
+ tags: p.find(r => r.full_name === name)
+ .tags.map(t => t[0].name),
+ };
+ }
+ return paginatable(`/v2/${name}/tags/list`, await tagsPerPage(), last);
}
async function tag(name, ref) {
- return get(`/v2/${name}/manifests/${ref}`);
+ return get(`/v2/${name}/manifests/${ref}`);
}
async function blob(name, digest) {
- const headers = await head(`/v2/${name}/blobs/${digest}`);
- return {
- contentLength: parseInt(headers.get('Content-Length'), 10),
- };
+ const headers = await head(`/v2/${name}/blobs/${digest}`);
+ return {
+ contentLength: parseInt(headers.get('Content-Length'), 10),
+ };
}
export {
- repos,
- repo,
- tags,
- tag,
- blob,
+ repos,
+ repo,
+ tags,
+ tag,
+ blob,
};
diff --git a/src/components/BlobSize.vue b/src/components/BlobSize.vue
index 71c0d84..20f9b71 100644
--- a/src/components/BlobSize.vue
+++ b/src/components/BlobSize.vue
@@ -8,21 +8,21 @@ import { blob } from '@/api';
import LoadableText from '@/components/LoadableText.vue';
export default {
- components: {
- LoadableText,
- },
- props: {
- repo: String,
- blob: String,
- },
- data() {
- return {
- size: '',
- };
- },
- async created() {
- const size = await blob(this.repo, this.blob);
- this.size = filesize(size.contentLength);
- },
+ components: {
+ LoadableText,
+ },
+ props: {
+ repo: String,
+ blob: String,
+ },
+ data() {
+ return {
+ size: '',
+ };
+ },
+ async created() {
+ const size = await blob(this.repo, this.blob);
+ this.size = filesize(size.contentLength);
+ },
};
diff --git a/src/components/Error.vue b/src/components/Error.vue
index e4d4db1..63cbe8d 100644
--- a/src/components/Error.vue
+++ b/src/components/Error.vue
@@ -4,9 +4,9 @@
diff --git a/src/components/Layout.vue b/src/components/Layout.vue
index 3403cab..bc83974 100644
--- a/src/components/Layout.vue
+++ b/src/components/Layout.vue
@@ -24,12 +24,12 @@
import { version, source } from '@/options';
export default {
- data() {
- return {
- version,
- source,
- };
- },
+ data() {
+ return {
+ version,
+ source,
+ };
+ },
};
diff --git a/src/components/ListItem.vue b/src/components/ListItem.vue
index cf87dd9..cf4dc91 100644
--- a/src/components/ListItem.vue
+++ b/src/components/ListItem.vue
@@ -10,9 +10,9 @@
diff --git a/src/components/LoadableText.vue b/src/components/LoadableText.vue
index 52e5a01..575db00 100644
--- a/src/components/LoadableText.vue
+++ b/src/components/LoadableText.vue
@@ -4,9 +4,9 @@
diff --git a/src/components/Paginator.vue b/src/components/Paginator.vue
index 159e0c5..1672deb 100644
--- a/src/components/Paginator.vue
+++ b/src/components/Paginator.vue
@@ -7,17 +7,17 @@
diff --git a/src/components/TagSize.vue b/src/components/TagSize.vue
index 4ff35f7..782e883 100644
--- a/src/components/TagSize.vue
+++ b/src/components/TagSize.vue
@@ -8,32 +8,32 @@ import { tag, blob } from '@/api';
import LoadableText from '@/components/LoadableText.vue';
export default {
- components: {
- LoadableText,
- },
- props: {
- repo: String,
- tag: String,
- },
- data() {
- return {
- size: '',
- };
- },
- async created() {
- const r = await tag(this.repo, this.tag);
- if (r.mediaType === 'application/vnd.docker.distribution.manifest.list.v2+json') {
- console.error('V2 manifest lists not supported yet');
- return;
- }
- if (r.schemaVersion === 1) {
- r.layers = r.fsLayers.map(l => ({ digest: l.blobSum }));
- }
- const sizes = await Promise.all(r.layers.map(async layer => (
- await blob(this.repo, layer.digest)
- ).contentLength));
- const total = sizes.reduce((a, b) => a + b, 0);
- this.size = filesize(total);
- },
+ components: {
+ LoadableText,
+ },
+ props: {
+ repo: String,
+ tag: String,
+ },
+ data() {
+ return {
+ size: '',
+ };
+ },
+ async created() {
+ const r = await tag(this.repo, this.tag);
+ if (r.mediaType === 'application/vnd.docker.distribution.manifest.list.v2+json') {
+ console.error('V2 manifest lists not supported yet');
+ return;
+ }
+ if (r.schemaVersion === 1) {
+ r.layers = r.fsLayers.map(l => ({ digest: l.blobSum }));
+ }
+ const sizes = await Promise.all(r.layers.map(async layer => (
+ await blob(this.repo, layer.digest)
+ ).contentLength));
+ const total = sizes.reduce((a, b) => a + b, 0);
+ this.size = filesize(total);
+ },
};
diff --git a/src/main.js b/src/main.js
index c3f9c80..dde04f8 100644
--- a/src/main.js
+++ b/src/main.js
@@ -7,6 +7,6 @@ import 'normalize.css';
Vue.config.productionTip = false;
new Vue({
- router,
- render: h => h(App),
+ router,
+ render: h => h(App),
}).$mount('#app');
diff --git a/src/options.js b/src/options.js
index 74f5c20..7813fb4 100644
--- a/src/options.js
+++ b/src/options.js
@@ -2,89 +2,89 @@ const version = process.env.VUE_APP_VERSION || '[master]';
const source = process.env.VUE_APP_SOURCE_LINK || 'https://github.com/productionwentdown/dri';
const defaultConfig = {
- merged: false,
+ merged: false,
- registryHost: process.env.VUE_APP_REGISTRY_HOST,
- registryAPI: process.env.VUE_APP_REGISTRY_API,
+ registryHost: process.env.VUE_APP_REGISTRY_HOST,
+ registryAPI: process.env.VUE_APP_REGISTRY_API,
- repositoriesPerPage: process.env.VUE_APP_REPOSITORIES_PER_PAGE,
- tagsPerPage: process.env.VUE_APP_TAGS_PER_PAGE,
+ repositoriesPerPage: process.env.VUE_APP_REPOSITORIES_PER_PAGE,
+ tagsPerPage: process.env.VUE_APP_TAGS_PER_PAGE,
- usePortusExplore: process.env.VUE_APP_USE_PORTUS_EXPLORE,
+ usePortusExplore: process.env.VUE_APP_USE_PORTUS_EXPLORE,
};
async function config() {
- if (defaultConfig.merged) {
- return defaultConfig;
- }
+ if (defaultConfig.merged) {
+ return defaultConfig;
+ }
- try {
- const response = await fetch('config.json');
- const jsonConfig = await response.json();
- defaultConfig.merged = true;
- return Object.assign(defaultConfig, jsonConfig);
- } catch (_) {
- defaultConfig.merged = true;
- return defaultConfig;
- }
+ try {
+ const response = await fetch('config.json');
+ const jsonConfig = await response.json();
+ defaultConfig.merged = true;
+ return Object.assign(defaultConfig, jsonConfig);
+ } catch (_) {
+ defaultConfig.merged = true;
+ return defaultConfig;
+ }
}
async function registryHost() {
- const c = await config();
- if (c.registryHost) {
- return c.registryHost;
- }
- return window.location.host;
+ const c = await config();
+ if (c.registryHost) {
+ return c.registryHost;
+ }
+ return window.location.host;
}
async function registryAPI() {
- const c = await config();
- if (c.registryAPI) {
- return c.registryAPI;
- }
- const host = await registryHost();
- // assume API uses the same protocol as the page
- // this is because browsers don't allow mixed content
- // if a HTTPS API needs to be accessed over HTTP, configure registryAPI
- return `${window.location.protocol}//${host}`;
+ const c = await config();
+ if (c.registryAPI) {
+ return c.registryAPI;
+ }
+ const host = await registryHost();
+ // assume API uses the same protocol as the page
+ // this is because browsers don't allow mixed content
+ // if a HTTPS API needs to be accessed over HTTP, configure registryAPI
+ return `${window.location.protocol}//${host}`;
}
async function usePortusExplore() {
- const c = await config();
- if (c.usePortusExplore) {
- return true;
- }
- return false;
+ const c = await config();
+ if (c.usePortusExplore) {
+ return true;
+ }
+ return false;
}
async function repositoriesPerPage() {
- const c = await config();
- try {
- const n = parseInt(c.repositoriesPerPage, 10);
- if (n > 0) return n;
- } catch (_) {
- return 0;
- }
- return 0;
+ const c = await config();
+ try {
+ const n = parseInt(c.repositoriesPerPage, 10);
+ if (n > 0) return n;
+ } catch (_) {
+ return 0;
+ }
+ return 0;
}
async function tagsPerPage() {
- const c = await config();
- try {
- const n = parseInt(c.tagsPerPage, 10);
- if (n > 0) return n;
- } catch (_) {
- return 0;
- }
- return 0;
+ const c = await config();
+ try {
+ const n = parseInt(c.tagsPerPage, 10);
+ if (n > 0) return n;
+ } catch (_) {
+ return 0;
+ }
+ return 0;
}
export {
- version,
- source,
- registryHost,
- registryAPI,
- repositoriesPerPage,
- tagsPerPage,
- usePortusExplore,
+ version,
+ source,
+ registryHost,
+ registryAPI,
+ repositoriesPerPage,
+ tagsPerPage,
+ usePortusExplore,
};
diff --git a/src/router.js b/src/router.js
index 4880ff6..b71f8b1 100644
--- a/src/router.js
+++ b/src/router.js
@@ -8,28 +8,40 @@ import Blob from '@/views/Blob.vue';
Vue.use(Router);
+const removeEncode = (to, _, next) => {
+ if (to.path.indexOf('%2F') > -1) {
+ return next({
+ path: to.path.replace('%2F', '/'),
+ });
+ }
+ return next();
+};
+
export default new Router({
- //mode: 'history',
- routes: [
- {
- path: '/',
- name: 'repos',
- component: Repos,
- },
- {
- path: '/:repo+/blobs/:digest',
- name: 'blob',
- component: Blob,
- },
- {
- path: '/:repo+/tags/:tag',
- name: 'tag',
- component: Tag,
- },
- {
- path: '/:repo+',
- name: 'repo',
- component: Repo,
- },
- ],
+ // mode: 'history',
+ routes: [
+ {
+ path: '/',
+ name: 'repos',
+ component: Repos,
+ },
+ {
+ path: '/:repo+/blobs/:digest',
+ name: 'blob',
+ component: Blob,
+ beforeEnter: removeEncode,
+ },
+ {
+ path: '/:repo+/tags/:tag',
+ name: 'tag',
+ component: Tag,
+ beforeEnter: removeEncode,
+ },
+ {
+ path: '/:repo+',
+ name: 'repo',
+ component: Repo,
+ beforeEnter: removeEncode,
+ },
+ ],
});
diff --git a/src/views/Blob.vue b/src/views/Blob.vue
index e5d9392..758f767 100644
--- a/src/views/Blob.vue
+++ b/src/views/Blob.vue
@@ -22,11 +22,11 @@ import ListItem from '@/components/ListItem.vue';
import BlobSize from '@/components/BlobSize.vue';
export default {
- components: {
- Layout,
- List,
- ListItem,
- BlobSize,
- },
+ components: {
+ Layout,
+ List,
+ ListItem,
+ BlobSize,
+ },
};
diff --git a/src/views/Repo.vue b/src/views/Repo.vue
index cc6134b..c68722f 100644
--- a/src/views/Repo.vue
+++ b/src/views/Repo.vue
@@ -39,44 +39,44 @@ import Paginator from '@/components/Paginator.vue';
import TagSize from '@/components/TagSize.vue';
export default {
- components: {
- Layout,
- Error,
- Toolbar,
- List,
- ListHeader,
- ListItem,
- Paginator,
- TagSize,
- },
- data() {
- return {
- error: '',
- registryHost: '',
- tags: [],
- nextLast: '',
- };
- },
- async created() {
- this.registryHost = await registryHost();
- await this.fetchTags();
- },
- methods: {
- async fetchTags() {
- try {
- const r = await tags(this.$route.params.repo, this.$route.query.last);
- this.tags = r.tags;
- this.nextLast = r.nextLast;
- } catch (e) {
- console.error(e);
- this.error = `Unable to fetch tags (${e.name})`;
- }
- },
- },
- watch: {
- async $route() {
- await this.fetchTags();
- },
- },
+ components: {
+ Layout,
+ Error,
+ Toolbar,
+ List,
+ ListHeader,
+ ListItem,
+ Paginator,
+ TagSize,
+ },
+ data() {
+ return {
+ error: '',
+ registryHost: '',
+ tags: [],
+ nextLast: '',
+ };
+ },
+ async created() {
+ this.registryHost = await registryHost();
+ await this.fetchTags();
+ },
+ methods: {
+ async fetchTags() {
+ try {
+ const r = await tags(this.$route.params.repo, this.$route.query.last);
+ this.tags = r.tags;
+ this.nextLast = r.nextLast;
+ } catch (e) {
+ console.error(e);
+ this.error = `Unable to fetch tags (${e.name})`;
+ }
+ },
+ },
+ watch: {
+ async $route() {
+ await this.fetchTags();
+ },
+ },
};
diff --git a/src/views/Repos.vue b/src/views/Repos.vue
index 0bbc991..00789a4 100644
--- a/src/views/Repos.vue
+++ b/src/views/Repos.vue
@@ -36,43 +36,43 @@ import ListItem from '@/components/ListItem.vue';
import Paginator from '@/components/Paginator.vue';
export default {
- components: {
- Layout,
- Error,
- Toolbar,
- List,
- ListHeader,
- ListItem,
- Paginator,
- },
- data() {
- return {
- error: '',
- registryHost: '',
- repos: [],
- nextLast: '',
- };
- },
- async created() {
- this.registryHost = await registryHost();
- await this.fetchRepos();
- },
- methods: {
- async fetchRepos() {
- try {
- const r = await repos(this.$route.query.last);
- this.repos = r.repositories;
- this.nextLast = r.nextLast;
- } catch (e) {
- console.error(e);
- this.error = `Unable to fetch repositories (${e.name})`;
- }
- },
- },
- watch: {
- async $route() {
- await this.fetchRepos();
- },
- },
+ components: {
+ Layout,
+ Error,
+ Toolbar,
+ List,
+ ListHeader,
+ ListItem,
+ Paginator,
+ },
+ data() {
+ return {
+ error: '',
+ registryHost: '',
+ repos: [],
+ nextLast: '',
+ };
+ },
+ async created() {
+ this.registryHost = await registryHost();
+ await this.fetchRepos();
+ },
+ methods: {
+ async fetchRepos() {
+ try {
+ const r = await repos(this.$route.query.last);
+ this.repos = r.repositories;
+ this.nextLast = r.nextLast;
+ } catch (e) {
+ console.error(e);
+ this.error = `Unable to fetch repositories (${e.name})`;
+ }
+ },
+ },
+ watch: {
+ async $route() {
+ await this.fetchRepos();
+ },
+ },
};
diff --git a/src/views/Tag.vue b/src/views/Tag.vue
index 4123193..9ec5043 100644
--- a/src/views/Tag.vue
+++ b/src/views/Tag.vue
@@ -14,7 +14,9 @@
Size
-
+
+
+
Layers
@@ -50,56 +52,56 @@ import TagSize from '@/components/TagSize.vue';
import BlobSize from '@/components/BlobSize.vue';
export default {
- components: {
- Layout,
- Error,
- Toolbar,
- List,
- ListHeader,
- ListItem,
- TagSize,
- BlobSize,
- },
- data() {
- return {
- error: '',
- registryHost: '',
- tag: {},
- layers: [],
- };
- },
- async created() {
- this.registryHost = await registryHost();
- await this.fetchTag();
- },
- methods: {
- async fetchTag() {
- try {
- const r = await tag(this.$route.params.repo, this.$route.params.tag);
- if (r.mediaType === 'application/vnd.docker.distribution.manifest.list.v2+json') {
- this.error = 'V2 manifest lists not supported yet';
- }
- if (r.schemaVersion === 1) {
- r.layers = r.fsLayers.map(l => ({ digest: l.blobSum }));
- }
- this.tag = r;
- console.log(r);
- } catch (e) {
- console.error(e);
- this.error = `Unable to fetch tag (${e.name})`;
- }
- },
- identifier(t, n) {
- return t.layers[n].digest.split(':')[1].slice(0, 10);
- },
- command() {
- return 'not implemented';
- },
- },
- watch: {
- async $route() {
- await this.fetchTag();
- },
- },
+ components: {
+ Layout,
+ Error,
+ Toolbar,
+ List,
+ ListHeader,
+ ListItem,
+ TagSize,
+ BlobSize,
+ },
+ data() {
+ return {
+ error: '',
+ registryHost: '',
+ tag: {},
+ layers: [],
+ };
+ },
+ async created() {
+ this.registryHost = await registryHost();
+ await this.fetchTag();
+ },
+ methods: {
+ async fetchTag() {
+ try {
+ const r = await tag(this.$route.params.repo, this.$route.params.tag);
+ if (r.mediaType === 'application/vnd.docker.distribution.manifest.list.v2+json') {
+ this.error = 'V2 manifest lists not supported yet';
+ }
+ if (r.schemaVersion === 1) {
+ r.layers = r.fsLayers.map(l => ({ digest: l.blobSum }));
+ }
+ this.tag = r;
+ console.log(r);
+ } catch (e) {
+ console.error(e);
+ this.error = `Unable to fetch tag (${e.name})`;
+ }
+ },
+ identifier(t, n) {
+ return t.layers[n].digest.split(':')[1].slice(0, 10);
+ },
+ command() {
+ return 'not implemented';
+ },
+ },
+ watch: {
+ async $route() {
+ await this.fetchTag();
+ },
+ },
};
diff --git a/vue.config.js b/vue.config.js
index 5252641..016ff07 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -1,4 +1,4 @@
module.exports = {
- lintOnSave: false,
- baseUrl: '',
+ lintOnSave: false,
+ baseUrl: '',
};
diff --git a/yarn.lock b/yarn.lock
index 0a27c41..75c07d8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1001,6 +1001,10 @@ ansi-colors@^3.0.0:
version "3.0.6"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.0.6.tgz#a0b9e00e8c1cc6685b1c3130dbeb9abed03ca6a4"
+ansi-escapes@^1.0.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
+
ansi-escapes@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
@@ -1021,12 +1025,16 @@ ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
-ansi-styles@^3.2.1:
+ansi-styles@^3.2.0, ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
dependencies:
color-convert "^1.9.0"
+any-observable@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242"
+
anymatch@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
@@ -1034,6 +1042,10 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
+app-root-path@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.1.0.tgz#98bf6599327ecea199309866e8140368fd2e646a"
+
aproba@^1.0.3, aproba@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@@ -1554,7 +1566,7 @@ caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
-chalk@^1.1.3:
+chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
@@ -1639,16 +1651,33 @@ clean-css@4.2.x:
dependencies:
source-map "~0.6.0"
+cli-cursor@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
+ dependencies:
+ restore-cursor "^1.0.1"
+
cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
dependencies:
restore-cursor "^2.0.0"
+cli-spinners@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c"
+
cli-spinners@^1.1.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.3.1.tgz#002c1990912d0d59580c93bd36c056de99e4259a"
+cli-truncate@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
+ dependencies:
+ slice-ansi "0.0.4"
+ string-width "^1.0.1"
+
cli-width@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
@@ -1741,7 +1770,7 @@ commander@2.17.x, commander@~2.17.1:
version "2.17.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
-commander@^2.13.0:
+commander@^2.11.0, commander@^2.13.0, commander@^2.9.0:
version "2.18.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970"
@@ -2119,6 +2148,10 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
+date-fns@^1.27.2:
+ version "1.29.0"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6"
+
date-now@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
@@ -2155,6 +2188,10 @@ decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
+dedent@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
+
deep-equal@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
@@ -2405,6 +2442,10 @@ electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.62:
version "1.3.70"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.70.tgz#ded377256d92d81b4257d36c65aa890274afcfd2"
+elegant-spinner@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
+
elliptic@^6.0.0:
version "6.4.1"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a"
@@ -2718,6 +2759,10 @@ execa@^0.8.0:
signal-exit "^3.0.0"
strip-eof "^1.0.0"
+exit-hook@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
+
expand-brackets@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
@@ -2876,6 +2921,13 @@ figgy-pudding@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
+figures@^1.7.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
+ dependencies:
+ escape-string-regexp "^1.0.5"
+ object-assign "^4.1.0"
+
figures@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
@@ -2951,6 +3003,10 @@ find-cache-dir@^1.0.0:
make-dir "^1.0.0"
pkg-dir "^2.0.0"
+find-parent-dir@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54"
+
find-root@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
@@ -3110,6 +3166,10 @@ get-caller-file@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
+get-own-enumerable-property-symbols@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz#5c4ad87f2834c4b9b4e84549dc1e0650fb38c24b"
+
get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
@@ -3504,6 +3564,16 @@ imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
+indent-string@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
+ dependencies:
+ repeating "^2.0.0"
+
+indent-string@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
+
indexes-of@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
@@ -3719,6 +3789,12 @@ is-extglob@^2.1.0, is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
+is-finite@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
+ dependencies:
+ number-is-nan "^1.0.0"
+
is-fullwidth-code-point@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
@@ -3763,10 +3839,16 @@ is-number@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff"
-is-obj@^1.0.0:
+is-obj@^1.0.0, is-obj@^1.0.1:
version "1.0.1"
resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
+is-observable@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2"
+ dependencies:
+ symbol-observable "^0.2.2"
+
is-path-cwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
@@ -3807,6 +3889,10 @@ is-regex@^1.0.4:
dependencies:
has "^1.0.1"
+is-regexp@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
+
is-relative@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5"
@@ -3891,6 +3977,19 @@ javascript-stringify@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-1.6.0.tgz#142d111f3a6e3dae8f4a9afd77d45855b5a9cce3"
+jest-get-type@^21.2.0:
+ version "21.2.0"
+ resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-21.2.0.tgz#f6376ab9db4b60d81e39f30749c6c466f40d4a23"
+
+jest-validate@^21.1.0:
+ version "21.2.1"
+ resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-21.2.1.tgz#cc0cbca653cd54937ba4f2a111796774530dd3c7"
+ dependencies:
+ chalk "^2.0.1"
+ jest-get-type "^21.2.0"
+ leven "^2.1.0"
+ pretty-format "^21.2.1"
+
joi@^13.0.0:
version "13.6.0"
resolved "https://registry.yarnpkg.com/joi/-/joi-13.6.0.tgz#877d820e3ad688a49c32421ffefc746bfbe2d0a0"
@@ -4030,6 +4129,10 @@ lcid@^2.0.0:
dependencies:
invert-kv "^2.0.0"
+leven@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
+
levn@^0.3.0, levn@~0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
@@ -4037,6 +4140,79 @@ levn@^0.3.0, levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
+lint-staged@^6.0.0:
+ version "6.1.1"
+ resolved "http://registry.npmjs.org/lint-staged/-/lint-staged-6.1.1.tgz#cd08c4d9b8ccc2d37198d1c47ce77d22be6cf324"
+ dependencies:
+ app-root-path "^2.0.0"
+ chalk "^2.1.0"
+ commander "^2.11.0"
+ cosmiconfig "^4.0.0"
+ debug "^3.1.0"
+ dedent "^0.7.0"
+ execa "^0.8.0"
+ find-parent-dir "^0.3.0"
+ is-glob "^4.0.0"
+ jest-validate "^21.1.0"
+ listr "^0.13.0"
+ lodash "^4.17.4"
+ log-symbols "^2.0.0"
+ minimatch "^3.0.0"
+ npm-which "^3.0.1"
+ p-map "^1.1.1"
+ path-is-inside "^1.0.2"
+ pify "^3.0.0"
+ staged-git-files "1.0.0"
+ stringify-object "^3.2.0"
+
+listr-silent-renderer@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
+
+listr-update-renderer@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7"
+ dependencies:
+ chalk "^1.1.3"
+ cli-truncate "^0.2.1"
+ elegant-spinner "^1.0.1"
+ figures "^1.7.0"
+ indent-string "^3.0.0"
+ log-symbols "^1.0.2"
+ log-update "^1.0.2"
+ strip-ansi "^3.0.1"
+
+listr-verbose-renderer@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35"
+ dependencies:
+ chalk "^1.1.3"
+ cli-cursor "^1.0.2"
+ date-fns "^1.27.2"
+ figures "^1.7.0"
+
+listr@^0.13.0:
+ version "0.13.0"
+ resolved "https://registry.yarnpkg.com/listr/-/listr-0.13.0.tgz#20bb0ba30bae660ee84cc0503df4be3d5623887d"
+ dependencies:
+ chalk "^1.1.3"
+ cli-truncate "^0.2.1"
+ figures "^1.7.0"
+ indent-string "^2.1.0"
+ is-observable "^0.2.0"
+ is-promise "^2.1.0"
+ is-stream "^1.1.0"
+ listr-silent-renderer "^1.1.1"
+ listr-update-renderer "^0.4.0"
+ listr-verbose-renderer "^0.4.0"
+ log-symbols "^1.0.2"
+ log-update "^1.0.2"
+ ora "^0.2.3"
+ p-map "^1.1.1"
+ rxjs "^5.4.2"
+ stream-to-observable "^0.2.0"
+ strip-ansi "^3.0.1"
+
load-json-file@^2.0.0:
version "2.0.0"
resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
@@ -4124,12 +4300,25 @@ lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5,
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
-log-symbols@^2.2.0:
+log-symbols@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
+ dependencies:
+ chalk "^1.0.0"
+
+log-symbols@^2.0.0, log-symbols@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
dependencies:
chalk "^2.0.1"
+log-update@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1"
+ dependencies:
+ ansi-escapes "^1.0.0"
+ cli-cursor "^1.0.2"
+
loglevel@^1.4.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
@@ -4314,7 +4503,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
-minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
+minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
@@ -4563,12 +4752,26 @@ npm-packlist@^1.1.6:
ignore-walk "^3.0.1"
npm-bundled "^1.0.1"
+npm-path@^2.0.2:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64"
+ dependencies:
+ which "^1.2.10"
+
npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
dependencies:
path-key "^2.0.0"
+npm-which@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa"
+ dependencies:
+ commander "^2.9.0"
+ npm-path "^2.0.2"
+ which "^1.2.10"
+
npmlog@^4.0.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
@@ -4680,6 +4883,10 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
dependencies:
wrappy "1"
+onetime@^1.0.0:
+ version "1.1.0"
+ resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
+
onetime@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
@@ -4707,6 +4914,15 @@ optionator@^0.8.2:
type-check "~0.3.2"
wordwrap "~1.0.0"
+ora@^0.2.3:
+ version "0.2.3"
+ resolved "http://registry.npmjs.org/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4"
+ dependencies:
+ chalk "^1.1.1"
+ cli-cursor "^1.0.2"
+ cli-spinners "^0.1.2"
+ object-assign "^4.0.1"
+
ora@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/ora/-/ora-2.1.0.tgz#6caf2830eb924941861ec53a173799e008b51e5b"
@@ -5298,6 +5514,13 @@ pretty-error@^2.0.2:
renderkid "^2.0.1"
utila "~0.4"
+pretty-format@^21.2.1:
+ version "21.2.1"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-21.2.1.tgz#ae5407f3cf21066cd011aa1ba5fce7b6a2eddb36"
+ dependencies:
+ ansi-regex "^3.0.0"
+ ansi-styles "^3.2.0"
+
private@^0.1.6:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
@@ -5602,6 +5825,12 @@ repeat-string@^1.5.2, repeat-string@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
+repeating@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
+ dependencies:
+ is-finite "^1.0.0"
+
request-promise-core@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6"
@@ -5688,6 +5917,13 @@ resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.6.0:
dependencies:
path-parse "^1.0.5"
+restore-cursor@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
+ dependencies:
+ exit-hook "^1.0.0"
+ onetime "^1.0.0"
+
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
@@ -5742,6 +5978,12 @@ rx-lite@*, rx-lite@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
+rxjs@^5.4.2:
+ version "5.5.12"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc"
+ dependencies:
+ symbol-observable "1.0.1"
+
safe-buffer@5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
@@ -5914,6 +6156,10 @@ slash@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
+slice-ansi@0.0.4:
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
+
slice-ansi@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
@@ -6081,6 +6327,10 @@ stackframe@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.0.4.tgz#357b24a992f9427cba6b545d96a14ed2cbca187b"
+staged-git-files@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.0.0.tgz#cdb847837c1fcc52c08a872d4883cc0877668a80"
+
static-extend@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
@@ -6128,6 +6378,12 @@ stream-shift@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952"
+stream-to-observable@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.2.0.tgz#59d6ea393d87c2c0ddac10aa0d561bc6ba6f0e10"
+ dependencies:
+ any-observable "^0.2.0"
+
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
@@ -6169,6 +6425,14 @@ string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
+stringify-object@^3.2.0:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.2.tgz#9853052e5a88fb605a44cd27445aa257ad7ffbcd"
+ dependencies:
+ get-own-enumerable-property-symbols "^2.0.1"
+ is-obj "^1.0.1"
+ is-regexp "^1.0.0"
+
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
@@ -6234,6 +6498,14 @@ svgo@^1.0.0:
unquote "~1.1.1"
util.promisify "~1.0.0"
+symbol-observable@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4"
+
+symbol-observable@^0.2.2:
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40"
+
table@4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36"
@@ -6809,7 +7081,7 @@ which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
-which@^1.2.9:
+which@^1.2.10, which@^1.2.9:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
dependencies: