feat: environment stage
This commit is contained in:
parent
9730b5733a
commit
5ccd873a54
@ -41,6 +41,7 @@
|
|||||||
"react-redux": "^5.0.5",
|
"react-redux": "^5.0.5",
|
||||||
"react-router": "^4.1.1",
|
"react-router": "^4.1.1",
|
||||||
"react-router-dom": "^4.1.1",
|
"react-router-dom": "^4.1.1",
|
||||||
|
"react-simple-table": "^1.0.1",
|
||||||
"react-styled-flexboxgrid": "^2.0.1",
|
"react-styled-flexboxgrid": "^2.0.1",
|
||||||
"redux": "^3.6.0",
|
"redux": "^3.6.0",
|
||||||
"redux-actions": "^2.0.3",
|
"redux-actions": "^2.0.3",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Field } from 'redux-form';
|
import { Field } from 'redux-form';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import SimpleTable from 'react-simple-table';
|
||||||
import { Row, Col } from 'react-styled-flexboxgrid';
|
import { Row, Col } from 'react-styled-flexboxgrid';
|
||||||
import { Dots2 } from 'styled-text-spinners';
|
import { Dots2 } from 'styled-text-spinners';
|
||||||
import Bundle from 'react-bundle';
|
import Bundle from 'react-bundle';
|
||||||
@ -48,9 +49,12 @@ const ButtonsRow = Row.extend`
|
|||||||
margin-bottom: ${remcalc(60)};
|
margin-bottom: ${remcalc(60)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Editor = ManifestEditor => ({ input, defaultValue }) =>
|
const MEditor = ManifestEditor => ({ input, defaultValue }) =>
|
||||||
<ManifestEditor mode="yaml" {...input} value={input.value || defaultValue} />;
|
<ManifestEditor mode="yaml" {...input} value={input.value || defaultValue} />;
|
||||||
|
|
||||||
|
const EEditor = ManifestEditor => ({ input, defaultValue }) =>
|
||||||
|
<ManifestEditor mode="ini" {...input} value={input.value || defaultValue} />;
|
||||||
|
|
||||||
export const Name = ({ handleSubmit, onCancel, dirty }) =>
|
export const Name = ({ handleSubmit, onCancel, dirty }) =>
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<Row>
|
<Row>
|
||||||
@ -67,14 +71,7 @@ export const Name = ({ handleSubmit, onCancel, dirty }) =>
|
|||||||
</ButtonsRow>
|
</ButtonsRow>
|
||||||
</form>;
|
</form>;
|
||||||
|
|
||||||
export const Manifest = ({
|
export const Manifest = ({ handleSubmit, onCancel, dirty, defaultValue }) =>
|
||||||
handleSubmit,
|
|
||||||
onCancel,
|
|
||||||
dirty,
|
|
||||||
defaultValue,
|
|
||||||
mode,
|
|
||||||
loading
|
|
||||||
}) =>
|
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<Bundle load={() => import('joyent-manifest-editor')}>
|
<Bundle load={() => import('joyent-manifest-editor')}>
|
||||||
{ManifestEditor =>
|
{ManifestEditor =>
|
||||||
@ -82,7 +79,33 @@ export const Manifest = ({
|
|||||||
? <Field
|
? <Field
|
||||||
name="manifest"
|
name="manifest"
|
||||||
defaultValue={defaultValue}
|
defaultValue={defaultValue}
|
||||||
component={Editor(ManifestEditor)}
|
component={MEditor(ManifestEditor)}
|
||||||
|
/>
|
||||||
|
: <Dots2 />}
|
||||||
|
</Bundle>
|
||||||
|
<ButtonsRow>
|
||||||
|
<Button onClick={onCancel} secondary>Cancel</Button>
|
||||||
|
<Button disabled={!dirty} type="submit">
|
||||||
|
Environment
|
||||||
|
</Button>
|
||||||
|
</ButtonsRow>
|
||||||
|
</form>;
|
||||||
|
|
||||||
|
export const Environment = ({
|
||||||
|
handleSubmit,
|
||||||
|
onCancel,
|
||||||
|
dirty,
|
||||||
|
defaultValue,
|
||||||
|
loading
|
||||||
|
}) =>
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<Bundle load={() => import('joyent-manifest-editor')}>
|
||||||
|
{ManifestEditor =>
|
||||||
|
ManifestEditor
|
||||||
|
? <Field
|
||||||
|
name="environment"
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
component={EEditor(ManifestEditor)}
|
||||||
/>
|
/>
|
||||||
: <Dots2 />}
|
: <Dots2 />}
|
||||||
</Bundle>
|
</Bundle>
|
||||||
@ -95,11 +118,29 @@ export const Manifest = ({
|
|||||||
</form>;
|
</form>;
|
||||||
|
|
||||||
export const Review = ({ handleSubmit, onCancel, dirty, ...state }) => {
|
export const Review = ({ handleSubmit, onCancel, dirty, ...state }) => {
|
||||||
const serviceList = forceArray(state.services).map(({ name, image }) =>
|
const serviceList = forceArray(state.services).map(({ name, config }) =>
|
||||||
<ServiceCard key={name}>
|
<ServiceCard key={name}>
|
||||||
<Dl>
|
<Dl>
|
||||||
<dt><ServiceName>{name}</ServiceName></dt>
|
<dt><ServiceName>{name}</ServiceName></dt>
|
||||||
<dt><ImageTitle>Image:</ImageTitle> <Image>{image}</Image></dt>
|
<dt><ImageTitle>Image:</ImageTitle> <Image>{config.image}</Image></dt>
|
||||||
|
{config.environment.length
|
||||||
|
? <dt><ImageTitle>Environment:</ImageTitle></dt>
|
||||||
|
: undefined}
|
||||||
|
{config.environment.length
|
||||||
|
? <SimpleTable
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
columnHeader: 'Name',
|
||||||
|
path: 'name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
columnHeader: 'Value',
|
||||||
|
path: 'value'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
data={config.environment}
|
||||||
|
/>
|
||||||
|
: undefined}
|
||||||
</Dl>
|
</Dl>
|
||||||
</ServiceCard>
|
</ServiceCard>
|
||||||
);
|
);
|
||||||
@ -136,7 +177,7 @@ export const Progress = ({ stage, create, edit }) => {
|
|||||||
</ProgressbarButton>
|
</ProgressbarButton>
|
||||||
</ProgressbarItem>;
|
</ProgressbarItem>;
|
||||||
|
|
||||||
const _manifestCompleted = stage === 'review';
|
const _manifestCompleted = ['environment', 'review'].indexOf(stage) >= 0;
|
||||||
const _manifestActive = create ? stage === 'manifest' : stage === 'edit';
|
const _manifestActive = create ? stage === 'manifest' : stage === 'edit';
|
||||||
|
|
||||||
const _manifest = (
|
const _manifest = (
|
||||||
@ -147,7 +188,22 @@ export const Progress = ({ stage, create, edit }) => {
|
|||||||
active={_manifestActive}
|
active={_manifestActive}
|
||||||
first={edit}
|
first={edit}
|
||||||
>
|
>
|
||||||
Define services
|
Define Services
|
||||||
|
</ProgressbarButton>
|
||||||
|
</ProgressbarItem>
|
||||||
|
);
|
||||||
|
|
||||||
|
const _environmentCompleted = stage === 'review';
|
||||||
|
const _environmentActive = stage === 'environment';
|
||||||
|
|
||||||
|
const _environment = (
|
||||||
|
<ProgressbarItem>
|
||||||
|
<ProgressbarButton
|
||||||
|
zIndex="8"
|
||||||
|
completed={_environmentCompleted}
|
||||||
|
active={_environmentActive}
|
||||||
|
>
|
||||||
|
Define Environment
|
||||||
</ProgressbarButton>
|
</ProgressbarButton>
|
||||||
</ProgressbarItem>
|
</ProgressbarItem>
|
||||||
);
|
);
|
||||||
@ -156,7 +212,7 @@ export const Progress = ({ stage, create, edit }) => {
|
|||||||
|
|
||||||
const _review = (
|
const _review = (
|
||||||
<ProgressbarItem>
|
<ProgressbarItem>
|
||||||
<ProgressbarButton zIndex="8" active={stage === 'review'} last>
|
<ProgressbarButton zIndex="7" active={_reviewActive} last>
|
||||||
Review and deploy
|
Review and deploy
|
||||||
</ProgressbarButton>
|
</ProgressbarButton>
|
||||||
</ProgressbarItem>
|
</ProgressbarItem>
|
||||||
@ -166,6 +222,7 @@ export const Progress = ({ stage, create, edit }) => {
|
|||||||
<Progressbar>
|
<Progressbar>
|
||||||
{_name}
|
{_name}
|
||||||
{_manifest}
|
{_manifest}
|
||||||
|
{_environment}
|
||||||
{_review}
|
{_review}
|
||||||
</Progressbar>
|
</Progressbar>
|
||||||
);
|
);
|
||||||
|
@ -96,6 +96,7 @@ const ServiceListItem = ({
|
|||||||
</CardDescription>
|
</CardDescription>
|
||||||
<CardOptions onClick={handleCardOptionsClick} />
|
<CardOptions onClick={handleCardOptionsClick} />
|
||||||
</StyledCardHeader>;
|
</StyledCardHeader>;
|
||||||
|
|
||||||
const view = children
|
const view = children
|
||||||
? <CardGroupView>
|
? <CardGroupView>
|
||||||
{children}
|
{children}
|
||||||
|
@ -12,7 +12,12 @@ import DeploymentGroupProvisionMutation from '@graphql/DeploymentGroupProvision.
|
|||||||
import DeploymentGroupConfigQuery from '@graphql/DeploymentGroupConfig.gql';
|
import DeploymentGroupConfigQuery from '@graphql/DeploymentGroupConfig.gql';
|
||||||
|
|
||||||
import { client } from '@state/store';
|
import { client } from '@state/store';
|
||||||
import { Name, Manifest, Review } from '@components/deployment-groups/create';
|
import {
|
||||||
|
Name,
|
||||||
|
Manifest,
|
||||||
|
Environment,
|
||||||
|
Review
|
||||||
|
} from '@components/deployment-groups/create';
|
||||||
|
|
||||||
// TODO: move state to redux. why: because in redux we can cache transactional
|
// TODO: move state to redux. why: because in redux we can cache transactional
|
||||||
// state between refreshes
|
// state between refreshes
|
||||||
@ -51,6 +56,12 @@ class DeploymentGroupEditOrCreate extends Component {
|
|||||||
forceUnregisterOnUnmount: true
|
forceUnregisterOnUnmount: true
|
||||||
})(Manifest);
|
})(Manifest);
|
||||||
|
|
||||||
|
const EnvironmentForm = reduxForm({
|
||||||
|
form: `${type}-deployment-group`,
|
||||||
|
destroyOnUnmount: true,
|
||||||
|
forceUnregisterOnUnmount: true
|
||||||
|
})(Environment);
|
||||||
|
|
||||||
const ReviewForm = reduxForm({
|
const ReviewForm = reduxForm({
|
||||||
form: `${type}-deployment-group`,
|
form: `${type}-deployment-group`,
|
||||||
destroyOnUnmount: true,
|
destroyOnUnmount: true,
|
||||||
@ -62,17 +73,20 @@ class DeploymentGroupEditOrCreate extends Component {
|
|||||||
manifestStage: create ? 'manifest' : 'edit',
|
manifestStage: create ? 'manifest' : 'edit',
|
||||||
name: '',
|
name: '',
|
||||||
manifest: '',
|
manifest: '',
|
||||||
|
environment: '',
|
||||||
services: [],
|
services: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
error: null,
|
error: null,
|
||||||
NameForm,
|
NameForm,
|
||||||
ManifestForm,
|
ManifestForm,
|
||||||
|
EnvironmentForm,
|
||||||
ReviewForm
|
ReviewForm
|
||||||
};
|
};
|
||||||
|
|
||||||
this.stages = {
|
this.stages = {
|
||||||
name: create && this.renderNameForm.bind(this),
|
name: create && this.renderNameForm.bind(this),
|
||||||
[create ? 'manifest' : 'edit']: this.renderManifestEditor.bind(this),
|
[create ? 'manifest' : 'edit']: this.renderManifestEditor.bind(this),
|
||||||
|
environment: this.renderEnvironmentEditor.bind(this),
|
||||||
review: this.renderReview.bind(this)
|
review: this.renderReview.bind(this)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,6 +94,7 @@ class DeploymentGroupEditOrCreate extends Component {
|
|||||||
type === 'create' && this.handleNameSubmit.bind(this);
|
type === 'create' && this.handleNameSubmit.bind(this);
|
||||||
|
|
||||||
this.handleManifestSubmit = this.handleManifestSubmit.bind(this);
|
this.handleManifestSubmit = this.handleManifestSubmit.bind(this);
|
||||||
|
this.handleEnvironmentSubmit = this.handleEnvironmentSubmit.bind(this);
|
||||||
this.handleReviewSubmit = this.handleReviewSubmit.bind(this);
|
this.handleReviewSubmit = this.handleReviewSubmit.bind(this);
|
||||||
this.handleCancel = this.handleCancel.bind(this);
|
this.handleCancel = this.handleCancel.bind(this);
|
||||||
|
|
||||||
@ -117,7 +132,7 @@ class DeploymentGroupEditOrCreate extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
provision = async deploymentGroupId => {
|
provision = async deploymentGroupId => {
|
||||||
const { manifest } = this.state;
|
const { manifest, environment } = this.state;
|
||||||
const { provisionManifest } = this.props;
|
const { provisionManifest } = this.props;
|
||||||
|
|
||||||
const [err] = await intercept(
|
const [err] = await intercept(
|
||||||
@ -125,6 +140,7 @@ class DeploymentGroupEditOrCreate extends Component {
|
|||||||
deploymentGroupId,
|
deploymentGroupId,
|
||||||
type: 'COMPOSE',
|
type: 'COMPOSE',
|
||||||
format: 'YAML',
|
format: 'YAML',
|
||||||
|
environment,
|
||||||
raw: manifest
|
raw: manifest
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -145,16 +161,24 @@ class DeploymentGroupEditOrCreate extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleManifestSubmit({ manifest = '' }) {
|
handleManifestSubmit({ manifest = '' }) {
|
||||||
const { name } = this.state;
|
this.setState({ manifest }, () => {
|
||||||
|
this.redirect({ stage: 'environment', prog: true });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEnvironmentSubmit({ environment = '' }) {
|
||||||
|
const { name, manifest } = this.state;
|
||||||
|
|
||||||
const getConfig = async () => {
|
const getConfig = async () => {
|
||||||
const [err, conf] = await intercept(
|
const [err, conf] = await intercept(
|
||||||
client.query({
|
client.query({
|
||||||
query: DeploymentGroupConfigQuery,
|
query: DeploymentGroupConfigQuery,
|
||||||
|
fetchPolicy: 'network-only',
|
||||||
variables: {
|
variables: {
|
||||||
deploymentGroupName: name,
|
deploymentGroupName: name,
|
||||||
type: 'COMPOSE',
|
type: 'COMPOSE',
|
||||||
format: 'YAML',
|
format: 'YAML',
|
||||||
|
environment,
|
||||||
raw: manifest
|
raw: manifest
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -174,7 +198,7 @@ class DeploymentGroupEditOrCreate extends Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setState({ manifest, loading: true }, getConfig);
|
this.setState({ environment, loading: true }, getConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleReviewSubmit() {
|
handleReviewSubmit() {
|
||||||
@ -237,6 +261,18 @@ class DeploymentGroupEditOrCreate extends Component {
|
|||||||
defaultValue={this.props.manifest}
|
defaultValue={this.props.manifest}
|
||||||
onSubmit={this.handleManifestSubmit}
|
onSubmit={this.handleManifestSubmit}
|
||||||
onCancel={this.handleCancel}
|
onCancel={this.handleCancel}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderEnvironmentEditor() {
|
||||||
|
const { EnvironmentForm } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EnvironmentForm
|
||||||
|
defaultValue={this.props.environment}
|
||||||
|
onSubmit={this.handleEnvironmentSubmit}
|
||||||
|
onCancel={this.handleCancel}
|
||||||
loading={this.state.loading}
|
loading={this.state.loading}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -276,10 +312,20 @@ class DeploymentGroupEditOrCreate extends Component {
|
|||||||
return this.redirect({ stage: defaultStage });
|
return this.redirect({ stage: defaultStage });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stage === 'review' && !this.state.manifest) {
|
if (stage === 'environment' && !this.state.manifest) {
|
||||||
return this.redirect({ stage: manifestStage });
|
return this.redirect({ stage: manifestStage });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stage === 'review' && !this.state.environment) {
|
||||||
|
if (!this.state.manifest) {
|
||||||
|
return this.redirect({ stage: manifestStage });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.state.environment) {
|
||||||
|
return this.redirect({ stage: 'environment' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return this.stages[stage]();
|
return this.stages[stage]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,22 @@
|
|||||||
#import "./ServiceInfo.gql"
|
#import "./ServiceInfo.gql"
|
||||||
|
|
||||||
query config($deploymentGroupName: String!, $type: ManifestType!, $format: ManifestFormat!, $raw: String!) {
|
query config($deploymentGroupName: String!, $type: ManifestType!, $format: ManifestFormat!, $environment: String!, $raw: String!) {
|
||||||
config(deploymentGroupName: $deploymentGroupName, type: $type, format: $format, raw: $raw) {
|
config(deploymentGroupName: $deploymentGroupName, type: $type, format: $format, environment: $environment, raw: $raw) {
|
||||||
image
|
|
||||||
...ServiceInfo
|
...ServiceInfo
|
||||||
|
config {
|
||||||
|
id
|
||||||
|
image
|
||||||
|
ports
|
||||||
|
environment {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
value
|
||||||
|
}
|
||||||
|
labels {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
mutation provisionManifest($deploymentGroupId: ID!, $type: ManifestType!, $format: ManifestFormat!, $raw: String!) {
|
mutation provisionManifest($deploymentGroupId: ID!, $type: ManifestType!, $format: ManifestFormat!, $environment: String!, $raw: String!) {
|
||||||
provisionManifest(deploymentGroupId: $deploymentGroupId, type: $type, format: $format, raw: $raw) {
|
provisionManifest(deploymentGroupId: $deploymentGroupId, type: $type, format: $format, environment: $environment, raw: $raw) {
|
||||||
scale {
|
scale {
|
||||||
serviceName
|
serviceName
|
||||||
replicas
|
replicas
|
||||||
|
@ -68,8 +68,7 @@ const activeInstanceStatuses = [
|
|||||||
'INCOMPLETE'
|
'INCOMPLETE'
|
||||||
];
|
];
|
||||||
|
|
||||||
const getInstanceStatuses = (service) => {
|
const getInstanceStatuses = service => {
|
||||||
|
|
||||||
const instanceStatuses = service.instances.reduce((statuses, instance) => {
|
const instanceStatuses = service.instances.reduce((statuses, instance) => {
|
||||||
// if (instance.status !== 'RUNNING') {
|
// if (instance.status !== 'RUNNING') {
|
||||||
if (statuses[instance.status]) {
|
if (statuses[instance.status]) {
|
||||||
@ -85,31 +84,35 @@ const getInstanceStatuses = (service) => {
|
|||||||
status,
|
status,
|
||||||
count: instanceStatuses[status]
|
count: instanceStatuses[status]
|
||||||
}));
|
}));
|
||||||
}
|
};
|
||||||
|
|
||||||
const getInstancesActive = (instanceStatuses) => {
|
const getInstancesActive = instanceStatuses => {
|
||||||
return instanceStatuses.reduce((active, instanceStatus) =>
|
return instanceStatuses.reduce(
|
||||||
activeInstanceStatuses.indexOf(instanceStatus.status) === -1 ?
|
(active, instanceStatus) =>
|
||||||
active : true, false);
|
activeInstanceStatuses.indexOf(instanceStatus.status) === -1
|
||||||
}
|
? active
|
||||||
|
: true,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const getService = (service, index) => {
|
const getService = (service, index) => {
|
||||||
|
|
||||||
const statuses = getInstanceStatuses(service);
|
const statuses = getInstanceStatuses(service);
|
||||||
const instancesActive = getInstancesActive(statuses);
|
const instancesActive = getInstancesActive(statuses);
|
||||||
const instanceStatuses = statuses.length === 1 && statuses[0].status === 'RUNNING' ?
|
const instanceStatuses = statuses.length === 1 &&
|
||||||
[] : statuses;
|
statuses[0].status === 'RUNNING'
|
||||||
return ({
|
? []
|
||||||
|
: statuses;
|
||||||
|
return {
|
||||||
index,
|
index,
|
||||||
...service,
|
...service,
|
||||||
instanceStatuses,
|
instanceStatuses,
|
||||||
instancesActive,
|
instancesActive,
|
||||||
isConsul: service.slug === 'consul'
|
isConsul: service.slug === 'consul'
|
||||||
});
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const processServices = (services) => {
|
const processServices = services => {
|
||||||
|
|
||||||
return forceArray(services).reduce((ss, s, i) => {
|
return forceArray(services).reduce((ss, s, i) => {
|
||||||
if (s.parent) {
|
if (s.parent) {
|
||||||
const parents = ss.filter(parentS => parentS.id === s.parent);
|
const parents = ss.filter(parentS => parentS.id === s.parent);
|
||||||
@ -124,7 +127,9 @@ const processServices = (services) => {
|
|||||||
parent.children = [];
|
parent.children = [];
|
||||||
}
|
}
|
||||||
const child = getService(s, i);
|
const child = getService(s, i);
|
||||||
parent.instancesActive = parent.instancesActive ? true : child.instancesActive;
|
parent.instancesActive = parent.instancesActive
|
||||||
|
? true
|
||||||
|
: child.instancesActive;
|
||||||
parent.children.push(child);
|
parent.children.push(child);
|
||||||
} else {
|
} else {
|
||||||
const serviceIndex = ss.findIndex(existingS => existingS.id === s.id);
|
const serviceIndex = ss.findIndex(existingS => existingS.id === s.id);
|
||||||
@ -141,19 +146,22 @@ const processServices = (services) => {
|
|||||||
}, []);
|
}, []);
|
||||||
};
|
};
|
||||||
|
|
||||||
const processServicesForTopology = (services) => {
|
const processServicesForTopology = services => {
|
||||||
|
|
||||||
const processedServices = processServices(services);
|
const processedServices = processServices(services);
|
||||||
|
|
||||||
const connectedServices = processedServices.reduce((connections, service) =>
|
const connectedServices = processedServices.reduce(
|
||||||
service.connections && service.connections.length ?
|
(connections, service) =>
|
||||||
connections.concat(service.connections).concat(service.id) : connections, []);
|
service.connections && service.connections.length
|
||||||
|
? connections.concat(service.connections).concat(service.id)
|
||||||
|
: connections,
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
return processedServices.map(service => ({
|
return processedServices.map(service => ({
|
||||||
...service,
|
...service,
|
||||||
connected: connectedServices.indexOf(service.id) !== -1
|
connected: connectedServices.indexOf(service.id) !== -1
|
||||||
}));
|
}));
|
||||||
}
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
deploymentGroupBySlug as deploymentGroupBySlugSelector,
|
deploymentGroupBySlug as deploymentGroupBySlugSelector,
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
scalar Date
|
|
||||||
scalar Object
|
|
||||||
|
|
||||||
type Portal {
|
type Portal {
|
||||||
id: ID!
|
id: ID!
|
||||||
user: User!
|
user: User!
|
||||||
@ -36,6 +33,7 @@ type DeploymentGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ServiceScale {
|
type ServiceScale {
|
||||||
|
id: ID!
|
||||||
serviceName: String!
|
serviceName: String!
|
||||||
replicas: Int!
|
replicas: Int!
|
||||||
}
|
}
|
||||||
@ -50,6 +48,7 @@ enum ConvergenceActionType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ConvergenceAction {
|
type ConvergenceAction {
|
||||||
|
id: ID!
|
||||||
type: ConvergenceActionType!
|
type: ConvergenceActionType!
|
||||||
service: String! # service name
|
service: String! # service name
|
||||||
toProcess: Int, # merely used for book keeping
|
toProcess: Int, # merely used for book keeping
|
||||||
@ -58,6 +57,7 @@ type ConvergenceAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Version {
|
type Version {
|
||||||
|
id: ID!
|
||||||
manifest: Manifest!
|
manifest: Manifest!
|
||||||
scale(serviceName: String): [ServiceScale]!
|
scale(serviceName: String): [ServiceScale]!
|
||||||
plan: [ConvergenceAction]
|
plan: [ConvergenceAction]
|
||||||
@ -79,8 +79,8 @@ type Manifest {
|
|||||||
id: ID!
|
id: ID!
|
||||||
type: ManifestType!
|
type: ManifestType!
|
||||||
format: ManifestFormat!
|
format: ManifestFormat!
|
||||||
|
environment: String!
|
||||||
raw: String!
|
raw: String!
|
||||||
obj: Object
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ServiceStatus {
|
enum ServiceStatus {
|
||||||
@ -95,6 +95,21 @@ enum ServiceStatus {
|
|||||||
UNKNOWN
|
UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type KeyValue {
|
||||||
|
id: ID!
|
||||||
|
name: String!
|
||||||
|
value: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceConfig {
|
||||||
|
id: ID!
|
||||||
|
package: Package # we don't have this in current mock data
|
||||||
|
environment: [KeyValue]
|
||||||
|
image: String # used only for config
|
||||||
|
labels: [KeyValue]
|
||||||
|
ports: [String]
|
||||||
|
}
|
||||||
|
|
||||||
# immutable
|
# immutable
|
||||||
type Service {
|
type Service {
|
||||||
id: ID! # unique id for db row
|
id: ID! # unique id for db row
|
||||||
@ -102,11 +117,9 @@ type Service {
|
|||||||
name: String! # human readable name
|
name: String! # human readable name
|
||||||
slug: String!
|
slug: String!
|
||||||
instances(name: String, machineId: ID, status: InstanceStatus): [Instance]!
|
instances(name: String, machineId: ID, status: InstanceStatus): [Instance]!
|
||||||
connections: [String!] # list of serviceIds
|
connections: [String] # list of serviceIds
|
||||||
parent: ID # parent service id
|
parent: ID # parent service id
|
||||||
package: Package! # we don't have this in current mock data,
|
config: ServiceConfig
|
||||||
environment: [Environment]
|
|
||||||
image: String # used only for config
|
|
||||||
status: ServiceStatus
|
status: ServiceStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,12 +137,6 @@ type Package {
|
|||||||
group: String!
|
group: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
# environment variables
|
|
||||||
type Environment {
|
|
||||||
name: String!
|
|
||||||
value: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
enum InstanceStatus {
|
enum InstanceStatus {
|
||||||
PROVISIONING
|
PROVISIONING
|
||||||
READY
|
READY
|
||||||
@ -184,7 +191,7 @@ type Query {
|
|||||||
datacenter(id: ID, region: String): Datacenter
|
datacenter(id: ID, region: String): Datacenter
|
||||||
datacenters: [Datacenter]
|
datacenters: [Datacenter]
|
||||||
|
|
||||||
config(deploymentGroupName: String!, type: ManifestType!, format: ManifestFormat!, raw: String!): [Service]
|
config(deploymentGroupName: String!, type: ManifestType!, format: ManifestFormat!, environment: String!, raw: String!): [Service]
|
||||||
importableDeploymentGroups: [DeploymentGroup]
|
importableDeploymentGroups: [DeploymentGroup]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +199,7 @@ type Mutation {
|
|||||||
createDeploymentGroup(name: String!): DeploymentGroup
|
createDeploymentGroup(name: String!): DeploymentGroup
|
||||||
updateDeploymentGroup(id: ID!, name: String!): DeploymentGroup
|
updateDeploymentGroup(id: ID!, name: String!): DeploymentGroup
|
||||||
|
|
||||||
provisionManifest(deploymentGroupId: ID!, type: ManifestType!, format: ManifestFormat!, raw: String!): Version
|
provisionManifest(deploymentGroupId: ID!, type: ManifestType!, format: ManifestFormat!, environment: String!, raw: String!): Version
|
||||||
scale(serviceId: ID!, replicas: Int!): Version
|
scale(serviceId: ID!, replicas: Int!): Version
|
||||||
|
|
||||||
stopServices(ids: [ID]!): [Service]
|
stopServices(ids: [ID]!): [Service]
|
||||||
|
@ -22,13 +22,17 @@ module.exports = class DockerComposeClient extends EventEmitter {
|
|||||||
return this.client.close();
|
return this.client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
provision({ projectName, manifest }, cb) {
|
provision({ projectName, environment, manifest }, cb) {
|
||||||
|
return this._invoke('up', {
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
return this._invoke('up', { project_name: projectName }, manifest, cb);
|
project_name: projectName,
|
||||||
|
environment
|
||||||
|
}, manifest, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
scale({ projectName, services, manifest }, cb) {
|
scale({ projectName, services, environment, manifest }, cb) {
|
||||||
const options = {
|
const options = {
|
||||||
|
environment,
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
project_name: projectName,
|
project_name: projectName,
|
||||||
services: Object.keys(services).map(name => ({
|
services: Object.keys(services).map(name => ({
|
||||||
@ -40,10 +44,11 @@ module.exports = class DockerComposeClient extends EventEmitter {
|
|||||||
return this._invoke('scale', options, manifest, cb);
|
return this._invoke('scale', options, manifest, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
config({ projectName, manifest }, cb) {
|
config({ projectName, environment, manifest }, cb) {
|
||||||
const options = {
|
const options = {
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
project_name: projectName
|
project_name: projectName,
|
||||||
|
environment
|
||||||
};
|
};
|
||||||
|
|
||||||
return this._invoke('config', options, manifest, cb);
|
return this._invoke('config', options, manifest, cb);
|
||||||
|
@ -4,6 +4,7 @@ import 'codemirror/addon/fold/foldgutter.css';
|
|||||||
import 'codemirror/addon/lint/lint.css';
|
import 'codemirror/addon/lint/lint.css';
|
||||||
import 'codemirror/mode/yaml/yaml';
|
import 'codemirror/mode/yaml/yaml';
|
||||||
import 'codemirror/mode/javascript/javascript';
|
import 'codemirror/mode/javascript/javascript';
|
||||||
|
import 'codemirror/mode/properties/properties';
|
||||||
import 'codemirror/addon/edit/closebrackets';
|
import 'codemirror/addon/edit/closebrackets';
|
||||||
import 'codemirror/addon/edit/matchbrackets';
|
import 'codemirror/addon/edit/matchbrackets';
|
||||||
import 'codemirror/addon/fold/foldcode';
|
import 'codemirror/addon/fold/foldcode';
|
||||||
@ -60,7 +61,8 @@ class ManifestEditor extends Component {
|
|||||||
name: 'javascript',
|
name: 'javascript',
|
||||||
json: true
|
json: true
|
||||||
},
|
},
|
||||||
yaml: 'yaml'
|
yaml: 'yaml',
|
||||||
|
ini: 'properties'
|
||||||
};
|
};
|
||||||
|
|
||||||
return Object.assign({}, options, {
|
return Object.assign({}, options, {
|
||||||
|
@ -13,7 +13,6 @@ const Hoek = require('hoek');
|
|||||||
const Triton = require('triton');
|
const Triton = require('triton');
|
||||||
const ParamCase = require('param-case');
|
const ParamCase = require('param-case');
|
||||||
const Penseur = require('penseur');
|
const Penseur = require('penseur');
|
||||||
const { DEPLOYMENT_GROUP, SERVICE, HASH } = require('../watch');
|
|
||||||
const UniqBy = require('lodash.uniqby');
|
const UniqBy = require('lodash.uniqby');
|
||||||
const Find = require('lodash.find');
|
const Find = require('lodash.find');
|
||||||
const Get = require('lodash.get');
|
const Get = require('lodash.get');
|
||||||
@ -24,6 +23,7 @@ const VAsync = require('vasync');
|
|||||||
|
|
||||||
// local modules
|
// local modules
|
||||||
const Transform = require('./transform');
|
const Transform = require('./transform');
|
||||||
|
const { DEPLOYMENT_GROUP, SERVICE, HASH } = require('../watch');
|
||||||
|
|
||||||
|
|
||||||
const NON_IMPORTABLE_STATES = [
|
const NON_IMPORTABLE_STATES = [
|
||||||
@ -153,7 +153,11 @@ class Data extends EventEmitter {
|
|||||||
const portal = portals.shift();
|
const portal = portals.shift();
|
||||||
|
|
||||||
// Sub query/filter for deploymentGroups
|
// Sub query/filter for deploymentGroups
|
||||||
const deploymentGroups = (args) => {
|
const deploymentGroups = (args, cb) => {
|
||||||
|
if (typeof cb === 'function') {
|
||||||
|
return this.getDeploymentGroups(args, cb);
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.getDeploymentGroups(args, internals.resolveCb(resolve, reject));
|
this.getDeploymentGroups(args, internals.resolveCb(resolve, reject));
|
||||||
});
|
});
|
||||||
@ -372,7 +376,7 @@ class Data extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!deploymentGroups || !deploymentGroups.length) {
|
if (!deploymentGroups || !deploymentGroups.length) {
|
||||||
return cb(null, {});
|
return cb();
|
||||||
}
|
}
|
||||||
|
|
||||||
cb(null, Transform.fromDeploymentGroup(this._getDeploymentGroupFns(deploymentGroups[0])));
|
cb(null, Transform.fromDeploymentGroup(this._getDeploymentGroupFns(deploymentGroups[0])));
|
||||||
@ -512,6 +516,7 @@ class Data extends EventEmitter {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
id: Uuid(),
|
||||||
serviceName: name,
|
serviceName: name,
|
||||||
replicas: Number.isFinite(currentScale) ? currentScale : 1
|
replicas: Number.isFinite(currentScale) ? currentScale : 1
|
||||||
};
|
};
|
||||||
@ -554,6 +559,7 @@ class Data extends EventEmitter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
id: Uuid(),
|
||||||
serviceName: name,
|
serviceName: name,
|
||||||
replicas: existingMachines.length ? existingMachines.length : 1
|
replicas: existingMachines.length ? existingMachines.length : 1
|
||||||
};
|
};
|
||||||
@ -565,7 +571,7 @@ class Data extends EventEmitter {
|
|||||||
this._listMachines(deploymentGroupName, handleMachinesList);
|
this._listMachines(deploymentGroupName, handleMachinesList);
|
||||||
}
|
}
|
||||||
|
|
||||||
scale ({ serviceId, replicas }, cb) {
|
scale ({ serviceId, environment, replicas }, cb) {
|
||||||
Hoek.assert(serviceId, 'service id is required');
|
Hoek.assert(serviceId, 'service id is required');
|
||||||
Hoek.assert(typeof replicas === 'number' && replicas >= 0, 'replicas must be a number no less than 0');
|
Hoek.assert(typeof replicas === 'number' && replicas >= 0, 'replicas must be a number no less than 0');
|
||||||
|
|
||||||
@ -636,6 +642,7 @@ class Data extends EventEmitter {
|
|||||||
|
|
||||||
this._dockerCompose.scale({
|
this._dockerCompose.scale({
|
||||||
projectName: ctx.deploymentGroup.name,
|
projectName: ctx.deploymentGroup.name,
|
||||||
|
environment,
|
||||||
services: {
|
services: {
|
||||||
[ctx.service.name]: replicas
|
[ctx.service.name]: replicas
|
||||||
},
|
},
|
||||||
@ -647,6 +654,7 @@ class Data extends EventEmitter {
|
|||||||
const getNewScale = () => {
|
const getNewScale = () => {
|
||||||
return ctx.currentScale.map(({ serviceName, replicas }) => {
|
return ctx.currentScale.map(({ serviceName, replicas }) => {
|
||||||
return {
|
return {
|
||||||
|
id: Uuid(),
|
||||||
serviceName: serviceName,
|
serviceName: serviceName,
|
||||||
replicas: serviceName === ctx.service.name ?
|
replicas: serviceName === ctx.service.name ?
|
||||||
(ctx.serviceScale + ctx.diff) :
|
(ctx.serviceScale + ctx.diff) :
|
||||||
@ -661,6 +669,7 @@ class Data extends EventEmitter {
|
|||||||
deploymentGroupId: ctx.deploymentGroup.id,
|
deploymentGroupId: ctx.deploymentGroup.id,
|
||||||
scale: getNewScale(),
|
scale: getNewScale(),
|
||||||
plan: [{
|
plan: [{
|
||||||
|
id: Uuid(),
|
||||||
type: 'REMOVE',
|
type: 'REMOVE',
|
||||||
service: ctx.service.name,
|
service: ctx.service.name,
|
||||||
toProcess: Math.abs(ctx.diff),
|
toProcess: Math.abs(ctx.diff),
|
||||||
@ -683,6 +692,7 @@ class Data extends EventEmitter {
|
|||||||
deploymentGroupId: ctx.deploymentGroup.id,
|
deploymentGroupId: ctx.deploymentGroup.id,
|
||||||
scale: getNewScale(),
|
scale: getNewScale(),
|
||||||
plan: [{
|
plan: [{
|
||||||
|
id: Uuid(),
|
||||||
type: 'CREATE',
|
type: 'CREATE',
|
||||||
service: ctx.service.name,
|
service: ctx.service.name,
|
||||||
toProcess: Math.abs(ctx.diff),
|
toProcess: Math.abs(ctx.diff),
|
||||||
@ -908,6 +918,7 @@ class Data extends EventEmitter {
|
|||||||
|
|
||||||
if (!provision) {
|
if (!provision) {
|
||||||
return {
|
return {
|
||||||
|
id: Uuid(),
|
||||||
type: 'REMOVE',
|
type: 'REMOVE',
|
||||||
service: name,
|
service: name,
|
||||||
toProcess: machines.length,
|
toProcess: machines.length,
|
||||||
@ -918,6 +929,7 @@ class Data extends EventEmitter {
|
|||||||
const ActionMap = {
|
const ActionMap = {
|
||||||
'NOOP': () => {
|
'NOOP': () => {
|
||||||
return {
|
return {
|
||||||
|
id: Uuid(),
|
||||||
type: 'NOOP',
|
type: 'NOOP',
|
||||||
service: name,
|
service: name,
|
||||||
machines
|
machines
|
||||||
@ -925,6 +937,7 @@ class Data extends EventEmitter {
|
|||||||
},
|
},
|
||||||
'CREATE': () => {
|
'CREATE': () => {
|
||||||
return {
|
return {
|
||||||
|
id: Uuid(),
|
||||||
type: 'CREATE',
|
type: 'CREATE',
|
||||||
service: name,
|
service: name,
|
||||||
toProcess: scale,
|
toProcess: scale,
|
||||||
@ -933,6 +946,7 @@ class Data extends EventEmitter {
|
|||||||
},
|
},
|
||||||
'RECREATE': () => {
|
'RECREATE': () => {
|
||||||
return {
|
return {
|
||||||
|
id: Uuid(),
|
||||||
type: 'CREATE',
|
type: 'CREATE',
|
||||||
service: name,
|
service: name,
|
||||||
toProcess: machines.length,
|
toProcess: machines.length,
|
||||||
@ -941,6 +955,7 @@ class Data extends EventEmitter {
|
|||||||
},
|
},
|
||||||
'START': () => {
|
'START': () => {
|
||||||
return {
|
return {
|
||||||
|
id: Uuid(),
|
||||||
type: 'START',
|
type: 'START',
|
||||||
service: name,
|
service: name,
|
||||||
machines
|
machines
|
||||||
@ -1077,12 +1092,17 @@ class Data extends EventEmitter {
|
|||||||
const action = Get(provision, 'plan.action', 'noop').toUpperCase();
|
const action = Get(provision, 'plan.action', 'noop').toUpperCase();
|
||||||
const service = services.shift();
|
const service = services.shift();
|
||||||
|
|
||||||
|
const { config } = Find(ctx.config, ['name', serviceName], {
|
||||||
|
config: {}
|
||||||
|
});
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
hash: provision.hash,
|
hash: provision.hash,
|
||||||
deploymentGroupId: ctx.currentDeploymentGroup.id,
|
deploymentGroupId: ctx.currentDeploymentGroup.id,
|
||||||
name: serviceName,
|
name: serviceName,
|
||||||
slug: ParamCase(serviceName),
|
slug: ParamCase(serviceName),
|
||||||
status: ServiceStatusFromPlan[action]
|
status: ServiceStatusFromPlan[action],
|
||||||
|
config
|
||||||
};
|
};
|
||||||
|
|
||||||
return !service ?
|
return !service ?
|
||||||
@ -1133,6 +1153,7 @@ class Data extends EventEmitter {
|
|||||||
|
|
||||||
this._dockerCompose.provision({
|
this._dockerCompose.provision({
|
||||||
projectName: ctx.currentDeploymentGroup.name,
|
projectName: ctx.currentDeploymentGroup.name,
|
||||||
|
environment: clientManifest.environment,
|
||||||
manifest: ctx.newManifest.raw
|
manifest: ctx.newManifest.raw
|
||||||
}, handleProvisionResponse);
|
}, handleProvisionResponse);
|
||||||
});
|
});
|
||||||
@ -1830,23 +1851,19 @@ class Data extends EventEmitter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateInstance ({ id, status, healthy}, cb) {
|
updateInstance (clientInstance, cb) {
|
||||||
const changes = { id };
|
const instance = Transform.toInstance(clientInstance);
|
||||||
|
|
||||||
if (typeof healthy === 'boolean') {
|
if (typeof instance.healthy !== 'boolean') {
|
||||||
changes.healthy = healthy;
|
instance.healthy = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status) {
|
this._db.instances.update([instance], (err) => {
|
||||||
changes.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._db.instances.update([changes], (err) => {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getInstance({ id }, cb);
|
this.getInstance({ id: instance.id }, cb);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1989,7 +2006,7 @@ class Data extends EventEmitter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getConfig ({deploymentGroupName = '', type = '', format = '', raw = '' }, cb) {
|
getConfig ({deploymentGroupName = '', type = '', format = '', environment = '', raw = '' }, cb) {
|
||||||
if (type.toUpperCase() !== 'COMPOSE') {
|
if (type.toUpperCase() !== 'COMPOSE') {
|
||||||
return cb(new Error('"COMPOSE" is the only `type` supported'));
|
return cb(new Error('"COMPOSE" is the only `type` supported'));
|
||||||
}
|
}
|
||||||
@ -2002,6 +2019,7 @@ class Data extends EventEmitter {
|
|||||||
|
|
||||||
this._dockerCompose.config({
|
this._dockerCompose.config({
|
||||||
projectName: deploymentGroupName,
|
projectName: deploymentGroupName,
|
||||||
|
environment,
|
||||||
manifest: raw
|
manifest: raw
|
||||||
}, (err, config = {}) => {
|
}, (err, config = {}) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -2021,15 +2039,34 @@ class Data extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cb(null, Object.keys(services).reduce((acc, serviceName) => {
|
cb(null, Object.keys(services).reduce((acc, serviceName) => {
|
||||||
|
const environment = Get(services, `${serviceName}.environment`, {});
|
||||||
|
const labels = Get(services, `${serviceName}.labels`, {});
|
||||||
|
const ports = Get(services, `${serviceName}.ports`, []);
|
||||||
|
const image = Get(services, `${serviceName}.image`, '');
|
||||||
|
|
||||||
|
const toKeyValue = (v) => {
|
||||||
|
return Object.keys(v).map((key) => {
|
||||||
|
return {
|
||||||
|
id: Uuid(),
|
||||||
|
name: key,
|
||||||
|
value: v[key]
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return acc.concat([{
|
return acc.concat([{
|
||||||
id: Uuid(),
|
id: Uuid(),
|
||||||
hash: Uuid(),
|
hash: Uuid(),
|
||||||
name: serviceName,
|
name: serviceName,
|
||||||
slug: ParamCase(serviceName),
|
slug: ParamCase(serviceName),
|
||||||
instances: [],
|
instances: [],
|
||||||
package: {},
|
config: {
|
||||||
active: true,
|
id: Uuid(),
|
||||||
image: services[serviceName].image
|
environment: toKeyValue(environment),
|
||||||
|
image: image,
|
||||||
|
labels: toKeyValue(labels),
|
||||||
|
ports: ports
|
||||||
|
}
|
||||||
}]);
|
}]);
|
||||||
}, []));
|
}, []));
|
||||||
});
|
});
|
||||||
|
@ -69,12 +69,10 @@ exports.fromService = function ({ service, instances, packages }) {
|
|||||||
deploymentGroupId: service.deployment_group_id,
|
deploymentGroupId: service.deployment_group_id,
|
||||||
name: service.name,
|
name: service.name,
|
||||||
slug: service.slug,
|
slug: service.slug,
|
||||||
environment: service.environment || [],
|
|
||||||
instances,
|
instances,
|
||||||
currentMetrics: [],
|
|
||||||
connections: service.service_dependency_ids,
|
connections: service.service_dependency_ids,
|
||||||
package: packages ? exports.fromPackage(packages) : {},
|
parent: service.parent_id,
|
||||||
parent: service.parent_id || '',
|
config: service.config ? service.config : undefined,
|
||||||
status: service.status,
|
status: service.status,
|
||||||
hasPlan: service.has_plan
|
hasPlan: service.has_plan
|
||||||
};
|
};
|
||||||
@ -88,15 +86,14 @@ exports.toService = function (clientService) {
|
|||||||
deployment_group_id: clientService.deploymentGroupId,
|
deployment_group_id: clientService.deploymentGroupId,
|
||||||
name: clientService.name,
|
name: clientService.name,
|
||||||
slug: clientService.slug,
|
slug: clientService.slug,
|
||||||
environment: clientService.environment,
|
|
||||||
instance_ids: clientService.instances ?
|
instance_ids: clientService.instances ?
|
||||||
clientService.instances.map((instance) => {
|
clientService.instances.map((instance) => {
|
||||||
return instance.id;
|
return instance.id;
|
||||||
}) :
|
}) :
|
||||||
undefined,
|
undefined,
|
||||||
service_dependency_ids: clientService.connections,
|
service_dependency_ids: clientService.connections,
|
||||||
package_id: clientService.package ? clientService.package.id : undefined,
|
|
||||||
parent_id: clientService.parent ? clientService.parent : undefined,
|
parent_id: clientService.parent ? clientService.parent : undefined,
|
||||||
|
config: clientService.config ? clientService.config : undefined,
|
||||||
status: clientService.status,
|
status: clientService.status,
|
||||||
has_plan: clientService.hasPlan
|
has_plan: clientService.hasPlan
|
||||||
});
|
});
|
||||||
@ -133,6 +130,7 @@ exports.toManifest = function (clientManifest) {
|
|||||||
created: clientManifest.created || Date.now(),
|
created: clientManifest.created || Date.now(),
|
||||||
type: clientManifest.type,
|
type: clientManifest.type,
|
||||||
format: clientManifest.format,
|
format: clientManifest.format,
|
||||||
|
environment: clientManifest.environment,
|
||||||
raw: clientManifest.raw,
|
raw: clientManifest.raw,
|
||||||
json: clientManifest.json || Yamljs.parse(clientManifest.raw)
|
json: clientManifest.json || Yamljs.parse(clientManifest.raw)
|
||||||
};
|
};
|
||||||
@ -145,6 +143,7 @@ exports.fromManifest = function (manifest) {
|
|||||||
created: manifest.created,
|
created: manifest.created,
|
||||||
type: manifest.type,
|
type: manifest.type,
|
||||||
format: manifest.format,
|
format: manifest.format,
|
||||||
|
environment: manifest.environment,
|
||||||
raw: manifest.raw,
|
raw: manifest.raw,
|
||||||
json: manifest.json
|
json: manifest.json
|
||||||
};
|
};
|
||||||
|
90
yarn.lock
90
yarn.lock
@ -123,8 +123,8 @@ acorn@^4.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
|
||||||
|
|
||||||
acorn@^5.0.0, acorn@^5.0.1, acorn@^5.0.3:
|
acorn@^5.0.0, acorn@^5.0.1, acorn@^5.0.3:
|
||||||
version "5.0.3"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75"
|
||||||
|
|
||||||
add-stream@^1.0.0:
|
add-stream@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
@ -403,8 +403,8 @@ arr-exclude@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/arr-exclude/-/arr-exclude-1.0.0.tgz#dfc7c2e552a270723ccda04cf3128c8cbfe5c631"
|
resolved "https://registry.yarnpkg.com/arr-exclude/-/arr-exclude-1.0.0.tgz#dfc7c2e552a270723ccda04cf3128c8cbfe5c631"
|
||||||
|
|
||||||
arr-flatten@^1.0.1:
|
arr-flatten@^1.0.1:
|
||||||
version "1.0.3"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1"
|
resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
|
||||||
|
|
||||||
arr-union@^3.0.0:
|
arr-union@^3.0.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
@ -497,6 +497,10 @@ ast-types@0.9.0:
|
|||||||
version "0.9.0"
|
version "0.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.0.tgz#c8721c8747ae4d5b29b929e99c5317b4e8745623"
|
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.0.tgz#c8721c8747ae4d5b29b929e99c5317b4e8745623"
|
||||||
|
|
||||||
|
ast-types@0.9.6:
|
||||||
|
version "0.9.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9"
|
||||||
|
|
||||||
async-each@^1.0.0:
|
async-each@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
|
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
|
||||||
@ -2902,6 +2906,10 @@ deep-extend@~0.4.0:
|
|||||||
version "0.4.2"
|
version "0.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
|
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
|
||||||
|
|
||||||
|
deep-get-set@^1.0.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/deep-get-set/-/deep-get-set-1.1.0.tgz#47bba2008a3fde9c753dcbe61a36241606d9836f"
|
||||||
|
|
||||||
deep-is@~0.1.3:
|
deep-is@~0.1.3:
|
||||||
version "0.1.3"
|
version "0.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||||
@ -2986,8 +2994,8 @@ diff-match-patch@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.0.tgz#1cc3c83a490d67f95d91e39f6ad1f2e086b63048"
|
resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.0.tgz#1cc3c83a490d67f95d91e39f6ad1f2e086b63048"
|
||||||
|
|
||||||
diff@3.x.x, diff@^3.0.0, diff@^3.0.1, diff@^3.2.0:
|
diff@3.x.x, diff@^3.0.0, diff@^3.0.1, diff@^3.2.0:
|
||||||
version "3.2.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
|
resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9"
|
||||||
|
|
||||||
diffie-hellman@^5.0.0:
|
diffie-hellman@^5.0.0:
|
||||||
version "5.0.2"
|
version "5.0.2"
|
||||||
@ -3329,7 +3337,7 @@ eslint-import-resolver-node@^0.3.1:
|
|||||||
debug "^2.6.8"
|
debug "^2.6.8"
|
||||||
resolve "^1.2.0"
|
resolve "^1.2.0"
|
||||||
|
|
||||||
eslint-module-utils@^2.0.0:
|
eslint-module-utils@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449"
|
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -3352,15 +3360,15 @@ eslint-plugin-hapi@4.x.x:
|
|||||||
no-arrowception "1.x.x"
|
no-arrowception "1.x.x"
|
||||||
|
|
||||||
eslint-plugin-import@^2.3.0:
|
eslint-plugin-import@^2.3.0:
|
||||||
version "2.6.1"
|
version "2.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.6.1.tgz#f580be62bb809421d46e338372764afcc9f59bf6"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz#21de33380b9efb55f5ef6d2e210ec0e07e7fa69f"
|
||||||
dependencies:
|
dependencies:
|
||||||
builtin-modules "^1.1.1"
|
builtin-modules "^1.1.1"
|
||||||
contains-path "^0.1.0"
|
contains-path "^0.1.0"
|
||||||
debug "^2.6.8"
|
debug "^2.6.8"
|
||||||
doctrine "1.5.0"
|
doctrine "1.5.0"
|
||||||
eslint-import-resolver-node "^0.3.1"
|
eslint-import-resolver-node "^0.3.1"
|
||||||
eslint-module-utils "^2.0.0"
|
eslint-module-utils "^2.1.1"
|
||||||
has "^1.0.1"
|
has "^1.0.1"
|
||||||
lodash.cond "^4.3.0"
|
lodash.cond "^4.3.0"
|
||||||
minimatch "^3.0.3"
|
minimatch "^3.0.3"
|
||||||
@ -3498,7 +3506,7 @@ esprima@^2.6.0, esprima@~2.7.1:
|
|||||||
version "2.7.3"
|
version "2.7.3"
|
||||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
|
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
|
||||||
|
|
||||||
esprima@^3.1.1:
|
esprima@^3.1.1, esprima@~3.1.0:
|
||||||
version "3.1.3"
|
version "3.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
|
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
|
||||||
|
|
||||||
@ -4437,6 +4445,10 @@ hoist-non-react-statics@^1.0.3, hoist-non-react-statics@^1.2.0:
|
|||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb"
|
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb"
|
||||||
|
|
||||||
|
hoist-non-react-statics@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.0.0.tgz#843180515e0281952b08f41c620ca74870c7e354"
|
||||||
|
|
||||||
home-or-tmp@^2.0.0:
|
home-or-tmp@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
|
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
|
||||||
@ -5385,8 +5397,8 @@ json5@0.5.x, json5@^0.5.0, json5@^0.5.1:
|
|||||||
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
||||||
|
|
||||||
jsonfile@^3.0.0:
|
jsonfile@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.0.tgz#92e7c7444e5ffd5fa32e6a9ae8b85034df8347d0"
|
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66"
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
graceful-fs "^4.1.6"
|
graceful-fs "^4.1.6"
|
||||||
|
|
||||||
@ -5522,8 +5534,8 @@ lerna-wizard@ramitos/lerna-wizard#7bcdc11:
|
|||||||
inquirer "^3.0.2"
|
inquirer "^3.0.2"
|
||||||
|
|
||||||
lerna@^2.0.0-rc.5:
|
lerna@^2.0.0-rc.5:
|
||||||
version "2.0.0-rc.5"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/lerna/-/lerna-2.0.0-rc.5.tgz#b59d168caaac6e3443078c1bce194208c9aa3090"
|
resolved "https://registry.yarnpkg.com/lerna/-/lerna-2.0.0.tgz#49a72fe70e06aebfd7ea23efb2ab41abe60ebeea"
|
||||||
dependencies:
|
dependencies:
|
||||||
async "^1.5.0"
|
async "^1.5.0"
|
||||||
chalk "^1.1.1"
|
chalk "^1.1.1"
|
||||||
@ -5706,6 +5718,10 @@ lodash.difference@^4.3.0, lodash.difference@^4.4.0, lodash.difference@^4.5.0:
|
|||||||
version "4.5.0"
|
version "4.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c"
|
resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c"
|
||||||
|
|
||||||
|
lodash.differenceby@^4.8.0:
|
||||||
|
version "4.8.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.differenceby/-/lodash.differenceby-4.8.0.tgz#cfd59e94353af5de51da5d302ca4ebff33faac57"
|
||||||
|
|
||||||
lodash.find@^4.6.0:
|
lodash.find@^4.6.0:
|
||||||
version "4.6.0"
|
version "4.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1"
|
resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1"
|
||||||
@ -7250,13 +7266,13 @@ rc@1.1.7, rc@^1.0.1, rc@^1.1.6, rc@^1.1.7:
|
|||||||
strip-json-comments "~2.0.1"
|
strip-json-comments "~2.0.1"
|
||||||
|
|
||||||
react-apollo@^1.4.2:
|
react-apollo@^1.4.2:
|
||||||
version "1.4.2"
|
version "1.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-apollo/-/react-apollo-1.4.2.tgz#e8ee035310b564fd1b42ee7e4f116086b5b06834"
|
resolved "https://registry.yarnpkg.com/react-apollo/-/react-apollo-1.4.3.tgz#be18bfe7f6609263f3ff623308f88108152a7573"
|
||||||
dependencies:
|
dependencies:
|
||||||
apollo-client "^1.4.0"
|
apollo-client "^1.4.0"
|
||||||
graphql-anywhere "^3.0.0"
|
graphql-anywhere "^3.0.0"
|
||||||
graphql-tag "^2.0.0"
|
graphql-tag "^2.0.0"
|
||||||
hoist-non-react-statics "^1.2.0"
|
hoist-non-react-statics "^2.0.0"
|
||||||
invariant "^2.2.1"
|
invariant "^2.2.1"
|
||||||
lodash.flatten "^4.2.0"
|
lodash.flatten "^4.2.0"
|
||||||
lodash.isequal "^4.1.1"
|
lodash.isequal "^4.1.1"
|
||||||
@ -7351,6 +7367,12 @@ react-router@^4.1.1:
|
|||||||
prop-types "^15.5.4"
|
prop-types "^15.5.4"
|
||||||
warning "^3.0.0"
|
warning "^3.0.0"
|
||||||
|
|
||||||
|
react-simple-table@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-simple-table/-/react-simple-table-1.0.1.tgz#941390bd68eca63d028c1873bd90772a21143b9c"
|
||||||
|
dependencies:
|
||||||
|
deep-get-set "^1.0.0"
|
||||||
|
|
||||||
react-styled-flexboxgrid@^2.0.1:
|
react-styled-flexboxgrid@^2.0.1:
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-styled-flexboxgrid/-/react-styled-flexboxgrid-2.0.3.tgz#308a8bbc80b1737a65f4ccf35d02afe20932a2f2"
|
resolved "https://registry.yarnpkg.com/react-styled-flexboxgrid/-/react-styled-flexboxgrid-2.0.3.tgz#308a8bbc80b1737a65f4ccf35d02afe20932a2f2"
|
||||||
@ -7529,7 +7551,7 @@ readline2@^1.0.1:
|
|||||||
is-fullwidth-code-point "^1.0.0"
|
is-fullwidth-code-point "^1.0.0"
|
||||||
mute-stream "0.0.5"
|
mute-stream "0.0.5"
|
||||||
|
|
||||||
recast@0.11.12, recast@^0.11.5:
|
recast@0.11.12:
|
||||||
version "0.11.12"
|
version "0.11.12"
|
||||||
resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.12.tgz#a79e4d3f82d5d72a82ee177aeaa791e793bbe5d6"
|
resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.12.tgz#a79e4d3f82d5d72a82ee177aeaa791e793bbe5d6"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -7538,6 +7560,15 @@ recast@0.11.12, recast@^0.11.5:
|
|||||||
private "~0.1.5"
|
private "~0.1.5"
|
||||||
source-map "~0.5.0"
|
source-map "~0.5.0"
|
||||||
|
|
||||||
|
recast@^0.11.5:
|
||||||
|
version "0.11.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3"
|
||||||
|
dependencies:
|
||||||
|
ast-types "0.9.6"
|
||||||
|
esprima "~3.1.0"
|
||||||
|
private "~0.1.5"
|
||||||
|
source-map "~0.5.0"
|
||||||
|
|
||||||
rechoir@^0.6.2:
|
rechoir@^0.6.2:
|
||||||
version "0.6.2"
|
version "0.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
|
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
|
||||||
@ -8763,6 +8794,12 @@ supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has-flag "^1.0.0"
|
has-flag "^1.0.0"
|
||||||
|
|
||||||
|
supports-color@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.1.0.tgz#92cc14bb3dad8928ca5656c33e19a19f20af5c7a"
|
||||||
|
dependencies:
|
||||||
|
has-flag "^2.0.0"
|
||||||
|
|
||||||
svg-tags@^1.0.0:
|
svg-tags@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764"
|
resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764"
|
||||||
@ -9502,17 +9539,18 @@ vfile-location@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.1.tgz#0bf8816f732b0f8bd902a56fda4c62c8e935dc52"
|
resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.1.tgz#0bf8816f732b0f8bd902a56fda4c62c8e935dc52"
|
||||||
|
|
||||||
vfile-reporter@^3.0.0:
|
vfile-reporter@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/vfile-reporter/-/vfile-reporter-3.0.0.tgz#fe50714e373e0d2940510038a99bd609bdc8209f"
|
resolved "https://registry.yarnpkg.com/vfile-reporter/-/vfile-reporter-3.1.0.tgz#a9b398c5e6dcbc8a9a08e6cf425f092e86a37000"
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk "^1.1.0"
|
|
||||||
log-symbols "^1.0.2"
|
|
||||||
plur "^2.0.0"
|
|
||||||
repeat-string "^1.5.0"
|
repeat-string "^1.5.0"
|
||||||
string-width "^1.0.0"
|
string-width "^1.0.0"
|
||||||
strip-ansi "^3.0.1"
|
supports-color "^4.1.0"
|
||||||
trim "0.0.1"
|
|
||||||
unist-util-stringify-position "^1.0.0"
|
unist-util-stringify-position "^1.0.0"
|
||||||
|
vfile-statistics "^1.0.0"
|
||||||
|
|
||||||
|
vfile-statistics@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vfile-statistics/-/vfile-statistics-1.0.0.tgz#003d356c0f3e0233f3a2271c65e2acee5ed4d0f8"
|
||||||
|
|
||||||
vfile@^2.0.0:
|
vfile@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user