{
diff --git a/scm-ui-components/packages/ui-components/src/forms/Select.js b/scm-ui-components/packages/ui-components/src/forms/Select.js
index 184359cc11..880b375999 100644
--- a/scm-ui-components/packages/ui-components/src/forms/Select.js
+++ b/scm-ui-components/packages/ui-components/src/forms/Select.js
@@ -1,5 +1,7 @@
//@flow
import React from "react";
+import classNames from "classnames";
+import { LabelWithHelpIcon } from "../index";
export type SelectItem = {
value: string,
@@ -10,7 +12,9 @@ type Props = {
label?: string,
options: SelectItem[],
value?: SelectItem,
- onChange: string => void
+ onChange: string => void,
+ loading?: boolean,
+ helpText?: string
};
class Select extends React.Component
{
@@ -28,21 +32,18 @@ class Select extends React.Component {
this.props.onChange(event.target.value);
};
- renderLabel = () => {
- const label = this.props.label;
- if (label) {
- return ;
- }
- return "";
- };
-
render() {
- const { options, value } = this.props;
+ const { options, value, label, helpText, loading } = this.props;
+ const loadingClass = loading ? "is-loading" : "";
+
return (
- {this.renderLabel()}
-
+
+
);
diff --git a/scm-ui/src/config/components/form/ProxySettings.js b/scm-ui/src/config/components/form/ProxySettings.js
index 0745312344..7656bc270c 100644
--- a/scm-ui/src/config/components/form/ProxySettings.js
+++ b/scm-ui/src/config/components/form/ProxySettings.js
@@ -42,6 +42,7 @@ class ProxySettings extends React.Component
{
label={t("proxy-settings.enable-proxy")}
onChange={this.handleEnableProxyChange}
disabled={!hasUpdatePermission}
+ helpText={t("help.enableProxyHelpText")}
/>
{
value={proxyPassword}
type="password"
disabled={!enableProxy || !hasUpdatePermission}
+ helpText={t("help.proxyPasswordHelpText")}
/>
{
removeLabel={t("admin-settings.remove-group-button")}
onRemove={this.removeEntry}
disabled={disabled}
+ helpText={t("help.adminGroupsHelpText")}
/>
);
}
diff --git a/scm-ui/src/config/components/table/AdminUserTable.js b/scm-ui/src/config/components/table/AdminUserTable.js
index d1f35e8424..a077a6d5d2 100644
--- a/scm-ui/src/config/components/table/AdminUserTable.js
+++ b/scm-ui/src/config/components/table/AdminUserTable.js
@@ -22,6 +22,7 @@ class AdminUserTable extends React.Component {
removeLabel={t("admin-settings.remove-user-button")}
onRemove={this.removeEntry}
disabled={disabled}
+ helpText={t("help.adminUsersHelpText")}
/>
);
}
diff --git a/scm-ui/src/config/components/table/ArrayConfigTable.js b/scm-ui/src/config/components/table/ArrayConfigTable.js
index d724caa6ae..21d53261f4 100644
--- a/scm-ui/src/config/components/table/ArrayConfigTable.js
+++ b/scm-ui/src/config/components/table/ArrayConfigTable.js
@@ -1,21 +1,22 @@
//@flow
import React from "react";
-import { RemoveEntryOfTableButton } from "@scm-manager/ui-components";
+import { RemoveEntryOfTableButton, LabelWithHelpIcon } from "@scm-manager/ui-components";
type Props = {
items: string[],
label: string,
removeLabel: string,
onRemove: (string[], string) => void,
- disabled: boolean
+ disabled: boolean,
+ helpText: string
};
class ArrayConfigTable extends React.Component {
render() {
- const { label, disabled, removeLabel, items } = this.props;
+ const { label, disabled, removeLabel, items, helpText } = this.props;
return (
-
+
{items.map(item => {
diff --git a/scm-ui/src/config/components/table/ProxyExcludesTable.js b/scm-ui/src/config/components/table/ProxyExcludesTable.js
index a7849ffdf2..d786810ad2 100644
--- a/scm-ui/src/config/components/table/ProxyExcludesTable.js
+++ b/scm-ui/src/config/components/table/ProxyExcludesTable.js
@@ -22,6 +22,7 @@ class ProxyExcludesTable extends React.Component {
removeLabel={t("proxy-settings.remove-proxy-exclude-button")}
onRemove={this.removeEntry}
disabled={disabled}
+ helpText={t("help.proxyExcludesHelpText")}
/>
);
}
diff --git a/scm-ui/src/config/modules/config.test.js b/scm-ui/src/config/modules/config.test.js
index 52cfd911ef..baff061a30 100644
--- a/scm-ui/src/config/modules/config.test.js
+++ b/scm-ui/src/config/modules/config.test.js
@@ -23,7 +23,7 @@ import reducer, {
getConfigUpdatePermission
} from "./config";
-const CONFIG_URL = "/api/rest/v2/config";
+const CONFIG_URL = "/api/v2/config";
const error = new Error("You have an error!");
@@ -51,8 +51,8 @@ const config = {
enabledXsrfProtection: true,
defaultNamespaceStrategy: "sonia.scm.repository.DefaultNamespaceStrategy",
_links: {
- self: { href: "http://localhost:8081/api/rest/v2/config" },
- update: { href: "http://localhost:8081/api/rest/v2/config" }
+ self: { href: "http://localhost:8081/api/v2/config" },
+ update: { href: "http://localhost:8081/api/v2/config" }
}
};
@@ -80,8 +80,8 @@ const configWithNullValues = {
enabledXsrfProtection: true,
defaultNamespaceStrategy: "sonia.scm.repository.DefaultNamespaceStrategy",
_links: {
- self: { href: "http://localhost:8081/api/rest/v2/config" },
- update: { href: "http://localhost:8081/api/rest/v2/config" }
+ self: { href: "http://localhost:8081/api/v2/config" },
+ update: { href: "http://localhost:8081/api/v2/config" }
}
};
@@ -135,7 +135,7 @@ describe("config fetch()", () => {
});
it("should successfully modify config", () => {
- fetchMock.putOnce("http://localhost:8081/api/rest/v2/config", {
+ fetchMock.putOnce("http://localhost:8081/api/v2/config", {
status: 204
});
@@ -150,7 +150,7 @@ describe("config fetch()", () => {
});
it("should call the callback after modifying config", () => {
- fetchMock.putOnce("http://localhost:8081/api/rest/v2/config", {
+ fetchMock.putOnce("http://localhost:8081/api/v2/config", {
status: 204
});
@@ -169,7 +169,7 @@ describe("config fetch()", () => {
});
it("should fail modifying config on HTTP 500", () => {
- fetchMock.putOnce("http://localhost:8081/api/rest/v2/config", {
+ fetchMock.putOnce("http://localhost:8081/api/v2/config", {
status: 500
});
diff --git a/scm-ui/src/createReduxStore.js b/scm-ui/src/createReduxStore.js
index c35898ddbf..710ade20e5 100644
--- a/scm-ui/src/createReduxStore.js
+++ b/scm-ui/src/createReduxStore.js
@@ -12,6 +12,7 @@ import groups from "./groups/modules/groups";
import auth from "./modules/auth";
import pending from "./modules/pending";
import failure from "./modules/failure";
+import permissions from "./repos/permissions/modules/permissions";
import config from "./config/modules/config";
import type { BrowserHistory } from "history/createBrowserHistory";
@@ -30,6 +31,7 @@ function createReduxStore(history: BrowserHistory) {
repositoryTypes,
changesets,
branches,
+ permissions,
groups,
auth,
config
diff --git a/scm-ui/src/groups/components/GroupForm.js b/scm-ui/src/groups/components/GroupForm.js
index 1a29c0a433..4958fbf0fa 100644
--- a/scm-ui/src/groups/components/GroupForm.js
+++ b/scm-ui/src/groups/components/GroupForm.js
@@ -80,6 +80,7 @@ class GroupForm extends React.Component {
onChange={this.handleGroupNameChange}
value={group.name}
validationError={this.state.nameValidationError}
+ helpText={t("group-form.help.nameHelpText")}
/>
);
}
@@ -93,6 +94,7 @@ class GroupForm extends React.Component {
onChange={this.handleDescriptionChange}
value={group.description}
validationError={false}
+ helpText={t("group-form.help.descriptionHelpText")}
/>
{
const { t } = this.props;
return (
-
+
{this.props.members.map(member => {
diff --git a/scm-ui/src/groups/modules/groups.test.js b/scm-ui/src/groups/modules/groups.test.js
index 5a15f68017..191a2122e4 100644
--- a/scm-ui/src/groups/modules/groups.test.js
+++ b/scm-ui/src/groups/modules/groups.test.js
@@ -44,7 +44,7 @@ import reducer, {
MODIFY_GROUP_SUCCESS,
MODIFY_GROUP_FAILURE
} from "./groups";
-const GROUPS_URL = "/api/rest/v2/groups";
+const GROUPS_URL = "/api/v2/groups";
const error = new Error("You have an error!");
@@ -57,13 +57,13 @@ const humanGroup = {
members: ["userZaphod"],
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/groups/humanGroup"
+ href: "http://localhost:8081/api/v2/groups/humanGroup"
},
delete: {
- href: "http://localhost:8081/api/rest/v2/groups/humanGroup"
+ href: "http://localhost:8081/api/v2/groups/humanGroup"
},
update: {
- href:"http://localhost:8081/api/rest/v2/groups/humanGroup"
+ href:"http://localhost:8081/api/v2/groups/humanGroup"
}
},
_embedded: {
@@ -72,7 +72,7 @@ const humanGroup = {
name: "userZaphod",
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/users/userZaphod"
+ href: "http://localhost:8081/api/v2/users/userZaphod"
}
}
}
@@ -89,13 +89,13 @@ const emptyGroup = {
members: [],
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/groups/emptyGroup"
+ href: "http://localhost:8081/api/v2/groups/emptyGroup"
},
delete: {
- href: "http://localhost:8081/api/rest/v2/groups/emptyGroup"
+ href: "http://localhost:8081/api/v2/groups/emptyGroup"
},
update: {
- href:"http://localhost:8081/api/rest/v2/groups/emptyGroup"
+ href:"http://localhost:8081/api/v2/groups/emptyGroup"
}
},
_embedded: {
@@ -108,16 +108,16 @@ const responseBody = {
pageTotal: 1,
_links: {
self: {
- href: "http://localhost:3000/api/rest/v2/groups/?page=0&pageSize=10"
+ href: "http://localhost:3000/api/v2/groups/?page=0&pageSize=10"
},
first: {
- href: "http://localhost:3000/api/rest/v2/groups/?page=0&pageSize=10"
+ href: "http://localhost:3000/api/v2/groups/?page=0&pageSize=10"
},
last: {
- href: "http://localhost:3000/api/rest/v2/groups/?page=0&pageSize=10"
+ href: "http://localhost:3000/api/v2/groups/?page=0&pageSize=10"
},
create: {
- href: "http://localhost:3000/api/rest/v2/groups/"
+ href: "http://localhost:3000/api/v2/groups/"
}
},
_embedded: {
@@ -244,7 +244,7 @@ describe("groups fetch()", () => {
});
it("should successfully modify group", () => {
- fetchMock.putOnce("http://localhost:8081/api/rest/v2/groups/humanGroup", {
+ fetchMock.putOnce("http://localhost:8081/api/v2/groups/humanGroup", {
status: 204
});
@@ -259,7 +259,7 @@ describe("groups fetch()", () => {
});
it("should call the callback after modifying group", () => {
- fetchMock.putOnce("http://localhost:8081/api/rest/v2/groups/humanGroup", {
+ fetchMock.putOnce("http://localhost:8081/api/v2/groups/humanGroup", {
status: 204
});
@@ -278,7 +278,7 @@ describe("groups fetch()", () => {
});
it("should fail modifying group on HTTP 500", () => {
- fetchMock.putOnce("http://localhost:8081/api/rest/v2/groups/humanGroup", {
+ fetchMock.putOnce("http://localhost:8081/api/v2/groups/humanGroup", {
status: 500
});
@@ -293,7 +293,7 @@ describe("groups fetch()", () => {
});
it("should delete successfully group humanGroup", () => {
- fetchMock.deleteOnce("http://localhost:8081/api/rest/v2/groups/humanGroup", {
+ fetchMock.deleteOnce("http://localhost:8081/api/v2/groups/humanGroup", {
status: 204
});
@@ -308,7 +308,7 @@ describe("groups fetch()", () => {
});
it("should call the callback, after successful delete", () => {
- fetchMock.deleteOnce("http://localhost:8081/api/rest/v2/groups/humanGroup", {
+ fetchMock.deleteOnce("http://localhost:8081/api/v2/groups/humanGroup", {
status: 204
});
@@ -324,7 +324,7 @@ describe("groups fetch()", () => {
});
it("should fail to delete group humanGroup", () => {
- fetchMock.deleteOnce("http://localhost:8081/api/rest/v2/groups/humanGroup", {
+ fetchMock.deleteOnce("http://localhost:8081/api/v2/groups/humanGroup", {
status: 500
});
diff --git a/scm-ui/src/modules/auth.test.js b/scm-ui/src/modules/auth.test.js
index 98691e85ac..3cea758566 100644
--- a/scm-ui/src/modules/auth.test.js
+++ b/scm-ui/src/modules/auth.test.js
@@ -78,7 +78,7 @@ describe("auth actions", () => {
});
it("should dispatch login success and dispatch fetch me", () => {
- fetchMock.postOnce("/api/rest/v2/auth/access_token", {
+ fetchMock.postOnce("/api/v2/auth/access_token", {
body: {
cookie: true,
grant_type: "password",
@@ -88,7 +88,7 @@ describe("auth actions", () => {
headers: { "content-type": "application/json" }
});
- fetchMock.getOnce("/api/rest/v2/me", {
+ fetchMock.getOnce("/api/v2/me", {
body: me,
headers: { "content-type": "application/json" }
});
@@ -106,7 +106,7 @@ describe("auth actions", () => {
});
it("should dispatch login failure", () => {
- fetchMock.postOnce("/api/rest/v2/auth/access_token", {
+ fetchMock.postOnce("/api/v2/auth/access_token", {
status: 400
});
@@ -120,7 +120,7 @@ describe("auth actions", () => {
});
it("should dispatch fetch me success", () => {
- fetchMock.getOnce("/api/rest/v2/me", {
+ fetchMock.getOnce("/api/v2/me", {
body: me,
headers: { "content-type": "application/json" }
});
@@ -141,7 +141,7 @@ describe("auth actions", () => {
});
it("should dispatch fetch me failure", () => {
- fetchMock.getOnce("/api/rest/v2/me", {
+ fetchMock.getOnce("/api/v2/me", {
status: 500
});
@@ -155,7 +155,7 @@ describe("auth actions", () => {
});
it("should dispatch fetch me unauthorized", () => {
- fetchMock.getOnce("/api/rest/v2/me", {
+ fetchMock.getOnce("/api/v2/me", {
status: 401
});
@@ -173,11 +173,11 @@ describe("auth actions", () => {
});
it("should dispatch logout success", () => {
- fetchMock.deleteOnce("/api/rest/v2/auth/access_token", {
+ fetchMock.deleteOnce("/api/v2/auth/access_token", {
status: 204
});
- fetchMock.getOnce("/api/rest/v2/me", {
+ fetchMock.getOnce("/api/v2/me", {
status: 401
});
@@ -194,7 +194,7 @@ describe("auth actions", () => {
});
it("should dispatch logout failure", () => {
- fetchMock.deleteOnce("/api/rest/v2/auth/access_token", {
+ fetchMock.deleteOnce("/api/v2/auth/access_token", {
status: 500
});
diff --git a/scm-ui/src/modules/failure.js b/scm-ui/src/modules/failure.js
index 67df22623b..49a48e7876 100644
--- a/scm-ui/src/modules/failure.js
+++ b/scm-ui/src/modules/failure.js
@@ -13,6 +13,20 @@ function extractIdentifierFromFailure(action: Action) {
return identifier;
}
+function removeAllEntriesOfIdentifierFromState(
+ state: Object,
+ payload: any,
+ identifier: string
+) {
+ const newState = {};
+ for (let failureType in state) {
+ if (failureType !== identifier && !failureType.startsWith(identifier)) {
+ newState[failureType] = state[failureType];
+ }
+ }
+ return newState;
+}
+
function removeFromState(state: Object, identifier: string) {
const newState = {};
for (let failureType in state) {
@@ -47,7 +61,9 @@ export default function reducer(
if (action.itemId) {
identifier += "/" + action.itemId;
}
- return removeFromState(state, identifier);
+ if (action.payload)
+ return removeAllEntriesOfIdentifierFromState(state, action.payload, identifier);
+ else return removeFromState(state, identifier);
}
}
return state;
diff --git a/scm-ui/src/modules/pending.js b/scm-ui/src/modules/pending.js
index e83345aee6..306d8a157a 100644
--- a/scm-ui/src/modules/pending.js
+++ b/scm-ui/src/modules/pending.js
@@ -19,6 +19,20 @@ function removeFromState(state: Object, identifier: string) {
return newState;
}
+function removeAllEntriesOfIdentifierFromState(
+ state: Object,
+ payload: any,
+ identifier: string
+) {
+ const newState = {};
+ for (let childType in state) {
+ if (childType !== identifier && !childType.startsWith(identifier)) {
+ newState[childType] = state[childType];
+ }
+ }
+ return newState;
+}
+
function extractIdentifierFromPending(action: Action) {
const type = action.type;
let identifier = type.substring(0, type.length - PENDING_SUFFIX.length);
@@ -48,7 +62,10 @@ export default function reducer(
if (action.itemId) {
identifier += "/" + action.itemId;
}
- return removeFromState(state, identifier);
+ if (action.payload)
+ return removeAllEntriesOfIdentifierFromState(state, action.payload, identifier);
+ else
+ return removeFromState(state, identifier);
}
}
}
diff --git a/scm-ui/src/repos/components/PermissionsNavLink.js b/scm-ui/src/repos/components/PermissionsNavLink.js
new file mode 100644
index 0000000000..cb6d0e0723
--- /dev/null
+++ b/scm-ui/src/repos/components/PermissionsNavLink.js
@@ -0,0 +1,28 @@
+//@flow
+import React from "react";
+import { NavLink } from "@scm-manager/ui-components";
+import { translate } from "react-i18next";
+import type { Repository } from "@scm-manager/ui-types";
+
+type Props = {
+ permissionUrl: string,
+ t: string => string,
+ repository: Repository
+};
+
+class PermissionsNavLink extends React.Component {
+ hasPermissionsLink = () => {
+ return this.props.repository._links.permissions;
+ };
+ render() {
+ if (!this.hasPermissionsLink()) {
+ return null;
+ }
+ const { permissionUrl, t } = this.props;
+ return (
+
+ );
+ }
+}
+
+export default translate("repos")(PermissionsNavLink);
diff --git a/scm-ui/src/repos/components/PermissionsNavLink.test.js b/scm-ui/src/repos/components/PermissionsNavLink.test.js
new file mode 100644
index 0000000000..450c7f49e6
--- /dev/null
+++ b/scm-ui/src/repos/components/PermissionsNavLink.test.js
@@ -0,0 +1,38 @@
+import React from "react";
+import { mount, shallow } from "enzyme";
+import "../../tests/enzyme";
+import "../../tests/i18n";
+import ReactRouterEnzymeContext from "react-router-enzyme-context";
+import PermissionsNavLink from "./PermissionsNavLink";
+
+describe("PermissionsNavLink", () => {
+ const options = new ReactRouterEnzymeContext();
+
+ it("should render nothing, if the modify link is missing", () => {
+ const repository = {
+ _links: {}
+ };
+
+ const navLink = shallow(
+ ,
+ options.get()
+ );
+ expect(navLink.text()).toBe("");
+ });
+
+ it("should render the navLink", () => {
+ const repository = {
+ _links: {
+ permissions: {
+ href: "/permissions"
+ }
+ }
+ };
+
+ const navLink = mount(
+ ,
+ options.get()
+ );
+ expect(navLink.text()).toBe("repository-root.permissions");
+ });
+});
diff --git a/scm-ui/src/repos/components/form/RepositoryForm.js b/scm-ui/src/repos/components/form/RepositoryForm.js
index 06833c7fd7..54abf8e08d 100644
--- a/scm-ui/src/repos/components/form/RepositoryForm.js
+++ b/scm-ui/src/repos/components/form/RepositoryForm.js
@@ -90,12 +90,14 @@ class RepositoryForm extends React.Component {
value={repository ? repository.contact : ""}
validationError={this.state.contactValidationError}
errorMessage={t("validation.contact-invalid")}
+ helpText={t("help.contactHelpText")}
/>
{
value={repository ? repository.name : ""}
validationError={this.state.nameValidationError}
errorMessage={t("validation.name-invalid")}
+ helpText={t("help.nameHelpText")}
/>
);
diff --git a/scm-ui/src/repos/containers/RepositoryRoot.js b/scm-ui/src/repos/containers/RepositoryRoot.js
index f7410cecc4..681327bc96 100644
--- a/scm-ui/src/repos/containers/RepositoryRoot.js
+++ b/scm-ui/src/repos/containers/RepositoryRoot.js
@@ -22,10 +22,12 @@ import { translate } from "react-i18next";
import RepositoryDetails from "../components/RepositoryDetails";
import DeleteNavAction from "../components/DeleteNavAction";
import Edit from "../containers/Edit";
+import Permissions from "../permissions/containers/Permissions";
import type { History } from "history";
import EditNavLink from "../components/EditNavLink";
import BranchRoot from "./BranchRoot";
+import PermissionsNavLink from "../components/PermissionsNavLink";
type Props = {
namespace: string,
@@ -108,6 +110,15 @@ class RepositoryRoot extends React.Component {
path={`${url}/edit`}
component={() => }
/>
+ (
+
+ )}
+ />
(
@@ -141,6 +152,10 @@ class RepositoryRoot extends React.Component {
activeWhenMatch={this.matches}
/>
+
diff --git a/scm-ui/src/repos/modules/repos.test.js b/scm-ui/src/repos/modules/repos.test.js
index d537f4bdc0..302918f02e 100644
--- a/scm-ui/src/repos/modules/repos.test.js
+++ b/scm-ui/src/repos/modules/repos.test.js
@@ -58,33 +58,33 @@ const hitchhikerPuzzle42: Repository = {
type: "svn",
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/repositories/hitchhiker/puzzle42"
+ href: "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42"
},
delete: {
- href: "http://localhost:8081/api/rest/v2/repositories/hitchhiker/puzzle42"
+ href: "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42"
},
update: {
- href: "http://localhost:8081/api/rest/v2/repositories/hitchhiker/puzzle42"
+ href: "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42"
},
permissions: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/permissions/"
},
tags: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/puzzle42/tags/"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/tags/"
},
branches: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/puzzle42/branches/"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/branches/"
},
changesets: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/puzzle42/changesets/"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/changesets/"
},
sources: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/puzzle42/sources/"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/puzzle42/sources/"
}
}
};
@@ -100,35 +100,35 @@ const hitchhikerRestatend: Repository = {
_links: {
self: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/restatend"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/restatend"
},
delete: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/restatend"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/restatend"
},
update: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/restatend"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/restatend"
},
permissions: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/restatend/permissions/"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/restatend/permissions/"
},
tags: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/restatend/tags/"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/restatend/tags/"
},
branches: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/restatend/branches/"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/restatend/branches/"
},
changesets: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/restatend/changesets/"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/restatend/changesets/"
},
sources: {
href:
- "http://localhost:8081/api/rest/v2/repositories/hitchhiker/restatend/sources/"
+ "http://localhost:8081/api/v2/repositories/hitchhiker/restatend/sources/"
}
}
};
@@ -142,32 +142,32 @@ const slartiFjords: Repository = {
creationDate: "2018-07-31T08:59:05.653Z",
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/repositories/slarti/fjords"
+ href: "http://localhost:8081/api/v2/repositories/slarti/fjords"
},
delete: {
- href: "http://localhost:8081/api/rest/v2/repositories/slarti/fjords"
+ href: "http://localhost:8081/api/v2/repositories/slarti/fjords"
},
update: {
- href: "http://localhost:8081/api/rest/v2/repositories/slarti/fjords"
+ href: "http://localhost:8081/api/v2/repositories/slarti/fjords"
},
permissions: {
href:
- "http://localhost:8081/api/rest/v2/repositories/slarti/fjords/permissions/"
+ "http://localhost:8081/api/v2/repositories/slarti/fjords/permissions/"
},
tags: {
- href: "http://localhost:8081/api/rest/v2/repositories/slarti/fjords/tags/"
+ href: "http://localhost:8081/api/v2/repositories/slarti/fjords/tags/"
},
branches: {
href:
- "http://localhost:8081/api/rest/v2/repositories/slarti/fjords/branches/"
+ "http://localhost:8081/api/v2/repositories/slarti/fjords/branches/"
},
changesets: {
href:
- "http://localhost:8081/api/rest/v2/repositories/slarti/fjords/changesets/"
+ "http://localhost:8081/api/v2/repositories/slarti/fjords/changesets/"
},
sources: {
href:
- "http://localhost:8081/api/rest/v2/repositories/slarti/fjords/sources/"
+ "http://localhost:8081/api/v2/repositories/slarti/fjords/sources/"
}
}
};
@@ -177,16 +177,16 @@ const repositoryCollection: RepositoryCollection = {
pageTotal: 1,
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/repositories/?page=0&pageSize=10"
+ href: "http://localhost:8081/api/v2/repositories/?page=0&pageSize=10"
},
first: {
- href: "http://localhost:8081/api/rest/v2/repositories/?page=0&pageSize=10"
+ href: "http://localhost:8081/api/v2/repositories/?page=0&pageSize=10"
},
last: {
- href: "http://localhost:8081/api/rest/v2/repositories/?page=0&pageSize=10"
+ href: "http://localhost:8081/api/v2/repositories/?page=0&pageSize=10"
},
create: {
- href: "http://localhost:8081/api/rest/v2/repositories/"
+ href: "http://localhost:8081/api/v2/repositories/"
}
},
_embedded: {
@@ -199,16 +199,16 @@ const repositoryCollectionWithNames: RepositoryCollection = {
pageTotal: 1,
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/repositories/?page=0&pageSize=10"
+ href: "http://localhost:8081/api/v2/repositories/?page=0&pageSize=10"
},
first: {
- href: "http://localhost:8081/api/rest/v2/repositories/?page=0&pageSize=10"
+ href: "http://localhost:8081/api/v2/repositories/?page=0&pageSize=10"
},
last: {
- href: "http://localhost:8081/api/rest/v2/repositories/?page=0&pageSize=10"
+ href: "http://localhost:8081/api/v2/repositories/?page=0&pageSize=10"
},
create: {
- href: "http://localhost:8081/api/rest/v2/repositories/"
+ href: "http://localhost:8081/api/v2/repositories/"
}
},
_embedded: {
@@ -221,7 +221,7 @@ const repositoryCollectionWithNames: RepositoryCollection = {
};
describe("repos fetch", () => {
- const REPOS_URL = "/api/rest/v2/repositories";
+ const REPOS_URL = "/api/v2/repositories";
const SORT = "sortBy=namespaceAndName";
const REPOS_URL_WITH_SORT = REPOS_URL + "?" + SORT;
const mockStore = configureMockStore([thunk]);
@@ -293,7 +293,7 @@ describe("repos fetch", () => {
it("should append sortby parameter and successfully fetch repos from link", () => {
fetchMock.getOnce(
- "/api/rest/v2/repositories?one=1&sortBy=namespaceAndName",
+ "/api/v2/repositories?one=1&sortBy=namespaceAndName",
repositoryCollection
);
@@ -421,7 +421,7 @@ describe("repos fetch", () => {
it("should successfully delete repo slarti/fjords", () => {
fetchMock.delete(
- "http://localhost:8081/api/rest/v2/repositories/slarti/fjords",
+ "http://localhost:8081/api/v2/repositories/slarti/fjords",
{
status: 204
}
@@ -448,7 +448,7 @@ describe("repos fetch", () => {
it("should successfully delete repo slarti/fjords and call the callback", () => {
fetchMock.delete(
- "http://localhost:8081/api/rest/v2/repositories/slarti/fjords",
+ "http://localhost:8081/api/v2/repositories/slarti/fjords",
{
status: 204
}
@@ -468,7 +468,7 @@ describe("repos fetch", () => {
it("should disapatch failure on delete, if server returns status code 500", () => {
fetchMock.delete(
- "http://localhost:8081/api/rest/v2/repositories/slarti/fjords",
+ "http://localhost:8081/api/v2/repositories/slarti/fjords",
{
status: 500
}
diff --git a/scm-ui/src/repos/modules/repositoryTypes.test.js b/scm-ui/src/repos/modules/repositoryTypes.test.js
index 0842333484..840a5bdeb8 100644
--- a/scm-ui/src/repos/modules/repositoryTypes.test.js
+++ b/scm-ui/src/repos/modules/repositoryTypes.test.js
@@ -22,7 +22,7 @@ const git = {
displayName: "Git",
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/repositoryTypes/git"
+ href: "http://localhost:8081/api/v2/repositoryTypes/git"
}
}
};
@@ -32,7 +32,7 @@ const hg = {
displayName: "Mercurial",
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/repositoryTypes/hg"
+ href: "http://localhost:8081/api/v2/repositoryTypes/hg"
}
}
};
@@ -42,7 +42,7 @@ const svn = {
displayName: "Subversion",
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/repositoryTypes/svn"
+ href: "http://localhost:8081/api/v2/repositoryTypes/svn"
}
}
};
@@ -53,7 +53,7 @@ const collection = {
},
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/repositoryTypes"
+ href: "http://localhost:8081/api/v2/repositoryTypes"
}
}
};
@@ -97,7 +97,7 @@ describe("repository types caching", () => {
});
describe("repository types fetch", () => {
- const URL = "/api/rest/v2/repositoryTypes";
+ const URL = "/api/v2/repositoryTypes";
const mockStore = configureMockStore([thunk]);
afterEach(() => {
diff --git a/scm-ui/src/repos/permissions/components/CreatePermissionForm.js b/scm-ui/src/repos/permissions/components/CreatePermissionForm.js
new file mode 100644
index 0000000000..595c27d8ef
--- /dev/null
+++ b/scm-ui/src/repos/permissions/components/CreatePermissionForm.js
@@ -0,0 +1,122 @@
+// @flow
+import React from "react";
+import { translate } from "react-i18next";
+import { Checkbox, InputField, SubmitButton } from "@scm-manager/ui-components";
+import TypeSelector from "./TypeSelector";
+import type {
+ PermissionCollection,
+ PermissionEntry
+} from "@scm-manager/ui-types";
+import * as validator from "./permissionValidation";
+
+type Props = {
+ t: string => string,
+ createPermission: (permission: PermissionEntry) => void,
+ loading: boolean,
+ currentPermissions: PermissionCollection
+};
+
+type State = {
+ name: string,
+ type: string,
+ groupPermission: boolean,
+ valid: boolean
+};
+
+class CreatePermissionForm extends React.Component {
+ constructor(props: Props) {
+ super(props);
+
+ this.state = {
+ name: "",
+ type: "READ",
+ groupPermission: false,
+ valid: true
+ };
+ }
+
+ render() {
+ const { t, loading } = this.props;
+ const { name, type, groupPermission } = this.state;
+
+ return (
+
+
+ {t("permission.add-permission.add-permission-heading")}
+
+
+
+ );
+ }
+
+ submit = e => {
+ this.props.createPermission({
+ name: this.state.name,
+ type: this.state.type,
+ groupPermission: this.state.groupPermission
+ });
+ this.removeState();
+ e.preventDefault();
+ };
+
+ removeState = () => {
+ this.setState({
+ name: "",
+ type: "READ",
+ groupPermission: false,
+ valid: true
+ });
+ };
+
+ handleTypeChange = (type: string) => {
+ this.setState({
+ type: type
+ });
+ };
+
+ handleNameChange = (name: string) => {
+ this.setState({
+ name: name,
+ valid: validator.isPermissionValid(
+ name,
+ this.state.groupPermission,
+ this.props.currentPermissions
+ )
+ });
+ };
+ handleGroupPermissionChange = (groupPermission: boolean) => {
+ this.setState({
+ groupPermission: groupPermission,
+ valid: validator.isPermissionValid(
+ this.state.name,
+ groupPermission,
+ this.props.currentPermissions
+ )
+ });
+ };
+}
+
+export default translate("repos")(CreatePermissionForm);
diff --git a/scm-ui/src/repos/permissions/components/TypeSelector.js b/scm-ui/src/repos/permissions/components/TypeSelector.js
new file mode 100644
index 0000000000..9f94c11d54
--- /dev/null
+++ b/scm-ui/src/repos/permissions/components/TypeSelector.js
@@ -0,0 +1,40 @@
+// @flow
+import React from "react";
+import { translate } from "react-i18next";
+import {
+ Select
+} from "@scm-manager/ui-components";
+
+type Props = {
+ t: string => string,
+ handleTypeChange: string => void,
+ type: string,
+ loading?: boolean
+};
+
+class TypeSelector extends React.Component {
+ render() {
+ const { type, handleTypeChange, loading } = this.props;
+ const types = ["READ", "OWNER", "WRITE"];
+
+ return (
+
+ );
+ }
+
+ createSelectOptions(types: string[]) {
+ return types.map(type => {
+ return {
+ label: type,
+ value: type
+ };
+ });
+ }
+}
+
+export default translate("permissions")(TypeSelector);
diff --git a/scm-ui/src/repos/permissions/components/buttons/DeletePermissionButton.js b/scm-ui/src/repos/permissions/components/buttons/DeletePermissionButton.js
new file mode 100644
index 0000000000..a3ba8616c9
--- /dev/null
+++ b/scm-ui/src/repos/permissions/components/buttons/DeletePermissionButton.js
@@ -0,0 +1,73 @@
+// @flow
+import React from "react";
+import { translate } from "react-i18next";
+import type { Permission } from "@scm-manager/ui-types";
+import { confirmAlert, DeleteButton } from "@scm-manager/ui-components";
+
+type Props = {
+ permission: Permission,
+ namespace: string,
+ repoName: string,
+ confirmDialog?: boolean,
+ t: string => string,
+ deletePermission: (
+ permission: Permission,
+ namespace: string,
+ repoName: string
+ ) => void,
+ loading: boolean
+};
+
+class DeletePermissionButton extends React.Component {
+ static defaultProps = {
+ confirmDialog: true
+ };
+
+ deletePermission = () => {
+ this.props.deletePermission(
+ this.props.permission,
+ this.props.namespace,
+ this.props.repoName
+ );
+ };
+
+ confirmDelete = () => {
+ const { t } = this.props;
+ confirmAlert({
+ title: t("permission.delete-permission-button.confirm-alert.title"),
+ message: t("permission.delete-permission-button.confirm-alert.message"),
+ buttons: [
+ {
+ label: t("permission.delete-permission-button.confirm-alert.submit"),
+ onClick: () => this.deletePermission()
+ },
+ {
+ label: t("permission.delete-permission-button.confirm-alert.cancel"),
+ onClick: () => null
+ }
+ ]
+ });
+ };
+
+ isDeletable = () => {
+ return this.props.permission._links.delete;
+ };
+
+ render() {
+ const { confirmDialog, loading, t } = this.props;
+ const action = confirmDialog ? this.confirmDelete : this.deletePermission;
+
+ if (!this.isDeletable()) {
+ return null;
+ }
+ return (
+
+ );
+ }
+}
+
+export default translate("repos")(DeletePermissionButton);
diff --git a/scm-ui/src/repos/permissions/components/buttons/DeletePermissionButton.test.js b/scm-ui/src/repos/permissions/components/buttons/DeletePermissionButton.test.js
new file mode 100644
index 0000000000..811c9dc335
--- /dev/null
+++ b/scm-ui/src/repos/permissions/components/buttons/DeletePermissionButton.test.js
@@ -0,0 +1,98 @@
+import React from "react";
+import { mount, shallow } from "enzyme";
+import "../../../../tests/enzyme";
+import "../../../../tests/i18n";
+import DeletePermissionButton from "./DeletePermissionButton";
+
+import { confirmAlert } from "@scm-manager/ui-components";
+import ReactRouterEnzymeContext from "react-router-enzyme-context";
+jest.mock("@scm-manager/ui-components", () => ({
+ confirmAlert: jest.fn(),
+ DeleteButton: require.requireActual("@scm-manager/ui-components").DeleteButton
+}));
+
+describe("DeletePermissionButton", () => {
+ const options = new ReactRouterEnzymeContext();
+
+ it("should render nothing, if the delete link is missing", () => {
+ const permission = {
+ _links: {}
+ };
+
+ const navLink = shallow(
+ {}}
+ />,
+ options.get()
+ );
+ expect(navLink.text()).toBe("");
+ });
+
+ it("should render the navLink", () => {
+ const permission = {
+ _links: {
+ delete: {
+ href: "/permission"
+ }
+ }
+ };
+
+ const navLink = mount(
+ {}}
+ />,
+ options.get()
+ );
+ expect(navLink.text()).not.toBe("");
+ });
+
+ it("should open the confirm dialog on button click", () => {
+ const permission = {
+ _links: {
+ delete: {
+ href: "/permission"
+ }
+ }
+ };
+
+ const button = mount(
+ {}}
+ />,
+ options.get()
+ );
+ button.find("button").simulate("click");
+
+ expect(confirmAlert.mock.calls.length).toBe(1);
+ });
+
+ it("should call the delete permission function with delete url", () => {
+ const permission = {
+ _links: {
+ delete: {
+ href: "/permission"
+ }
+ }
+ };
+
+ let calledUrl = null;
+ function capture(permission) {
+ calledUrl = permission._links.delete.href;
+ }
+
+ const button = mount(
+ ,
+ options.get()
+ );
+ button.find("button").simulate("click");
+
+ expect(calledUrl).toBe("/permission");
+ });
+});
diff --git a/scm-ui/src/repos/permissions/components/permissionValidation.js b/scm-ui/src/repos/permissions/components/permissionValidation.js
new file mode 100644
index 0000000000..b74ae40988
--- /dev/null
+++ b/scm-ui/src/repos/permissions/components/permissionValidation.js
@@ -0,0 +1,23 @@
+// @flow
+import { validation } from "@scm-manager/ui-components";
+import type {
+ PermissionCollection,
+} from "@scm-manager/ui-types";
+const isNameValid = validation.isNameValid;
+
+export { isNameValid };
+
+export const isPermissionValid = (name: string, groupPermission: boolean, permissions: PermissionCollection) => {
+ return isNameValid(name) && !currentPermissionIncludeName(name, groupPermission, permissions);
+};
+
+const currentPermissionIncludeName = (name: string, groupPermission: boolean, permissions: PermissionCollection) => {
+ for (let i = 0; i < permissions.length; i++) {
+ if (
+ permissions[i].name === name &&
+ permissions[i].groupPermission == groupPermission
+ )
+ return true;
+ }
+ return false;
+};
diff --git a/scm-ui/src/repos/permissions/components/permissionValidation.test.js b/scm-ui/src/repos/permissions/components/permissionValidation.test.js
new file mode 100644
index 0000000000..036375a348
--- /dev/null
+++ b/scm-ui/src/repos/permissions/components/permissionValidation.test.js
@@ -0,0 +1,66 @@
+//@flow
+import * as validator from "./permissionValidation";
+
+describe("permission validation", () => {
+ it("should return true if permission is valid and does not exist", () => {
+ const permissions = [];
+ const name = "PermissionName";
+ const groupPermission = false;
+
+ expect(
+ validator.isPermissionValid(name, groupPermission, permissions)
+ ).toBe(true);
+ });
+
+ it("should return true if permission is valid and does not exists with same group permission", () => {
+ const permissions = [
+ {
+ name: "PermissionName",
+ groupPermission: true,
+ type: "READ"
+ }
+ ];
+ const name = "PermissionName";
+ const groupPermission = false;
+
+ expect(
+ validator.isPermissionValid(name, groupPermission, permissions)
+ ).toBe(true);
+ });
+
+ it("should return false if permission is valid but exists", () => {
+ const permissions = [
+ {
+ name: "PermissionName",
+ groupPermission: false,
+ type: "READ"
+ }
+ ];
+ const name = "PermissionName";
+ const groupPermission = false;
+
+ expect(
+ validator.isPermissionValid(name, groupPermission, permissions)
+ ).toBe(false);
+ });
+
+ it("should return false if permission does not exist but is invalid", () => {
+ const permissions = [];
+ const name = "@PermissionName";
+ const groupPermission = false;
+
+ expect(
+ validator.isPermissionValid(name, groupPermission, permissions)
+ ).toBe(false);
+ });
+
+ it("should return false if permission is not valid and does not exist", () => {
+ const permissions = [];
+ const name = "@PermissionName";
+ const groupPermission = false;
+
+ expect(
+ validator.isPermissionValid(name, groupPermission, permissions)
+ ).toBe(false);
+ });
+});
diff --git a/scm-ui/src/repos/permissions/containers/Permissions.js b/scm-ui/src/repos/permissions/containers/Permissions.js
new file mode 100644
index 0000000000..e70e02f443
--- /dev/null
+++ b/scm-ui/src/repos/permissions/containers/Permissions.js
@@ -0,0 +1,201 @@
+//@flow
+import React from "react";
+import { connect } from "react-redux";
+import { translate } from "react-i18next";
+import {
+ fetchPermissions,
+ getFetchPermissionsFailure,
+ isFetchPermissionsPending,
+ getPermissionsOfRepo,
+ hasCreatePermission,
+ createPermission,
+ isCreatePermissionPending,
+ getCreatePermissionFailure,
+ createPermissionReset,
+ getDeletePermissionsFailure,
+ getModifyPermissionsFailure,
+ modifyPermissionReset,
+ deletePermissionReset
+} from "../modules/permissions";
+import { Loading, ErrorPage } from "@scm-manager/ui-components";
+import type {
+ Permission,
+ PermissionCollection,
+ PermissionEntry
+} from "@scm-manager/ui-types";
+import SinglePermission from "./SinglePermission";
+import CreatePermissionForm from "../components/CreatePermissionForm";
+import type { History } from "history";
+
+type Props = {
+ namespace: string,
+ repoName: string,
+ loading: boolean,
+ error: Error,
+ permissions: PermissionCollection,
+ hasPermissionToCreate: boolean,
+ loadingCreatePermission: boolean,
+
+ //dispatch functions
+ fetchPermissions: (namespace: string, repoName: string) => void,
+ createPermission: (
+ permission: PermissionEntry,
+ namespace: string,
+ repoName: string,
+ callback?: () => void
+ ) => void,
+ createPermissionReset: (string, string) => void,
+ modifyPermissionReset: (string, string) => void,
+ deletePermissionReset: (string, string) => void,
+ // context props
+ t: string => string,
+ match: any,
+ history: History
+};
+
+class Permissions extends React.Component {
+ componentDidMount() {
+ const {
+ fetchPermissions,
+ namespace,
+ repoName,
+ modifyPermissionReset,
+ createPermissionReset,
+ deletePermissionReset
+ } = this.props;
+
+ createPermissionReset(namespace, repoName);
+ modifyPermissionReset(namespace, repoName);
+ deletePermissionReset(namespace, repoName);
+ fetchPermissions(namespace, repoName);
+ }
+
+ createPermission = (permission: Permission) => {
+ this.props.createPermission(
+ permission,
+ this.props.namespace,
+ this.props.repoName
+ );
+ };
+
+ render() {
+ const {
+ loading,
+ error,
+ permissions,
+ t,
+ namespace,
+ repoName,
+ loadingCreatePermission,
+ hasPermissionToCreate
+ } = this.props;
+ if (error) {
+ return (
+
+ );
+ }
+
+ if (loading || !permissions) {
+ return ;
+ }
+
+ const createPermissionForm = hasPermissionToCreate ? (
+ this.createPermission(permission)}
+ loading={loadingCreatePermission}
+ currentPermissions={permissions}
+ />
+ ) : null;
+
+ return (
+
+
+
+
+ | {t("permission.name")} |
+
+ {t("permission.group-permission")}
+ |
+ {t("permission.type")} |
+ |
+
+
+
+ {permissions.map(permission => {
+ return (
+
+ );
+ })}
+
+
+ {createPermissionForm}
+
+ );
+ }
+}
+
+const mapStateToProps = (state, ownProps) => {
+ const namespace = ownProps.namespace;
+ const repoName = ownProps.repoName;
+ const error =
+ getFetchPermissionsFailure(state, namespace, repoName) ||
+ getCreatePermissionFailure(state, namespace, repoName) ||
+ getDeletePermissionsFailure(state, namespace, repoName) ||
+ getModifyPermissionsFailure(state, namespace, repoName);
+ const loading = isFetchPermissionsPending(state, namespace, repoName);
+ const permissions = getPermissionsOfRepo(state, namespace, repoName);
+ const loadingCreatePermission = isCreatePermissionPending(
+ state,
+ namespace,
+ repoName
+ );
+ const hasPermissionToCreate = hasCreatePermission(state, namespace, repoName);
+ return {
+ namespace,
+ repoName,
+ error,
+ loading,
+ permissions,
+ hasPermissionToCreate,
+ loadingCreatePermission
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ fetchPermissions: (namespace: string, repoName: string) => {
+ dispatch(fetchPermissions(namespace, repoName));
+ },
+ createPermission: (
+ permission: PermissionEntry,
+ namespace: string,
+ repoName: string,
+ callback?: () => void
+ ) => {
+ dispatch(createPermission(permission, namespace, repoName, callback));
+ },
+ createPermissionReset: (namespace: string, repoName: string) => {
+ dispatch(createPermissionReset(namespace, repoName));
+ },
+ modifyPermissionReset: (namespace: string, repoName: string) => {
+ dispatch(modifyPermissionReset(namespace, repoName));
+ },
+ deletePermissionReset: (namespace: string, repoName: string) => {
+ dispatch(deletePermissionReset(namespace, repoName));
+ }
+ };
+};
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(translate("repos")(Permissions));
diff --git a/scm-ui/src/repos/permissions/containers/SinglePermission.js b/scm-ui/src/repos/permissions/containers/SinglePermission.js
new file mode 100644
index 0000000000..9426fbcd9f
--- /dev/null
+++ b/scm-ui/src/repos/permissions/containers/SinglePermission.js
@@ -0,0 +1,176 @@
+// @flow
+import React from "react";
+import type { Permission } from "@scm-manager/ui-types";
+import { translate } from "react-i18next";
+import {
+ modifyPermission,
+ isModifyPermissionPending,
+ deletePermission,
+ isDeletePermissionPending
+} from "../modules/permissions";
+import { connect } from "react-redux";
+import type { History } from "history";
+import { Checkbox } from "@scm-manager/ui-components";
+import DeletePermissionButton from "../components/buttons/DeletePermissionButton";
+import TypeSelector from "../components/TypeSelector";
+
+type Props = {
+ submitForm: Permission => void,
+ modifyPermission: (Permission, string, string) => void,
+ permission: Permission,
+ t: string => string,
+ namespace: string,
+ repoName: string,
+ match: any,
+ history: History,
+ loading: boolean,
+ deletePermission: (Permission, string, string) => void,
+ deleteLoading: boolean
+};
+
+type State = {
+ permission: Permission
+};
+
+class SinglePermission extends React.Component {
+ constructor(props: Props) {
+ super(props);
+
+ this.state = {
+ permission: {
+ name: "",
+ type: "READ",
+ groupPermission: false,
+ _links: {}
+ }
+ };
+ }
+
+ componentDidMount() {
+ const { permission } = this.props;
+ if (permission) {
+ this.setState({
+ permission: {
+ name: permission.name,
+ type: permission.type,
+ groupPermission: permission.groupPermission,
+ _links: permission._links
+ }
+ });
+ }
+ }
+
+ deletePermission = () => {
+ this.props.deletePermission(
+ this.props.permission,
+ this.props.namespace,
+ this.props.repoName
+ );
+ };
+
+ render() {
+ const { permission } = this.state;
+ const { loading, namespace, repoName } = this.props;
+ const typeSelector =
+ this.props.permission._links && this.props.permission._links.update ? (
+
+
+ |
+ ) : (
+ {permission.type} |
+ );
+
+ return (
+
+ | {permission.name} |
+
+
+ |
+ {typeSelector}
+
+
+ |
+
+ );
+ }
+
+ handleTypeChange = (type: string) => {
+ this.setState({
+ permission: {
+ ...this.state.permission,
+ type: type
+ }
+ });
+ this.modifyPermission(type);
+ };
+
+ modifyPermission = (type: string) => {
+ let permission = this.state.permission;
+ permission.type = type;
+ this.props.modifyPermission(
+ permission,
+ this.props.namespace,
+ this.props.repoName
+ );
+ };
+
+ createSelectOptions(types: string[]) {
+ return types.map(type => {
+ return {
+ label: type,
+ value: type
+ };
+ });
+ }
+}
+
+const mapStateToProps = (state, ownProps) => {
+ const permission = ownProps.permission;
+ const loading = isModifyPermissionPending(
+ state,
+ ownProps.namespace,
+ ownProps.repoName,
+ permission
+ );
+ const deleteLoading = isDeletePermissionPending(
+ state,
+ ownProps.namespace,
+ ownProps.repoName,
+ permission
+ );
+
+ return { loading, deleteLoading };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ modifyPermission: (
+ permission: Permission,
+ namespace: string,
+ repoName: string
+ ) => {
+ dispatch(modifyPermission(permission, namespace, repoName));
+ },
+ deletePermission: (
+ permission: Permission,
+ namespace: string,
+ repoName: string
+ ) => {
+ dispatch(deletePermission(permission, namespace, repoName));
+ }
+ };
+};
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(translate("repos")(SinglePermission));
diff --git a/scm-ui/src/repos/permissions/modules/permissions.js b/scm-ui/src/repos/permissions/modules/permissions.js
new file mode 100644
index 0000000000..86d78e7ae9
--- /dev/null
+++ b/scm-ui/src/repos/permissions/modules/permissions.js
@@ -0,0 +1,624 @@
+// @flow
+
+import { apiClient } from "@scm-manager/ui-components";
+import * as types from "../../../modules/types";
+import type { Action } from "@scm-manager/ui-components";
+import type {
+ PermissionCollection,
+ Permission,
+ PermissionEntry
+} from "@scm-manager/ui-types";
+import { isPending } from "../../../modules/pending";
+import { getFailure } from "../../../modules/failure";
+import { Dispatch } from "redux";
+
+export const FETCH_PERMISSIONS = "scm/permissions/FETCH_PERMISSIONS";
+export const FETCH_PERMISSIONS_PENDING = `${FETCH_PERMISSIONS}_${
+ types.PENDING_SUFFIX
+}`;
+export const FETCH_PERMISSIONS_SUCCESS = `${FETCH_PERMISSIONS}_${
+ types.SUCCESS_SUFFIX
+}`;
+export const FETCH_PERMISSIONS_FAILURE = `${FETCH_PERMISSIONS}_${
+ types.FAILURE_SUFFIX
+}`;
+export const MODIFY_PERMISSION = "scm/permissions/MODFIY_PERMISSION";
+export const MODIFY_PERMISSION_PENDING = `${MODIFY_PERMISSION}_${
+ types.PENDING_SUFFIX
+}`;
+export const MODIFY_PERMISSION_SUCCESS = `${MODIFY_PERMISSION}_${
+ types.SUCCESS_SUFFIX
+}`;
+export const MODIFY_PERMISSION_FAILURE = `${MODIFY_PERMISSION}_${
+ types.FAILURE_SUFFIX
+}`;
+export const MODIFY_PERMISSION_RESET = `${MODIFY_PERMISSION}_${
+ types.RESET_SUFFIX
+}`;
+export const CREATE_PERMISSION = "scm/permissions/CREATE_PERMISSION";
+export const CREATE_PERMISSION_PENDING = `${CREATE_PERMISSION}_${
+ types.PENDING_SUFFIX
+}`;
+export const CREATE_PERMISSION_SUCCESS = `${CREATE_PERMISSION}_${
+ types.SUCCESS_SUFFIX
+}`;
+export const CREATE_PERMISSION_FAILURE = `${CREATE_PERMISSION}_${
+ types.FAILURE_SUFFIX
+}`;
+export const CREATE_PERMISSION_RESET = `${CREATE_PERMISSION}_${
+ types.RESET_SUFFIX
+}`;
+export const DELETE_PERMISSION = "scm/permissions/DELETE_PERMISSION";
+export const DELETE_PERMISSION_PENDING = `${DELETE_PERMISSION}_${
+ types.PENDING_SUFFIX
+}`;
+export const DELETE_PERMISSION_SUCCESS = `${DELETE_PERMISSION}_${
+ types.SUCCESS_SUFFIX
+}`;
+export const DELETE_PERMISSION_FAILURE = `${DELETE_PERMISSION}_${
+ types.FAILURE_SUFFIX
+}`;
+export const DELETE_PERMISSION_RESET = `${DELETE_PERMISSION}_${
+ types.RESET_SUFFIX
+}`;
+
+const REPOS_URL = "repositories";
+const PERMISSIONS_URL = "permissions";
+const CONTENT_TYPE = "application/vnd.scmm-permission+json";
+
+// fetch permissions
+
+export function fetchPermissions(namespace: string, repoName: string) {
+ return function(dispatch: any) {
+ dispatch(fetchPermissionsPending(namespace, repoName));
+ return apiClient
+ .get(`${REPOS_URL}/${namespace}/${repoName}/${PERMISSIONS_URL}`)
+ .then(response => response.json())
+ .then(permissions => {
+ dispatch(fetchPermissionsSuccess(permissions, namespace, repoName));
+ })
+ .catch(err => {
+ dispatch(fetchPermissionsFailure(namespace, repoName, err));
+ });
+ };
+}
+
+export function fetchPermissionsPending(
+ namespace: string,
+ repoName: string
+): Action {
+ return {
+ type: FETCH_PERMISSIONS_PENDING,
+ payload: {
+ namespace,
+ repoName
+ },
+ itemId: namespace + "/" + repoName
+ };
+}
+
+export function fetchPermissionsSuccess(
+ permissions: any,
+ namespace: string,
+ repoName: string
+): Action {
+ return {
+ type: FETCH_PERMISSIONS_SUCCESS,
+ payload: permissions,
+ itemId: namespace + "/" + repoName
+ };
+}
+
+export function fetchPermissionsFailure(
+ namespace: string,
+ repoName: string,
+ error: Error
+): Action {
+ return {
+ type: FETCH_PERMISSIONS_FAILURE,
+ payload: {
+ namespace,
+ repoName,
+ error
+ },
+ itemId: namespace + "/" + repoName
+ };
+}
+
+// modify permission
+
+export function modifyPermission(
+ permission: Permission,
+ namespace: string,
+ repoName: string,
+ callback?: () => void
+) {
+ return function(dispatch: any) {
+ dispatch(modifyPermissionPending(permission, namespace, repoName));
+ return apiClient
+ .put(permission._links.update.href, permission, CONTENT_TYPE)
+ .then(() => {
+ dispatch(modifyPermissionSuccess(permission, namespace, repoName));
+ if (callback) {
+ callback();
+ }
+ })
+ .catch(cause => {
+ const error = new Error(
+ `failed to modify permission: ${cause.message}`
+ );
+ dispatch(
+ modifyPermissionFailure(permission, error, namespace, repoName)
+ );
+ });
+ };
+}
+
+export function modifyPermissionPending(
+ permission: Permission,
+ namespace: string,
+ repoName: string
+): Action {
+ return {
+ type: MODIFY_PERMISSION_PENDING,
+ payload: permission,
+ itemId: createItemId(permission, namespace, repoName)
+ };
+}
+
+export function modifyPermissionSuccess(
+ permission: Permission,
+ namespace: string,
+ repoName: string
+): Action {
+ return {
+ type: MODIFY_PERMISSION_SUCCESS,
+ payload: {
+ permission,
+ position: namespace + "/" + repoName
+ },
+ itemId: createItemId(permission, namespace, repoName)
+ };
+}
+
+export function modifyPermissionFailure(
+ permission: Permission,
+ error: Error,
+ namespace: string,
+ repoName: string
+): Action {
+ return {
+ type: MODIFY_PERMISSION_FAILURE,
+ payload: { error, permission },
+ itemId: createItemId(permission, namespace, repoName)
+ };
+}
+
+function newPermissions(
+ oldPermissions: PermissionCollection,
+ newPermission: Permission
+) {
+ for (let i = 0; i < oldPermissions.length; i++) {
+ if (oldPermissions[i].name === newPermission.name) {
+ oldPermissions.splice(i, 1, newPermission);
+ return oldPermissions;
+ }
+ }
+}
+
+export function modifyPermissionReset(namespace: string, repoName: string) {
+ return {
+ type: MODIFY_PERMISSION_RESET,
+ payload: {
+ namespace,
+ repoName
+ },
+ itemId: namespace + "/" + repoName
+ };
+}
+
+// create permission
+export function createPermission(
+ permission: PermissionEntry,
+ namespace: string,
+ repoName: string,
+ callback?: () => void
+) {
+ return function(dispatch: Dispatch) {
+ dispatch(createPermissionPending(permission, namespace, repoName));
+ return apiClient
+ .post(
+ `${REPOS_URL}/${namespace}/${repoName}/${PERMISSIONS_URL}`,
+ permission,
+ CONTENT_TYPE
+ )
+ .then(response => {
+ const location = response.headers.get("Location");
+ return apiClient.get(location);
+ })
+ .then(response => response.json())
+ .then(createdPermission => {
+ dispatch(
+ createPermissionSuccess(createdPermission, namespace, repoName)
+ );
+ if (callback) {
+ callback();
+ }
+ })
+ .catch(err =>
+ dispatch(
+ createPermissionFailure(
+ new Error(
+ `failed to add permission ${permission.name}: ${err.message}`
+ ),
+ namespace,
+ repoName
+ )
+ )
+ );
+ };
+}
+
+export function createPermissionPending(
+ permission: PermissionEntry,
+ namespace: string,
+ repoName: string
+): Action {
+ return {
+ type: CREATE_PERMISSION_PENDING,
+ payload: permission,
+ itemId: namespace + "/" + repoName
+ };
+}
+
+export function createPermissionSuccess(
+ permission: PermissionEntry,
+ namespace: string,
+ repoName: string
+): Action {
+ return {
+ type: CREATE_PERMISSION_SUCCESS,
+ payload: {
+ permission,
+ position: namespace + "/" + repoName
+ },
+ itemId: namespace + "/" + repoName
+ };
+}
+
+export function createPermissionFailure(
+ error: Error,
+ namespace: string,
+ repoName: string
+): Action {
+ return {
+ type: CREATE_PERMISSION_FAILURE,
+ payload: error,
+ itemId: namespace + "/" + repoName
+ };
+}
+
+export function createPermissionReset(namespace: string, repoName: string) {
+ return {
+ type: CREATE_PERMISSION_RESET,
+ itemId: namespace + "/" + repoName
+ };
+}
+
+// delete permission
+
+export function deletePermission(
+ permission: Permission,
+ namespace: string,
+ repoName: string,
+ callback?: () => void
+) {
+ return function(dispatch: any) {
+ dispatch(deletePermissionPending(permission, namespace, repoName));
+ return apiClient
+ .delete(permission._links.delete.href)
+ .then(() => {
+ dispatch(deletePermissionSuccess(permission, namespace, repoName));
+ if (callback) {
+ callback();
+ }
+ })
+ .catch(cause => {
+ const error = new Error(
+ `could not delete permission ${permission.name}: ${cause.message}`
+ );
+ dispatch(
+ deletePermissionFailure(permission, namespace, repoName, error)
+ );
+ });
+ };
+}
+
+export function deletePermissionPending(
+ permission: Permission,
+ namespace: string,
+ repoName: string
+): Action {
+ return {
+ type: DELETE_PERMISSION_PENDING,
+ payload: permission,
+ itemId: createItemId(permission, namespace, repoName)
+ };
+}
+
+export function deletePermissionSuccess(
+ permission: Permission,
+ namespace: string,
+ repoName: string
+): Action {
+ return {
+ type: DELETE_PERMISSION_SUCCESS,
+ payload: {
+ permission,
+ position: namespace + "/" + repoName
+ },
+ itemId: createItemId(permission, namespace, repoName)
+ };
+}
+
+export function deletePermissionFailure(
+ permission: Permission,
+ namespace: string,
+ repoName: string,
+ error: Error
+): Action {
+ return {
+ type: DELETE_PERMISSION_FAILURE,
+ payload: {
+ error,
+ permission
+ },
+ itemId: createItemId(permission, namespace, repoName)
+ };
+}
+
+export function deletePermissionReset(namespace: string, repoName: string) {
+ return {
+ type: DELETE_PERMISSION_RESET,
+ payload: {
+ namespace,
+ repoName
+ },
+ itemId: namespace + "/" + repoName
+ };
+}
+function deletePermissionFromState(
+ oldPermissions: PermissionCollection,
+ permission: Permission
+) {
+ let newPermission = [];
+ for (let i = 0; i < oldPermissions.length; i++) {
+ if (oldPermissions[i] !== permission) {
+ newPermission.push(oldPermissions[i]);
+ }
+ }
+ return newPermission;
+}
+
+function createItemId(
+ permission: Permission,
+ namespace: string,
+ repoName: string
+) {
+ let groupPermission = permission.groupPermission ? "@" : "";
+ return namespace + "/" + repoName + "/" + groupPermission + permission.name;
+}
+
+// reducer
+export default function reducer(
+ state: Object = {},
+ action: Action = { type: "UNKNOWN" }
+): Object {
+ if (!action.payload) {
+ return state;
+ }
+ switch (action.type) {
+ case FETCH_PERMISSIONS_SUCCESS:
+ return {
+ ...state,
+ [action.itemId]: {
+ entries: action.payload._embedded.permissions,
+ createPermission: action.payload._links.create ? true : false
+ }
+ };
+ case MODIFY_PERMISSION_SUCCESS:
+ const positionOfPermission = action.payload.position;
+ const newPermission = newPermissions(
+ state[action.payload.position].entries,
+ action.payload.permission
+ );
+ return {
+ ...state,
+ [positionOfPermission]: {
+ ...state[positionOfPermission],
+ entries: newPermission
+ }
+ };
+ case CREATE_PERMISSION_SUCCESS:
+ // return state;
+ const position = action.payload.position;
+ const permissions = state[action.payload.position].entries;
+ permissions.push(action.payload.permission);
+ return {
+ ...state,
+ [position]: {
+ ...state[position],
+ entries: permissions
+ }
+ };
+ case DELETE_PERMISSION_SUCCESS:
+ const permissionPosition = action.payload.position;
+ const new_Permissions = deletePermissionFromState(
+ state[action.payload.position].entries,
+ action.payload.permission
+ );
+ return {
+ ...state,
+ [permissionPosition]: {
+ ...state[permissionPosition],
+ entries: new_Permissions
+ }
+ };
+ default:
+ return state;
+ }
+}
+
+// selectors
+
+export function getPermissionsOfRepo(
+ state: Object,
+ namespace: string,
+ repoName: string
+) {
+ if (state.permissions && state.permissions[namespace + "/" + repoName]) {
+ const permissions = state.permissions[namespace + "/" + repoName].entries;
+ return permissions;
+ }
+}
+
+export function isFetchPermissionsPending(
+ state: Object,
+ namespace: string,
+ repoName: string
+) {
+ return isPending(state, FETCH_PERMISSIONS, namespace + "/" + repoName);
+}
+
+export function getFetchPermissionsFailure(
+ state: Object,
+ namespace: string,
+ repoName: string
+) {
+ return getFailure(state, FETCH_PERMISSIONS, namespace + "/" + repoName);
+}
+
+export function isModifyPermissionPending(
+ state: Object,
+ namespace: string,
+ repoName: string,
+ permission: Permission
+) {
+ return isPending(
+ state,
+ MODIFY_PERMISSION,
+ createItemId(permission, namespace, repoName)
+ );
+}
+
+export function getModifyPermissionFailure(
+ state: Object,
+ namespace: string,
+ repoName: string,
+ permission: Permission
+) {
+ return getFailure(
+ state,
+ MODIFY_PERMISSION,
+ createItemId(permission, namespace, repoName)
+ );
+}
+
+export function hasCreatePermission(
+ state: Object,
+ namespace: string,
+ repoName: string
+) {
+ if (state.permissions && state.permissions[namespace + "/" + repoName])
+ return state.permissions[namespace + "/" + repoName].createPermission;
+ else return null;
+}
+
+export function isCreatePermissionPending(
+ state: Object,
+ namespace: string,
+ repoName: string
+) {
+ return isPending(state, CREATE_PERMISSION, namespace + "/" + repoName);
+}
+export function getCreatePermissionFailure(
+ state: Object,
+ namespace: string,
+ repoName: string
+) {
+ return getFailure(state, CREATE_PERMISSION, namespace + "/" + repoName);
+}
+
+export function isDeletePermissionPending(
+ state: Object,
+ namespace: string,
+ repoName: string,
+ permission: Permission
+) {
+ return isPending(
+ state,
+ DELETE_PERMISSION,
+ createItemId(permission, namespace, repoName)
+ );
+}
+
+export function getDeletePermissionFailure(
+ state: Object,
+ namespace: string,
+ repoName: string,
+ permission: Permission
+) {
+ return getFailure(
+ state,
+ DELETE_PERMISSION,
+ createItemId(permission, namespace, repoName)
+ );
+}
+
+export function getDeletePermissionsFailure(
+ state: Object,
+ namespace: string,
+ repoName: string
+) {
+ const permissions =
+ state.permissions && state.permissions[namespace + "/" + repoName]
+ ? state.permissions[namespace + "/" + repoName].entries
+ : null;
+ if (permissions == null) return undefined;
+ for (let i = 0; i < permissions.length; i++) {
+ if (
+ getDeletePermissionFailure(state, namespace, repoName, permissions[i])
+ ) {
+ return getFailure(
+ state,
+ DELETE_PERMISSION,
+ createItemId(permissions[i], namespace, repoName)
+ );
+ }
+ }
+ return null;
+}
+
+export function getModifyPermissionsFailure(
+ state: Object,
+ namespace: string,
+ repoName: string
+) {
+ const permissions =
+ state.permissions && state.permissions[namespace + "/" + repoName]
+ ? state.permissions[namespace + "/" + repoName].entries
+ : null;
+ if (permissions == null) return undefined;
+ for (let i = 0; i < permissions.length; i++) {
+ if (
+ getModifyPermissionFailure(state, namespace, repoName, permissions[i])
+ ) {
+ return getFailure(
+ state,
+ MODIFY_PERMISSION,
+ createItemId(permissions[i], namespace, repoName)
+ );
+ }
+ }
+ return null;
+}
diff --git a/scm-ui/src/repos/permissions/modules/permissions.test.js b/scm-ui/src/repos/permissions/modules/permissions.test.js
new file mode 100644
index 0000000000..e546f6cb00
--- /dev/null
+++ b/scm-ui/src/repos/permissions/modules/permissions.test.js
@@ -0,0 +1,769 @@
+// @flow
+import configureMockStore from "redux-mock-store";
+import thunk from "redux-thunk";
+import fetchMock from "fetch-mock";
+import reducer, {
+ fetchPermissions,
+ fetchPermissionsSuccess,
+ getPermissionsOfRepo,
+ isFetchPermissionsPending,
+ getFetchPermissionsFailure,
+ modifyPermission,
+ modifyPermissionSuccess,
+ getModifyPermissionFailure,
+ isModifyPermissionPending,
+ createPermission,
+ hasCreatePermission,
+ deletePermission,
+ deletePermissionSuccess,
+ getDeletePermissionFailure,
+ isDeletePermissionPending,
+ getModifyPermissionsFailure,
+ MODIFY_PERMISSION_FAILURE,
+ MODIFY_PERMISSION_PENDING,
+ FETCH_PERMISSIONS,
+ FETCH_PERMISSIONS_PENDING,
+ FETCH_PERMISSIONS_SUCCESS,
+ FETCH_PERMISSIONS_FAILURE,
+ MODIFY_PERMISSION_SUCCESS,
+ MODIFY_PERMISSION,
+ CREATE_PERMISSION_PENDING,
+ CREATE_PERMISSION_SUCCESS,
+ CREATE_PERMISSION_FAILURE,
+ DELETE_PERMISSION,
+ DELETE_PERMISSION_PENDING,
+ DELETE_PERMISSION_SUCCESS,
+ DELETE_PERMISSION_FAILURE,
+ CREATE_PERMISSION,
+ createPermissionSuccess,
+ getCreatePermissionFailure,
+ isCreatePermissionPending,
+ getDeletePermissionsFailure
+} from "./permissions";
+import type { Permission, PermissionCollection } from "@scm-manager/ui-types";
+
+const hitchhiker_puzzle42Permission_user_eins: Permission = {
+ name: "user_eins",
+ type: "READ",
+ groupPermission: false,
+ _links: {
+ self: {
+ href:
+ "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
+ },
+ delete: {
+ href:
+ "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
+ },
+ update: {
+ href:
+ "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
+ }
+ }
+};
+
+const hitchhiker_puzzle42Permission_user_zwei: Permission = {
+ name: "user_zwei",
+ type: "WRITE",
+ groupPermission: true,
+ _links: {
+ self: {
+ href:
+ "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
+ },
+ delete: {
+ href:
+ "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
+ },
+ update: {
+ href:
+ "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
+ }
+ }
+};
+
+const hitchhiker_puzzle42Permissions: PermissionCollection = [
+ hitchhiker_puzzle42Permission_user_eins,
+ hitchhiker_puzzle42Permission_user_zwei
+];
+
+const hitchhiker_puzzle42RepoPermissions = {
+ _embedded: {
+ permissions: hitchhiker_puzzle42Permissions
+ },
+ _links: {
+ create: {
+ href:
+ "http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions"
+ }
+ }
+};
+
+describe("permission fetch", () => {
+ const REPOS_URL = "/api/v2/repositories";
+ const mockStore = configureMockStore([thunk]);
+
+ afterEach(() => {
+ fetchMock.reset();
+ fetchMock.restore();
+ });
+
+ it("should successfully fetch permissions to repo hitchhiker/puzzle42", () => {
+ fetchMock.getOnce(
+ REPOS_URL + "/hitchhiker/puzzle42/permissions",
+ hitchhiker_puzzle42RepoPermissions
+ );
+
+ const expectedActions = [
+ {
+ type: FETCH_PERMISSIONS_PENDING,
+ payload: {
+ namespace: "hitchhiker",
+ repoName: "puzzle42"
+ },
+ itemId: "hitchhiker/puzzle42"
+ },
+ {
+ type: FETCH_PERMISSIONS_SUCCESS,
+ payload: hitchhiker_puzzle42RepoPermissions,
+ itemId: "hitchhiker/puzzle42"
+ }
+ ];
+
+ const store = mockStore({});
+ return store
+ .dispatch(fetchPermissions("hitchhiker", "puzzle42"))
+ .then(() => {
+ expect(store.getActions()).toEqual(expectedActions);
+ });
+ });
+
+ it("should dispatch FETCH_PERMISSIONS_FAILURE, it the request fails", () => {
+ fetchMock.getOnce(REPOS_URL + "/hitchhiker/puzzle42/permissions", {
+ status: 500
+ });
+
+ const store = mockStore({});
+ return store
+ .dispatch(fetchPermissions("hitchhiker", "puzzle42"))
+ .then(() => {
+ const actions = store.getActions();
+ expect(actions[0].type).toEqual(FETCH_PERMISSIONS_PENDING);
+ expect(actions[1].type).toEqual(FETCH_PERMISSIONS_FAILURE);
+ expect(actions[1].payload).toBeDefined();
+ });
+ });
+
+ it("should successfully modify user_eins permission", () => {
+ fetchMock.putOnce(
+ hitchhiker_puzzle42Permission_user_eins._links.update.href,
+ {
+ status: 204
+ }
+ );
+
+ let editedPermission = { ...hitchhiker_puzzle42Permission_user_eins };
+ editedPermission.type = "OWNER";
+
+ const store = mockStore({});
+
+ return store
+ .dispatch(modifyPermission(editedPermission, "hitchhiker", "puzzle42"))
+ .then(() => {
+ const actions = store.getActions();
+ expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
+ expect(actions[1].type).toEqual(MODIFY_PERMISSION_SUCCESS);
+ });
+ });
+
+ it("should successfully modify user_eins permission and call the callback", () => {
+ fetchMock.putOnce(
+ hitchhiker_puzzle42Permission_user_eins._links.update.href,
+ {
+ status: 204
+ }
+ );
+
+ let editedPermission = { ...hitchhiker_puzzle42Permission_user_eins };
+ editedPermission.type = "OWNER";
+
+ const store = mockStore({});
+
+ let called = false;
+ const callback = () => {
+ called = true;
+ };
+
+ return store
+ .dispatch(
+ modifyPermission(editedPermission, "hitchhiker", "puzzle42", callback)
+ )
+ .then(() => {
+ const actions = store.getActions();
+ expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
+ expect(actions[1].type).toEqual(MODIFY_PERMISSION_SUCCESS);
+ expect(called).toBe(true);
+ });
+ });
+
+ it("should fail modifying on HTTP 500", () => {
+ fetchMock.putOnce(
+ hitchhiker_puzzle42Permission_user_eins._links.update.href,
+ {
+ status: 500
+ }
+ );
+
+ let editedPermission = { ...hitchhiker_puzzle42Permission_user_eins };
+ editedPermission.type = "OWNER";
+
+ const store = mockStore({});
+
+ return store
+ .dispatch(modifyPermission(editedPermission, "hitchhiker", "puzzle42"))
+ .then(() => {
+ const actions = store.getActions();
+ expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
+ expect(actions[1].type).toEqual(MODIFY_PERMISSION_FAILURE);
+ expect(actions[1].payload).toBeDefined();
+ });
+ });
+
+ it("should add a permission successfully", () => {
+ // unmatched
+ fetchMock.postOnce(REPOS_URL + "/hitchhiker/puzzle42/permissions", {
+ status: 204,
+ headers: {
+ location: "repositories/hitchhiker/puzzle42/permissions/user_eins"
+ }
+ });
+
+ fetchMock.getOnce(
+ REPOS_URL + "/hitchhiker/puzzle42/permissions/user_eins",
+ hitchhiker_puzzle42Permission_user_eins
+ );
+
+ const store = mockStore({});
+ return store
+ .dispatch(
+ createPermission(
+ hitchhiker_puzzle42Permission_user_eins,
+ "hitchhiker",
+ "puzzle42"
+ )
+ )
+ .then(() => {
+ const actions = store.getActions();
+ expect(actions[0].type).toEqual(CREATE_PERMISSION_PENDING);
+ expect(actions[1].type).toEqual(CREATE_PERMISSION_SUCCESS);
+ });
+ });
+
+ it("should fail adding a permission on HTTP 500", () => {
+ fetchMock.postOnce(REPOS_URL + "/hitchhiker/puzzle42/permissions", {
+ status: 500
+ });
+
+ const store = mockStore({});
+ return store
+ .dispatch(
+ createPermission(
+ hitchhiker_puzzle42Permission_user_eins,
+ "hitchhiker",
+ "puzzle42"
+ )
+ )
+ .then(() => {
+ const actions = store.getActions();
+ expect(actions[0].type).toEqual(CREATE_PERMISSION_PENDING);
+ expect(actions[1].type).toEqual(CREATE_PERMISSION_FAILURE);
+ expect(actions[1].payload).toBeDefined();
+ });
+ });
+
+ it("should call the callback after permission successfully created", () => {
+ // unmatched
+ fetchMock.postOnce(REPOS_URL + "/hitchhiker/puzzle42/permissions", {
+ status: 204,
+ headers: {
+ location: "repositories/hitchhiker/puzzle42/permissions/user_eins"
+ }
+ });
+
+ fetchMock.getOnce(
+ REPOS_URL + "/hitchhiker/puzzle42/permissions/user_eins",
+ hitchhiker_puzzle42Permission_user_eins
+ );
+ let callMe = "not yet";
+
+ const callback = () => {
+ callMe = "yeah";
+ };
+
+ const store = mockStore({});
+ return store
+ .dispatch(
+ createPermission(
+ hitchhiker_puzzle42Permission_user_eins,
+ "hitchhiker",
+ "puzzle42",
+ callback
+ )
+ )
+ .then(() => {
+ expect(callMe).toBe("yeah");
+ });
+ });
+ it("should delete successfully permission user_eins", () => {
+ fetchMock.deleteOnce(
+ hitchhiker_puzzle42Permission_user_eins._links.delete.href,
+ {
+ status: 204
+ }
+ );
+
+ const store = mockStore({});
+ return store
+ .dispatch(
+ deletePermission(
+ hitchhiker_puzzle42Permission_user_eins,
+ "hitchhiker",
+ "puzzle42"
+ )
+ )
+ .then(() => {
+ const actions = store.getActions();
+ expect(actions.length).toBe(2);
+ expect(actions[0].type).toEqual(DELETE_PERMISSION_PENDING);
+ expect(actions[0].payload).toBe(
+ hitchhiker_puzzle42Permission_user_eins
+ );
+ expect(actions[1].type).toEqual(DELETE_PERMISSION_SUCCESS);
+ });
+ });
+
+ it("should call the callback, after successful delete", () => {
+ fetchMock.deleteOnce(
+ hitchhiker_puzzle42Permission_user_eins._links.delete.href,
+ {
+ status: 204
+ }
+ );
+
+ let called = false;
+ const callMe = () => {
+ called = true;
+ };
+
+ const store = mockStore({});
+ return store
+ .dispatch(
+ deletePermission(
+ hitchhiker_puzzle42Permission_user_eins,
+ "hitchhiker",
+ "puzzle42",
+ callMe
+ )
+ )
+ .then(() => {
+ expect(called).toBeTruthy();
+ });
+ });
+
+ it("should fail to delete permission", () => {
+ fetchMock.deleteOnce(
+ hitchhiker_puzzle42Permission_user_eins._links.delete.href,
+ {
+ status: 500
+ }
+ );
+
+ const store = mockStore({});
+ return store
+ .dispatch(
+ deletePermission(
+ hitchhiker_puzzle42Permission_user_eins,
+ "hitchhiker",
+ "puzzle42"
+ )
+ )
+ .then(() => {
+ const actions = store.getActions();
+ expect(actions[0].type).toEqual(DELETE_PERMISSION_PENDING);
+ expect(actions[0].payload).toBe(
+ hitchhiker_puzzle42Permission_user_eins
+ );
+ expect(actions[1].type).toEqual(DELETE_PERMISSION_FAILURE);
+ expect(actions[1].payload).toBeDefined();
+ });
+ });
+});
+
+describe("permissions reducer", () => {
+ it("should return empty object, if state and action is undefined", () => {
+ expect(reducer()).toEqual({});
+ });
+
+ it("should return the same state, if the action is undefined", () => {
+ const state = { x: true };
+ expect(reducer(state)).toBe(state);
+ });
+
+ it("should return the same state, if the action is unknown to the reducer", () => {
+ const state = { x: true };
+ expect(reducer(state, { type: "EL_SPECIALE" })).toBe(state);
+ });
+
+ it("should store the permissions on FETCH_PERMISSION_SUCCESS", () => {
+ const newState = reducer(
+ {},
+ fetchPermissionsSuccess(
+ hitchhiker_puzzle42RepoPermissions,
+ "hitchhiker",
+ "puzzle42"
+ )
+ );
+
+ expect(newState["hitchhiker/puzzle42"].entries).toBe(
+ hitchhiker_puzzle42Permissions
+ );
+ });
+
+ it("should update permission", () => {
+ const oldState = {
+ "hitchhiker/puzzle42": {
+ entries: [hitchhiker_puzzle42Permission_user_eins]
+ }
+ };
+ let permissionEdited = { ...hitchhiker_puzzle42Permission_user_eins };
+ permissionEdited.type = "OWNER";
+ let expectedState = {
+ "hitchhiker/puzzle42": {
+ entries: [permissionEdited]
+ }
+ };
+ const newState = reducer(
+ oldState,
+ modifyPermissionSuccess(permissionEdited, "hitchhiker", "puzzle42")
+ );
+ expect(newState["hitchhiker/puzzle42"]).toEqual(
+ expectedState["hitchhiker/puzzle42"]
+ );
+ });
+
+ it("should remove permission from state when delete succeeds", () => {
+ const state = {
+ "hitchhiker/puzzle42": {
+ entries: [
+ hitchhiker_puzzle42Permission_user_eins,
+ hitchhiker_puzzle42Permission_user_zwei
+ ]
+ }
+ };
+
+ const expectedState = {
+ "hitchhiker/puzzle42": {
+ entries: [hitchhiker_puzzle42Permission_user_zwei]
+ }
+ };
+
+ const newState = reducer(
+ state,
+ deletePermissionSuccess(
+ hitchhiker_puzzle42Permission_user_eins,
+ "hitchhiker",
+ "puzzle42"
+ )
+ );
+ expect(newState["hitchhiker/puzzle42"]).toEqual(
+ expectedState["hitchhiker/puzzle42"]
+ );
+ });
+
+ it("should add permission", () => {
+ //changing state had to be removed because of errors
+ const oldState = {
+ "hitchhiker/puzzle42": {
+ entries: [hitchhiker_puzzle42Permission_user_eins]
+ }
+ };
+ let expectedState = {
+ "hitchhiker/puzzle42": {
+ entries: [
+ hitchhiker_puzzle42Permission_user_eins,
+ hitchhiker_puzzle42Permission_user_zwei
+ ]
+ }
+ };
+ const newState = reducer(
+ oldState,
+ createPermissionSuccess(
+ hitchhiker_puzzle42Permission_user_zwei,
+ "hitchhiker",
+ "puzzle42"
+ )
+ );
+ expect(newState["hitchhiker/puzzle42"]).toEqual(
+ expectedState["hitchhiker/puzzle42"]
+ );
+ });
+});
+
+describe("permissions selectors", () => {
+ const error = new Error("something goes wrong");
+
+ it("should return the permissions of one repository", () => {
+ const state = {
+ permissions: {
+ "hitchhiker/puzzle42": {
+ entries: hitchhiker_puzzle42Permissions
+ }
+ }
+ };
+
+ const repoPermissions = getPermissionsOfRepo(
+ state,
+ "hitchhiker",
+ "puzzle42"
+ );
+ expect(repoPermissions).toEqual(hitchhiker_puzzle42Permissions);
+ });
+
+ it("should return true, when fetch permissions is pending", () => {
+ const state = {
+ pending: {
+ [FETCH_PERMISSIONS + "/hitchhiker/puzzle42"]: true
+ }
+ };
+ expect(isFetchPermissionsPending(state, "hitchhiker", "puzzle42")).toEqual(
+ true
+ );
+ });
+
+ it("should return false, when fetch permissions is not pending", () => {
+ expect(isFetchPermissionsPending({}, "hitchiker", "puzzle42")).toEqual(
+ false
+ );
+ });
+
+ it("should return error when fetch permissions did fail", () => {
+ const state = {
+ failure: {
+ [FETCH_PERMISSIONS + "/hitchhiker/puzzle42"]: error
+ }
+ };
+ expect(getFetchPermissionsFailure(state, "hitchhiker", "puzzle42")).toEqual(
+ error
+ );
+ });
+
+ it("should return undefined when fetch permissions did not fail", () => {
+ expect(getFetchPermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(
+ undefined
+ );
+ });
+
+ it("should return true, when modify permission is pending", () => {
+ const state = {
+ pending: {
+ [MODIFY_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: true
+ }
+ };
+ expect(
+ isModifyPermissionPending(
+ state,
+ "hitchhiker",
+ "puzzle42",
+ hitchhiker_puzzle42Permission_user_eins
+ )
+ ).toEqual(true);
+ });
+
+ it("should return false, when modify permission is not pending", () => {
+ expect(
+ isModifyPermissionPending(
+ {},
+ "hitchiker",
+ "puzzle42",
+ hitchhiker_puzzle42Permission_user_eins
+ )
+ ).toEqual(false);
+ });
+
+ it("should return error when modify permission did fail", () => {
+ const state = {
+ failure: {
+ [MODIFY_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: error
+ }
+ };
+ expect(
+ getModifyPermissionFailure(
+ state,
+ "hitchhiker",
+ "puzzle42",
+ hitchhiker_puzzle42Permission_user_eins
+ )
+ ).toEqual(error);
+ });
+
+ it("should return undefined when modify permission did not fail", () => {
+ expect(
+ getModifyPermissionFailure(
+ {},
+ "hitchhiker",
+ "puzzle42",
+ hitchhiker_puzzle42Permission_user_eins
+ )
+ ).toBe(undefined);
+ });
+
+ it("should return error when one of the modify permissions did fail", () => {
+ const state = {
+ permissions: {
+ "hitchhiker/puzzle42": { entries: hitchhiker_puzzle42Permissions }
+ },
+ failure: {
+ [MODIFY_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: error
+ }
+ };
+ expect(
+ getModifyPermissionsFailure(state, "hitchhiker", "puzzle42")
+ ).toEqual(error);
+ });
+
+ it("should return undefined when no modify permissions did not fail", () => {
+ expect(getModifyPermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(
+ undefined
+ );
+ });
+
+ it("should return true, when createPermission is true", () => {
+ const state = {
+ permissions: {
+ ["hitchhiker/puzzle42"]: {
+ createPermission: true
+ }
+ }
+ };
+ expect(hasCreatePermission(state, "hitchhiker", "puzzle42")).toBe(true);
+ });
+
+ it("should return false, when createPermission is false", () => {
+ const state = {
+ permissions: {
+ ["hitchhiker/puzzle42"]: {
+ createPermission: false
+ }
+ }
+ };
+ expect(hasCreatePermission(state, "hitchhiker", "puzzle42")).toEqual(false);
+ });
+
+ it("should return true, when delete permission is pending", () => {
+ const state = {
+ pending: {
+ [DELETE_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: true
+ }
+ };
+ expect(
+ isDeletePermissionPending(
+ state,
+ "hitchhiker",
+ "puzzle42",
+ hitchhiker_puzzle42Permission_user_eins
+ )
+ ).toEqual(true);
+ });
+
+ it("should return false, when delete permission is not pending", () => {
+ expect(
+ isDeletePermissionPending(
+ {},
+ "hitchiker",
+ "puzzle42",
+ hitchhiker_puzzle42Permission_user_eins
+ )
+ ).toEqual(false);
+ });
+
+ it("should return error when delete permission did fail", () => {
+ const state = {
+ failure: {
+ [DELETE_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: error
+ }
+ };
+ expect(
+ getDeletePermissionFailure(
+ state,
+ "hitchhiker",
+ "puzzle42",
+ hitchhiker_puzzle42Permission_user_eins
+ )
+ ).toEqual(error);
+ });
+
+ it("should return undefined when delete permission did not fail", () => {
+ expect(
+ getDeletePermissionFailure(
+ {},
+ "hitchhiker",
+ "puzzle42",
+ hitchhiker_puzzle42Permission_user_eins
+ )
+ ).toBe(undefined);
+ });
+
+ it("should return error when one of the delete permissions did fail", () => {
+ const state = {
+ permissions: {
+ "hitchhiker/puzzle42": { entries: hitchhiker_puzzle42Permissions }
+ },
+ failure: {
+ [DELETE_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: error
+ }
+ };
+ expect(
+ getDeletePermissionsFailure(state, "hitchhiker", "puzzle42")
+ ).toEqual(error);
+ });
+
+ it("should return undefined when no delete permissions did not fail", () => {
+ expect(getDeletePermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(
+ undefined
+ );
+ });
+
+ it("should return true, when create permission is pending", () => {
+ const state = {
+ pending: {
+ [CREATE_PERMISSION + "/hitchhiker/puzzle42"]: true
+ }
+ };
+ expect(isCreatePermissionPending(state, "hitchhiker", "puzzle42")).toEqual(
+ true
+ );
+ });
+
+ it("should return false, when create permissions is not pending", () => {
+ expect(isCreatePermissionPending({}, "hitchiker", "puzzle42")).toEqual(
+ false
+ );
+ });
+
+ it("should return error when create permissions did fail", () => {
+ const state = {
+ failure: {
+ [CREATE_PERMISSION + "/hitchhiker/puzzle42"]: error
+ }
+ };
+ expect(getCreatePermissionFailure(state, "hitchhiker", "puzzle42")).toEqual(
+ error
+ );
+ });
+
+ it("should return undefined when create permissions did not fail", () => {
+ expect(getCreatePermissionFailure({}, "hitchhiker", "puzzle42")).toBe(
+ undefined
+ );
+ });
+});
diff --git a/scm-ui/src/users/components/UserForm.js b/scm-ui/src/users/components/UserForm.js
index 3e33dcffea..80ade5e070 100644
--- a/scm-ui/src/users/components/UserForm.js
+++ b/scm-ui/src/users/components/UserForm.js
@@ -97,6 +97,7 @@ class UserForm extends React.Component {
value={user ? user.name : ""}
validationError={this.state.nameValidationError}
errorMessage={t("validation.name-invalid")}
+ helpText={t("help.usernameHelpText")}
/>
);
}
@@ -109,6 +110,7 @@ class UserForm extends React.Component {
value={user ? user.displayName : ""}
validationError={this.state.displayNameValidationError}
errorMessage={t("validation.displayname-invalid")}
+ helpText={t("help.displayNameHelpText")}
/>
{
value={user ? user.mail : ""}
validationError={this.state.mailValidationError}
errorMessage={t("validation.mail-invalid")}
+ helpText={t("help.mailHelpText")}
/>
{
value={user ? user.password : ""}
validationError={this.state.validatePasswordError}
errorMessage={t("validation.password-invalid")}
+ helpText={t("help.passwordHelpText")}
/>
{
value={this.state ? this.state.validatePassword : ""}
validationError={this.state.passwordValidationError}
errorMessage={t("validation.passwordValidation-invalid")}
+ helpText={t("help.passwordConfirmHelpText")}
/>
{
return false;
};
export const isPasswordValid = (password: string) => {
- return password.length > 6 && password.length < 32;
+ return password.length >= 6 && password.length < 32;
};
diff --git a/scm-ui/src/users/modules/users.test.js b/scm-ui/src/users/modules/users.test.js
index c8c56f2ef5..c61d288c94 100644
--- a/scm-ui/src/users/modules/users.test.js
+++ b/scm-ui/src/users/modules/users.test.js
@@ -61,13 +61,13 @@ const userZaphod = {
properties: {},
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/users/zaphod"
+ href: "http://localhost:8081/api/v2/users/zaphod"
},
delete: {
- href: "http://localhost:8081/api/rest/v2/users/zaphod"
+ href: "http://localhost:8081/api/v2/users/zaphod"
},
update: {
- href: "http://localhost:8081/api/rest/v2/users/zaphod"
+ href: "http://localhost:8081/api/v2/users/zaphod"
}
}
};
@@ -84,13 +84,13 @@ const userFord = {
properties: {},
_links: {
self: {
- href: "http://localhost:8081/api/rest/v2/users/ford"
+ href: "http://localhost:8081/api/v2/users/ford"
},
delete: {
- href: "http://localhost:8081/api/rest/v2/users/ford"
+ href: "http://localhost:8081/api/v2/users/ford"
},
update: {
- href: "http://localhost:8081/api/rest/v2/users/ford"
+ href: "http://localhost:8081/api/v2/users/ford"
}
}
};
@@ -100,16 +100,16 @@ const responseBody = {
pageTotal: 1,
_links: {
self: {
- href: "http://localhost:3000/api/rest/v2/users/?page=0&pageSize=10"
+ href: "http://localhost:3000/api/v2/users/?page=0&pageSize=10"
},
first: {
- href: "http://localhost:3000/api/rest/v2/users/?page=0&pageSize=10"
+ href: "http://localhost:3000/api/v2/users/?page=0&pageSize=10"
},
last: {
- href: "http://localhost:3000/api/rest/v2/users/?page=0&pageSize=10"
+ href: "http://localhost:3000/api/v2/users/?page=0&pageSize=10"
},
create: {
- href: "http://localhost:3000/api/rest/v2/users/"
+ href: "http://localhost:3000/api/v2/users/"
}
},
_embedded: {
@@ -122,7 +122,7 @@ const response = {
responseBody
};
-const USERS_URL = "/api/rest/v2/users";
+const USERS_URL = "/api/v2/users";
const error = new Error("KAPUTT");
@@ -241,7 +241,7 @@ describe("users fetch()", () => {
});
it("successfully update user", () => {
- fetchMock.putOnce("http://localhost:8081/api/rest/v2/users/zaphod", {
+ fetchMock.putOnce("http://localhost:8081/api/v2/users/zaphod", {
status: 204
});
@@ -255,7 +255,7 @@ describe("users fetch()", () => {
});
it("should call callback, after successful modified user", () => {
- fetchMock.putOnce("http://localhost:8081/api/rest/v2/users/zaphod", {
+ fetchMock.putOnce("http://localhost:8081/api/v2/users/zaphod", {
status: 204
});
@@ -271,7 +271,7 @@ describe("users fetch()", () => {
});
it("should fail updating user on HTTP 500", () => {
- fetchMock.putOnce("http://localhost:8081/api/rest/v2/users/zaphod", {
+ fetchMock.putOnce("http://localhost:8081/api/v2/users/zaphod", {
status: 500
});
@@ -285,7 +285,7 @@ describe("users fetch()", () => {
});
it("should delete successfully user zaphod", () => {
- fetchMock.deleteOnce("http://localhost:8081/api/rest/v2/users/zaphod", {
+ fetchMock.deleteOnce("http://localhost:8081/api/v2/users/zaphod", {
status: 204
});
@@ -300,7 +300,7 @@ describe("users fetch()", () => {
});
it("should call the callback, after successful delete", () => {
- fetchMock.deleteOnce("http://localhost:8081/api/rest/v2/users/zaphod", {
+ fetchMock.deleteOnce("http://localhost:8081/api/v2/users/zaphod", {
status: 204
});
@@ -316,7 +316,7 @@ describe("users fetch()", () => {
});
it("should fail to delete user zaphod", () => {
- fetchMock.deleteOnce("http://localhost:8081/api/rest/v2/users/zaphod", {
+ fetchMock.deleteOnce("http://localhost:8081/api/v2/users/zaphod", {
status: 500
});
diff --git a/scm-ui/styles/scm.scss b/scm-ui/styles/scm.scss
index 43701de5eb..3ebe407a38 100644
--- a/scm-ui/styles/scm.scss
+++ b/scm-ui/styles/scm.scss
@@ -35,6 +35,7 @@ $blue: #33B2E8;
// 6. Import the rest of Bulma
@import "bulma/bulma";
+@import "bulma-tooltip/dist/css/bulma-tooltip";
// import at the end, because we need a lot of stuff from bulma/bulma
.box-link-shadow {
diff --git a/scm-ui/yarn.lock b/scm-ui/yarn.lock
index f5461f2014..16d5590aba 100644
--- a/scm-ui/yarn.lock
+++ b/scm-ui/yarn.lock
@@ -2,12 +2,6 @@
# yarn lockfile v1
-"@babel/code-frame@7.0.0-beta.51":
- version "7.0.0-beta.51"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.51.tgz#bd71d9b192af978df915829d39d4094456439a0c"
- dependencies:
- "@babel/highlight" "7.0.0-beta.51"
-
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8"
@@ -15,16 +9,16 @@
"@babel/highlight" "^7.0.0"
"@babel/core@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0.tgz#0cb0c0fd2e78a0a2bec97698f549ae9ce0b99515"
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.2.tgz#f8d2a9ceb6832887329a7b60f9d035791400ba4e"
dependencies:
"@babel/code-frame" "^7.0.0"
- "@babel/generator" "^7.0.0"
- "@babel/helpers" "^7.0.0"
- "@babel/parser" "^7.0.0"
- "@babel/template" "^7.0.0"
- "@babel/traverse" "^7.0.0"
- "@babel/types" "^7.0.0"
+ "@babel/generator" "^7.1.2"
+ "@babel/helpers" "^7.1.2"
+ "@babel/parser" "^7.1.2"
+ "@babel/template" "^7.1.2"
+ "@babel/traverse" "^7.1.0"
+ "@babel/types" "^7.1.2"
convert-source-map "^1.1.0"
debug "^3.1.0"
json5 "^0.5.0"
@@ -33,21 +27,11 @@
semver "^5.4.1"
source-map "^0.5.0"
-"@babel/generator@7.0.0-beta.51":
- version "7.0.0-beta.51"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.51.tgz#6c7575ffde761d07485e04baedc0392c6d9e30f6"
+"@babel/generator@^7.0.0", "@babel/generator@^7.1.2":
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.2.tgz#fde75c072575ce7abbd97322e8fef5bae67e4630"
dependencies:
- "@babel/types" "7.0.0-beta.51"
- jsesc "^2.5.1"
- lodash "^4.17.5"
- source-map "^0.5.0"
- trim-right "^1.0.1"
-
-"@babel/generator@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0.tgz#1efd58bffa951dc846449e58ce3a1d7f02d393aa"
- dependencies:
- "@babel/types" "^7.0.0"
+ "@babel/types" "^7.1.2"
jsesc "^2.5.1"
lodash "^4.17.10"
source-map "^0.5.0"
@@ -59,11 +43,11 @@
dependencies:
"@babel/types" "^7.0.0"
-"@babel/helper-builder-binary-assignment-operator-visitor@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0.tgz#ba26336beb2abb547d58b6eba5b84d77975a39eb"
+"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f"
dependencies:
- "@babel/helper-explode-assignable-expression" "^7.0.0"
+ "@babel/helper-explode-assignable-expression" "^7.1.0"
"@babel/types" "^7.0.0"
"@babel/helper-builder-react-jsx@^7.0.0":
@@ -73,51 +57,37 @@
"@babel/types" "^7.0.0"
esutils "^2.0.0"
-"@babel/helper-call-delegate@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0.tgz#e036956bb33d76e59c07a04a1fff144e9f62ab78"
+"@babel/helper-call-delegate@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz#6a957f105f37755e8645343d3038a22e1449cc4a"
dependencies:
"@babel/helper-hoist-variables" "^7.0.0"
- "@babel/traverse" "^7.0.0"
+ "@babel/traverse" "^7.1.0"
"@babel/types" "^7.0.0"
-"@babel/helper-define-map@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.0.0.tgz#a5684dd2adf30f0137cf9b0bde436f8c2db17225"
+"@babel/helper-define-map@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c"
dependencies:
- "@babel/helper-function-name" "^7.0.0"
+ "@babel/helper-function-name" "^7.1.0"
"@babel/types" "^7.0.0"
lodash "^4.17.10"
-"@babel/helper-explode-assignable-expression@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0.tgz#fdfa4c88603ae3e954d0fc3244d5ca82fb468497"
+"@babel/helper-explode-assignable-expression@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6"
dependencies:
- "@babel/traverse" "^7.0.0"
+ "@babel/traverse" "^7.1.0"
"@babel/types" "^7.0.0"
-"@babel/helper-function-name@7.0.0-beta.51":
- version "7.0.0-beta.51"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.51.tgz#21b4874a227cf99ecafcc30a90302da5a2640561"
- dependencies:
- "@babel/helper-get-function-arity" "7.0.0-beta.51"
- "@babel/template" "7.0.0-beta.51"
- "@babel/types" "7.0.0-beta.51"
-
-"@babel/helper-function-name@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0.tgz#a68cc8d04420ccc663dd258f9cc41b8261efa2d4"
+"@babel/helper-function-name@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53"
dependencies:
"@babel/helper-get-function-arity" "^7.0.0"
- "@babel/template" "^7.0.0"
+ "@babel/template" "^7.1.0"
"@babel/types" "^7.0.0"
-"@babel/helper-get-function-arity@7.0.0-beta.51":
- version "7.0.0-beta.51"
- resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.51.tgz#3281b2d045af95c172ce91b20825d85ea4676411"
- dependencies:
- "@babel/types" "7.0.0-beta.51"
-
"@babel/helper-get-function-arity@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3"
@@ -142,14 +112,14 @@
dependencies:
"@babel/types" "^7.0.0"
-"@babel/helper-module-transforms@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0.tgz#b01ee7d543e81e8c3fc404b19c9f26acb6e4cf4c"
+"@babel/helper-module-transforms@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.1.0.tgz#470d4f9676d9fad50b324cdcce5fbabbc3da5787"
dependencies:
"@babel/helper-module-imports" "^7.0.0"
- "@babel/helper-simple-access" "^7.0.0"
+ "@babel/helper-simple-access" "^7.1.0"
"@babel/helper-split-export-declaration" "^7.0.0"
- "@babel/template" "^7.0.0"
+ "@babel/template" "^7.1.0"
"@babel/types" "^7.0.0"
lodash "^4.17.10"
@@ -169,68 +139,54 @@
dependencies:
lodash "^4.17.10"
-"@babel/helper-remap-async-to-generator@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0.tgz#6512273c2feb91587822335cf913fdf680c26901"
+"@babel/helper-remap-async-to-generator@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f"
dependencies:
"@babel/helper-annotate-as-pure" "^7.0.0"
- "@babel/helper-wrap-function" "^7.0.0"
- "@babel/template" "^7.0.0"
- "@babel/traverse" "^7.0.0"
+ "@babel/helper-wrap-function" "^7.1.0"
+ "@babel/template" "^7.1.0"
+ "@babel/traverse" "^7.1.0"
"@babel/types" "^7.0.0"
-"@babel/helper-replace-supers@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0.tgz#b6f21237280e0be54f591f63a464b66627ced707"
+"@babel/helper-replace-supers@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz#5fc31de522ec0ef0899dc9b3e7cf6a5dd655f362"
dependencies:
"@babel/helper-member-expression-to-functions" "^7.0.0"
"@babel/helper-optimise-call-expression" "^7.0.0"
- "@babel/traverse" "^7.0.0"
+ "@babel/traverse" "^7.1.0"
"@babel/types" "^7.0.0"
-"@babel/helper-simple-access@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0.tgz#ff36a27983ae4c27122da2f7f294dced80ecbd08"
+"@babel/helper-simple-access@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c"
dependencies:
- "@babel/template" "^7.0.0"
+ "@babel/template" "^7.1.0"
"@babel/types" "^7.0.0"
-"@babel/helper-split-export-declaration@7.0.0-beta.51":
- version "7.0.0-beta.51"
- resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.51.tgz#8a6c3f66c4d265352fc077484f9f6e80a51ab978"
- dependencies:
- "@babel/types" "7.0.0-beta.51"
-
"@babel/helper-split-export-declaration@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813"
dependencies:
"@babel/types" "^7.0.0"
-"@babel/helper-wrap-function@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0.tgz#1c8e42a2cfb0808e3140189dfe9490782a6fa740"
+"@babel/helper-wrap-function@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.1.0.tgz#8cf54e9190706067f016af8f75cb3df829cc8c66"
dependencies:
- "@babel/helper-function-name" "^7.0.0"
- "@babel/template" "^7.0.0"
- "@babel/traverse" "^7.0.0"
+ "@babel/helper-function-name" "^7.1.0"
+ "@babel/template" "^7.1.0"
+ "@babel/traverse" "^7.1.0"
"@babel/types" "^7.0.0"
-"@babel/helpers@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0.tgz#7213388341eeb07417f44710fd7e1d00acfa6ac0"
+"@babel/helpers@^7.1.2":
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.1.2.tgz#ab752e8c35ef7d39987df4e8586c63b8846234b5"
dependencies:
- "@babel/template" "^7.0.0"
- "@babel/traverse" "^7.0.0"
- "@babel/types" "^7.0.0"
-
-"@babel/highlight@7.0.0-beta.51":
- version "7.0.0-beta.51"
- resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.51.tgz#e8844ae25a1595ccfd42b89623b4376ca06d225d"
- dependencies:
- chalk "^2.0.0"
- esutils "^2.0.2"
- js-tokens "^3.0.0"
+ "@babel/template" "^7.1.2"
+ "@babel/traverse" "^7.1.0"
+ "@babel/types" "^7.1.2"
"@babel/highlight@^7.0.0":
version "7.0.0"
@@ -240,31 +196,27 @@
esutils "^2.0.2"
js-tokens "^4.0.0"
-"@babel/parser@7.0.0-beta.51":
- version "7.0.0-beta.51"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-beta.51.tgz#27cec2df409df60af58270ed8f6aa55409ea86f6"
+"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.1.2":
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.2.tgz#85c5c47af6d244fab77bce6b9bd830e38c978409"
-"@babel/parser@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0.tgz#697655183394facffb063437ddf52c0277698775"
-
-"@babel/plugin-proposal-async-generator-functions@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0.tgz#5d1eb6b44fd388b97f964350007ab9da090b1d70"
+"@babel/plugin-proposal-async-generator-functions@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce"
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-remap-async-to-generator" "^7.0.0"
+ "@babel/helper-remap-async-to-generator" "^7.1.0"
"@babel/plugin-syntax-async-generators" "^7.0.0"
"@babel/plugin-proposal-class-properties@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0.tgz#a16b5c076ba6c3d87df64d2480a380e979543731"
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.1.0.tgz#9af01856b1241db60ec8838d84691aa0bd1e8df4"
dependencies:
- "@babel/helper-function-name" "^7.0.0"
+ "@babel/helper-function-name" "^7.1.0"
"@babel/helper-member-expression-to-functions" "^7.0.0"
"@babel/helper-optimise-call-expression" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-replace-supers" "^7.0.0"
+ "@babel/helper-replace-supers" "^7.1.0"
"@babel/plugin-syntax-class-properties" "^7.0.0"
"@babel/plugin-proposal-json-strings@^7.0.0":
@@ -344,13 +296,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
-"@babel/plugin-transform-async-to-generator@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0.tgz#feaf18f4bfeaf2236eea4b2d4879da83006cc8f5"
+"@babel/plugin-transform-async-to-generator@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811"
dependencies:
"@babel/helper-module-imports" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-remap-async-to-generator" "^7.0.0"
+ "@babel/helper-remap-async-to-generator" "^7.1.0"
"@babel/plugin-transform-block-scoped-functions@^7.0.0":
version "7.0.0"
@@ -365,16 +317,16 @@
"@babel/helper-plugin-utils" "^7.0.0"
lodash "^4.17.10"
-"@babel/plugin-transform-classes@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0.tgz#9e65ca401747dde99e344baea90ab50dccb4c468"
+"@babel/plugin-transform-classes@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249"
dependencies:
"@babel/helper-annotate-as-pure" "^7.0.0"
- "@babel/helper-define-map" "^7.0.0"
- "@babel/helper-function-name" "^7.0.0"
+ "@babel/helper-define-map" "^7.1.0"
+ "@babel/helper-function-name" "^7.1.0"
"@babel/helper-optimise-call-expression" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-replace-supers" "^7.0.0"
+ "@babel/helper-replace-supers" "^7.1.0"
"@babel/helper-split-export-declaration" "^7.0.0"
globals "^11.1.0"
@@ -385,8 +337,8 @@
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-destructuring@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0.tgz#68e911e1935dda2f06b6ccbbf184ffb024e9d43a"
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.1.2.tgz#5fa77d473f5a0a3f5266ad7ce2e8c995a164d60a"
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
@@ -404,11 +356,11 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
-"@babel/plugin-transform-exponentiation-operator@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0.tgz#c51b45e090a01876f64d32b5b46c0799c85ea56c"
+"@babel/plugin-transform-exponentiation-operator@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73"
dependencies:
- "@babel/helper-builder-binary-assignment-operator-visitor" "^7.0.0"
+ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-flow-strip-types@^7.0.0":
@@ -424,11 +376,11 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
-"@babel/plugin-transform-function-name@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0.tgz#eeda18dc22584e13c3581a68f6be4822bb1d1d81"
+"@babel/plugin-transform-function-name@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb"
dependencies:
- "@babel/helper-function-name" "^7.0.0"
+ "@babel/helper-function-name" "^7.1.0"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-literals@^7.0.0":
@@ -437,20 +389,20 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
-"@babel/plugin-transform-modules-amd@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.0.0.tgz#2430ab73db9960c4ca89966f425b803f5d0d0468"
+"@babel/plugin-transform-modules-amd@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.1.0.tgz#f9e0a7072c12e296079b5a59f408ff5b97bf86a8"
dependencies:
- "@babel/helper-module-transforms" "^7.0.0"
+ "@babel/helper-module-transforms" "^7.1.0"
"@babel/helper-plugin-utils" "^7.0.0"
-"@babel/plugin-transform-modules-commonjs@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0.tgz#20b906e5ab130dd8e456b694a94d9575da0fd41f"
+"@babel/plugin-transform-modules-commonjs@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c"
dependencies:
- "@babel/helper-module-transforms" "^7.0.0"
+ "@babel/helper-module-transforms" "^7.1.0"
"@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-simple-access" "^7.0.0"
+ "@babel/helper-simple-access" "^7.1.0"
"@babel/plugin-transform-modules-systemjs@^7.0.0":
version "7.0.0"
@@ -459,11 +411,11 @@
"@babel/helper-hoist-variables" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0"
-"@babel/plugin-transform-modules-umd@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.0.0.tgz#e7bb4f2a6cd199668964241951a25013450349be"
+"@babel/plugin-transform-modules-umd@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.1.0.tgz#a29a7d85d6f28c3561c33964442257cc6a21f2a8"
dependencies:
- "@babel/helper-module-transforms" "^7.0.0"
+ "@babel/helper-module-transforms" "^7.1.0"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-new-target@^7.0.0":
@@ -472,18 +424,18 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
-"@babel/plugin-transform-object-super@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.0.0.tgz#b8587d511309b3a0e96e9e38169908b3e392041e"
+"@babel/plugin-transform-object-super@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.1.0.tgz#b1ae194a054b826d8d4ba7ca91486d4ada0f91bb"
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
- "@babel/helper-replace-supers" "^7.0.0"
+ "@babel/helper-replace-supers" "^7.1.0"
-"@babel/plugin-transform-parameters@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0.tgz#da864efa111816a6df161d492f33de10e74b1949"
+"@babel/plugin-transform-parameters@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed"
dependencies:
- "@babel/helper-call-delegate" "^7.0.0"
+ "@babel/helper-call-delegate" "^7.1.0"
"@babel/helper-get-function-arity" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0"
@@ -562,12 +514,12 @@
regexpu-core "^4.1.3"
"@babel/preset-env@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.0.0.tgz#f450f200c14e713f98cb14d113bf0c2cfbb89ca9"
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.1.0.tgz#e67ea5b0441cfeab1d6f41e9b5c79798800e8d11"
dependencies:
"@babel/helper-module-imports" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-proposal-async-generator-functions" "^7.0.0"
+ "@babel/plugin-proposal-async-generator-functions" "^7.1.0"
"@babel/plugin-proposal-json-strings" "^7.0.0"
"@babel/plugin-proposal-object-rest-spread" "^7.0.0"
"@babel/plugin-proposal-optional-catch-binding" "^7.0.0"
@@ -576,25 +528,25 @@
"@babel/plugin-syntax-object-rest-spread" "^7.0.0"
"@babel/plugin-syntax-optional-catch-binding" "^7.0.0"
"@babel/plugin-transform-arrow-functions" "^7.0.0"
- "@babel/plugin-transform-async-to-generator" "^7.0.0"
+ "@babel/plugin-transform-async-to-generator" "^7.1.0"
"@babel/plugin-transform-block-scoped-functions" "^7.0.0"
"@babel/plugin-transform-block-scoping" "^7.0.0"
- "@babel/plugin-transform-classes" "^7.0.0"
+ "@babel/plugin-transform-classes" "^7.1.0"
"@babel/plugin-transform-computed-properties" "^7.0.0"
"@babel/plugin-transform-destructuring" "^7.0.0"
"@babel/plugin-transform-dotall-regex" "^7.0.0"
"@babel/plugin-transform-duplicate-keys" "^7.0.0"
- "@babel/plugin-transform-exponentiation-operator" "^7.0.0"
+ "@babel/plugin-transform-exponentiation-operator" "^7.1.0"
"@babel/plugin-transform-for-of" "^7.0.0"
- "@babel/plugin-transform-function-name" "^7.0.0"
+ "@babel/plugin-transform-function-name" "^7.1.0"
"@babel/plugin-transform-literals" "^7.0.0"
- "@babel/plugin-transform-modules-amd" "^7.0.0"
- "@babel/plugin-transform-modules-commonjs" "^7.0.0"
+ "@babel/plugin-transform-modules-amd" "^7.1.0"
+ "@babel/plugin-transform-modules-commonjs" "^7.1.0"
"@babel/plugin-transform-modules-systemjs" "^7.0.0"
- "@babel/plugin-transform-modules-umd" "^7.0.0"
+ "@babel/plugin-transform-modules-umd" "^7.1.0"
"@babel/plugin-transform-new-target" "^7.0.0"
- "@babel/plugin-transform-object-super" "^7.0.0"
- "@babel/plugin-transform-parameters" "^7.0.0"
+ "@babel/plugin-transform-object-super" "^7.1.0"
+ "@babel/plugin-transform-parameters" "^7.1.0"
"@babel/plugin-transform-regenerator" "^7.0.0"
"@babel/plugin-transform-shorthand-properties" "^7.0.0"
"@babel/plugin-transform-spread" "^7.0.0"
@@ -624,63 +576,31 @@
"@babel/plugin-transform-react-jsx-self" "^7.0.0"
"@babel/plugin-transform-react-jsx-source" "^7.0.0"
-"@babel/template@7.0.0-beta.51":
- version "7.0.0-beta.51"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.51.tgz#9602a40aebcf357ae9677e2532ef5fc810f5fbff"
- dependencies:
- "@babel/code-frame" "7.0.0-beta.51"
- "@babel/parser" "7.0.0-beta.51"
- "@babel/types" "7.0.0-beta.51"
- lodash "^4.17.5"
-
-"@babel/template@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0.tgz#c2bc9870405959c89a9c814376a2ecb247838c80"
+"@babel/template@^7.1.0", "@babel/template@^7.1.2":
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644"
dependencies:
"@babel/code-frame" "^7.0.0"
- "@babel/parser" "^7.0.0"
- "@babel/types" "^7.0.0"
+ "@babel/parser" "^7.1.2"
+ "@babel/types" "^7.1.2"
-"@babel/traverse@7.0.0-beta.51":
- version "7.0.0-beta.51"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.51.tgz#981daf2cec347a6231d3aa1d9e1803b03aaaa4a8"
- dependencies:
- "@babel/code-frame" "7.0.0-beta.51"
- "@babel/generator" "7.0.0-beta.51"
- "@babel/helper-function-name" "7.0.0-beta.51"
- "@babel/helper-split-export-declaration" "7.0.0-beta.51"
- "@babel/parser" "7.0.0-beta.51"
- "@babel/types" "7.0.0-beta.51"
- debug "^3.1.0"
- globals "^11.1.0"
- invariant "^2.2.0"
- lodash "^4.17.5"
-
-"@babel/traverse@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0.tgz#b1fe9b6567fdf3ab542cfad6f3b31f854d799a61"
+"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.0.tgz#503ec6669387efd182c3888c4eec07bcc45d91b2"
dependencies:
"@babel/code-frame" "^7.0.0"
"@babel/generator" "^7.0.0"
- "@babel/helper-function-name" "^7.0.0"
+ "@babel/helper-function-name" "^7.1.0"
"@babel/helper-split-export-declaration" "^7.0.0"
- "@babel/parser" "^7.0.0"
+ "@babel/parser" "^7.1.0"
"@babel/types" "^7.0.0"
debug "^3.1.0"
globals "^11.1.0"
lodash "^4.17.10"
-"@babel/types@7.0.0-beta.51":
- version "7.0.0-beta.51"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.51.tgz#d802b7b543b5836c778aa691797abf00f3d97ea9"
- dependencies:
- esutils "^2.0.2"
- lodash "^4.17.5"
- to-fast-properties "^2.0.0"
-
-"@babel/types@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0.tgz#6e191793d3c854d19c6749989e3bc55f0e962118"
+"@babel/types@^7.0.0", "@babel/types@^7.1.2":
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.2.tgz#183e7952cf6691628afdc2e2b90d03240bac80c0"
dependencies:
esutils "^2.0.2"
lodash "^4.17.10"
@@ -690,13 +610,6 @@
version "5.3.1"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.3.1.tgz#5466b8f31c1f493a96754c1426c25796d0633dd9"
-"@gimenete/type-writer@^0.1.3":
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/@gimenete/type-writer/-/type-writer-0.1.3.tgz#2d4f26118b18d71f5b34ca24fdd6d1fd455c05b6"
- dependencies:
- camelcase "^5.0.0"
- prettier "^1.13.7"
-
"@gulp-sourcemaps/identity-map@1.X":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz#1e6fe5d8027b1f285dc0d31762f566bccd73d5a9"
@@ -715,10 +628,9 @@
through2 "^2.0.3"
"@octokit/rest@^15.2.6":
- version "15.11.0"
- resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-15.11.0.tgz#4851f24cf1ae26aa813c871cfc39a8287a42e8e8"
+ version "15.13.0"
+ resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-15.13.0.tgz#078262de2f1d1b02ead7a00c4a3870f517528bcb"
dependencies:
- "@gimenete/type-writer" "^0.1.3"
before-after-hook "^1.1.0"
btoa-lite "^1.0.0"
debug "^3.1.0"
@@ -726,6 +638,7 @@
https-proxy-agent "^2.2.0"
lodash "^4.17.4"
node-fetch "^2.1.1"
+ universal-user-agent "^2.0.0"
url-template "^2.0.8"
"@scm-manager/eslint-config@^0.0.2":
@@ -781,8 +694,8 @@
react-dom "^16.4.2"
"@types/node@*":
- version "10.9.4"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-10.9.4.tgz#0f4cb2dc7c1de6096055357f70179043c33e9897"
+ version "10.11.4"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.4.tgz#e8bd933c3f78795d580ae41d86590bfc1f4f389d"
JSONStream@^1.0.3:
version "1.3.4"
@@ -806,17 +719,12 @@ accepts@~1.3.4:
mime-types "~2.1.18"
negotiator "0.6.1"
-acorn-dynamic-import@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278"
- dependencies:
- acorn "^5.0.0"
-
acorn-globals@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538"
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.0.tgz#e3b6f8da3c1552a95ae627571f7dd6923bb54103"
dependencies:
- acorn "^5.0.0"
+ acorn "^6.0.1"
+ acorn-walk "^6.0.1"
acorn-jsx@^4.1.1:
version "4.1.1"
@@ -825,16 +733,24 @@ acorn-jsx@^4.1.1:
acorn "^5.0.3"
acorn-node@^1.2.0, acorn-node@^1.3.0, acorn-node@^1.5.2:
- version "1.5.2"
- resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.5.2.tgz#2ca723df19d997b05824b69f6c7fb091fc42c322"
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.6.0.tgz#725c6b8b432451383b5d2816a18a5ab13288aa58"
dependencies:
- acorn "^5.7.1"
- acorn-dynamic-import "^3.0.0"
+ acorn "^6.0.1"
+ acorn-walk "^6.0.1"
xtend "^4.0.1"
-acorn@5.X, acorn@^5.0.0, acorn@^5.0.3, acorn@^5.5.3, acorn@^5.6.0, acorn@^5.7.1:
- version "5.7.2"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.2.tgz#91fa871883485d06708800318404e72bfb26dcc5"
+acorn-walk@^6.0.1:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.0.tgz#c957f4a1460da46af4a0388ce28b4c99355b0cbc"
+
+acorn@5.X, acorn@^5.0.3, acorn@^5.5.3, acorn@^5.6.0:
+ version "5.7.3"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
+
+acorn@^6.0.1:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.2.tgz#6a459041c320ab17592c6317abbfdf4bbaa98ca4"
after@0.8.2:
version "0.8.2"
@@ -860,22 +776,14 @@ ajv@^5.1.0, ajv@^5.3.0:
json-schema-traverse "^0.3.0"
ajv@^6.0.1, ajv@^6.5.3:
- version "6.5.3"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9"
+ version "6.5.4"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.4.tgz#247d5274110db653706b550fcc2b797ca28cfc59"
dependencies:
fast-deep-equal "^2.0.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
-align-text@^0.1.1, align-text@^0.1.3:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
- dependencies:
- kind-of "^3.0.2"
- longest "^1.0.1"
- repeat-string "^1.5.2"
-
amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
@@ -926,11 +834,11 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
-append-transform@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab"
+append-transform@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991"
dependencies:
- default-require-extensions "^2.0.0"
+ default-require-extensions "^1.0.0"
aproba@^1.0.3:
version "1.2.0"
@@ -1051,10 +959,6 @@ arrify@^1.0.0, arrify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
-asap@~2.0.3:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
-
asn1.js@^4.0.0:
version "4.10.1"
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
@@ -1111,11 +1015,11 @@ async-limiter@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
-async@1.5.2, async@^1.4.0:
+async@1.5.2:
version "1.5.2"
- resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
+ resolved "http://registry.npmjs.org/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
-async@^2.1.4:
+async@^2.1.4, async@^2.5.0:
version "2.6.1"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
dependencies:
@@ -1221,9 +1125,9 @@ babel-helpers@^6.24.1:
babel-runtime "^6.22.0"
babel-template "^6.24.1"
-babel-jest@^23.4.2:
- version "23.4.2"
- resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.4.2.tgz#f276de67798a5d68f2d6e87ff518c2f6e1609877"
+babel-jest@^23.4.2, babel-jest@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.6.0.tgz#a644232366557a2240a0c083da6b25786185a2f1"
dependencies:
babel-plugin-istanbul "^4.1.6"
babel-preset-jest "^23.2.0"
@@ -1236,7 +1140,7 @@ babel-messages@^6.23.0:
babel-plugin-istanbul@^4.1.6:
version "4.1.6"
- resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45"
+ resolved "http://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45"
dependencies:
babel-plugin-syntax-object-rest-spread "^6.13.0"
find-up "^2.1.0"
@@ -1383,12 +1287,12 @@ better-assert@~1.0.0:
callsite "1.0.0"
big-integer@^1.6.17:
- version "1.6.35"
- resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.35.tgz#e093c3a50f63fb6bda0b5511c9425f1befcba74d"
+ version "1.6.36"
+ resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36"
binary-extensions@^1.0.0:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"
+ version "1.12.0"
+ resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14"
binary@~0.3.0:
version "0.3.0"
@@ -1399,7 +1303,7 @@ binary@~0.3.0:
bl@^1.2.1:
version "1.2.2"
- resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
+ resolved "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
dependencies:
readable-stream "^2.3.5"
safe-buffer "^5.1.1"
@@ -1486,8 +1390,8 @@ browser-pack@^6.0.1:
umd "^3.0.0"
browser-process-hrtime@^0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e"
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4"
browser-resolve@^1.11.0, browser-resolve@^1.11.3, browser-resolve@^1.7.0:
version "1.11.3"
@@ -1495,35 +1399,44 @@ browser-resolve@^1.11.0, browser-resolve@^1.11.3, browser-resolve@^1.7.0:
dependencies:
resolve "1.1.7"
-browser-sync-ui@v1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/browser-sync-ui/-/browser-sync-ui-1.0.1.tgz#9740527b26d1d7ace259acc0c79e5b5e37d0fdf2"
+browser-sync-client@^2.26.0:
+ version "2.26.0"
+ resolved "https://registry.yarnpkg.com/browser-sync-client/-/browser-sync-client-2.26.0.tgz#ea8b38a251e8445177e23a0e37b68b1e4eeff0a0"
+ dependencies:
+ mitt "^1.1.3"
+ rxjs "^5.5.6"
+
+browser-sync-ui@^2.26.0:
+ version "2.26.0"
+ resolved "https://registry.yarnpkg.com/browser-sync-ui/-/browser-sync-ui-2.26.0.tgz#8fd7ec972fc30288ca3706df6c3e79ef784710e5"
dependencies:
async-each-series "0.1.1"
- connect-history-api-fallback "^1.1.0"
- immutable "^3.7.6"
+ connect-history-api-fallback "^1"
+ immutable "^3"
server-destroy "1.0.1"
- socket.io-client "2.0.4"
+ socket.io-client "^2.0.4"
stream-throttle "^0.1.3"
browser-sync@^2.24.7:
- version "2.24.7"
- resolved "https://registry.yarnpkg.com/browser-sync/-/browser-sync-2.24.7.tgz#0f93bcaabfb84a35a5c98e07682c9e45c6251a93"
+ version "2.26.0"
+ resolved "https://registry.yarnpkg.com/browser-sync/-/browser-sync-2.26.0.tgz#63b401c51b715e85dc4df9ef1d135a63a6d3889e"
dependencies:
- browser-sync-ui v1.0.1
+ browser-sync-client "^2.26.0"
+ browser-sync-ui "^2.26.0"
bs-recipes "1.3.4"
- chokidar "1.7.0"
+ bs-snippet-injector "^2.0.1"
+ chokidar "^2.0.4"
connect "3.6.6"
- connect-history-api-fallback "^1.5.0"
+ connect-history-api-fallback "^1"
dev-ip "^1.0.1"
easy-extender "^2.3.4"
- eazy-logger "3.0.2"
+ eazy-logger "^3"
etag "^1.8.1"
fresh "^0.5.2"
fs-extra "3.0.1"
http-proxy "1.15.2"
- immutable "3.8.2"
- localtunnel "1.9.0"
+ immutable "^3"
+ localtunnel "1.9.1"
micromatch "2.3.11"
opn "5.3.0"
portscanner "2.1.1"
@@ -1540,7 +1453,7 @@ browser-sync@^2.24.7:
browserify-aes@^1.0.0, browserify-aes@^1.0.4:
version "1.2.0"
- resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
+ resolved "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
dependencies:
buffer-xor "^1.0.3"
cipher-base "^1.0.0"
@@ -1581,7 +1494,7 @@ browserify-des@^1.0.0:
browserify-rsa@^4.0.0:
version "4.0.1"
- resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524"
+ resolved "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524"
dependencies:
bn.js "^4.1.0"
randombytes "^2.0.1"
@@ -1605,8 +1518,8 @@ browserify-zlib@~0.2.0:
pako "~1.0.5"
browserify@^16.1.0, browserify@^16.2.2:
- version "16.2.2"
- resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.2.2.tgz#4b1f66ba0e54fa39dbc5aa4be9629142143d91b0"
+ version "16.2.3"
+ resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.2.3.tgz#7ee6e654ba4f92bce6ab3599c3485b1cc7a0ad0b"
dependencies:
JSONStream "^1.0.3"
assert "^1.4.0"
@@ -1658,17 +1571,21 @@ browserify@^16.1.0, browserify@^16.2.2:
xtend "^4.0.0"
browserslist@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.1.0.tgz#81cbb8e52dfa09918f93c6e051d779cb7360785d"
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.2.0.tgz#3e5e5edf7fa9758ded0885cf88c1e4be753a591c"
dependencies:
- caniuse-lite "^1.0.30000878"
- electron-to-chromium "^1.3.61"
- node-releases "^1.0.0-alpha.11"
+ caniuse-lite "^1.0.30000889"
+ electron-to-chromium "^1.3.73"
+ node-releases "^1.0.0-alpha.12"
bs-recipes@1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/bs-recipes/-/bs-recipes-1.3.4.tgz#0d2d4d48a718c8c044769fdc4f89592dc8b69585"
+bs-snippet-injector@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz#61b5393f11f52559ed120693100343b6edb04dd5"
+
bser@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719"
@@ -1714,6 +1631,10 @@ builtin-status-codes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
+bulma-tooltip@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/bulma-tooltip/-/bulma-tooltip-2.0.2.tgz#cf0bf5ad2dc75492cbcbd4816e1a005314dc90ac"
+
bulma@^0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.7.1.tgz#73c2e3b2930c90cc272029cbd19918b493fca486"
@@ -1765,10 +1686,6 @@ camelcase-keys@^2.0.0:
camelcase "^2.0.0"
map-obj "^1.0.0"
-camelcase@^1.0.2:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
-
camelcase@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
@@ -1781,13 +1698,9 @@ camelcase@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
-camelcase@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42"
-
-caniuse-lite@^1.0.30000878:
- version "1.0.30000884"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000884.tgz#eb82a959698745033b26a4dcd34d89dba7cc6eb3"
+caniuse-lite@^1.0.30000889:
+ version "1.0.30000890"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000890.tgz#86a18ffcc65d79ec6a437e985761b8bf1c4efeaf"
capture-exit@^1.2.0:
version "1.2.0"
@@ -1803,13 +1716,6 @@ caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
-center-align@^0.1.1:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
- dependencies:
- align-text "^0.1.3"
- lazy-cache "^1.0.3"
-
chainsaw@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98"
@@ -1853,7 +1759,7 @@ cheerio@^1.0.0-rc.2:
lodash "^4.15.0"
parse5 "^3.0.1"
-chokidar@1.7.0, chokidar@^1.0.0:
+chokidar@^1.0.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
dependencies:
@@ -1888,12 +1794,12 @@ chokidar@^2.0.4:
fsevents "^1.2.2"
chownr@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494"
-ci-info@^1.3.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.4.0.tgz#4841d53cad49f11b827b648ebde27a6e189b412f"
+ci-info@^1.5.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
@@ -1935,14 +1841,6 @@ cli-width@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
-cliui@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
- dependencies:
- center-align "^0.1.1"
- right-align "^0.1.1"
- wordwrap "0.0.2"
-
cliui@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
@@ -2037,20 +1935,26 @@ combine-source-map@^0.8.0, combine-source-map@~0.8.0:
lodash.memoize "~3.0.3"
source-map "~0.5.3"
-combined-stream@1.0.6, combined-stream@^1.0.5, combined-stream@~1.0.5, combined-stream@~1.0.6:
+combined-stream@1.0.6:
version "1.0.6"
- resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
+ resolved "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
dependencies:
delayed-stream "~1.0.0"
-commander@^2.11.0, commander@^2.17.1, commander@^2.2.0, commander@^2.9.0, commander@~2.17.1:
+combined-stream@^1.0.5, combined-stream@~1.0.5, combined-stream@~1.0.6:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
+ dependencies:
+ delayed-stream "~1.0.0"
+
+commander@^2.11.0, commander@^2.17.1, commander@^2.2.0, commander@^2.9.0:
+ version "2.18.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970"
+
+commander@~2.17.1:
version "2.17.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
-compare-versions@^3.1.0:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26"
-
component-bind@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1"
@@ -2076,7 +1980,7 @@ concat-stream@^1.6.0, concat-stream@^1.6.1, concat-stream@~1.6.0:
readable-stream "^2.2.2"
typedarray "^0.0.6"
-connect-history-api-fallback@^1.1.0, connect-history-api-fallback@^1.5.0:
+connect-history-api-fallback@^1, connect-history-api-fallback@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#b06873934bc5e344fef611a196a6faae0aee015a"
@@ -2108,12 +2012,14 @@ contains-path@^0.1.0:
resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
convert-source-map@1.X, convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5"
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20"
+ dependencies:
+ safe-buffer "~5.1.1"
convert-source-map@~1.1.0:
version "1.1.3"
- resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860"
+ resolved "http://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860"
cookie@0.3.1:
version "0.3.1"
@@ -2124,8 +2030,8 @@ copy-descriptor@^0.1.0:
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
copyfiles@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.0.0.tgz#bbd78bb78e8fd6db5c67adf54249317b24560f2a"
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.1.0.tgz#0e2a4188162d6b2f3c5adfe34e9c0bd564d23164"
dependencies:
glob "^7.0.5"
minimatch "^3.0.3"
@@ -2134,10 +2040,6 @@ copyfiles@^2.0.0:
through2 "^2.0.1"
yargs "^11.0.0"
-core-js@^1.0.0:
- version "1.2.7"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
-
core-js@^2.4.0, core-js@^2.5.0:
version "2.5.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
@@ -2165,7 +2067,7 @@ create-ecdh@^4.0.0:
create-hash@^1.1.0, create-hash@^1.1.2:
version "1.2.0"
- resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
+ resolved "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
dependencies:
cipher-base "^1.0.1"
inherits "^2.0.1"
@@ -2175,7 +2077,7 @@ create-hash@^1.1.0, create-hash@^1.1.2:
create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
version "1.1.7"
- resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
+ resolved "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
dependencies:
cipher-base "^1.0.3"
create-hash "^1.1.0"
@@ -2255,12 +2157,12 @@ css-what@2.1:
resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd"
css@2.X, css@^2.2.1:
- version "2.2.3"
- resolved "https://registry.yarnpkg.com/css/-/css-2.2.3.tgz#f861f4ba61e79bedc962aa548e5780fd95cbc6be"
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929"
dependencies:
- inherits "^2.0.1"
- source-map "^0.1.38"
- source-map-resolve "^0.5.1"
+ inherits "^2.0.3"
+ source-map "^0.6.1"
+ source-map-resolve "^0.5.2"
urix "^0.1.0"
cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
@@ -2319,25 +2221,31 @@ debug-fabulous@1.X:
memoizee "0.4.X"
object-assign "4.X"
-debug@2.6.8:
- version "2.6.8"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
- dependencies:
- ms "2.0.0"
-
-debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9, debug@~2.6.4:
+debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
ms "2.0.0"
-debug@3.1.0, debug@3.X, debug@^3.1.0, debug@~3.1.0:
+debug@3.1.0, debug@=3.1.0, debug@~3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
dependencies:
ms "2.0.0"
-decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2:
+debug@3.X, debug@^3.1.0:
+ version "3.2.5"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.5.tgz#c2418fbfd7a29f4d4f70ff4cea604d4b64c46407"
+ dependencies:
+ ms "^2.1.1"
+
+debug@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.0.1.tgz#f9bb36d439b8d1f0dd52d8fb6b46e4ebb8c1cd5b"
+ dependencies:
+ ms "^2.1.1"
+
+decamelize@^1.1.1, decamelize@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
@@ -2363,11 +2271,11 @@ deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
-default-require-extensions@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7"
+default-require-extensions@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8"
dependencies:
- strip-bom "^3.0.0"
+ strip-bom "^2.0.0"
defaults@^1.0.0:
version "1.0.3"
@@ -2494,7 +2402,7 @@ diff@^3.2.0:
diffie-hellman@^5.0.0:
version "5.0.3"
- resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
+ resolved "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
dependencies:
bn.js "^4.1.0"
miller-rabin "^4.0.0"
@@ -2578,9 +2486,9 @@ duplexer3@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
-duplexer@~0.1.1:
+duplexer@^0.1.1, duplexer@~0.1.1:
version "0.1.1"
- resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
+ resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
easy-extender@^2.3.4:
version "2.3.4"
@@ -2588,7 +2496,7 @@ easy-extender@^2.3.4:
dependencies:
lodash "^4.17.10"
-eazy-logger@3.0.2:
+eazy-logger@^3:
version "3.0.2"
resolved "https://registry.yarnpkg.com/eazy-logger/-/eazy-logger-3.0.2.tgz#a325aa5e53d13a2225889b2ac4113b2b9636f4fc"
dependencies:
@@ -2605,9 +2513,9 @@ ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
-electron-to-chromium@^1.3.61:
- version "1.3.62"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.62.tgz#2e8e2dc070c800ec8ce23ff9dfcceb585d6f9ed8"
+electron-to-chromium@^1.3.73:
+ version "1.3.75"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.75.tgz#dd04551739e7371862b0ac7f4ddaa9f3f95b7e68"
elliptic@^6.0.0:
version "6.4.1"
@@ -2629,34 +2537,12 @@ encodeurl@~1.0.1, encodeurl@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
-encoding@^0.1.11:
- version "0.1.12"
- resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
- dependencies:
- iconv-lite "~0.4.13"
-
end-of-stream@~0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf"
dependencies:
once "~1.3.0"
-engine.io-client@~3.1.0:
- version "3.1.6"
- resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.1.6.tgz#5bdeb130f8b94a50ac5cbeb72583e7a4a063ddfd"
- dependencies:
- component-emitter "1.2.1"
- component-inherit "0.0.3"
- debug "~3.1.0"
- engine.io-parser "~2.1.1"
- has-cors "1.1.0"
- indexof "0.0.1"
- parseqs "0.0.5"
- parseuri "0.0.5"
- ws "~3.3.1"
- xmlhttprequest-ssl "~1.5.4"
- yeast "0.1.2"
-
engine.io-client@~3.2.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36"
@@ -2699,28 +2585,28 @@ entities@^1.1.1, entities@~1.1.1:
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
enzyme-adapter-react-16@^1.1.1:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.4.0.tgz#c70aa6d085c5a6708b032406f5c73280d3f6a34b"
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.6.0.tgz#3fca28d3c32f3ff427495380fe2dd51494689073"
dependencies:
- enzyme-adapter-utils "^1.6.0"
+ enzyme-adapter-utils "^1.8.0"
function.prototype.name "^1.1.0"
object.assign "^4.1.0"
object.values "^1.0.4"
prop-types "^15.6.2"
- react-is "^16.4.2"
+ react-is "^16.5.2"
react-test-renderer "^16.0.0-0"
-enzyme-adapter-utils@^1.6.0:
- version "1.6.1"
- resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.6.1.tgz#f19acb8b23ddd21b2de99506b181e46138368f2a"
+enzyme-adapter-utils@^1.8.0:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.8.1.tgz#a927d840ce2c14b42892a533aec836809d4e022b"
dependencies:
function.prototype.name "^1.1.0"
object.assign "^4.1.0"
prop-types "^15.6.2"
enzyme@^3.3.0:
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.5.1.tgz#aad0cbd005fee4cfd800b6451b64112b5374da67"
+ version "3.7.0"
+ resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.7.0.tgz#9b499e8ca155df44fef64d9f1558961ba1385a46"
dependencies:
array.prototype.flat "^1.2.1"
cheerio "^1.0.0-rc.2"
@@ -2759,14 +2645,14 @@ es-abstract@^1.10.0, es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.5.1,
is-regex "^1.0.4"
es-to-primitive@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377"
dependencies:
- is-callable "^1.1.1"
+ is-callable "^1.1.4"
is-date-object "^1.0.1"
- is-symbol "^1.0.1"
+ is-symbol "^1.0.2"
-es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2:
+es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.46"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.46.tgz#efd99f67c5a7ec789baa3daa7f79870388f7f572"
dependencies:
@@ -2783,8 +2669,8 @@ es6-iterator@^2.0.1, es6-iterator@~2.0.3:
es6-symbol "^3.1.1"
es6-promise@^4.0.3:
- version "4.2.4"
- resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29"
+ version "4.2.5"
+ resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054"
es6-promisify@^5.0.0:
version "5.0.0"
@@ -2846,8 +2732,8 @@ eslint-module-utils@^2.2.0:
pkg-dir "^1.0.0"
eslint-plugin-flowtype@^2.50.0:
- version "2.50.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.0.tgz#953e262fa9b5d0fa76e178604892cf60dfb916da"
+ version "2.50.3"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz#61379d6dce1d010370acd6681740fd913d68175f"
dependencies:
lodash "^4.17.10"
@@ -2867,8 +2753,8 @@ eslint-plugin-import@^2.14.0:
resolve "^1.6.0"
eslint-plugin-jsx-a11y@^6.1.1:
- version "6.1.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.1.tgz#7bf56dbe7d47d811d14dbb3ddff644aa656ce8e1"
+ version "6.1.2"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.2.tgz#69bca4890b36dcf0fe16dd2129d2d88b98f33f88"
dependencies:
aria-query "^3.0.0"
array-includes "^3.0.3"
@@ -2912,14 +2798,14 @@ eslint-visitor-keys@^1.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
eslint@^5.4.0:
- version "5.5.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.5.0.tgz#8557fcceab5141a8197da9ffd9904f89f64425c6"
+ version "5.6.1"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.6.1.tgz#348134e32ccc09abb2df1bf282b3f6eed8c7b480"
dependencies:
"@babel/code-frame" "^7.0.0"
ajv "^6.5.3"
chalk "^2.1.0"
cross-spawn "^6.0.5"
- debug "^3.1.0"
+ debug "^4.0.1"
doctrine "^2.1.0"
eslint-scope "^4.0.0"
eslint-utils "^1.3.1"
@@ -3005,16 +2891,17 @@ event-emitter@^0.3.5:
es5-ext "~0.10.14"
event-stream@~3.3.0:
- version "3.3.4"
- resolved "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
+ version "3.3.6"
+ resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.6.tgz#cac1230890e07e73ec9cacd038f60a5b66173eef"
dependencies:
- duplexer "~0.1.1"
- from "~0"
- map-stream "~0.1.0"
- pause-stream "0.0.11"
- split "0.3"
- stream-combiner "~0.0.4"
- through "~2.3.1"
+ duplexer "^0.1.1"
+ flatmap-stream "^0.1.0"
+ from "^0.1.7"
+ map-stream "0.0.7"
+ pause-stream "^0.0.11"
+ split "^1.0.1"
+ stream-combiner "^0.2.2"
+ through "^2.3.8"
eventemitter3@1.x.x:
version "1.2.0"
@@ -3089,14 +2976,14 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2:
dependencies:
homedir-polyfill "^1.0.1"
-expect@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/expect/-/expect-23.5.0.tgz#18999a0eef8f8acf99023fde766d9c323c2562ed"
+expect@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98"
dependencies:
ansi-styles "^3.2.0"
- jest-diff "^23.5.0"
+ jest-diff "^23.6.0"
jest-get-type "^22.1.0"
- jest-matcher-utils "^23.5.0"
+ jest-matcher-utils "^23.6.0"
jest-message-util "^23.4.0"
jest-regex-util "^23.3.0"
@@ -3177,8 +3064,8 @@ fast-levenshtein@~2.0.4:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
fast-xml-parser@^3.12.0:
- version "3.12.0"
- resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.12.0.tgz#84ddcd98ca005f94e99af3ac387adc32ffb239d8"
+ version "3.12.5"
+ resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.12.5.tgz#756e4da382f403f88990a62344add00948820fe0"
dependencies:
nimnjs "^1.3.2"
@@ -3188,18 +3075,6 @@ fb-watchman@^2.0.0:
dependencies:
bser "^2.0.0"
-fbjs@^0.8.16:
- version "0.8.17"
- resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
- dependencies:
- core-js "^1.0.0"
- isomorphic-fetch "^2.1.1"
- loose-envify "^1.0.0"
- object-assign "^4.1.0"
- promise "^7.1.1"
- setimmediate "^1.0.5"
- ua-parser-js "^0.7.18"
-
fetch-mock@^6.5.0:
version "6.5.2"
resolved "https://registry.yarnpkg.com/fetch-mock/-/fetch-mock-6.5.2.tgz#b3842b305c13ea0f81c85919cfaa7de387adfa3e"
@@ -3332,6 +3207,10 @@ flat-cache@^1.2.1:
graceful-fs "^4.1.2"
write "^0.2.1"
+flatmap-stream@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.1.tgz#d34f39ef3b9aa5a2fc225016bd3adf28ac5ae6ea"
+
flow-bin@^0.79.1:
version "0.79.1"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.79.1.tgz#01c9f427baa6556753fa878c192d42e1ecb764b6"
@@ -3357,10 +3236,10 @@ flow-typed@^2.5.1:
yargs "^4.2.0"
follow-redirects@^1.2.5:
- version "1.5.7"
- resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.7.tgz#a39e4804dacb90202bca76a9e2ac10433ca6a69a"
+ version "1.5.8"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.8.tgz#1dbfe13e45ad969f813e86c00e5296f525c885a1"
dependencies:
- debug "^3.1.0"
+ debug "=3.1.0"
font-awesome@^4.7.0:
version "4.7.0"
@@ -3412,7 +3291,7 @@ fresh@0.5.2, fresh@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
-from@~0:
+from@^0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
@@ -3529,7 +3408,7 @@ get-stdin@^4.0.1:
get-stream@^3.0.0:
version "3.0.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
+ resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
get-value@^2.0.3, get-value@^2.0.6:
version "2.0.6"
@@ -3651,8 +3530,8 @@ global-prefix@^1.0.1:
which "^1.2.14"
globals@^11.1.0, globals@^11.7.0:
- version "11.7.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673"
+ version "11.8.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.8.0.tgz#c1ef45ee9bed6badf0663c5cb90e8d1adec1321d"
globals@^9.18.0:
version "9.18.0"
@@ -3782,7 +3661,7 @@ gulp-util@^3.0.0:
gulp@^3.9.1:
version "3.9.1"
- resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4"
+ resolved "http://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4"
dependencies:
archy "^1.0.0"
chalk "^1.0.0"
@@ -3804,15 +3683,15 @@ gulplog@^1.0.0:
dependencies:
glogg "^1.0.0"
-handlebars@^4.0.11:
- version "4.0.11"
- resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc"
+handlebars@^4.0.3:
+ version "4.0.12"
+ resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5"
dependencies:
- async "^1.4.0"
+ async "^2.5.0"
optimist "^0.6.1"
- source-map "^0.4.4"
+ source-map "^0.6.1"
optionalDependencies:
- uglify-js "^2.6"
+ uglify-js "^3.1.4"
har-schema@^2.0.0:
version "2.0.0"
@@ -4017,7 +3896,7 @@ htmlparser2@^3.9.1:
http-errors@1.6.3, http-errors@~1.6.2:
version "1.6.3"
- resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
+ resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
dependencies:
depd "~1.1.2"
inherits "2.0.3"
@@ -4084,8 +3963,8 @@ i18next-xhr-backend@^1.4.3:
resolved "https://registry.yarnpkg.com/i18next-xhr-backend/-/i18next-xhr-backend-1.5.1.tgz#50282610780c6a696d880dfa7f4ac1d01e8c3ad5"
i18next@^11.4.0:
- version "11.6.0"
- resolved "https://registry.yarnpkg.com/i18next/-/i18next-11.6.0.tgz#e0047aa3e3a0080f6f318426f90597cbb0d6ddd5"
+ version "11.9.0"
+ resolved "https://registry.yarnpkg.com/i18next/-/i18next-11.9.0.tgz#c30c0a5e0a857124923a8dd1ce8f1df603e30c70"
iconv-lite@0.4.23:
version "0.4.23"
@@ -4093,7 +3972,7 @@ iconv-lite@0.4.23:
dependencies:
safer-buffer ">= 2.1.2 < 3"
-iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
+iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
dependencies:
@@ -4113,7 +3992,7 @@ ignore@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
-immutable@3.8.2, immutable@^3.7.6:
+immutable@^3:
version "3.8.2"
resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3"
@@ -4208,7 +4087,7 @@ interpret@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
-invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4:
+invariant@^2.0.0, invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
dependencies:
@@ -4257,19 +4136,19 @@ is-buffer@^1.1.0, is-buffer@^1.1.5, is-buffer@~1.1.1:
is-builtin-module@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
+ resolved "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
dependencies:
builtin-modules "^1.0.0"
-is-callable@^1.1.1, is-callable@^1.1.3, is-callable@^1.1.4:
+is-callable@^1.1.3, is-callable@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
is-ci@^1.0.10:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.0.tgz#3f4a08d6303a09882cef3f0fb97439c5f5ce2d53"
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c"
dependencies:
- ci-info "^1.3.0"
+ ci-info "^1.5.0"
is-data-descriptor@^0.1.4:
version "0.1.4"
@@ -4487,7 +4366,7 @@ is-retry-allowed@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
-is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
+is-stream@^1.0.0, is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
@@ -4499,9 +4378,11 @@ is-subset@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
-is-symbol@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
+is-symbol@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38"
+ dependencies:
+ has-symbols "^1.0.0"
is-typedarray@~1.0.0:
version "1.0.0"
@@ -4559,96 +4440,72 @@ isobject@^3.0.0, isobject@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
-isomorphic-fetch@^2.1.1:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
- dependencies:
- node-fetch "^1.0.1"
- whatwg-fetch ">=0.10.0"
-
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
istanbul-api@^1.3.1:
- version "1.3.6"
- resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.6.tgz#0c695f17e533131de8c49e0657175dcfd8af8a8f"
+ version "1.3.7"
+ resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa"
dependencies:
async "^2.1.4"
- compare-versions "^3.1.0"
fileset "^2.0.2"
- istanbul-lib-coverage "^1.2.0"
- istanbul-lib-hook "^1.2.0"
- istanbul-lib-instrument "^2.1.0"
- istanbul-lib-report "^1.1.4"
- istanbul-lib-source-maps "^1.2.5"
- istanbul-reports "^1.4.1"
+ istanbul-lib-coverage "^1.2.1"
+ istanbul-lib-hook "^1.2.2"
+ istanbul-lib-instrument "^1.10.2"
+ istanbul-lib-report "^1.1.5"
+ istanbul-lib-source-maps "^1.2.6"
+ istanbul-reports "^1.5.1"
js-yaml "^3.7.0"
mkdirp "^0.5.1"
once "^1.4.0"
-istanbul-lib-coverage@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz#f7d8f2e42b97e37fe796114cb0f9d68b5e3a4341"
-
-istanbul-lib-coverage@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda"
-
-istanbul-lib-hook@^1.2.0:
+istanbul-lib-coverage@^1.2.0, istanbul-lib-coverage@^1.2.1:
version "1.2.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.1.tgz#f614ec45287b2a8fc4f07f5660af787575601805"
- dependencies:
- append-transform "^1.0.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0"
-istanbul-lib-instrument@^1.10.1:
- version "1.10.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz#724b4b6caceba8692d3f1f9d0727e279c401af7b"
+istanbul-lib-hook@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86"
+ dependencies:
+ append-transform "^0.4.0"
+
+istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2:
+ version "1.10.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca"
dependencies:
babel-generator "^6.18.0"
babel-template "^6.16.0"
babel-traverse "^6.18.0"
babel-types "^6.18.0"
babylon "^6.18.0"
- istanbul-lib-coverage "^1.2.0"
+ istanbul-lib-coverage "^1.2.1"
semver "^5.3.0"
-istanbul-lib-instrument@^2.1.0:
- version "2.3.2"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-2.3.2.tgz#b287cbae2b5f65f3567b05e2e29b275eaf92d25e"
+istanbul-lib-report@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c"
dependencies:
- "@babel/generator" "7.0.0-beta.51"
- "@babel/parser" "7.0.0-beta.51"
- "@babel/template" "7.0.0-beta.51"
- "@babel/traverse" "7.0.0-beta.51"
- "@babel/types" "7.0.0-beta.51"
- istanbul-lib-coverage "^2.0.1"
- semver "^5.5.0"
-
-istanbul-lib-report@^1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz#e886cdf505c4ebbd8e099e4396a90d0a28e2acb5"
- dependencies:
- istanbul-lib-coverage "^1.2.0"
+ istanbul-lib-coverage "^1.2.1"
mkdirp "^0.5.1"
path-parse "^1.0.5"
supports-color "^3.1.2"
-istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.5.tgz#ffe6be4e7ab86d3603e4290d54990b14506fc9b1"
+istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.6:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f"
dependencies:
debug "^3.1.0"
- istanbul-lib-coverage "^1.2.0"
+ istanbul-lib-coverage "^1.2.1"
mkdirp "^0.5.1"
rimraf "^2.6.1"
source-map "^0.5.3"
-istanbul-reports@^1.4.1:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.0.tgz#c6c2867fa65f59eb7dcedb7f845dfc76aaee70f9"
+istanbul-reports@^1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a"
dependencies:
- handlebars "^4.0.11"
+ handlebars "^4.0.3"
isurl@^1.0.0-alpha5:
version "1.0.0"
@@ -4663,9 +4520,9 @@ jest-changed-files@^23.4.2:
dependencies:
throat "^4.0.0"
-jest-cli@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.5.0.tgz#d316b8e34a38a610a1efc4f0403d8ef8a55e4492"
+jest-cli@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.6.0.tgz#61ab917744338f443ef2baa282ddffdd658a5da4"
dependencies:
ansi-escapes "^3.0.0"
chalk "^2.0.1"
@@ -4679,18 +4536,18 @@ jest-cli@^23.5.0:
istanbul-lib-instrument "^1.10.1"
istanbul-lib-source-maps "^1.2.4"
jest-changed-files "^23.4.2"
- jest-config "^23.5.0"
+ jest-config "^23.6.0"
jest-environment-jsdom "^23.4.0"
jest-get-type "^22.1.0"
- jest-haste-map "^23.5.0"
+ jest-haste-map "^23.6.0"
jest-message-util "^23.4.0"
jest-regex-util "^23.3.0"
- jest-resolve-dependencies "^23.5.0"
- jest-runner "^23.5.0"
- jest-runtime "^23.5.0"
- jest-snapshot "^23.5.0"
+ jest-resolve-dependencies "^23.6.0"
+ jest-runner "^23.6.0"
+ jest-runtime "^23.6.0"
+ jest-snapshot "^23.6.0"
jest-util "^23.4.0"
- jest-validate "^23.5.0"
+ jest-validate "^23.6.0"
jest-watcher "^23.4.0"
jest-worker "^23.2.0"
micromatch "^2.3.11"
@@ -4704,33 +4561,33 @@ jest-cli@^23.5.0:
which "^1.2.12"
yargs "^11.0.0"
-jest-config@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.5.0.tgz#3770fba03f7507ee15f3b8867c742e48f31a9773"
+jest-config@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.6.0.tgz#f82546a90ade2d8c7026fbf6ac5207fc22f8eb1d"
dependencies:
babel-core "^6.0.0"
- babel-jest "^23.4.2"
+ babel-jest "^23.6.0"
chalk "^2.0.1"
glob "^7.1.1"
jest-environment-jsdom "^23.4.0"
jest-environment-node "^23.4.0"
jest-get-type "^22.1.0"
- jest-jasmine2 "^23.5.0"
+ jest-jasmine2 "^23.6.0"
jest-regex-util "^23.3.0"
- jest-resolve "^23.5.0"
+ jest-resolve "^23.6.0"
jest-util "^23.4.0"
- jest-validate "^23.5.0"
+ jest-validate "^23.6.0"
micromatch "^2.3.11"
- pretty-format "^23.5.0"
+ pretty-format "^23.6.0"
-jest-diff@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.5.0.tgz#250651a433dd0050290a07642946cc9baaf06fba"
+jest-diff@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d"
dependencies:
chalk "^2.0.1"
diff "^3.2.0"
jest-get-type "^22.1.0"
- pretty-format "^23.5.0"
+ pretty-format "^23.6.0"
jest-docblock@^23.2.0:
version "23.2.0"
@@ -4738,12 +4595,12 @@ jest-docblock@^23.2.0:
dependencies:
detect-newline "^2.1.0"
-jest-each@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.5.0.tgz#77f7e2afe6132a80954b920006e78239862b10ba"
+jest-each@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.6.0.tgz#ba0c3a82a8054387016139c733a05242d3d71575"
dependencies:
chalk "^2.0.1"
- pretty-format "^23.5.0"
+ pretty-format "^23.6.0"
jest-environment-jsdom@^23.4.0:
version "23.4.0"
@@ -4764,9 +4621,9 @@ jest-get-type@^22.1.0:
version "22.4.3"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4"
-jest-haste-map@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.5.0.tgz#d4ca618188bd38caa6cb20349ce6610e194a8065"
+jest-haste-map@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.6.0.tgz#2e3eb997814ca696d62afdb3f2529f5bbc935e16"
dependencies:
fb-watchman "^2.0.0"
graceful-fs "^4.1.11"
@@ -4777,45 +4634,46 @@ jest-haste-map@^23.5.0:
micromatch "^2.3.11"
sane "^2.0.0"
-jest-jasmine2@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.5.0.tgz#05fe7f1788e650eeb5a03929e6461ea2e9f3db53"
+jest-jasmine2@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz#840e937f848a6c8638df24360ab869cc718592e0"
dependencies:
babel-traverse "^6.0.0"
chalk "^2.0.1"
co "^4.6.0"
- expect "^23.5.0"
+ expect "^23.6.0"
is-generator-fn "^1.0.0"
- jest-diff "^23.5.0"
- jest-each "^23.5.0"
- jest-matcher-utils "^23.5.0"
+ jest-diff "^23.6.0"
+ jest-each "^23.6.0"
+ jest-matcher-utils "^23.6.0"
jest-message-util "^23.4.0"
- jest-snapshot "^23.5.0"
+ jest-snapshot "^23.6.0"
jest-util "^23.4.0"
- pretty-format "^23.5.0"
+ pretty-format "^23.6.0"
jest-junit@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-5.1.0.tgz#e8e497d810a829bf02783125aab74b5df6caa8fe"
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-5.2.0.tgz#980401db7aa69999cf117c6d740a8135c22ae379"
dependencies:
+ jest-config "^23.6.0"
jest-validate "^23.0.1"
mkdirp "^0.5.1"
strip-ansi "^4.0.0"
xml "^1.0.1"
-jest-leak-detector@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.5.0.tgz#14ac2a785bd625160a2ea968fd5d98b7dcea3e64"
+jest-leak-detector@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz#e4230fd42cf381a1a1971237ad56897de7e171de"
dependencies:
- pretty-format "^23.5.0"
+ pretty-format "^23.6.0"
-jest-matcher-utils@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.5.0.tgz#0e2ea67744cab78c9ab15011c4d888bdd3e49e2a"
+jest-matcher-utils@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80"
dependencies:
chalk "^2.0.1"
jest-get-type "^22.1.0"
- pretty-format "^23.5.0"
+ pretty-format "^23.6.0"
jest-message-util@^23.4.0:
version "23.4.0"
@@ -4835,42 +4693,42 @@ jest-regex-util@^23.3.0:
version "23.3.0"
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5"
-jest-resolve-dependencies@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.5.0.tgz#10c4d135beb9d2256de1fedc7094916c3ad74af7"
+jest-resolve-dependencies@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz#b4526af24c8540d9a3fab102c15081cf509b723d"
dependencies:
jest-regex-util "^23.3.0"
- jest-snapshot "^23.5.0"
+ jest-snapshot "^23.6.0"
-jest-resolve@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.5.0.tgz#3b8e7f67e84598f0caf63d1530bd8534a189d0e6"
+jest-resolve@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.6.0.tgz#cf1d1a24ce7ee7b23d661c33ba2150f3aebfa0ae"
dependencies:
browser-resolve "^1.11.3"
chalk "^2.0.1"
realpath-native "^1.0.0"
-jest-runner@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.5.0.tgz#570f7a044da91648b5bb9b6baacdd511076c71d7"
+jest-runner@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.6.0.tgz#3894bd219ffc3f3cb94dc48a4170a2e6f23a5a38"
dependencies:
exit "^0.1.2"
graceful-fs "^4.1.11"
- jest-config "^23.5.0"
+ jest-config "^23.6.0"
jest-docblock "^23.2.0"
- jest-haste-map "^23.5.0"
- jest-jasmine2 "^23.5.0"
- jest-leak-detector "^23.5.0"
+ jest-haste-map "^23.6.0"
+ jest-jasmine2 "^23.6.0"
+ jest-leak-detector "^23.6.0"
jest-message-util "^23.4.0"
- jest-runtime "^23.5.0"
+ jest-runtime "^23.6.0"
jest-util "^23.4.0"
jest-worker "^23.2.0"
source-map-support "^0.5.6"
throat "^4.0.0"
-jest-runtime@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.5.0.tgz#eb503525a196dc32f2f9974e3482d26bdf7b63ce"
+jest-runtime@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.6.0.tgz#059e58c8ab445917cd0e0d84ac2ba68de8f23082"
dependencies:
babel-core "^6.0.0"
babel-plugin-istanbul "^4.1.6"
@@ -4879,14 +4737,14 @@ jest-runtime@^23.5.0:
exit "^0.1.2"
fast-json-stable-stringify "^2.0.0"
graceful-fs "^4.1.11"
- jest-config "^23.5.0"
- jest-haste-map "^23.5.0"
+ jest-config "^23.6.0"
+ jest-haste-map "^23.6.0"
jest-message-util "^23.4.0"
jest-regex-util "^23.3.0"
- jest-resolve "^23.5.0"
- jest-snapshot "^23.5.0"
+ jest-resolve "^23.6.0"
+ jest-snapshot "^23.6.0"
jest-util "^23.4.0"
- jest-validate "^23.5.0"
+ jest-validate "^23.6.0"
micromatch "^2.3.11"
realpath-native "^1.0.0"
slash "^1.0.0"
@@ -4898,19 +4756,19 @@ jest-serializer@^23.0.1:
version "23.0.1"
resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165"
-jest-snapshot@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.5.0.tgz#cc368ebd8513e1175e2a7277f37a801b7358ae79"
+jest-snapshot@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.6.0.tgz#f9c2625d1b18acda01ec2d2b826c0ce58a5aa17a"
dependencies:
babel-types "^6.0.0"
chalk "^2.0.1"
- jest-diff "^23.5.0"
- jest-matcher-utils "^23.5.0"
+ jest-diff "^23.6.0"
+ jest-matcher-utils "^23.6.0"
jest-message-util "^23.4.0"
- jest-resolve "^23.5.0"
+ jest-resolve "^23.6.0"
mkdirp "^0.5.1"
natural-compare "^1.4.0"
- pretty-format "^23.5.0"
+ pretty-format "^23.6.0"
semver "^5.5.0"
jest-util@^23.4.0:
@@ -4926,14 +4784,14 @@ jest-util@^23.4.0:
slash "^1.0.0"
source-map "^0.6.0"
-jest-validate@^23.0.1, jest-validate@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.5.0.tgz#f5df8f761cf43155e1b2e21d6e9de8a2852d0231"
+jest-validate@^23.0.1, jest-validate@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474"
dependencies:
chalk "^2.0.1"
jest-get-type "^22.1.0"
leven "^2.1.0"
- pretty-format "^23.5.0"
+ pretty-format "^23.6.0"
jest-watcher@^23.4.0:
version "23.4.0"
@@ -4950,28 +4808,28 @@ jest-worker@^23.2.0:
merge-stream "^1.0.1"
jest@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/jest/-/jest-23.5.0.tgz#80de353d156ea5ea4a7332f7962ac79135fbc62e"
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest/-/jest-23.6.0.tgz#ad5835e923ebf6e19e7a1d7529a432edfee7813d"
dependencies:
import-local "^1.0.0"
- jest-cli "^23.5.0"
+ jest-cli "^23.6.0"
js-base64@^2.1.8:
version "2.4.9"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.9.tgz#748911fb04f48a60c4771b375cac45a80df11c03"
js-levenshtein@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.3.tgz#3ef627df48ec8cf24bacf05c0f184ff30ef413c5"
-
-js-tokens@^3.0.0, js-tokens@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.4.tgz#3a56e3cbf589ca0081eb22cd9ba0b1290a16d26e"
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+js-tokens@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
+
js-yaml@3.6.1:
version "3.6.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30"
@@ -5065,7 +4923,7 @@ json-stringify-safe@~5.0.1:
json5@^0.5.0, json5@^0.5.1:
version "0.5.1"
- resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
+ resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
jsonfile@^3.0.0:
version "3.0.1"
@@ -5213,10 +5071,6 @@ labeled-stream-splicer@^2.0.0:
isarray "^2.0.4"
stream-splicer "^2.0.0"
-lazy-cache@^1.0.3:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
-
lcid@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
@@ -5265,7 +5119,7 @@ listenercount@~1.0.1:
load-json-file@^1.0.0:
version "1.1.0"
- resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
+ resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
dependencies:
graceful-fs "^4.1.2"
parse-json "^2.2.0"
@@ -5275,7 +5129,7 @@ load-json-file@^1.0.0:
load-json-file@^2.0.0:
version "2.0.0"
- resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
+ resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
dependencies:
graceful-fs "^4.1.2"
parse-json "^2.2.0"
@@ -5291,12 +5145,12 @@ load-json-file@^4.0.0:
pify "^3.0.0"
strip-bom "^3.0.0"
-localtunnel@1.9.0:
- version "1.9.0"
- resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.9.0.tgz#8ffecdcf8c8a14f62df1056cf9d54acbb0bb9a8f"
+localtunnel@1.9.1:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.9.1.tgz#1d1737eab658add5a40266d8e43f389b646ee3b1"
dependencies:
axios "0.17.1"
- debug "2.6.8"
+ debug "2.6.9"
openurl "1.1.1"
yargs "6.6.0"
@@ -5308,8 +5162,8 @@ locate-path@^2.0.0:
path-exists "^3.0.0"
lodash-es@^4.17.5:
- version "4.17.10"
- resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.10.tgz#62cd7104cdf5dd87f235a837f0ede0e8e5117e05"
+ version "4.17.11"
+ resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.11.tgz#145ab4a7ac5c5e52a3531fb4f310255a152b4be0"
lodash._basecopy@^3.0.0:
version "3.0.1"
@@ -5439,8 +5293,8 @@ lodash.templatesettings@^3.0.0:
lodash.escape "^3.0.0"
lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.10:
- version "4.17.10"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
+ version "4.17.11"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
lodash@~1.0.1:
version "1.0.2"
@@ -5450,10 +5304,6 @@ log-driver@1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056"
-longest@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
-
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -5488,6 +5338,10 @@ lru-queue@0.1:
dependencies:
es5-ext "~0.10.2"
+macos-release@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-1.1.0.tgz#831945e29365b470aa8724b0ab36c8f8959d10fb"
+
make-error-cause@^1.1.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/make-error-cause/-/make-error-cause-1.2.2.tgz#df0388fcd0b37816dff0a5fb8108939777dcbc9d"
@@ -5518,9 +5372,9 @@ map-obj@^1.0.0, map-obj@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
-map-stream@~0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
+map-stream@0.0.7:
+ version "0.0.7"
+ resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8"
map-visit@^1.0.0:
version "1.0.0"
@@ -5533,11 +5387,12 @@ math-random@^1.0.1:
resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac"
md5.js@^1.3.4:
- version "1.3.4"
- resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
dependencies:
hash-base "^3.0.0"
inherits "^2.0.1"
+ safe-buffer "^5.1.2"
md5@^2.1.0:
version "2.2.1"
@@ -5613,7 +5468,7 @@ micromatch@2.3.11, micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7:
parse-glob "^3.0.4"
regex-cache "^0.4.2"
-micromatch@^3.0.4, micromatch@^3.1.4:
+micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4:
version "3.1.10"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
dependencies:
@@ -5716,6 +5571,10 @@ minizlib@^1.1.0:
dependencies:
minipass "^2.2.1"
+mitt@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.1.3.tgz#528c506238a05dce11cd914a741ea2cc332da9b8"
+
mixin-deep@^1.2.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe"
@@ -5761,6 +5620,10 @@ ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
+ms@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
+
multipipe@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b"
@@ -5776,8 +5639,8 @@ mute-stream@0.0.7:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
nan@^2.10.0, nan@^2.9.2:
- version "2.11.0"
- resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099"
+ version "2.11.1"
+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766"
nanomatch@^1.2.9:
version "1.2.13"
@@ -5796,8 +5659,8 @@ nanomatch@^1.2.9:
to-regex "^3.0.1"
natives@^1.1.0:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.4.tgz#2f0f224fc9a7dd53407c7667c84cf8dbe773de58"
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.5.tgz#3bdbdb4104023e5dd239b56fc7ef3d9a17acc6aa"
natural-compare@^1.4.0:
version "1.4.0"
@@ -5814,8 +5677,8 @@ nearley@^2.7.10:
semver "^5.4.1"
needle@^2.2.1:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.2.tgz#1120ca4c41f2fcc6976fd28a8968afe239929418"
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e"
dependencies:
debug "^2.1.2"
iconv-lite "^0.4.4"
@@ -5848,13 +5711,6 @@ nimnjs@^1.3.2:
nimn-date-parser "^1.0.0"
nimn_schema_builder "^1.0.0"
-node-fetch@^1.0.1:
- version "1.7.3"
- resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
- dependencies:
- encoding "^0.1.11"
- is-stream "^1.0.1"
-
node-fetch@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5"
@@ -5908,9 +5764,9 @@ node-pre-gyp@^0.10.0:
semver "^5.3.0"
tar "^4"
-node-releases@^1.0.0-alpha.11:
- version "1.0.0-alpha.11"
- resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.0-alpha.11.tgz#73c810acc2e5b741a17ddfbb39dfca9ab9359d8a"
+node-releases@^1.0.0-alpha.12:
+ version "1.0.0-alpha.12"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.0-alpha.12.tgz#32e461b879ea76ac674e511d9832cf29da345268"
dependencies:
semver "^5.3.0"
@@ -5927,7 +5783,7 @@ node-sass-chokidar@^1.3.0:
sass-graph "^2.1.1"
stdout-stream "^1.4.0"
-node-sass@^4.9.2:
+node-sass@^4.9.2, node-sass@^4.9.3:
version "4.9.3"
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.9.3.tgz#f407cf3d66f78308bb1e346b24fa428703196224"
dependencies:
@@ -6190,7 +6046,7 @@ openurl@1.1.1:
opn@5.3.0:
version "5.3.0"
- resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c"
+ resolved "http://registry.npmjs.org/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c"
dependencies:
is-wsl "^1.1.0"
@@ -6246,6 +6102,13 @@ os-locale@^2.0.0:
lcid "^1.0.0"
mem "^1.1.0"
+os-name@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/os-name/-/os-name-2.0.1.tgz#b9a386361c17ae3a21736ef0599405c9a8c5dc5e"
+ dependencies:
+ macos-release "^1.0.0"
+ win-release "^1.0.0"
+
os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@@ -6305,7 +6168,7 @@ parents@^1.0.0, parents@^1.0.1:
parse-asn1@^5.0.0:
version "5.1.1"
- resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8"
+ resolved "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8"
dependencies:
asn1.js "^4.0.0"
browserify-aes "^1.0.0"
@@ -6455,15 +6318,15 @@ path-type@^3.0.0:
dependencies:
pify "^3.0.0"
-pause-stream@0.0.11:
+pause-stream@^0.0.11:
version "0.0.11"
- resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
+ resolved "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
dependencies:
through "~2.3"
pbkdf2@^3.0.3:
- version "3.0.16"
- resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c"
+ version "3.0.17"
+ resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
dependencies:
create-hash "^1.1.2"
create-hmac "^1.1.4"
@@ -6546,12 +6409,12 @@ preserve@^0.2.0:
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
prettier@^1.13.7, prettier@^1.14.2:
- version "1.14.2"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.2.tgz#0ac1c6e1a90baa22a62925f41963c841983282f9"
+ version "1.14.3"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895"
-pretty-format@^23.5.0:
- version "23.5.0"
- resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.5.0.tgz#0f9601ad9da70fe690a269cd3efca732c210687c"
+pretty-format@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760"
dependencies:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
@@ -6580,12 +6443,6 @@ progress@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
-promise@^7.1.1:
- version "7.3.1"
- resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
- dependencies:
- asap "~2.0.3"
-
prompts@^0.1.9:
version "0.1.14"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2"
@@ -6615,14 +6472,15 @@ psl@^1.1.24:
resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67"
public-encrypt@^4.0.0:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.2.tgz#46eb9107206bf73489f8b85b69d91334c6610994"
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
dependencies:
bn.js "^4.1.0"
browserify-rsa "^4.0.0"
create-hash "^1.1.0"
parse-asn1 "^5.0.0"
randombytes "^2.0.1"
+ safe-buffer "^5.1.2"
punycode@1.3.2:
version "1.3.2"
@@ -6717,13 +6575,13 @@ rc@^1.2.7:
strip-json-comments "~2.0.1"
react-dom@^16.4.2:
- version "16.4.2"
- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.4.2.tgz#4afed569689f2c561d2b8da0b819669c38a0bda4"
+ version "16.5.2"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.5.2.tgz#b69ee47aa20bab5327b2b9d7c1fe2a30f2cfa9d7"
dependencies:
- fbjs "^0.8.16"
loose-envify "^1.1.0"
object-assign "^4.1.1"
- prop-types "^15.6.0"
+ prop-types "^15.6.2"
+ schedule "^0.5.0"
react-dom@^16.5.2:
version "16.5.2"
@@ -6735,16 +6593,16 @@ react-dom@^16.5.2:
schedule "^0.5.0"
react-i18next@^7.9.0:
- version "7.11.1"
- resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-7.11.1.tgz#eacaec8357f5557eaf290eae198025fe0a682603"
+ version "7.13.0"
+ resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-7.13.0.tgz#a6f64fd749215ec70400f90da6cbde2a9c5b1588"
dependencies:
hoist-non-react-statics "^2.3.1"
html-parse-stringify2 "2.0.1"
prop-types "^15.6.0"
-react-is@^16.4.2:
- version "16.4.2"
- resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.4.2.tgz#84891b56c2b6d9efdee577cc83501dfc5ecead88"
+react-is@^16.5.2:
+ version "16.5.2"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.5.2.tgz#e2a7b7c3f5d48062eb769fcb123505eb928722e3"
react-jss@^8.6.0:
version "8.6.1"
@@ -6758,7 +6616,7 @@ react-jss@^8.6.0:
react-redux@^5.0.7:
version "5.0.7"
- resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
+ resolved "http://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
dependencies:
hoist-non-react-statics "^2.5.0"
invariant "^2.0.0"
@@ -6806,22 +6664,22 @@ react-router@^4.2.0, react-router@^4.3.1:
warning "^4.0.1"
react-test-renderer@^16.0.0-0, react-test-renderer@^16.4.1:
- version "16.4.2"
- resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.4.2.tgz#4e03eca9359bb3210d4373f7547d1364218ef74e"
+ version "16.5.2"
+ resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.5.2.tgz#92e9d2c6f763b9821b2e0b22f994ee675068b5ae"
dependencies:
- fbjs "^0.8.16"
object-assign "^4.1.1"
- prop-types "^15.6.0"
- react-is "^16.4.2"
+ prop-types "^15.6.2"
+ react-is "^16.5.2"
+ schedule "^0.5.0"
react@^16.4.2:
- version "16.4.2"
- resolved "https://registry.yarnpkg.com/react/-/react-16.4.2.tgz#2cd90154e3a9d9dd8da2991149fdca3c260e129f"
+ version "16.5.2"
+ resolved "https://registry.yarnpkg.com/react/-/react-16.5.2.tgz#19f6b444ed139baa45609eee6dc3d318b3895d42"
dependencies:
- fbjs "^0.8.16"
loose-envify "^1.1.0"
object-assign "^4.1.1"
- prop-types "^15.6.0"
+ prop-types "^15.6.2"
+ schedule "^0.5.0"
react@^16.5.2:
version "16.5.2"
@@ -6852,13 +6710,6 @@ read-pkg-up@^2.0.0:
find-up "^2.0.0"
read-pkg "^2.0.0"
-read-pkg-up@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07"
- dependencies:
- find-up "^2.0.0"
- read-pkg "^3.0.0"
-
read-pkg@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
@@ -6885,7 +6736,7 @@ read-pkg@^3.0.0:
"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.31:
version "1.0.34"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
+ resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
@@ -6894,7 +6745,7 @@ read-pkg@^3.0.0:
readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.5, readable-stream@^2.3.6:
version "2.3.6"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
+ resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
@@ -6906,7 +6757,7 @@ readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable
readable-stream@~1.1.9:
version "1.1.14"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
+ resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
@@ -6915,7 +6766,7 @@ readable-stream@~1.1.9:
readable-stream@~2.1.5:
version "2.1.5"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0"
+ resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0"
dependencies:
buffer-shims "^1.0.0"
core-util-is "~1.0.0"
@@ -6926,17 +6777,16 @@ readable-stream@~2.1.5:
util-deprecate "~1.0.1"
readdirp@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
dependencies:
- graceful-fs "^4.1.2"
- minimatch "^3.0.2"
+ graceful-fs "^4.1.11"
+ micromatch "^3.1.10"
readable-stream "^2.0.2"
- set-immediate-shim "^1.0.1"
realpath-native@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.1.tgz#07f40a0cce8f8261e2e8b7ebebf5c95965d7b633"
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560"
dependencies:
util.promisify "^1.0.0"
@@ -7018,8 +6868,8 @@ regex-not@^1.0.0, regex-not@^1.0.2:
safe-regex "^1.1.0"
regexpp@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.0.tgz#b2a7534a85ca1b033bcf5ce9ff8e56d4e0755365"
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
regexpu-core@^4.1.3, regexpu-core@^4.2.0:
version "4.2.0"
@@ -7240,12 +7090,6 @@ ret@~0.1.10:
version "0.1.15"
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
-right-align@^0.1.1:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
- dependencies:
- align-text "^0.1.1"
-
rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
@@ -7280,9 +7124,15 @@ rx@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
+rxjs@^5.5.6:
+ version "5.5.12"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc"
+ dependencies:
+ symbol-observable "1.0.1"
+
rxjs@^6.1.0:
- version "6.3.1"
- resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.1.tgz#878a1a8c64b8a5da11dcf74b5033fe944cdafb84"
+ version "6.3.3"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55"
dependencies:
tslib "^1.9.0"
@@ -7341,7 +7191,7 @@ scss-tokenizer@^0.2.3:
js-base64 "^2.1.8"
source-map "^0.4.2"
-"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1:
+"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1:
version "5.5.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477"
@@ -7404,10 +7254,6 @@ set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
-set-immediate-shim@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
-
set-value@^0.4.3:
version "0.4.3"
resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1"
@@ -7426,7 +7272,7 @@ set-value@^2.0.0:
is-plain-object "^2.0.3"
split-string "^3.0.1"
-setimmediate@^1.0.5, setimmediate@~1.0.4:
+setimmediate@~1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
@@ -7436,14 +7282,14 @@ setprototypeof@1.1.0:
sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4:
version "2.4.11"
- resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
+ resolved "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
dependencies:
inherits "^2.0.1"
safe-buffer "^5.0.1"
shasum@^1.0.0:
version "1.0.2"
- resolved "https://registry.yarnpkg.com/shasum/-/shasum-1.0.2.tgz#e7012310d8f417f4deb5712150e5678b87ae565f"
+ resolved "http://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz#e7012310d8f417f4deb5712150e5678b87ae565f"
dependencies:
json-stable-stringify "~0.0.0"
sha.js "~2.4.4"
@@ -7534,25 +7380,7 @@ socket.io-adapter@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b"
-socket.io-client@2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.0.4.tgz#0918a552406dc5e540b380dcd97afc4a64332f8e"
- dependencies:
- backo2 "1.0.2"
- base64-arraybuffer "0.1.5"
- component-bind "1.0.0"
- component-emitter "1.2.1"
- debug "~2.6.4"
- engine.io-client "~3.1.0"
- has-cors "1.1.0"
- indexof "0.0.1"
- object-component "0.0.3"
- parseqs "0.0.5"
- parseuri "0.0.5"
- socket.io-parser "~3.1.1"
- to-array "0.1.4"
-
-socket.io-client@2.1.1:
+socket.io-client@2.1.1, socket.io-client@^2.0.4:
version "2.1.1"
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.1.1.tgz#dcb38103436ab4578ddb026638ae2f21b623671f"
dependencies:
@@ -7571,15 +7399,6 @@ socket.io-client@2.1.1:
socket.io-parser "~3.2.0"
to-array "0.1.4"
-socket.io-parser@~3.1.1:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.1.3.tgz#ed2da5ee79f10955036e3da413bfd7f1e4d86c8e"
- dependencies:
- component-emitter "1.2.1"
- debug "~3.1.0"
- has-binary2 "~1.0.2"
- isarray "2.0.1"
-
socket.io-parser@~3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077"
@@ -7599,7 +7418,7 @@ socket.io@2.1.1:
socket.io-client "2.1.1"
socket.io-parser "~3.2.0"
-source-map-resolve@^0.5.0, source-map-resolve@^0.5.1:
+source-map-resolve@^0.5.0, source-map-resolve@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259"
dependencies:
@@ -7626,23 +7445,17 @@ source-map-url@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
-source-map@^0.1.38:
- version "0.1.43"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
- dependencies:
- amdefine ">=0.0.4"
-
-source-map@^0.4.2, source-map@^0.4.4:
+source-map@^0.4.2:
version "0.4.4"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
dependencies:
amdefine ">=0.0.4"
-source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, source-map@~0.5.3:
+source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.3:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
-source-map@^0.6.0, source-map@~0.6.0, source-map@~0.6.1:
+source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
@@ -7651,15 +7464,15 @@ sparkles@^1.0.0:
resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c"
spdx-correct@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82"
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e"
dependencies:
spdx-expression-parse "^3.0.0"
spdx-license-ids "^3.0.0"
spdx-exceptions@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9"
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977"
spdx-expression-parse@^3.0.0:
version "3.0.0"
@@ -7669,8 +7482,8 @@ spdx-expression-parse@^3.0.0:
spdx-license-ids "^3.0.0"
spdx-license-ids@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87"
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz#e2a303236cac54b04031fa7a5a79c7e701df852f"
split-string@^3.0.1, split-string@^3.0.2:
version "3.1.0"
@@ -7678,9 +7491,9 @@ split-string@^3.0.1, split-string@^3.0.2:
dependencies:
extend-shallow "^3.0.0"
-split@0.3:
- version "0.3.3"
- resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f"
+split@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
dependencies:
through "2"
@@ -7750,11 +7563,12 @@ stream-combiner2@^1.1.1:
duplexer2 "~0.1.0"
readable-stream "^2.0.2"
-stream-combiner@~0.0.4:
- version "0.0.4"
- resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14"
+stream-combiner@^0.2.2:
+ version "0.2.2"
+ resolved "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858"
dependencies:
duplexer "~0.1.1"
+ through "~2.3.4"
stream-consume@~0.1.0:
version "0.1.1"
@@ -7838,7 +7652,7 @@ stringstream@~0.0.4:
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"
+ resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
dependencies:
ansi-regex "^2.0.0"
@@ -7911,6 +7725,10 @@ supports-color@^5.3.0:
dependencies:
has-flag "^3.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@^1.1.0, symbol-observable@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
@@ -7957,12 +7775,13 @@ tar@^4:
yallist "^3.0.2"
test-exclude@^4.2.1:
- version "4.2.2"
- resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.2.tgz#8b67aa8408f84afc225b06669e25c510f8582820"
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20"
dependencies:
arrify "^1.0.1"
- minimatch "^3.0.4"
- read-pkg-up "^3.0.0"
+ micromatch "^2.3.11"
+ object-assign "^4.1.0"
+ read-pkg-up "^1.0.1"
require-main-filename "^1.0.1"
text-table@^0.2.0:
@@ -8003,9 +7822,9 @@ through2@^0.6.1:
readable-stream ">=1.0.33-1 <1.1.0-0"
xtend ">=4.0.0 <4.1.0-0"
-through@2, "through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.1:
+through@2, "through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.4:
version "2.3.8"
- resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+ resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
tildify@^1.0.0:
version "1.2.0"
@@ -8028,10 +7847,10 @@ timers-browserify@^1.0.1:
process "~0.11.0"
timers-ext@^0.1.5:
- version "0.1.5"
- resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.5.tgz#77147dd4e76b660c2abb8785db96574cbbd12922"
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6"
dependencies:
- es5-ext "~0.10.14"
+ es5-ext "~0.10.46"
next-tick "1"
tmp@^0.0.33:
@@ -8159,30 +7978,13 @@ ua-parser-js@0.7.17:
version "0.7.17"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
-ua-parser-js@^0.7.18:
- version "0.7.18"
- resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.18.tgz#a7bfd92f56edfb117083b69e31d2aa8882d4b1ed"
-
-uglify-js@^2.6:
- version "2.8.29"
- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
- dependencies:
- source-map "~0.5.1"
- yargs "~3.10.0"
- optionalDependencies:
- uglify-to-browserify "~1.0.0"
-
-uglify-js@^3.0.5:
+uglify-js@^3.0.5, uglify-js@^3.1.4:
version "3.4.9"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3"
dependencies:
commander "~2.17.1"
source-map "~0.6.1"
-uglify-to-browserify@~1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
-
ultron@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
@@ -8240,6 +8042,12 @@ unique-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b"
+universal-user-agent@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-2.0.1.tgz#18e591ca52b1cb804f6b9cbc4c336cf8191f80e1"
+ dependencies:
+ os-name "^2.0.1"
+
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
@@ -8483,18 +8291,14 @@ webidl-conversions@^4.0.2:
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.4.tgz#63fb016b7435b795d9025632c086a5209dbd2621"
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
dependencies:
- iconv-lite "0.4.23"
-
-whatwg-fetch@>=0.10.0:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f"
+ iconv-lite "0.4.24"
whatwg-mimetype@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz#f0f21d76cbba72362eb609dbed2a30cd17fcc7d4"
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.2.0.tgz#a3d58ef10b76009b042d03e25591ece89b88d171"
whatwg-url@^6.4.1:
version "6.5.0"
@@ -8532,18 +8336,16 @@ wide-align@^1.1.0:
dependencies:
string-width "^1.0.2 || 2"
-window-size@0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
+win-release@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/win-release/-/win-release-1.1.1.tgz#5fa55e02be7ca934edfc12665632e849b72e5209"
+ dependencies:
+ semver "^5.0.1"
window-size@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075"
-wordwrap@0.0.2:
- version "0.0.2"
- resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
-
wordwrap@~0.0.2:
version "0.0.3"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
@@ -8632,14 +8434,14 @@ yallist@^3.0.0, yallist@^3.0.2:
yargs-parser@^2.4.1:
version "2.4.1"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4"
+ resolved "http://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4"
dependencies:
camelcase "^3.0.0"
lodash.assign "^4.0.6"
yargs-parser@^4.1.0, yargs-parser@^4.2.0:
version "4.2.1"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c"
+ resolved "http://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c"
dependencies:
camelcase "^3.0.0"
@@ -8657,7 +8459,7 @@ yargs-parser@^9.0.2:
yargs@6.4.0:
version "6.4.0"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.4.0.tgz#816e1a866d5598ccf34e5596ddce22d92da490d4"
+ resolved "http://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz#816e1a866d5598ccf34e5596ddce22d92da490d4"
dependencies:
camelcase "^3.0.0"
cliui "^3.2.0"
@@ -8676,7 +8478,7 @@ yargs@6.4.0:
yargs@6.6.0:
version "6.6.0"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208"
+ resolved "http://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208"
dependencies:
camelcase "^3.0.0"
cliui "^3.2.0"
@@ -8694,7 +8496,7 @@ yargs@6.6.0:
yargs@^11.0.0:
version "11.1.0"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77"
+ resolved "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77"
dependencies:
cliui "^4.0.0"
decamelize "^1.1.1"
@@ -8711,7 +8513,7 @@ yargs@^11.0.0:
yargs@^4.2.0:
version "4.8.1"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0"
+ resolved "http://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0"
dependencies:
cliui "^3.2.0"
decamelize "^1.1.1"
@@ -8746,15 +8548,6 @@ yargs@^7.0.0:
y18n "^3.2.1"
yargs-parser "^5.0.0"
-yargs@~3.10.0:
- version "3.10.0"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"
- dependencies:
- camelcase "^1.0.2"
- cliui "^2.1.0"
- decamelize "^1.0.0"
- window-size "0.1.0"
-
yeast@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
diff --git a/scm-webapp/src/main/doc/enunciate.xml b/scm-webapp/src/main/doc/enunciate.xml
index 9bed97455a..6e7fc218aa 100644
--- a/scm-webapp/src/main/doc/enunciate.xml
+++ b/scm-webapp/src/main/doc/enunciate.xml
@@ -62,7 +62,7 @@
-
+
diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java
index e9ec9e4a39..90764a7e00 100644
--- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java
+++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java
@@ -152,7 +152,7 @@ public class ScmServletModule extends ServletModule
public static final String PATTERN_PLUGIN_SCRIPT = "/plugins/resources/js/*";
/** Field description */
- public static final String PATTERN_RESTAPI = "/api/rest/*";
+ public static final String PATTERN_RESTAPI = "/api/*";
/** Field description */
public static final String PATTERN_SCRIPT = "*.js";
diff --git a/scm-webapp/src/main/java/sonia/scm/WebResourceServlet.java b/scm-webapp/src/main/java/sonia/scm/WebResourceServlet.java
index 059c990718..6b4a29961d 100644
--- a/scm-webapp/src/main/java/sonia/scm/WebResourceServlet.java
+++ b/scm-webapp/src/main/java/sonia/scm/WebResourceServlet.java
@@ -58,8 +58,10 @@ public class WebResourceServlet extends HttpServlet {
LOG.trace("try to load {}", uri);
URL url = webResourceLoader.getResource(uri);
if (url != null) {
+ LOG.trace("found {} -- serve as resource {}", uri, url);
serveResource(request, response, url);
} else {
+ LOG.trace("could not find {} -- dispatch", uri);
dispatch(request, response, uri);
}
}
@@ -79,6 +81,7 @@ public class WebResourceServlet extends HttpServlet {
private void serveResource(HttpServletRequest request, HttpServletResponse response, URL url) {
try {
+ LOG.debug("using sender to serve {}", request.getRequestURI());
sender.resource(url).send(request, response);
} catch (IOException ex) {
LOG.warn("failed to serve resource: {}", url);
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/ValidationConstraints.java b/scm-webapp/src/main/java/sonia/scm/api/v2/ValidationConstraints.java
new file mode 100644
index 0000000000..b136ee1bf7
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/ValidationConstraints.java
@@ -0,0 +1,14 @@
+package sonia.scm.api.v2;
+
+public final class ValidationConstraints {
+
+ private ValidationConstraints() {}
+
+ /**
+ * A user or group name should not start with @ or a whitespace
+ * and it not contains whitespaces
+ * and the characters: . - _ @ are allowed
+ */
+ public static final String USER_GROUP_PATTERN = "^[A-Za-z0-9\\.\\-_][A-Za-z0-9\\.\\-_@]*$";
+
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteResource.java
new file mode 100644
index 0000000000..005e29e9ea
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AutoCompleteResource.java
@@ -0,0 +1,79 @@
+package sonia.scm.api.v2.resources;
+
+import com.webcohesion.enunciate.metadata.rs.ResponseCode;
+import com.webcohesion.enunciate.metadata.rs.StatusCodes;
+import org.hibernate.validator.constraints.NotEmpty;
+import sonia.scm.ReducedModelObject;
+import sonia.scm.group.GroupManager;
+import sonia.scm.user.UserManager;
+import sonia.scm.web.VndMediaType;
+
+import javax.inject.Inject;
+import javax.validation.constraints.Size;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+@Path(AutoCompleteResource.PATH)
+public class AutoCompleteResource {
+ public static final String PATH = "v2/autocomplete/";
+ public static final int MIN_SEARCHED_CHARS = 2;
+
+ public static final String PARAMETER_IS_REQUIRED = "The parameter is required.";
+ public static final String INVALID_PARAMETER_LENGTH = "Invalid parameter length.";
+
+
+ private ReducedObjectModelToDtoMapper mapper;
+
+ private UserManager userManager;
+ private GroupManager groupManager;
+
+ @Inject
+ public AutoCompleteResource(ReducedObjectModelToDtoMapper mapper, UserManager userManager, GroupManager groupManager) {
+ this.mapper = mapper;
+ this.userManager = userManager;
+ this.groupManager = groupManager;
+ }
+
+ @GET
+ @Path("users")
+ @Produces(VndMediaType.AUTOCOMPLETE)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 400, condition = "if the searched string contains less than 2 characters"),
+ @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
+ @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user:autocomplete\" privilege"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ public List searchUser(@NotEmpty(message = PARAMETER_IS_REQUIRED) @Size(min = MIN_SEARCHED_CHARS, message = INVALID_PARAMETER_LENGTH) @QueryParam("q") String filter) {
+ return map(userManager.autocomplete(filter));
+ }
+
+ @GET
+ @Path("groups")
+ @Produces(VndMediaType.AUTOCOMPLETE)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "success"),
+ @ResponseCode(code = 400, condition = "if the searched string contains less than 2 characters"),
+ @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
+ @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"group:autocomplete\" privilege"),
+ @ResponseCode(code = 500, condition = "internal server error")
+ })
+ public List searchGroup(@NotEmpty(message = PARAMETER_IS_REQUIRED) @Size(min = MIN_SEARCHED_CHARS, message = INVALID_PARAMETER_LENGTH) @QueryParam("q") String filter) {
+ return map(groupManager.autocomplete(filter));
+ }
+
+ private List map(Collection autocomplete) {
+ return autocomplete
+ .stream()
+ .map(mapper::map)
+ .collect(Collectors.toList());
+ }
+
+
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchChangesetCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchChangesetCollectionToDtoMapper.java
index afe8ad318b..8842d176fa 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchChangesetCollectionToDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchChangesetCollectionToDtoMapper.java
@@ -12,12 +12,12 @@ public class BranchChangesetCollectionToDtoMapper extends ChangesetCollectionToD
@Inject
public BranchChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
- super(changesetToChangesetDtoMapper);
+ super(changesetToChangesetDtoMapper, resourceLinks);
this.resourceLinks = resourceLinks;
}
public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository, String branch) {
- return this.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository, branch));
+ return this.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository, branch), branch);
}
private String createSelfLink(Repository repository, String branch) {
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchReferenceDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchReferenceDto.java
new file mode 100644
index 0000000000..129d8d8bfa
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchReferenceDto.java
@@ -0,0 +1,19 @@
+package sonia.scm.api.v2.resources;
+
+import de.otto.edison.hal.HalRepresentation;
+import de.otto.edison.hal.Links;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor @AllArgsConstructor @Getter @Setter
+public class BranchReferenceDto extends HalRepresentation {
+ private String name;
+
+ @Override
+ @SuppressWarnings("squid:S1185") // We want to have this method available in this package
+ protected HalRepresentation add(Links links) {
+ return super.add(links);
+ }
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java
index 24ee9b0ce1..87f3454e0f 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java
@@ -12,10 +12,13 @@ public class ChangesetCollectionToDtoMapper extends ChangesetCollectionToDtoMapp
@Inject
public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
- super(changesetToChangesetDtoMapper);
+ super(changesetToChangesetDtoMapper, resourceLinks);
this.resourceLinks = resourceLinks;
}
+ public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository, String branchName) {
+ return super.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository), branchName);
+ }
public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository) {
return super.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository));
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperBase.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperBase.java
index e29a0a92b2..a34b7d44d6 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperBase.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperBase.java
@@ -1,5 +1,6 @@
package sonia.scm.api.v2.resources;
+import de.otto.edison.hal.Links;
import sonia.scm.PageResult;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.Repository;
@@ -10,14 +11,28 @@ import java.util.function.Supplier;
class ChangesetCollectionToDtoMapperBase extends PagedCollectionToDtoMapper {
private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper;
+ private final ResourceLinks resourceLinks;
- ChangesetCollectionToDtoMapperBase(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper) {
+ ChangesetCollectionToDtoMapperBase(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
super("changesets");
this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper;
+ this.resourceLinks = resourceLinks;
}
CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository, Supplier selfLinkSupplier) {
return super.map(pageNumber, pageSize, pageResult, selfLinkSupplier.get(), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository));
}
-}
+ CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository, Supplier selfLinkSupplier, String branchName) {
+ CollectionDto collectionDto = this.map(pageNumber, pageSize, pageResult, repository, selfLinkSupplier);
+ collectionDto.withEmbedded("branch", createBranchReferenceDto(repository, branchName));
+ return collectionDto;
+ }
+
+ private BranchReferenceDto createBranchReferenceDto(Repository repository, String branchName) {
+ BranchReferenceDto branchReferenceDto = new BranchReferenceDto();
+ branchReferenceDto.setName(branchName);
+ branchReferenceDto.add(Links.linkingTo().self(resourceLinks.branch().self(repository.getNamespaceAndName(), branchName)).build());
+ return branchReferenceDto;
+ }
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java
index 97a23684a5..8900183f5b 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java
@@ -67,7 +67,11 @@ public class ChangesetRootResource {
.getChangesets();
if (changesets != null && changesets.getChangesets() != null) {
PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal());
- return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build();
+ if (changesets.getBranchName() != null) {
+ return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository, changesets.getBranchName())).build();
+ } else {
+ return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build();
+ }
} else {
return Response.ok().build();
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionDto.java
index c10e18267c..b59d697c2e 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionDto.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionDto.java
@@ -15,4 +15,9 @@ class CollectionDto extends HalRepresentation {
CollectionDto(Links links, Embedded embedded) {
super(links, embedded);
}
+
+ @Override
+ protected HalRepresentation withEmbedded(String rel, HalRepresentation embeddedItem) {
+ return super.withEmbedded(rel, embeddedItem);
+ }
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java
index af7fb2ed83..57e5667c65 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java
@@ -13,7 +13,7 @@ public class FileHistoryCollectionToDtoMapper extends ChangesetCollectionToDtoMa
@Inject
public FileHistoryCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
- super(changesetToChangesetDtoMapper);
+ super(changesetToChangesetDtoMapper, resourceLinks);
this.resourceLinks = resourceLinks;
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java
index 2577b46c4e..760beab1da 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java
@@ -13,6 +13,8 @@ import java.time.Instant;
import java.util.List;
import java.util.Map;
+import static sonia.scm.api.v2.ValidationConstraints.USER_GROUP_PATTERN;
+
@Getter @Setter @NoArgsConstructor
public class GroupDto extends HalRepresentation {
@@ -20,7 +22,7 @@ public class GroupDto extends HalRepresentation {
private String description;
@JsonInclude(JsonInclude.Include.NON_NULL)
private Instant lastModified;
- @Pattern(regexp = "^[A-z0-9\\.\\-_@]|[^ ]([A-z0-9\\.\\-_@ ]*[A-z0-9\\.\\-_@]|[^ ])?$")
+ @Pattern(regexp = USER_GROUP_PATTERN)
private String name;
private String type;
private Map properties;
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDto.java
new file mode 100644
index 0000000000..9346420f58
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDto.java
@@ -0,0 +1,16 @@
+package sonia.scm.api.v2.resources;
+
+import de.otto.edison.hal.HalRepresentation;
+import de.otto.edison.hal.Links;
+import lombok.Getter;
+
+@Getter
+public class IndexDto extends HalRepresentation {
+
+ private final String version;
+
+ IndexDto(String version, Links links) {
+ super(links);
+ this.version = version;
+ }
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDtoGenerator.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDtoGenerator.java
new file mode 100644
index 0000000000..da4368d9b9
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDtoGenerator.java
@@ -0,0 +1,61 @@
+package sonia.scm.api.v2.resources;
+
+import com.google.common.collect.Lists;
+import de.otto.edison.hal.Link;
+import de.otto.edison.hal.Links;
+import org.apache.shiro.SecurityUtils;
+import sonia.scm.SCMContextProvider;
+import sonia.scm.config.ConfigurationPermissions;
+import sonia.scm.group.GroupPermissions;
+import sonia.scm.user.UserPermissions;
+
+import javax.inject.Inject;
+import java.util.List;
+
+import static de.otto.edison.hal.Link.link;
+
+public class IndexDtoGenerator {
+
+ private final ResourceLinks resourceLinks;
+ private final SCMContextProvider scmContextProvider;
+
+ @Inject
+ public IndexDtoGenerator(ResourceLinks resourceLinks, SCMContextProvider scmContextProvider) {
+ this.resourceLinks = resourceLinks;
+ this.scmContextProvider = scmContextProvider;
+ }
+
+ public IndexDto generate() {
+ Links.Builder builder = Links.linkingTo();
+ List autoCompleteLinks = Lists.newArrayList();
+ builder.self(resourceLinks.index().self());
+ builder.single(link("uiPlugins", resourceLinks.uiPluginCollection().self()));
+ if (SecurityUtils.getSubject().isAuthenticated()) {
+ builder.single(
+ link("me", resourceLinks.me().self()),
+ link("logout", resourceLinks.authentication().logout())
+ );
+ if (UserPermissions.list().isPermitted()) {
+ builder.single(link("users", resourceLinks.userCollection().self()));
+ }
+ if (UserPermissions.autocomplete().isPermitted()) {
+ autoCompleteLinks.add(Link.linkBuilder("autocomplete", resourceLinks.autoComplete().users()).withName("users").build());
+ }
+ if (GroupPermissions.autocomplete().isPermitted()) {
+ autoCompleteLinks.add(Link.linkBuilder("autocomplete", resourceLinks.autoComplete().groups()).withName("groups").build());
+ }
+ builder.array(autoCompleteLinks);
+ if (GroupPermissions.list().isPermitted()) {
+ builder.single(link("groups", resourceLinks.groupCollection().self()));
+ }
+ if (ConfigurationPermissions.list().isPermitted()) {
+ builder.single(link("config", resourceLinks.config().self()));
+ }
+ builder.single(link("repositories", resourceLinks.repositoryCollection().self()));
+ } else {
+ builder.single(link("login", resourceLinks.authentication().jsonLogin()));
+ }
+
+ return new IndexDto(scmContextProvider.getVersion(), builder.build());
+ }
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexResource.java
new file mode 100644
index 0000000000..088558c7dc
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexResource.java
@@ -0,0 +1,29 @@
+package sonia.scm.api.v2.resources;
+
+import com.webcohesion.enunciate.metadata.rs.TypeHint;
+import sonia.scm.web.VndMediaType;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+@Path(IndexResource.INDEX_PATH_V2)
+public class IndexResource {
+ public static final String INDEX_PATH_V2 = "v2/";
+
+ private final IndexDtoGenerator indexDtoGenerator;
+
+ @Inject
+ public IndexResource(IndexDtoGenerator indexDtoGenerator) {
+ this.indexDtoGenerator = indexDtoGenerator;
+ }
+
+ @GET
+ @Path("")
+ @Produces(VndMediaType.INDEX)
+ @TypeHint(IndexDto.class)
+ public IndexDto getIndex() {
+ return indexDtoGenerator.generate();
+ }
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java
index 03b5728627..6497cb9315 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java
@@ -37,6 +37,8 @@ public class MapperModule extends AbstractModule {
bind(FileObjectToFileObjectDtoMapper.class).to(Mappers.getMapper(FileObjectToFileObjectDtoMapper.class).getClass());
bind(ModificationsToDtoMapper.class).to(Mappers.getMapper(ModificationsToDtoMapper.class).getClass());
+ bind(ReducedObjectModelToDtoMapper.class).to(Mappers.getMapper(ReducedObjectModelToDtoMapper.class).getClass());
+
// no mapstruct required
bind(UIPluginDtoMapper.class);
bind(UIPluginDtoCollectionMapper.class);
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionDto.java
index 581b2c24cd..82405a6ac2 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionDto.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionDto.java
@@ -4,15 +4,20 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Links;
import lombok.Getter;
+import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
-@Getter @Setter @ToString
+import javax.validation.constraints.Pattern;
+
+import static sonia.scm.api.v2.ValidationConstraints.USER_GROUP_PATTERN;
+
+@Getter @Setter @ToString @NoArgsConstructor
public class PermissionDto extends HalRepresentation {
public static final String GROUP_PREFIX = "@";
- @JsonInclude(JsonInclude.Include.NON_NULL)
+ @Pattern(regexp = USER_GROUP_PATTERN)
private String name;
/**
@@ -28,9 +33,6 @@ public class PermissionDto extends HalRepresentation {
private boolean groupPermission = false;
- public PermissionDto() {
- }
-
public PermissionDto(String permissionName, boolean groupPermission) {
name = permissionName;
this.groupPermission = groupPermission;
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java
index b7f6df8c2d..af1ba3bf64 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java
@@ -16,6 +16,7 @@ import sonia.scm.repository.RepositoryPermissions;
import sonia.scm.web.VndMediaType;
import javax.inject.Inject;
+import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
@@ -70,14 +71,15 @@ public class PermissionRootResource {
@TypeHint(TypeHint.NO_CONTENT.class)
@Consumes(VndMediaType.PERMISSION)
@Path("")
- public Response create(@PathParam("namespace") String namespace, @PathParam("name") String name, PermissionDto permission) throws Exception {
+ public Response create(@PathParam("namespace") String namespace, @PathParam("name") String name,@Valid PermissionDto permission) throws AlreadyExistsException, NotFoundException {
log.info("try to add new permission: {}", permission);
Repository repository = load(namespace, name);
RepositoryPermissions.permissionWrite(repository).check();
checkPermissionAlreadyExists(permission, repository);
repository.getPermissions().add(dtoToModelMapper.map(permission));
manager.modify(repository);
- return Response.created(URI.create(resourceLinks.permission().self(namespace, name, permission.getName()))).build();
+ String urlPermissionName = modelToDtoMapper.getUrlPermissionName(permission);
+ return Response.created(URI.create(resourceLinks.permission().self(namespace, name, urlPermissionName))).build();
}
@@ -156,7 +158,7 @@ public class PermissionRootResource {
public Response update(@PathParam("namespace") String namespace,
@PathParam("name") String name,
@PathParam("permission-name") String permissionName,
- PermissionDto permission) throws NotFoundException, AlreadyExistsException {
+ @Valid PermissionDto permission) throws NotFoundException, AlreadyExistsException {
log.info("try to update the permission with name: {}. the modified permission is: {}", permissionName, permission);
Repository repository = load(namespace, name);
RepositoryPermissions.permissionWrite(repository).check();
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionToPermissionDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionToPermissionDtoMapper.java
index 8ebe10eb6f..d6ab3721cf 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionToPermissionDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionToPermissionDtoMapper.java
@@ -41,9 +41,7 @@ public abstract class PermissionToPermissionDtoMapper {
*/
@AfterMapping
void appendLinks(@MappingTarget PermissionDto target, @Context Repository repository) {
- String permissionName = Optional.of(target.getName())
- .filter(p -> !target.isGroupPermission())
- .orElse(GROUP_PREFIX + target.getName());
+ String permissionName = getUrlPermissionName(target);
Links.Builder linksBuilder = linkingTo()
.self(resourceLinks.permission().self(repository.getNamespace(), repository.getName(), permissionName));
if (RepositoryPermissions.permissionWrite(repository).isPermitted()) {
@@ -52,4 +50,10 @@ public abstract class PermissionToPermissionDtoMapper {
}
target.add(linksBuilder.build());
}
+
+ public String getUrlPermissionName(PermissionDto permissionDto) {
+ return Optional.of(permissionDto.getName())
+ .filter(p -> !permissionDto.isGroupPermission())
+ .orElse(GROUP_PREFIX + permissionDto.getName());
+ }
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelDto.java
new file mode 100644
index 0000000000..821af03995
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelDto.java
@@ -0,0 +1,16 @@
+package sonia.scm.api.v2.resources;
+
+import de.otto.edison.hal.HalRepresentation;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+public class ReducedObjectModelDto extends HalRepresentation {
+
+ private String id;
+
+ private String displayName;
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelToDtoMapper.java
new file mode 100644
index 0000000000..e188de7d65
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ReducedObjectModelToDtoMapper.java
@@ -0,0 +1,13 @@
+package sonia.scm.api.v2.resources;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import sonia.scm.ReducedModelObject;
+
+@Mapper
+public abstract class ReducedObjectModelToDtoMapper {
+
+ @Mapping(target = "attributes", ignore = true) // We do not map HAL attributes
+ public abstract ReducedObjectModelDto map(ReducedModelObject modelObject);
+
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java
index e978de443a..820e722814 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java
@@ -3,7 +3,6 @@ package sonia.scm.api.v2.resources;
import sonia.scm.repository.NamespaceAndName;
import javax.inject.Inject;
-import javax.ws.rs.core.UriInfo;
import java.net.URI;
class ResourceLinks {
@@ -143,6 +142,26 @@ class ResourceLinks {
}
}
+ AutoCompleteLinks autoComplete() {
+ return new AutoCompleteLinks (scmPathInfoStore.get());
+ }
+
+ static class AutoCompleteLinks {
+ private final LinkBuilder linkBuilder;
+
+ AutoCompleteLinks (ScmPathInfo pathInfo) {
+ linkBuilder = new LinkBuilder(pathInfo, AutoCompleteResource.class);
+ }
+
+ String users() {
+ return linkBuilder.method("searchUser").parameters().href();
+ }
+
+ String groups() {
+ return linkBuilder.method("searchGroup").parameters().href();
+ }
+ }
+
ConfigLinks config() {
return new ConfigLinks(scmPathInfoStore.get());
}
@@ -441,7 +460,6 @@ class ResourceLinks {
}
}
-
public UIPluginLinks uiPlugin() {
return new UIPluginLinks(scmPathInfoStore.get());
}
@@ -473,4 +491,45 @@ class ResourceLinks {
return uiPluginCollectionLinkBuilder.method("plugins").parameters().method("getInstalledPlugins").parameters().href();
}
}
+
+ public AuthenticationLinks authentication() {
+ return new AuthenticationLinks(scmPathInfoStore.get());
+ }
+
+ static class AuthenticationLinks {
+ private final LinkBuilder loginLinkBuilder;
+
+ AuthenticationLinks(ScmPathInfo pathInfo) {
+ this.loginLinkBuilder = new LinkBuilder(pathInfo, AuthenticationResource.class);
+ }
+
+ String formLogin() {
+ return loginLinkBuilder.method("authenticateViaForm").parameters().href();
+ }
+
+ String jsonLogin() {
+ return loginLinkBuilder.method("authenticateViaJSONBody").parameters().href();
+ }
+
+ String logout() {
+ return loginLinkBuilder.method("logout").parameters().href();
+ }
+ }
+
+ public IndexLinks index() {
+ return new IndexLinks(scmPathInfoStore.get());
+ }
+
+ static class IndexLinks {
+ private final LinkBuilder indexLinkBuilder;
+
+ IndexLinks(ScmPathInfo pathInfo) {
+ indexLinkBuilder = new LinkBuilder(pathInfo, IndexResource.class);
+ }
+
+ String self() {
+ return indexLinkBuilder.method("getIndex").parameters().href();
+ }
+ }
+
}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserDto.java
index 4e4345445a..9dc5b850bd 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserDto.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserDto.java
@@ -13,6 +13,8 @@ import javax.validation.constraints.Pattern;
import java.time.Instant;
import java.util.Map;
+import static sonia.scm.api.v2.ValidationConstraints.USER_GROUP_PATTERN;
+
@NoArgsConstructor @Getter @Setter
public class UserDto extends HalRepresentation {
private boolean active;
@@ -24,7 +26,7 @@ public class UserDto extends HalRepresentation {
private Instant lastModified;
@NotEmpty @Email
private String mail;
- @Pattern(regexp = "^[A-z0-9\\.\\-_@]|[^ ]([A-z0-9\\.\\-_@ ]*[A-z0-9\\.\\-_@]|[^ ])?$")
+ @Pattern(regexp = USER_GROUP_PATTERN)
private String name;
@JsonInclude(JsonInclude.Include.NON_NULL)
private String password;
diff --git a/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java b/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java
index de0d689c52..d97a5b050e 100644
--- a/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java
+++ b/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java
@@ -84,7 +84,7 @@ public class SecurityFilter extends HttpFilter
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException
{
- if (!SecurityRequests.isAuthenticationRequest(request))
+ if (!SecurityRequests.isAuthenticationRequest(request) && !SecurityRequests.isIndexRequest(request))
{
Subject subject = SecurityUtils.getSubject();
if (hasPermission(subject))
diff --git a/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java b/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java
index c3dcb6db8c..655e0001ce 100644
--- a/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java
+++ b/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java
@@ -242,6 +242,13 @@ public class DefaultGroupManager extends AbstractGroupManager
return group;
}
+ @Override
+ public Collection autocomplete(String filter) {
+ GroupPermissions.autocomplete().check();
+ SearchRequest searchRequest = new SearchRequest(filter, true, DEFAULT_LIMIT);
+ return SearchUtil.search(searchRequest, groupDAO.getAll(), group -> matches(searchRequest,group)?group:null);
+ }
+
/**
* Method description
*
diff --git a/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java b/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java
index 1b9abb058b..36b7f4089d 100644
--- a/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java
+++ b/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java
@@ -52,10 +52,13 @@ import org.slf4j.LoggerFactory;
import sonia.scm.cache.Cache;
import sonia.scm.cache.CacheManager;
import sonia.scm.group.GroupNames;
+import sonia.scm.group.GroupPermissions;
import sonia.scm.plugin.Extension;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryDAO;
+import sonia.scm.repository.RepositoryPermissions;
import sonia.scm.user.User;
+import sonia.scm.user.UserPermissions;
import sonia.scm.util.Util;
import java.util.List;
@@ -74,7 +77,7 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
// TODO move to util class
private static final String SEPARATOR = System.getProperty("line.separator", "\n");
-
+
/** Field description */
private static final String ADMIN_PERMISSION = "*";
@@ -88,7 +91,7 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
LoggerFactory.getLogger(DefaultAuthorizationCollector.class);
//~--- constructors ---------------------------------------------------------
-
+
/**
* Constructs ...
*
@@ -209,7 +212,7 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
String perm = permission.getType().getPermissionPrefix().concat(repository.getId());
if (logger.isTraceEnabled())
{
- logger.trace("add repository permission {} for user {} at repository {}",
+ logger.trace("add repository permission {} for user {} at repository {}",
perm, user.getName(), repository.getName());
}
@@ -254,6 +257,9 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
collectGlobalPermissions(builder, user, groups);
collectRepositoryPermissions(builder, user, groups);
+ builder.add(canReadOwnUser(user));
+ builder.add(getUserAutocompletePermission());
+ builder.add(getGroupAutocompletePermission());
permissions = builder.build();
}
@@ -262,6 +268,18 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
return info;
}
+ private String getGroupAutocompletePermission() {
+ return GroupPermissions.autocomplete().asShiroString();
+ }
+
+ private String getUserAutocompletePermission() {
+ return UserPermissions.autocomplete().asShiroString();
+ }
+
+ private String canReadOwnUser(User user) {
+ return UserPermissions.read(user.getName()).asShiroString();
+ }
+
//~--- get methods ----------------------------------------------------------
private boolean isUserPermitted(User user, GroupNames groups,
@@ -272,7 +290,7 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
|| ((!perm.isGroupPermission()) && user.getName().equals(perm.getName()));
//J+
}
-
+
@Subscribe
public void invalidateCache(AuthorizationChangedEvent event) {
if (event.isEveryUserAffected()) {
@@ -281,12 +299,12 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
invalidateCache();
}
}
-
+
private void invalidateUserCache(final String username) {
logger.info("invalidate cache for user {}, because of a received authorization event", username);
cache.removeAll((CacheKey item) -> username.equalsIgnoreCase(item.username));
}
-
+
private void invalidateCache() {
logger.info("invalidate cache, because of a received authorization event");
cache.clear();
diff --git a/scm-webapp/src/main/java/sonia/scm/security/SecurityRequests.java b/scm-webapp/src/main/java/sonia/scm/security/SecurityRequests.java
index 81bb2092c9..49d03f598b 100644
--- a/scm-webapp/src/main/java/sonia/scm/security/SecurityRequests.java
+++ b/scm-webapp/src/main/java/sonia/scm/security/SecurityRequests.java
@@ -11,6 +11,7 @@ import static sonia.scm.api.v2.resources.ScmPathInfo.REST_API_PATH;
public final class SecurityRequests {
private static final Pattern URI_LOGIN_PATTERN = Pattern.compile(REST_API_PATH + "(?:/v2)?/auth/access_token");
+ private static final Pattern URI_INDEX_PATTERN = Pattern.compile(REST_API_PATH + "/v2/?");
private SecurityRequests() {}
@@ -23,4 +24,13 @@ public final class SecurityRequests {
return URI_LOGIN_PATTERN.matcher(uri).matches();
}
+ public static boolean isIndexRequest(HttpServletRequest request) {
+ String uri = request.getRequestURI().substring(request.getContextPath().length());
+ return isIndexRequest(uri);
+ }
+
+ public static boolean isIndexRequest(String uri) {
+ return URI_INDEX_PATTERN.matcher(uri).matches();
+ }
+
}
diff --git a/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java b/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java
index 876b0f094c..21cd4cc319 100644
--- a/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java
+++ b/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java
@@ -229,6 +229,13 @@ public class DefaultUserManager extends AbstractUserManager
fresh.copyProperties(user);
}
+ @Override
+ public Collection autocomplete(String filter) {
+ UserPermissions.autocomplete().check();
+ SearchRequest searchRequest = new SearchRequest(filter, true, DEFAULT_LIMIT);
+ return SearchUtil.search(searchRequest, userDAO.getAll(), user -> matches(searchRequest,user)?user:null);
+ }
+
/**
* Method description
*
@@ -258,7 +265,7 @@ public class DefaultUserManager extends AbstractUserManager
}
});
}
-
+
private boolean matches(SearchRequest searchRequest, User user) {
return SearchUtil.matchesOne(searchRequest, user.getName(), user.getDisplayName(), user.getMail());
}
@@ -277,7 +284,7 @@ public class DefaultUserManager extends AbstractUserManager
public User get(String id)
{
UserPermissions.read().check(id);
-
+
User user = userDAO.get(id);
if (user != null)
diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java b/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java
index d8fe469af9..c2444b43f5 100644
--- a/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java
+++ b/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java
@@ -99,7 +99,7 @@ public class ApiAuthenticationFilter extends AuthenticationFilter
throws IOException, ServletException
{
// skip filter on login resource
- if (SecurityRequests.isAuthenticationRequest(request))
+ if (SecurityRequests.isAuthenticationRequest(request) )
{
chain.doFilter(request, response);
}
diff --git a/scm-webapp/src/main/webapp/WEB-INF/web.xml b/scm-webapp/src/main/webapp/WEB-INF/web.xml
index b65f1f3c6b..8abba66aa3 100644
--- a/scm-webapp/src/main/webapp/WEB-INF/web.xml
+++ b/scm-webapp/src/main/webapp/WEB-INF/web.xml
@@ -59,7 +59,7 @@
resteasy.servlet.mapping.prefix
- /api/rest
+ /api
@@ -71,7 +71,7 @@
Resteasy
- /api/rest/*
+ /api/*
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/ValidationConstraints_IllegalCharactersTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/ValidationConstraints_IllegalCharactersTest.java
new file mode 100644
index 0000000000..c56f6195fe
--- /dev/null
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/ValidationConstraints_IllegalCharactersTest.java
@@ -0,0 +1,47 @@
+package sonia.scm.api.v2;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertFalse;
+import static sonia.scm.api.v2.ValidationConstraints.USER_GROUP_PATTERN;
+
+@RunWith(Parameterized.class)
+public class ValidationConstraints_IllegalCharactersTest {
+
+ private static final List ACCEPTED_CHARS = asList('@', '_', '-', '.');
+
+ private final Pattern userGroupPattern=Pattern.compile(USER_GROUP_PATTERN);
+
+ private final String expression;
+
+ public ValidationConstraints_IllegalCharactersTest(String expression) {
+ this.expression = expression;
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection createParameters() {
+ return Stream.concat(IntStream.range(0x20, 0x2f).mapToObj(i -> (char) i), // chars before '0'
+ Stream.concat(IntStream.range(0x3a, 0x40).mapToObj(i -> (char) i), // chars between '9' and 'A'
+ Stream.concat(IntStream.range(0x5b, 0x60).mapToObj(i -> (char) i), // chars between 'Z' and 'a'
+ IntStream.range(0x7b, 0xff).mapToObj(i -> (char) i)))) // chars after 'z'
+ .filter(c -> !ACCEPTED_CHARS.contains(c))
+ .flatMap(c -> Stream.of("abc" + c + "xyz", "@" + c, c + "tail"))
+ .map(c -> new String[] {c})
+ .collect(Collectors.toList());
+ }
+
+ @Test
+ public void shouldNotAcceptSpecialCharacters() {
+ assertFalse(userGroupPattern.matcher(expression).matches());
+ }
+}
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java
new file mode 100644
index 0000000000..2cab41bfbf
--- /dev/null
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java
@@ -0,0 +1,263 @@
+package sonia.scm.api.v2.resources;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.sdorra.shiro.ShiroRule;
+import com.github.sdorra.shiro.SubjectAware;
+import org.apache.shiro.util.ThreadContext;
+import org.assertj.core.util.Lists;
+import org.jboss.resteasy.core.Dispatcher;
+import org.jboss.resteasy.mock.MockHttpRequest;
+import org.jboss.resteasy.mock.MockHttpResponse;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+import sonia.scm.Manager;
+import sonia.scm.group.DefaultGroupManager;
+import sonia.scm.group.Group;
+import sonia.scm.group.GroupManager;
+import sonia.scm.group.xml.XmlGroupDAO;
+import sonia.scm.store.ConfigurationStore;
+import sonia.scm.store.ConfigurationStoreFactory;
+import sonia.scm.user.DefaultUserManager;
+import sonia.scm.user.User;
+import sonia.scm.user.UserManager;
+import sonia.scm.user.xml.XmlUserDAO;
+import sonia.scm.web.VndMediaType;
+import sonia.scm.xml.XmlDatabase;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+import static sonia.scm.api.v2.resources.DispatcherMock.createDispatcher;
+
+@SubjectAware(configuration = "classpath:sonia/scm/shiro-002.ini")
+@RunWith(MockitoJUnitRunner.Silent.class)
+public class AutoCompleteResourceTest {
+
+ @Rule
+ public final ShiroRule shiroRule = new ShiroRule();
+
+ public static final String URL = "/" + AutoCompleteResource.PATH;
+ private final Integer defaultLimit = Manager.DEFAULT_LIMIT;
+ private Dispatcher dispatcher;
+
+ private XmlUserDAO userDao;
+ private XmlGroupDAO groupDao;
+ private XmlDatabase xmlDB;
+ private ObjectMapper jsonObjectMapper = new ObjectMapper();
+
+ @Before
+ public void prepareEnvironment() {
+ initMocks(this);
+ ConfigurationStoreFactory storeFactory = mock(ConfigurationStoreFactory.class);
+ ConfigurationStore