Compare commits

..

2 Commits

Author SHA1 Message Date
eb5096482f 1.0.7 2017-06-26 15:46:18 +02:00
6d56a09dd7 now has working wait for line method 2017-06-26 15:46:15 +02:00
23 changed files with 804 additions and 2265 deletions

22
.gitignore vendored
View File

@ -1,22 +1,4 @@
.nogit/
# artifacts
coverage/
public/
pages/
# installs
node_modules/
# caches
.yarn/
.cache/
.rpt2_cache
# builds
dist/
dist_web/
dist_serve/
dist_ts_web/
# custom
pages/
public/

View File

@ -3,123 +3,66 @@ image: hosttoday/ht-docker-node:npmci
cache:
paths:
- .npmci_cache/
- .yarn/
key: "$CI_BUILD_STAGE"
stages:
- security
- test
- release
- metadata
- trigger
- pages
# ====================
# security stage
# ====================
mirror:
stage: security
testLEGACY:
stage: test
script:
- npmci git mirror
- npmci test legacy
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
snyk:
stage: security
script:
- npmci npm prepare
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts
- npmci command snyk test
tags:
- docker
- notpriv
# ====================
# test stage
# ====================
- docker
allow_failure: true
testLTS:
stage: test
script:
- npmci npm prepare
- npmci node install lts
- npmci npm install
- npmci npm test
- npmci test lts
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
- docker
testSTABLE:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci npm test
- npmci test stable
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
- docker
release:
stage: release
script:
- npmci node install stable
- npmci npm publish
- npmci publish
only:
- tags
tags:
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
image: docker:stable
allow_failure: true
services:
- docker:stable-dind
script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts:
paths: [codeclimate.json]
tags:
- docker
- priv
trigger:
stage: metadata
script:
- npmci trigger
only:
- tags
tags:
- docker
- notpriv
pages:
image: hosttoday/ht-docker-node:npmci
stage: metadata
script:
- npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare
- npmci npm install
- npmci command tsdoc
- tags
tags:
- docker
- notpriv
trigger:
stage: trigger
script:
- npmci trigger
only:
- tags
tags:
- docker
pages:
image: hosttoday/ht-docker-node:npmpage
stage: pages
script:
- npmci command npmpage --publish gitlab
only:
- tags
artifacts:
expire_in: 1 week
paths:
- public
allow_failure: true

View File

