mirror of
https://github.com/yldio/copilot.git
synced 2024-11-28 06:00:06 +02:00
feat(portal-data): can stop services
This commit is contained in:
parent
7e01748e8a
commit
1e157641b2
@ -120,6 +120,7 @@ enum InstanceStatus {
|
||||
PAUSED
|
||||
EXITED
|
||||
DELETED
|
||||
STOPPED
|
||||
}
|
||||
|
||||
type Instance {
|
||||
|
@ -39,4 +39,16 @@ module.exports = class DockerComposeClient extends EventEmitter {
|
||||
|
||||
return this._invoke('scale', options, manifest, cb);
|
||||
}
|
||||
|
||||
config({ projectName, services, manifest }, cb) {
|
||||
const options = {
|
||||
// eslint-disable-next-line camelcase
|
||||
project_name: projectName,
|
||||
services: services.map(service => ({
|
||||
name: service
|
||||
}))
|
||||
};
|
||||
|
||||
return this._invoke('config', options, manifest, cb);
|
||||
}
|
||||
};
|
||||
|
@ -69,6 +69,30 @@ const server = new Server({
|
||||
projectName: options.project_name,
|
||||
services: options.services
|
||||
});
|
||||
},
|
||||
// eslint-disable-next-line object-shorthand
|
||||
config: function(options, manifest, fn) {
|
||||
if (typeof options !== 'object') {
|
||||
return fn(new Error('Expected options'));
|
||||
}
|
||||
|
||||
if (typeof options.project_name !== 'string') {
|
||||
return fn(new Error('Expected project name'));
|
||||
}
|
||||
|
||||
if (typeof manifest !== 'string') {
|
||||
return fn(new Error('Expected manifest'));
|
||||
}
|
||||
|
||||
try {
|
||||
safeLoad(manifest);
|
||||
} catch (err) {
|
||||
return fn(err);
|
||||
}
|
||||
|
||||
fn(null, {
|
||||
projectName: options.project_name
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -123,6 +147,30 @@ it('scale()', done => {
|
||||
);
|
||||
});
|
||||
|
||||
it('config()', done => {
|
||||
const manifest = `
|
||||
hello:
|
||||
image: hello-world:latest
|
||||
world:
|
||||
image: consul:latest
|
||||
node:
|
||||
image: node:latest
|
||||
`;
|
||||
|
||||
client.config(
|
||||
{
|
||||
projectName,
|
||||
services: ['hello'],
|
||||
manifest
|
||||
},
|
||||
(err, res) => {
|
||||
expect(err).to.not.exist();
|
||||
expect(res).to.exist();
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('handles errors', done => {
|
||||
client.once('error', err => {
|
||||
expect(err).to.exist();
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const EventEmitter = require('events');
|
||||
const DockerClient = require('docker-compose-client');
|
||||
const Dockerode = require('dockerode');
|
||||
const Hoek = require('hoek');
|
||||
const Penseur = require('penseur');
|
||||
const VAsync = require('vasync');
|
||||
@ -14,7 +15,7 @@ const internals = {
|
||||
db: {
|
||||
test: false
|
||||
},
|
||||
dockerHost: 'tcp://0.0.0.0:4242'
|
||||
dockerComposeHost: 'tcp://0.0.0.0:4242'
|
||||
},
|
||||
tables: {
|
||||
'portals': { id: { type: 'uuid' }, primary: 'id', secondary: false, purge: false },
|
||||
@ -36,9 +37,10 @@ module.exports = class Data extends EventEmitter {
|
||||
|
||||
// Penseur will assert that the options are correct
|
||||
this._db = new Penseur.Db(settings.name, settings.db);
|
||||
this._docker = new DockerClient(settings.dockerHost);
|
||||
this._dockerCompose = new DockerClient(settings.dockerComposeHost);
|
||||
this._docker = new Dockerode(settings.docker);
|
||||
|
||||
this._docker.on('error', (err) => {
|
||||
this._dockerCompose.on('error', (err) => {
|
||||
this.emit('error', err);
|
||||
});
|
||||
}
|
||||
@ -489,7 +491,7 @@ module.exports = class Data extends EventEmitter {
|
||||
manifest: manifest.raw
|
||||
};
|
||||
options.services[service.name] = replicas;
|
||||
this._docker.scale(options, (err) => {
|
||||
this._dockerCompose.scale(options, (err) => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
@ -523,7 +525,7 @@ module.exports = class Data extends EventEmitter {
|
||||
|
||||
setImmediate(() => {
|
||||
let isHandled = false;
|
||||
this._docker.provision({ projectName: deploymentGroup.name, manifest: clientManifest.raw }, (err, res) => {
|
||||
this._dockerCompose.provision({ projectName: deploymentGroup.name, manifest: clientManifest.raw }, (err, res) => {
|
||||
if (err) {
|
||||
this.emit('error', err);
|
||||
return;
|
||||
@ -538,7 +540,8 @@ module.exports = class Data extends EventEmitter {
|
||||
const options = {
|
||||
manifestServices: manifest.json.services || manifest.json,
|
||||
deploymentGroup,
|
||||
manifestId: key
|
||||
manifestId: key,
|
||||
provisionRes: res
|
||||
};
|
||||
this.provisionServices(options);
|
||||
});
|
||||
@ -575,7 +578,7 @@ module.exports = class Data extends EventEmitter {
|
||||
|
||||
// services
|
||||
|
||||
provisionServices ({ manifestServices, deploymentGroup, manifestId }, cb) {
|
||||
provisionServices ({ manifestServices, deploymentGroup, manifestId, provisionRes }, cb) {
|
||||
// insert instance information
|
||||
// insert service information
|
||||
// insert version information -- will update deploymentGroups
|
||||
@ -591,7 +594,7 @@ module.exports = class Data extends EventEmitter {
|
||||
const manifestService = manifestServices[serviceName];
|
||||
const clientInstance = {
|
||||
name: serviceName,
|
||||
machineId: `${deploymentGroup.name}_${serviceName}_1`,
|
||||
machineId: provisionRes[serviceName].plan.containers[0].id,
|
||||
status: 'CREATED'
|
||||
};
|
||||
this.createInstance(clientInstance, (err, createdInstance) => {
|
||||
@ -604,7 +607,8 @@ module.exports = class Data extends EventEmitter {
|
||||
name: serviceName,
|
||||
slug: serviceName,
|
||||
deploymentGroupId: deploymentGroup.id,
|
||||
instances: [createdInstance]
|
||||
instances: [createdInstance],
|
||||
info: provisionRes[serviceName]
|
||||
};
|
||||
|
||||
this.createService(clientService, (err, createdService) => {
|
||||
@ -750,6 +754,62 @@ module.exports = class Data extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
stopServices ({ ids }, cb) {
|
||||
this._db.services.get(ids, (err, services) => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
if (!services || !services.length) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
let instanceIds = [];
|
||||
services.forEach((service) => {
|
||||
instanceIds = instanceIds.concat(service.instance_ids);
|
||||
});
|
||||
|
||||
VAsync.forEachParallel({
|
||||
func: (instanceId, next) => {
|
||||
this._db.instances.get(instanceId, (err, instance) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
const container = this._docker.getContainer(instance.machine_id);
|
||||
|
||||
container.stop((err) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
this.updateInstance({ id: instance.id, status: 'STOPPED' }, next);
|
||||
});
|
||||
});
|
||||
},
|
||||
inputs: instanceIds
|
||||
}, (err, results) => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
this.getServices({ ids }, cb);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
startServices ({ ids }, cb) {
|
||||
|
||||
}
|
||||
|
||||
restartServices ({ ids }, cb) {
|
||||
|
||||
}
|
||||
|
||||
deleteServices ({ ids }, cb) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// instances
|
||||
|
||||
@ -774,6 +834,16 @@ module.exports = class Data extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
updateInstance ({ id, status }, cb) {
|
||||
this._db.instances.update(id, { status }, (err, instance) => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
cb(null, instance ? Transform.fromInstance(instance) : {});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// packages
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"docker-compose-client": "^1.0.7",
|
||||
"dockerode": "^2.4.3",
|
||||
"hoek": "^4.1.1",
|
||||
"penseur": "^7.8.1",
|
||||
"vasync": "^1.6.4",
|
||||
|
@ -6,16 +6,32 @@ const Code = require('code');
|
||||
const Lab = require('lab');
|
||||
const PortalData = require('../');
|
||||
|
||||
|
||||
const lab = exports.lab = Lab.script();
|
||||
const afterEach = lab.afterEach;
|
||||
const it = lab.it;
|
||||
const describe = lab.describe;
|
||||
const expect = Code.expect;
|
||||
|
||||
|
||||
const internals = {
|
||||
options: { name: 'test', db: { test: true } },
|
||||
options: {
|
||||
name: 'test',
|
||||
db: { test: true }
|
||||
},
|
||||
composeFile: Fs.readFileSync(Path.join(__dirname, 'docker-compose.yml')).toString()
|
||||
};
|
||||
|
||||
|
||||
afterEach((done) => {
|
||||
const data = new PortalData({ name: 'test', db: { test: true } });
|
||||
data.connect(() => {
|
||||
data._db.r.dbDrop('test').run(data._db._connection, () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('connect()', () => {
|
||||
it('connects to the database', (done) => {
|
||||
const data = new PortalData(internals.options);
|
||||
@ -688,3 +704,38 @@ describe.skip('scale()', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// skipping by default since it takes so long
|
||||
describe.skip('stopServices()', () => {
|
||||
it('stops all instances of a service', { timeout: 180000 }, (done) => {
|
||||
const data = new PortalData(internals.options);
|
||||
data.connect((err) => {
|
||||
expect(err).to.not.exist();
|
||||
data.createDeploymentGroup({ name: 'something' }, (err, deploymentGroup) => {
|
||||
expect(err).to.not.exist();
|
||||
const clientManifest = {
|
||||
deploymentGroupId: deploymentGroup.id,
|
||||
type: 'compose',
|
||||
format: 'yml',
|
||||
raw: internals.composeFile
|
||||
};
|
||||
data.provisionManifest(clientManifest, (err, manifest) => {
|
||||
expect(err).to.not.exist();
|
||||
setTimeout(() => {
|
||||
data.getDeploymentGroup({ id: deploymentGroup.id }, (err, deploymentGroup) => {
|
||||
expect(err).to.not.exist();
|
||||
deploymentGroup.services().then((deploymentGroupServices) => {
|
||||
data.stopServices({ ids: [deploymentGroupServices[0].id] }, (err, services) => {
|
||||
expect(err).to.not.exist();
|
||||
expect(services).to.exist();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}, 80000);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -2,6 +2,13 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
JSONStream@0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-0.10.0.tgz#74349d0d89522b71f30f0a03ff9bd20ca6f12ac0"
|
||||
dependencies:
|
||||
jsonparse "0.0.5"
|
||||
through ">=2.2.7 <3"
|
||||
|
||||
acorn-jsx@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
|
||||
@ -105,6 +112,12 @@ bindings@~1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11"
|
||||
|
||||
bl@^1.0.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e"
|
||||
dependencies:
|
||||
readable-stream "^2.0.5"
|
||||
|
||||
"bluebird@>= 2.3.2 < 3":
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
|
||||
@ -212,6 +225,14 @@ concat-stream@^1.5.2:
|
||||
readable-stream "^2.2.2"
|
||||
typedarray "^0.0.6"
|
||||
|
||||
concat-stream@~1.5.1:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266"
|
||||
dependencies:
|
||||
inherits "~2.0.1"
|
||||
readable-stream "~2.0.0"
|
||||
typedarray "~0.0.5"
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
@ -222,7 +243,7 @@ d@1:
|
||||
dependencies:
|
||||
es5-ext "^0.10.9"
|
||||
|
||||
debug@^2.1.1:
|
||||
debug@^2.1.1, debug@^2.6.0:
|
||||
version "2.6.8"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
|
||||
dependencies:
|
||||
@ -259,6 +280,23 @@ docker-compose-client@^1.0.7:
|
||||
apr-awaitify "^1.0.4"
|
||||
zerorpc "^0.9.7"
|
||||
|
||||
docker-modem@0.3.x:
|
||||
version "0.3.7"
|
||||
resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-0.3.7.tgz#3f510d09f5d334dc2134228f92bd344671227df4"
|
||||
dependencies:
|
||||
JSONStream "0.10.0"
|
||||
debug "^2.6.0"
|
||||
readable-stream "~1.0.26-4"
|
||||
split-ca "^1.0.0"
|
||||
|
||||
dockerode@^2.4.3:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-2.4.3.tgz#7ec55b492fc9f289e77325ff07c6a3a96021b4f2"
|
||||
dependencies:
|
||||
concat-stream "~1.5.1"
|
||||
docker-modem "0.3.x"
|
||||
tar-fs "~1.12.0"
|
||||
|
||||
doctrine@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63"
|
||||
@ -266,6 +304,12 @@ doctrine@^2.0.0:
|
||||
esutils "^2.0.2"
|
||||
isarray "^1.0.0"
|
||||
|
||||
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206"
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14:
|
||||
version "0.10.21"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.21.tgz#19a725f9e51d0300bbc1e8e821109fd9daf55925"
|
||||
@ -636,6 +680,10 @@ is-resolvable@^1.0.0:
|
||||
dependencies:
|
||||
tryit "^1.0.1"
|
||||
|
||||
isarray@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
|
||||
|
||||
isarray@^1.0.0, isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
@ -682,6 +730,10 @@ jsonify@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
|
||||
|
||||
jsonparse@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-0.0.5.tgz#330542ad3f0a654665b778f3eb2d9a9fa507ac64"
|
||||
|
||||
jsonpointer@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
|
||||
@ -786,7 +838,7 @@ object-assign@^4.0.1, object-assign@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
once@^1.3.0:
|
||||
once@^1.3.0, once@^1.3.1, once@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
dependencies:
|
||||
@ -871,11 +923,18 @@ progress@^1.1.8:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
|
||||
|
||||
pump@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.2.tgz#3b3ee6512f94f0e575538c17995f9f16990a5d51"
|
||||
dependencies:
|
||||
end-of-stream "^1.1.0"
|
||||
once "^1.3.1"
|
||||
|
||||
radix62@1.x.x:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/radix62/-/radix62-1.0.1.tgz#cc2f27a49543b44ddaac712380409354bbe009a5"
|
||||
|
||||
readable-stream@^2.2.2:
|
||||
readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2:
|
||||
version "2.2.9"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8"
|
||||
dependencies:
|
||||
@ -887,6 +946,26 @@ readable-stream@^2.2.2:
|
||||
string_decoder "~1.0.0"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readable-stream@~1.0.26-4:
|
||||
version "1.0.34"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.1"
|
||||
isarray "0.0.1"
|
||||
string_decoder "~0.10.x"
|
||||
|
||||
readable-stream@~2.0.0:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.1"
|
||||
isarray "~1.0.0"
|
||||
process-nextick-args "~1.0.6"
|
||||
string_decoder "~0.10.x"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readline2@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35"
|
||||
@ -993,6 +1072,10 @@ source-map@^0.4.4:
|
||||
dependencies:
|
||||
amdefine ">=0.0.4"
|
||||
|
||||
split-ca@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6"
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
@ -1012,6 +1095,10 @@ string-width@^2.0.0:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
|
||||
string_decoder@~0.10.x:
|
||||
version "0.10.31"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
|
||||
|
||||
string_decoder@~1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.1.tgz#62e200f039955a6810d8df0a33ffc0f013662d98"
|
||||
@ -1047,11 +1134,28 @@ table@^3.7.8:
|
||||
slice-ansi "0.0.4"
|
||||
string-width "^2.0.0"
|
||||
|
||||
tar-fs@~1.12.0:
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.12.0.tgz#a6a80553d8a54c73de1d0ae0e79de77035605e1d"
|
||||
dependencies:
|
||||
mkdirp "^0.5.0"
|
||||
pump "^1.0.0"
|
||||
tar-stream "^1.1.2"
|
||||
|
||||
tar-stream@^1.1.2:
|
||||
version "1.5.4"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.4.tgz#36549cf04ed1aee9b2a30c0143252238daf94016"
|
||||
dependencies:
|
||||
bl "^1.0.0"
|
||||
end-of-stream "^1.0.0"
|
||||
readable-stream "^2.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
text-table@~0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
|
||||
through@^2.3.6:
|
||||
"through@>=2.2.7 <3", through@^2.3.6:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
|
||||
@ -1071,7 +1175,7 @@ type-check@~0.3.2:
|
||||
dependencies:
|
||||
prelude-ls "~1.1.2"
|
||||
|
||||
typedarray@^0.0.6:
|
||||
typedarray@^0.0.6, typedarray@~0.0.5:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user