@ -1,28 +1,28 @@
# @pushrocks/smartshell
# smartshell
shell actions designed as promises
## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/smartshell)
* [gitlab.com (source)](https://gitlab.com/pushrocks/smartshell)
* [github.com (source mirror)](https://github.com/pushrocks/smartshell)
* [docs (typedoc)](https://pushrocks.gitlab.io/smartshell/)
## Availabililty
[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/smartshell)
[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/pushrocks/smartshell)
[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/smartshell)
[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/smartshell/)
## Status for master
[![build status](https://gitlab.com/pushrocks/smartshell/badges/master/build.svg)](https://gitlab.com/pushrocks/smartshell/commits/master)
[![coverage report](https://gitlab.com/pushrocks/smartshell/badges/master/coverage.svg)](https://gitlab.com/pushrocks/smartshell/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/@pushrocks/smartshell.svg)](https://www.npmjs.com/package/@pushrocks/smartshell)
[![Known Vulnerabilities](https://snyk.io/test/npm/@pushrocks/smartshell/badge.svg)](https://snyk.io/test/npm/@pushrocks/smartshell)
[![TypeScript](https://img.shields.io/badge/TypeScript->=%203.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://prettier.io/)
[![build status](https://GitLab.com/pushrocks/smartshell/badges/master/build.svg)](https://GitLab.com/pushrocks/smartshell/commits/master)
[![coverage report](https://GitLab.com/pushrocks/smartshell/badges/master/coverage.svg)](https://GitLab.com/pushrocks/smartshell/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/smartshell.svg)](https://www.npmjs.com/package/smartshell)
[![Dependency Status](https://david-dm.org/pushrocks/smartshell.svg)](https://david-dm.org/pushrocks/smartshell)
[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/smartshell/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/smartshell/master/dependencies/npm)
[![bitHound Code](https://www.bithound.io/github/pushrocks/smartshell/badges/code.svg)](https://www.bithound.io/github/pushrocks/smartshell)
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Usage
Use TypeScript for best in class instellisense.
For further information read the linked docs at the top of this readme.
For further information read the linked docs at the top of this README.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://maintainedby.lossless.com)
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)

2
dist/index.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export * from './smartshell.wrap';
export * from './smartshell.classes.smartshell';

8
dist/index.js vendored Normal file
View File

@ -0,0 +1,8 @@
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./smartshell.wrap"));
__export(require("./smartshell.classes.smartshell"));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHVDQUFpQztBQUNqQyxxREFBK0MifQ==

28
dist/smartshell.classes.smartshell.d.ts vendored Normal file
View File

@ -0,0 +1,28 @@
import * as smartshellWrap from './smartshell.wrap';
export declare type TExecutor = 'sh' | 'bash';
export interface ISmartshellContructorOptions {
executor: TExecutor;
sourceFilePaths: string[];
}
export declare class Smartshell {
executor: TExecutor;
sourceFileArray: string[];
constructor(optionsArg: ISmartshellContructorOptions);
addSourceFiles(sourceFilePathsArray: string[]): void;
cleanSourceFiles(): void;
/**
* executes silently and returns IExecResult
* @param commandArg
*/
execSilent(commandArg: string): Promise<smartshellWrap.IExecResult>;
/**
* executes and returns IExecResult
* @param commandArg
*/
exec(commandArg: string): Promise<smartshellWrap.IExecResult>;
/**
* creates the final sourcing string
* @param commandArg
*/
private createExecString(commandArg);
}

66
dist/smartshell.classes.smartshell.js vendored Normal file
View File

@ -0,0 +1,66 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const smartshellWrap = require("./smartshell.wrap");
class Smartshell {
constructor(optionsArg) {
this.sourceFileArray = [];
this.executor = optionsArg.executor;
for (let sourceFilePath of optionsArg.sourceFilePaths) {
this.sourceFileArray.push(sourceFilePath);
}
}
addSourceFiles(sourceFilePathsArray) {
for (let sourceFilePath of sourceFilePathsArray) {
this.sourceFileArray.push(sourceFilePath);
}
}
cleanSourceFiles() {
this.sourceFileArray = [];
}
/**
* executes silently and returns IExecResult
* @param commandArg
*/
execSilent(commandArg) {
return __awaiter(this, void 0, void 0, function* () {
let execCommand = this.createExecString(commandArg);
return yield smartshellWrap.execSilent(execCommand);
});
}
/**
* executes and returns IExecResult
* @param commandArg
*/
exec(commandArg) {
return __awaiter(this, void 0, void 0, function* () {
let execCommand = this.createExecString(commandArg);
return yield smartshellWrap.exec(execCommand);
});
}
/**
* creates the final sourcing string
* @param commandArg
*/
createExecString(commandArg) {
if (this.executor === 'bash') {
let sourceString = '';
for (let sourceFilePath of this.sourceFileArray) {
sourceString = sourceString + `source ${sourceFilePath} && `;
}
return `bash -c '${sourceString} ${commandArg}'`;
}
else {
return commandArg;
}
}
}
exports.Smartshell = Smartshell;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzaGVsbC5jbGFzc2VzLnNtYXJ0c2hlbGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHNoZWxsLmNsYXNzZXMuc21hcnRzaGVsbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQ0Esb0RBQW1EO0FBVW5EO0lBR0UsWUFBYSxVQUF3QztRQURyRCxvQkFBZSxHQUFhLEVBQUUsQ0FBQTtRQUU1QixJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUE7UUFDbkMsR0FBRyxDQUFDLENBQUMsSUFBSSxjQUFjLElBQUksVUFBVSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7WUFDdEQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUE7UUFDM0MsQ0FBQztJQUNILENBQUM7SUFFRCxjQUFjLENBQUUsb0JBQThCO1FBQzVDLEdBQUcsQ0FBQyxDQUFDLElBQUksY0FBYyxJQUFJLG9CQUFvQixDQUFDLENBQUMsQ0FBQztZQUNoRCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQTtRQUMzQyxDQUFDO0lBQ0gsQ0FBQztJQUVELGdCQUFnQjtRQUNkLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFBO0lBQzNCLENBQUM7SUFFRDs7O09BR0c7SUFDRyxVQUFVLENBQUUsVUFBa0I7O1lBQ2xDLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQTtZQUNuRCxNQUFNLENBQUMsTUFBTSxjQUFjLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFBO1FBQ3JELENBQUM7S0FBQTtJQUVEOzs7T0FHRztJQUNHLElBQUksQ0FBRSxVQUFrQjs7WUFDNUIsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQ25ELE1BQU0sQ0FBQyxNQUFNLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUE7UUFDL0MsQ0FBQztLQUFBO0lBRUQ7OztPQUdHO0lBQ0ssZ0JBQWdCLENBQUUsVUFBVTtRQUNsQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDN0IsSUFBSSxZQUFZLEdBQUcsRUFBRSxDQUFBO1lBQ3JCLEdBQUcsQ0FBQyxDQUFDLElBQUksY0FBYyxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO2dCQUNoRCxZQUFZLEdBQUcsWUFBWSxHQUFHLFVBQVUsY0FBYyxNQUFNLENBQUE7WUFDOUQsQ0FBQztZQUNELE1BQU0sQ0FBQyxZQUFZLFlBQVksSUFBSSxVQUFVLEdBQUcsQ0FBQTtRQUNsRCxDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTixNQUFNLENBQUMsVUFBVSxDQUFBO1FBQ25CLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFyREQsZ0NBcURDIn0=

4
dist/smartshell.plugins.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
import * as shelljs from 'shelljs';
import * as smartq from 'smartq';
import * as which from 'which';
export { shelljs, smartq, which };

9
dist/smartshell.plugins.js vendored Normal file
View File

@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const shelljs = require("shelljs");
exports.shelljs = shelljs;
const smartq = require("smartq");
exports.smartq = smartq;
const which = require("which");
exports.which = which;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzaGVsbC5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRzaGVsbC5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbUNBQWtDO0FBS2hDLDBCQUFPO0FBSlQsaUNBQWdDO0FBSzlCLHdCQUFNO0FBSlIsK0JBQThCO0FBSzVCLHNCQUFLIn0=

43
dist/smartshell.wrap.d.ts vendored Normal file
View File

@ -0,0 +1,43 @@
/// <reference types="node" />
import { ChildProcess } from 'child_process';
/**
* interface for ExecResult
*/
export interface IExecResult {
exitCode: number;
stdout: string;
}
/**
* interface for streaming ExecResult
*/
export interface IExecResultStreaming {
childProcess: ChildProcess;
finalPromise: Promise<IExecResult>;
}
/**
* executes a given command async
* @param commandStringArg
*/
export declare let exec: (commandStringArg: string) => Promise<IExecResult>;
/**
* executes a given command async and silent
* @param commandStringArg
*/
export declare let execSilent: (commandStringArg: string) => Promise<IExecResult>;
/**
* executes a command and allws you to stream output
*/
export declare let execStreaming: (commandStringArg: string) => {
childProcess: ChildProcess;
finalPromise: Promise<IExecResult>;
};
/**
* executes a command and returns promise that will be fullfilled once an putput line matches RegexArg
* @param commandStringArg
* @param regexArg
*/
export declare let execAndWaitForLine: (commandStringArg: string, regexArg: RegExp) => Promise<{}>;
/**
* get a path
*/
export declare let which: (cmd: string) => Promise<string>;

76
dist/smartshell.wrap.js vendored Normal file
View File

@ -0,0 +1,76 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartshell.plugins");
/**
* executes a given command async
* @param commandStringArg
*/
exports.exec = (commandStringArg) => {
let done = plugins.smartq.defer();
plugins.shelljs.exec(commandStringArg, { async: true }, (code, stdout, stderr) => {
done.resolve({
exitCode: code,
stdout: stdout
});
});
return done.promise;
};
/**
* executes a given command async and silent
* @param commandStringArg
*/
exports.execSilent = (commandStringArg) => {
let done = plugins.smartq.defer();
plugins.shelljs.exec(commandStringArg, { async: true, silent: true }, (code, stdout, stderr) => {
done.resolve({
exitCode: code,
stdout: stdout
});
});
return done.promise;
};
/**
* executes a command and allws you to stream output
*/
exports.execStreaming = (commandStringArg) => {
let childProcessEnded = plugins.smartq.defer();
let execChildProcess = plugins.shelljs.exec(commandStringArg, { async: true, silent: true }, (code, stdout, stderr) => {
childProcessEnded.resolve({
exitCode: code,
stdout: stdout
});
});
return {
childProcess: execChildProcess,
finalPromise: childProcessEnded.promise
};
};
/**
* executes a command and returns promise that will be fullfilled once an putput line matches RegexArg
* @param commandStringArg
* @param regexArg
*/
exports.execAndWaitForLine = (commandStringArg, regexArg) => {
let done = plugins.smartq.defer();
let execStreamingResult = exports.execStreaming(commandStringArg);
execStreamingResult.childProcess.stdout.on('data', (stdOutChunk) => {
if (regexArg.test(stdOutChunk)) {
done.resolve();
}
});
return done.promise;
};
/**
* get a path
*/
exports.which = (cmd) => {
let done = plugins.smartq.defer();
plugins.which(cmd, (err, path) => {
if (err) {
done.reject(err);
}
done.resolve(path);
});
return done.promise;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzaGVsbC53cmFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRzaGVsbC53cmFwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsZ0RBQStDO0FBc0IvQzs7O0dBR0c7QUFDUSxRQUFBLElBQUksR0FBRyxDQUFDLGdCQUF3QjtJQUN6QyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBZSxDQUFBO0lBQzlDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNO1FBQzNFLElBQUksQ0FBQyxPQUFPLENBQUM7WUFDWCxRQUFRLEVBQUUsSUFBSTtZQUNkLE1BQU0sRUFBRSxNQUFNO1NBQ2YsQ0FBQyxDQUFBO0lBQ0osQ0FBQyxDQUFDLENBQUE7SUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtBQUNyQixDQUFDLENBQUE7QUFFRDs7O0dBR0c7QUFDUSxRQUFBLFVBQVUsR0FBRyxDQUFDLGdCQUF3QjtJQUMvQyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBZSxDQUFBO0lBQzlDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU07UUFDekYsSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUNYLFFBQVEsRUFBRSxJQUFJO1lBQ2QsTUFBTSxFQUFFLE1BQU07U0FDZixDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtJQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0FBQ3JCLENBQUMsQ0FBQTtBQUVEOztHQUVHO0FBQ1EsUUFBQSxhQUFhLEdBQUcsQ0FBQyxnQkFBd0I7SUFDbEQsSUFBSSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBZSxDQUFBO0lBQzNELElBQUksZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTTtRQUM5RyxpQkFBaUIsQ0FBQyxPQUFPLENBQUM7WUFDeEIsUUFBUSxFQUFFLElBQUk7WUFDZCxNQUFNLEVBQUUsTUFBTTtTQUNmLENBQUMsQ0FBQTtJQUNKLENBQUMsQ0FBQyxDQUFBO0lBQ0YsTUFBTSxDQUFDO1FBQ0wsWUFBWSxFQUFFLGdCQUFnQjtRQUM5QixZQUFZLEVBQUUsaUJBQWlCLENBQUMsT0FBTztLQUN4QyxDQUFBO0FBQ0gsQ0FBQyxDQUFBO0FBRUQ7Ozs7R0FJRztBQUNRLFFBQUEsa0JBQWtCLEdBQUcsQ0FBQyxnQkFBd0IsRUFBRSxRQUFnQjtJQUN6RSxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFBO0lBQ2pDLElBQUksbUJBQW1CLEdBQUcscUJBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO0lBQ3pELG1CQUFtQixDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLFdBQW1CO1FBQ3JFLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtRQUNoQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUE7SUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtBQUNyQixDQUFDLENBQUE7QUFFRDs7R0FFRztBQUNRLFFBQUEsS0FBSyxHQUFHLENBQUMsR0FBVztJQUM3QixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFBO0lBQ2pDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLElBQVk7UUFDbkMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNSLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDbEIsQ0FBQztRQUNELElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDcEIsQ0FBQyxDQUFDLENBQUE7SUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtBQUNyQixDQUFDLENBQUEifQ==

View File

@ -1,17 +1,8 @@
{
"npmci": {
"npmGlobalTools": [],
"npmAccessLevel": "public",
"npmRegistryUrl": "registry.npmjs.org"
},
"gitzone": {
"module": {
"githost": "gitlab.com",
"gitscope": "pushrocks",
"gitrepo": "smartshell",
"shortDescription": "shell actions designed as promises",
"npmPackagename": "@pushrocks/smartshell",
"license": "MIT"
}
"globalNpmTools": [
"npmts",
"ts-node"
]
}
}

1713
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,11 @@
{
"name": "@pushrocks/smartshell",
"private": false,
"version": "2.0.23",
"name": "smartshell",
"version": "1.0.7",
"description": "shell actions designed as promises",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {
"test": "(tstest test/)",
"build": "(tsbuild)"
"test": "(npmts --notest && ts-node --compilerOptions '{\"target\":\"es6\"}' test/test.ts)"
},
"repository": {
"type": "git",
@ -24,19 +22,14 @@
},
"homepage": "https://gitlab.com/pushrocks/smartshell#README",
"devDependencies": {
"@gitzone/tsbuild": "^2.1.11",
"@gitzone/tsrun": "^1.2.6",
"@gitzone/tstest": "^1.0.23",
"@pushrocks/tapbundle": "^3.0.9",
"@types/node": "^12.0.2",
"tslint": "^5.16.0",
"tslint-config-prettier": "^1.18.0"
"tapbundle": "^1.0.14"
},
"dependencies": {
"@pushrocks/smartdelay": "^2.0.3",
"@pushrocks/smartexit": "^1.0.15",
"@pushrocks/smartpromise": "^3.0.2",
"@types/which": "^1.3.1",
"which": "^1.3.1"
"@types/shelljs": "^0.7.2",
"@types/which": "^1.0.28",
"shelljs": "^0.7.8",
"smartq": "^1.1.1",
"typings-global": "^1.0.19",
"which": "^1.2.14"
}
}

View File

@ -1,57 +1,49 @@
import { expect, tap } from '@pushrocks/tapbundle';
import { expect, tap } from 'tapbundle'
import * as smartshell from '../ts';
import * as smartpromise from '@pushrocks/smartpromise';
import * as smartshell from '../dist/index'
import * as smartq from 'smartq'
let testSmartshell: smartshell.Smartshell;
let testSmartshell: smartshell.Smartshell
tap.test('smartshell should run async', async () => {
let execResult = await smartshell.exec('npm -v')
expect(execResult.stdout).to.match(/[0-9\.]*/)
})
tap.test('smartshell should run async and silent', async () => {
let execResult = await smartshell.execSilent('npm -v')
expect(execResult.stdout).to.match(/[0-9\.]*/)
})
tap.test('smartshell should stream a shell execution', async () => {
let done = smartq.defer()
let execStreamingResponse = smartshell.execStreaming('npm -v')
execStreamingResponse.childProcess.stdout.on('data', data => {
done.resolve(data)
})
let data = await done.promise
expect(data).to.equal('5.0.3\n')
await execStreamingResponse.finalPromise
})
tap.test('it should execute and wait for a line in the output', async () => {
await smartshell.execAndWaitForLine('npm -v', /5.0.3/)
})
// Smartshell class
tap.test('smartshell should create a Smartshell instance', async () => {
testSmartshell = new smartshell.Smartshell({
executor: 'bash',
sourceFilePaths: []
});
expect(testSmartshell).to.be.instanceof(smartshell.Smartshell);
});
})
expect(testSmartshell).to.be.instanceof(smartshell.Smartshell)
})
tap.test('smartshell should run async', async () => {
let execResult = await testSmartshell.exec('npm -v');
expect(execResult.stdout).to.match(/[0-9\.]*/);
});
return testSmartshell.execSilent('sleep 1 && npm -v').then(async (execResult) => {
console.log(execResult.stdout)
})
})
tap.test('smartshell should run async and silent', async () => {
let execResult = await testSmartshell.execSilent('npm -v');
expect(execResult.stdout).to.match(/[0-9\.]*/);
});
tap.test('smartshell should stream a shell execution', async () => {
let done = smartpromise.defer();
let execStreamingResponse = await testSmartshell.execStreaming('npm -v');
execStreamingResponse.childProcess.stdout.on('data', data => {
done.resolve(data);
});
let data = await done.promise;
expect(data).to.match(/[0-9\.]*/);
await execStreamingResponse.finalPromise;
});
tap.test('it should execute and wait for a line in the output', async () => {
await testSmartshell.execAndWaitForLine('echo "5.0.4"', /5.0.4/);
});
tap.test('smartshell should run async', async () => {
return testSmartshell.execSilent('sleep 1 && npm -v').then(async execResult => {
console.log(execResult.stdout);
});
});
tap.test('should be able to find git', async () => {
await testSmartshell.exec('git --version');
});
tap.test('should spawn an interactive cli', async () => {
await testSmartshell.execInteractive('echo "hi"');
});
tap.start({
throwOnError: true
});
tap.start()

View File

@ -1 +1,2 @@
export * from './smartshell.classes.smartshell';
export * from './smartshell.wrap'
export * from './smartshell.classes.smartshell'

View File

@ -1,103 +0,0 @@
export type TExecutor = 'sh' | 'bash';
export interface IShellEnvContructorOptions {
executor: TExecutor;
sourceFilePaths?: string[];
pathDirectories?: string[];
}
export class ShellEnv {
executor: TExecutor;
sourceFileArray: string[] = [];
pathDirArray: string[] = [];
/**
* constructor for the shellenv
*/
constructor(optionsArg: IShellEnvContructorOptions) {
this.executor = optionsArg.executor;
// add sourcefiles
if (optionsArg.sourceFilePaths) {
this.sourceFileArray = this.sourceFileArray.concat(optionsArg.sourceFilePaths);
}
// add pathDirectories
if (optionsArg.pathDirectories) {
this.pathDirArray = this.pathDirArray.concat(optionsArg.pathDirectories);
}
}
/**
* imports path into the shell from env if available and returns it with
*/
private _setPath(commandStringArg): string {
let commandResult = commandStringArg;
let commandPaths: string[] = [];
commandPaths = commandPaths.concat(process.env.PATH.split(':'));
if (process.env.SMARTSHELL_PATH) {
commandPaths = commandPaths.concat(process.env.SMARTSHELL_PATH.split(':'));
}
// lets filter for unwanted paths
// Windows WSL
commandPaths = commandPaths.filter(commandPathArg => {
const filterResult =
!commandPathArg.startsWith('/mnt/c/') &&
!commandPathArg.startsWith('Files/1E') &&
!commandPathArg.includes(' ');
if (!filterResult) {
// console.log(`${commandPathArg} will be filtered!`);
}
return filterResult;
});
commandResult = `PATH=${commandPaths.join(':')} && ${commandStringArg}`;
return commandResult;
}
/**
* add files that are going to be sourced when running a command
* @param sourceFilePathsArray
*/
addSourceFiles(sourceFilePathsArray: string[]) {
for (let sourceFilePath of sourceFilePathsArray) {
this.sourceFileArray.push(sourceFilePath);
}
}
/**
* cleans the source files array
*/
cleanSourceFiles() {
this.sourceFileArray = [];
}
public createEnvExecString(commandArg: string): string {
let commandResult = '';
let sourceString = '';
// deal with sourcestring
for (const sourceFilePath of this.sourceFileArray) {
sourceString = sourceString + `source ${sourceFilePath} && `;
}
// deal with avaiable path
let pathString = 'PATH=$PATH';
for (const pathDir of this.pathDirArray) {
pathString += `:${pathDir}`;
}
pathString += ` && `;
switch (this.executor) {
case 'bash':
commandResult = `bash -c '${pathString}${sourceString}${commandArg}'`;
break;
case 'sh':
commandResult = `${pathString}${sourceString}${commandArg}`;
break;
}
commandResult = this._setPath(commandResult);
return commandResult;
}
}

View File

@ -1,38 +0,0 @@
import * as plugins from './smartshell.plugins';
/**
* a log handler for spawned logs
* making sure the process doesn't run out of memory
*/
export class ShellLog {
public logStore = Buffer.from('');
/**
* log data to console
* @param dataArg
*/
public writeToConsole(dataArg: string | Buffer): void {
// make sure we have the data as string
process.stdout.write(dataArg);
}
/**
* add data to Buffer for later consumption
* @param dataArg
*/
public addToBuffer(dataArg: string | Buffer): void {
// make sure we have the data as Buffer
const dataBuffer: Buffer = (() => {
if (!Buffer.isBuffer(dataArg)) {
return Buffer.from(dataArg);
}
return dataArg;
})();
this.logStore = Buffer.concat([this.logStore, dataBuffer]);
}
public logAndAdd(dataArg: string | Buffer): void {
this.writeToConsole(dataArg);
this.addToBuffer(dataArg);
}
}

View File

@ -1,201 +1,65 @@
// -- imports --
import * as plugins from './smartshell.plugins';
import { ShellEnv, IShellEnvContructorOptions, TExecutor } from './smartshell.classes.shellenv';
import { ShellLog } from './smartshell.classes.shelllog';
import * as plugins from './smartshell.plugins'
import * as smartshellWrap from './smartshell.wrap'
import * as cp from 'child_process';
import { Deferred } from '@pushrocks/smartpromise';
export type TExecutor = 'sh' | 'bash'
export interface ISmartshellContructorOptions {
executor: TExecutor
sourceFilePaths: string[]
// -- interfaces --
/**
* interface for ExecResult
*/
export interface IExecResult {
exitCode: number;
stdout: string;
}
/**
* interface for streaming ExecResult
*/
export interface IExecResultStreaming {
childProcess: cp.ChildProcess;
finalPromise: Promise<IExecResult>;
kill: () => void;
}
// -- SmartShell --
export class Smartshell {
public shellEnv: ShellEnv;
public smartexit = new plugins.smartexit.SmartExit();
constructor(optionsArg: IShellEnvContructorOptions) {
this.shellEnv = new ShellEnv(optionsArg);
}
/**
* executes a given command async
* @param commandStringArg
*/
private async _exec(
commandStringArg: string,
silentArg: boolean = false,
strictArg = false,
streamingArg = false
): Promise<IExecResult | IExecResultStreaming> {
// flow control promises
const done = plugins.smartpromise.defer<IExecResult | IExecResultStreaming>();
const childProcessEnded = plugins.smartpromise.defer<IExecResult>();
// build commandToExecute
let commandToExecute = commandStringArg;
commandToExecute = this.shellEnv.createEnvExecString(commandStringArg);
const spawnlogInstance = new ShellLog();
const execChildProcess = cp.spawn(commandToExecute, [], {
shell: true,
env: process.env,
detached: false
});
this.smartexit.addProcess(execChildProcess);
execChildProcess.stdout.on('data', data => {
if (!silentArg) {
spawnlogInstance.writeToConsole(data);
}
spawnlogInstance.addToBuffer(data);
});
execChildProcess.stderr.on('data', data => {
if (!silentArg) {
spawnlogInstance.writeToConsole(data);
}
spawnlogInstance.addToBuffer(data);
});
if (streamingArg) {
done.resolve({
childProcess: execChildProcess,
finalPromise: childProcessEnded.promise,
kill: () => {
// this notation with the - kills the whole process group
process.kill(-execChildProcess.pid);
}
});
executor: TExecutor
sourceFileArray: string[] = []
constructor (optionsArg: ISmartshellContructorOptions) {
this.executor = optionsArg.executor
for (let sourceFilePath of optionsArg.sourceFilePaths) {
this.sourceFileArray.push(sourceFilePath)
}
execChildProcess.on('exit', (code, signal) => {
this.smartexit.removeProcess(execChildProcess);
if (strictArg && code === 1) {
done.reject();
}
const execResult = {
exitCode: code,
stdout: spawnlogInstance.logStore.toString()
};
if (!streamingArg) {
done.resolve(execResult);
}
childProcessEnded.resolve(execResult);
});
const result = await done.promise;
return result;
}
public async exec(commandStringArg: string): Promise<IExecResult> {
return (await this._exec(commandStringArg, false)) as IExecResult;
}
/**
* executes a given command async and silent
* @param commandStringArg
*/
public async execSilent(commandStringArg: string): Promise<IExecResult> {
return (await this._exec(commandStringArg, true)) as IExecResult;
}
/**
* executes a command async and strict, meaning it rejects the promise if something happens
*/
public async execStrict(commandStringArg: string): Promise<IExecResult> {
return (await this._exec(commandStringArg, false, true)) as IExecResult;
}
public async execStrictSilent (commandStringArg: string): Promise<IExecResult> {
return (await this._exec(commandStringArg, true, true)) as IExecResult;
}
/**
* executes a command and allows you to stream output
*/
public async execStreaming(
commandStringArg: string,
silentArg: boolean = false
): Promise<IExecResultStreaming> {
return (await this._exec(commandStringArg, silentArg, false, true)) as IExecResultStreaming;
}
public async execStreamingSilent(commandStringArg: string) {
return (await this.execStreaming(commandStringArg, true)) as IExecResultStreaming;
}
/**
* executes a command and returns promise that will be fullfilled once an putput line matches RegexArg
* @param commandStringArg
* @param regexArg
*/
public async execAndWaitForLine(
commandStringArg: string,
regexArg: RegExp,
silentArg: boolean = false
) {
let done = plugins.smartpromise.defer();
let execStreamingResult = await this.execStreaming(commandStringArg, silentArg);
execStreamingResult.childProcess.stdout.on('data', (stdOutChunk: string) => {
if (regexArg.test(stdOutChunk)) {
done.resolve();
}
});
return done.promise;
}
public async execAndWaitForLineSilent(commandStringArg: string, regexArg: RegExp) {
this.execAndWaitForLine(commandStringArg, regexArg, true);
}
/**
* execs an command and then enters interactive CLI
* @param commandStringArg
* @param regexArg
*/
public async execInteractive(commandStringArg: string) {
if (process.env.CI) {
return;
addSourceFiles (sourceFilePathsArray: string[]) {
for (let sourceFilePath of sourceFilePathsArray) {
this.sourceFileArray.push(sourceFilePath)
}
const done = plugins.smartpromise.defer();
const shell = cp.spawn('sh', [], { stdio: 'pipe' });
this.smartexit.addProcess(shell);
const shellLog = new ShellLog();
const stdInStream = process.stdin.pipe(shell.stdin);
const stdOutStream = shell.stdout.pipe(process.stdout);
shell.on('close', code => {
console.log(`interactive shell terminated with code ${code}`);
stdInStream.removeAllListeners();
stdInStream.uncork();
stdOutStream.removeAllListeners();
stdOutStream.unpipe();
shell.kill('SIGTERM');
process.stdin.pause();
done.resolve();
});
let commandString = commandStringArg;
if (process.env.CI) {
commandString += ' && exit';
}
commandString += '\n';
}
shell.stdin.write(commandString);
await done.promise;
cleanSourceFiles () {
this.sourceFileArray = []
}
/**
* executes silently and returns IExecResult
* @param commandArg
*/
async execSilent (commandArg: string) {
let execCommand = this.createExecString(commandArg)
return await smartshellWrap.execSilent(execCommand)
}
/**
* executes and returns IExecResult
* @param commandArg
*/
async exec (commandArg: string) {
let execCommand = this.createExecString(commandArg)
return await smartshellWrap.exec(execCommand)
}
/**
* creates the final sourcing string
* @param commandArg
*/
private createExecString (commandArg): string {
if (this.executor === 'bash') {
let sourceString = ''
for (let sourceFilePath of this.sourceFileArray) {
sourceString = sourceString + `source ${sourceFilePath} && `
}
return `bash -c '${sourceString} ${commandArg}'`
} else {
return commandArg
}
}
}

View File

@ -1,6 +1,9 @@
import * as smartdelay from '@pushrocks/smartdelay';
import * as smartexit from '@pushrocks/smartexit';
import * as smartpromise from '@pushrocks/smartpromise';
import * as which from 'which';
import * as shelljs from 'shelljs'
import * as smartq from 'smartq'
import * as which from 'which'
export { smartdelay, smartexit, smartpromise, which };
export {
shelljs,
smartq,
which
}

98
ts/smartshell.wrap.ts Normal file
View File

@ -0,0 +1,98 @@
import * as plugins from './smartshell.plugins'
// interfaces
import { ChildProcess } from 'child_process'
import { Deferred } from 'smartq'
/**
* interface for ExecResult
*/
export interface IExecResult {
exitCode: number,
stdout: string
}
/**
* interface for streaming ExecResult
*/
export interface IExecResultStreaming {
childProcess: ChildProcess,
finalPromise: Promise<IExecResult>
}
/**
* executes a given command async
* @param commandStringArg
*/
export let exec = (commandStringArg: string): Promise<IExecResult> => {
let done = plugins.smartq.defer<IExecResult>()
plugins.shelljs.exec(commandStringArg, { async: true }, (code, stdout, stderr) => {
done.resolve({
exitCode: code,
stdout: stdout
})
})
return done.promise
}
/**
* executes a given command async and silent
* @param commandStringArg
*/
export let execSilent = (commandStringArg: string) => {
let done = plugins.smartq.defer<IExecResult>()
plugins.shelljs.exec(commandStringArg, { async: true, silent: true }, (code, stdout, stderr) => {
done.resolve({
exitCode: code,
stdout: stdout
})
})
return done.promise
}
/**
* executes a command and allws you to stream output
*/
export let execStreaming = (commandStringArg: string) => {
let childProcessEnded = plugins.smartq.defer<IExecResult>()
let execChildProcess = plugins.shelljs.exec(commandStringArg, {async: true, silent: true}, (code, stdout, stderr) => {
childProcessEnded.resolve({
exitCode: code,
stdout: stdout
})
})
return {
childProcess: execChildProcess,
finalPromise: childProcessEnded.promise
}
}
/**
* executes a command and returns promise that will be fullfilled once an putput line matches RegexArg
* @param commandStringArg
* @param regexArg
*/
export let execAndWaitForLine = (commandStringArg: string, regexArg: RegExp) => {
let done = plugins.smartq.defer()
let execStreamingResult = execStreaming(commandStringArg)
execStreamingResult.childProcess.stdout.on('data', (stdOutChunk: string) => {
if (regexArg.test(stdOutChunk)) {
done.resolve()
}
})
return done.promise
}
/**
* get a path
*/
export let which = (cmd: string): Promise<string> => {
let done = plugins.smartq.defer()
plugins.which(cmd, (err, path: string) => {
if (err) {
done.reject(err)
}
done.resolve(path)
})
return done.promise
}

View File

@ -1,17 +1,3 @@
{
"extends": ["tslint:latest", "tslint-config-prettier"],
"rules": {
"semicolon": [true, "always"],
"no-console": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"member-ordering": {
"options":{
"order": [
"static-method"
]
}
}
},
"defaultSeverity": "warning"
"extends": "tslint-config-standard"
}

304
yarn.lock Normal file
View File

@ -0,0 +1,304 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/chai-as-promised@0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-0.0.29.tgz#43d52892aa998e185a3de3e2477edb8573be1d77"
dependencies:
"@types/chai" "*"
"@types/promises-a-plus" "*"
"@types/chai-string@^1.1.30":
version "1.1.30"
resolved "https://registry.yarnpkg.com/@types/chai-string/-/chai-string-1.1.30.tgz#4d8744b31a5a2295fc01c981ed1e2d4c8a070f0a"
dependencies:
"@types/chai" "*"
"@types/chai@*", "@types/chai@^3.4.35":
version "3.5.2"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-3.5.2.tgz#c11cd2817d3a401b7ba0f5a420f35c56139b1c1e"
"@types/node@*":
version "8.0.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.1.tgz#89c271e0c3b9ebb6a3756dd601336970b6228b77"
"@types/promises-a-plus@*":
version "0.0.27"
resolved "https://registry.yarnpkg.com/@types/promises-a-plus/-/promises-a-plus-0.0.27.tgz#c64651134614c84b8f5d7114ce8901d36a609780"
"@types/shelljs@^0.6.0":
version "0.6.0"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.6.0.tgz#090b705c102ce7fc5c0c5ea9b524418ff15840df"
dependencies:
"@types/node" "*"
"@types/shelljs@^0.7.2":
version "0.7.2"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.2.tgz#c2bdb3fe80cd7a3da08750ca898ae44c589671f3"
dependencies:
"@types/node" "*"
"@types/which@^1.0.28":
version "1.0.28"
resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6"
ansi-256-colors@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ansi-256-colors/-/ansi-256-colors-1.1.0.tgz#910de50efcc7c09e3d82f2f87abd6b700c18818a"
assertion-error@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
beautycolor@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/beautycolor/-/beautycolor-1.0.7.tgz#a4715738ac4c8221371e9cbeb5a6cc6d11ecbf7c"
dependencies:
ansi-256-colors "^1.1.0"
typings-global "^1.0.14"
bindings@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11"
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
chai-as-promised@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-6.0.0.tgz#1a02a433a6f24dafac63b9c96fa1684db1aa8da6"
dependencies:
check-error "^1.0.2"
chai-string@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/chai-string/-/chai-string-1.4.0.tgz#359140c051d36a4e4b1a5fc6b910152f438a8d49"
chai@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247"
dependencies:
assertion-error "^1.0.1"
deep-eql "^0.1.3"
type-detect "^1.0.0"
check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
deep-eql@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2"
dependencies:
type-detect "0.1.1"
early@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/early/-/early-2.1.1.tgz#841e23254ea5dc54d8afaeee82f5ab65c00ee23c"
dependencies:
beautycolor "^1.0.7"
smartq "^1.1.1"
typings-global "^1.0.16"
es6-error@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.0.2.tgz#eec5c726eacef51b7f6b73c20db6e1b13b069c98"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
glob@^7.0.0:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
interpret@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
leakage@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/leakage/-/leakage-0.3.0.tgz#15d698abdc76bbc6439601f4f3020e77e2d50c39"
dependencies:
es6-error "^4.0.2"
left-pad "^1.1.3"
memwatch-next "^0.3.0"
minimist "^1.2.0"
pretty-bytes "^4.0.2"
left-pad@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.1.3.tgz#612f61c033f3a9e08e939f1caebeea41b6f3199a"
memwatch-next@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/memwatch-next/-/memwatch-next-0.3.0.tgz#2111050f9a906e0aa2d72a4ec0f0089c78726f8f"
dependencies:
bindings "^1.2.1"
nan "^2.3.2"
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
nan@^2.3.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45"
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
wrappy "1"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
path-parse@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
pretty-bytes@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9"
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
dependencies:
resolve "^1.1.6"
resolve@^1.1.6:
version "1.3.3"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
dependencies:
path-parse "^1.0.5"
semver@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
shelljs@^0.7.6, shelljs@^0.7.8:
version "0.7.8"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3"
dependencies:
glob "^7.0.0"
interpret "^1.0.0"
rechoir "^0.6.2"
smartchai@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/smartchai/-/smartchai-1.0.3.tgz#de6d010bb8b5aef24cb70b31a5f5334e8c41b72f"
dependencies:
"@types/chai" "^3.4.35"
"@types/chai-as-promised" "0.0.29"
"@types/chai-string" "^1.1.30"
chai "^3.5.0"
chai-as-promised "^6.0.0"
chai-string "^1.3.0"
smartdelay@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/smartdelay/-/smartdelay-1.0.3.tgz#5fd44dad77262d110702f0293efa80c072cfb579"
dependencies:
smartq "^1.1.1"
typings-global "^1.0.16"
smartq@^1.1.0, smartq@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/smartq/-/smartq-1.1.1.tgz#efb358705260d41ae18aef7ffd815f7b6fe17dd3"
dependencies:
typed-promisify "^0.3.0"
typings-global "^1.0.14"
smartshell@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/smartshell/-/smartshell-1.0.6.tgz#27b1c79029784abe72ac7e91fe698b7ebecc6629"
dependencies:
"@types/shelljs" "^0.6.0"
"@types/which" "^1.0.28"
shelljs "^0.7.6"
smartq "^1.1.0"
which "^1.2.12"
tapbundle@^1.0.14:
version "1.0.14"
resolved "https://registry.yarnpkg.com/tapbundle/-/tapbundle-1.0.14.tgz#75827e335fcb02216f0267a26a26d702ddc02e3c"
dependencies:
early "^2.1.1"
leakage "^0.3.0"
smartchai "^1.0.3"
smartdelay "^1.0.3"
smartq "^1.1.1"
typings-global "^1.0.16"
type-detect@0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822"
type-detect@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2"
typed-promisify@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/typed-promisify/-/typed-promisify-0.3.0.tgz#1ba0af5e444c87d8047406f18ce49092a1191853"
typings-global@^1.0.14, typings-global@^1.0.16, typings-global@^1.0.19:
version "1.0.19"
resolved "https://registry.yarnpkg.com/typings-global/-/typings-global-1.0.19.tgz#3376a72d4de1e5541bf5702248ff64c3e6ea316c"
dependencies:
semver "^5.3.0"
smartshell "^1.0.6"
which@^1.2.12, which@^1.2.14:
version "1.2.14"
resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
dependencies:
isexe "^2.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"