From 12623377fa7f361dfe33da9a9bd6635290328680 Mon Sep 17 00:00:00 2001 From: PhilKunz Date: Sun, 20 Nov 2016 01:11:22 +0100 Subject: [PATCH] initial --- .gitignore | 4 + .gitlab-ci.yml | 59 ++++++++++++ README.md | 39 ++++++++ dist/index.d.ts | 1 + dist/index.js | 6 ++ dist/smartinteract.classes.smartinteract.d.ts | 46 +++++++++ dist/smartinteract.classes.smartinteract.js | 69 ++++++++++++++ dist/smartinteract.plugins.d.ts | 3 + dist/smartinteract.plugins.js | 5 + package.json | 36 +++++++ test/test.d.ts | 1 + test/test.js | 14 +++ test/test.ts | 16 ++++ ts/index.ts | 1 + ts/smartinteract.classes.smartinteract.ts | 94 +++++++++++++++++++ ts/smartinteract.plugins.ts | 6 ++ tslint.json | 3 + 17 files changed, 403 insertions(+) create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 README.md create mode 100644 dist/index.d.ts create mode 100644 dist/index.js create mode 100644 dist/smartinteract.classes.smartinteract.d.ts create mode 100644 dist/smartinteract.classes.smartinteract.js create mode 100644 dist/smartinteract.plugins.d.ts create mode 100644 dist/smartinteract.plugins.js create mode 100644 package.json create mode 100644 test/test.d.ts create mode 100644 test/test.js create mode 100644 test/test.ts create mode 100644 ts/index.ts create mode 100644 ts/smartinteract.classes.smartinteract.ts create mode 100644 ts/smartinteract.plugins.ts create mode 100644 tslint.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85c4869 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +public/ +pages/ +coverage/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..f2d2ff7 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,59 @@ +image: hosttoday/ht-docker-node:npmts + +stages: +- test +- release +- trigger +- pages + +testLEGACY: + stage: test + script: + - npmci test legacy + tags: + - docker + allow_failure: true + +testLTS: + stage: test + script: + - npmci test lts + tags: + - docker + +testSTABLE: + stage: test + script: + - npmci test stable + tags: + - docker + +release: + stage: release + script: + - npmci publish + only: + - tags + tags: + - docker + +trigger: + stage: trigger + script: + - npmci trigger + only: + - tags + tags: + - docker + +pages: + image: hosttoday/ht-docker-node:npmpage + stage: pages + script: + - npmci command npmpage --host gitlab + only: + - tags + artifacts: + expire_in: 1 week + paths: + - public diff --git a/README.md b/README.md new file mode 100644 index 0000000..04e71d7 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# smartinteract +interact with terminal users + +## Availabililty +[![npm](https://push.rocks/assets/repo-button-npm.svg)](https://www.npmjs.com/package/interact) +[![git](https://push.rocks/assets/repo-button-git.svg)](https://gitlab.com/pushrocks/interact) +[![git](https://push.rocks/assets/repo-button-mirror.svg)](https://github.com/pushrocks/interact) +[![docs](https://push.rocks/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/interact/) + +## Status for master +[![build status](https://gitlab.com/pushrocks/interact/badges/master/build.svg)](https://gitlab.com/pushrocks/interact/commits/master) +[![coverage report](https://gitlab.com/pushrocks/interact/badges/master/coverage.svg)](https://gitlab.com/pushrocks/interact/commits/master) +[![Dependency Status](https://david-dm.org/pushrocks/interact.svg)](https://david-dm.org/pushrocks/interact) +[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/interact/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/interact/master/dependencies/npm) +[![bitHound Code](https://www.bithound.io/github/pushrocks/interact/badges/code.svg)](https://www.bithound.io/github/pushrocks/interact) +[![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 +We recommend the use of TypeScript for best in class intellesense + +```javascript +import { SmartInteract } from 'smartinteract' + +let myInteract = new SmartInteract([{ // note: its an array. You can specify multiple questions + type: 'input', + message: 'Who are you?', + default: 'Somebody', + choices: { ... }, // optional, only needed if type is 'choice' + validate: (inputString) => { return true } // implement your own validation +}]) +SmartInteract.addQuestions([ ... ]) // add more questions +SmartInteract.runQueue() + .then(answersArray => { + // do something with the answers + }) + +``` \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..6b04a04 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1 @@ +export * from './smartinteract.classes.smartinteract'; diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..04aee63 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,6 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./smartinteract.classes.smartinteract")); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsMkRBQXFEIn0= \ No newline at end of file diff --git a/dist/smartinteract.classes.smartinteract.d.ts b/dist/smartinteract.classes.smartinteract.d.ts new file mode 100644 index 0000000..d447a9e --- /dev/null +++ b/dist/smartinteract.classes.smartinteract.d.ts @@ -0,0 +1,46 @@ +/// +import * as q from 'q'; +export declare type questionType = 'input' | 'confirm' | 'list' | 'rawlist' | 'expand' | 'checkbox' | 'password' | 'editor'; +export interface IChoiceObject { + name: string; + value: any; +} +export interface IQuestionObject { + name: string; + type: questionType; + message: string; + default: any; + choices: string[] | IChoiceObject[]; + validate: IValidateFunction; +} +export interface IAnswerObject { +} +export interface IValidateFunction { + (anyObject: any): boolean; +} +/** + * class SmartInteract - allows to specify an user interaction during runtime + */ +export declare class SmartInteract { + /** + * holds the qestion queue, that is emptied once you call + */ + private questionMap; + /** + * constructor of class SmartInteract + */ + constructor(questionArrayArg?: IQuestionObject[]); + /** + * allows you to ask a single question and returns the answer in a promise + * skips the queue + */ + askQuestion(optionsArg: IQuestionObject): q.Promise; + /** + * add questions to queue + */ + addQuestions(questionArrayArg: IQuestionObject[]): void; + /** + * run the question queue + */ + runQueue(): q.Promise; +} diff --git a/dist/smartinteract.classes.smartinteract.js b/dist/smartinteract.classes.smartinteract.js new file mode 100644 index 0000000..56edbfb --- /dev/null +++ b/dist/smartinteract.classes.smartinteract.js @@ -0,0 +1,69 @@ +"use strict"; +const plugins = require("./smartinteract.plugins"); +const q = require("q"); +const lik_1 = require("lik"); +/** + * class SmartInteract - allows to specify an user interaction during runtime + */ +class SmartInteract { + /** + * constructor of class SmartInteract + */ + constructor(questionArrayArg) { + /** + * holds the qestion queue, that is emptied once you call + */ + this.questionMap = new lik_1.Objectmap(); + if (questionArrayArg) { + this.addQuestions(questionArrayArg); + } + } + /** + * allows you to ask a single question and returns the answer in a promise + * skips the queue + */ + askQuestion(optionsArg) { + let done = q.defer(); + plugins.inquirer.prompt([{ + name: optionsArg.name, + type: optionsArg.type, + message: optionsArg.message, + default: optionsArg.default, + choices: optionsArg.choices, + validate: optionsArg.validate + }]).then((answers) => { + console.log(answers); + done.resolve(answers); + }); + return done.promise; + } + /** + * add questions to queue + */ + addQuestions(questionArrayArg) { + this.questionMap.addArray(questionArrayArg); + } + /** + * run the question queue + */ + runQueue() { + let done = q.defer(); + let answerMap = new lik_1.Objectmap(); + let handleQuestion = () => { + let oneQuestion = this.questionMap.getOneAndRemove(); + this.askQuestion(oneQuestion).then(x => { + answerMap.addArray(x); + if (!this.questionMap.isEmpty()) { + handleQuestion(); // recursion: as questions until empty + } + else { + done.resolve(answerMap.getArray()); // when empty, then resolve promise + } + }); + }; + handleQuestion(); + return done.promise; + } +} +exports.SmartInteract = SmartInteract; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRpbnRlcmFjdC5jbGFzc2VzLnNtYXJ0aW50ZXJhY3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGludGVyYWN0LmNsYXNzZXMuc21hcnRpbnRlcmFjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsbURBQWtEO0FBQ2xELHVCQUFzQjtBQUN0Qiw2QkFBK0I7QUEwQi9COztHQUVHO0FBQ0g7SUFPSTs7T0FFRztJQUNILFlBQVksZ0JBQW9DO1FBUmhEOztXQUVHO1FBQ0ssZ0JBQVcsR0FBRyxJQUFJLGVBQVMsRUFBbUIsQ0FBQTtRQU1sRCxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7WUFDbkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO1FBQ3ZDLENBQUM7SUFDTCxDQUFDO0lBQ0Q7OztPQUdHO0lBQ0gsV0FBVyxDQUFDLFVBQTJCO1FBQ25DLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQW1CLENBQUE7UUFDckMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDckIsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO2dCQUNyQixJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUk7Z0JBQ3JCLE9BQU8sRUFBRSxVQUFVLENBQUMsT0FBTztnQkFDM0IsT0FBTyxFQUFFLFVBQVUsQ0FBQyxPQUFPO2dCQUMzQixPQUFPLEVBQUUsVUFBVSxDQUFDLE9BQU87Z0JBQzNCLFFBQVEsRUFBRSxVQUFVLENBQUMsUUFBUTthQUNoQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUF3QjtZQUM5QixPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3BCLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDekIsQ0FBQyxDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxZQUFZLENBQUMsZ0JBQW1DO1FBQzVDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUE7SUFDL0MsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUTtRQUNKLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQW1CLENBQUE7UUFDckMsSUFBSSxTQUFTLEdBQUcsSUFBSSxlQUFTLEVBQWlCLENBQUE7UUFDOUMsSUFBSSxjQUFjLEdBQUc7WUFDakIsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQTtZQUNwRCxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNoQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFBO2dCQUNyQixFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUM5QixjQUFjLEVBQUUsQ0FBQSxDQUFDLHNDQUFzQztnQkFDM0QsQ0FBQztnQkFBQyxJQUFJLENBQUMsQ0FBQztvQkFDSixJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFBLENBQUMsbUNBQW1DO2dCQUMxRSxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUE7UUFDTixDQUFDLENBQUE7UUFDRCxjQUFjLEVBQUUsQ0FBQTtRQUNoQixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0NBQ0o7QUE5REQsc0NBOERDIn0= \ No newline at end of file diff --git a/dist/smartinteract.plugins.d.ts b/dist/smartinteract.plugins.d.ts new file mode 100644 index 0000000..7329caa --- /dev/null +++ b/dist/smartinteract.plugins.d.ts @@ -0,0 +1,3 @@ +import 'typings-global'; +import * as inquirer from 'inquirer'; +export { inquirer }; diff --git a/dist/smartinteract.plugins.js b/dist/smartinteract.plugins.js new file mode 100644 index 0000000..075995b --- /dev/null +++ b/dist/smartinteract.plugins.js @@ -0,0 +1,5 @@ +"use strict"; +require("typings-global"); +const inquirer = require("inquirer"); +exports.inquirer = inquirer; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRpbnRlcmFjdC5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRpbnRlcmFjdC5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwwQkFBdUI7QUFDdkIscUNBQW9DO0FBR2hDLDRCQUFRIn0= \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..7f11528 --- /dev/null +++ b/package.json @@ -0,0 +1,36 @@ +{ + "name": "smartinteract", + "version": "1.0.0", + "description": "smart cli interaction", + "main": "dist/index.js", + "typings": "dist/index.d.ts", + "scripts": { + "test": "(npmts)" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@gitlab.com/pushrocks/smartinteract.git" + }, + "keywords": [ + "interaction", + "cli" + ], + "author": "Lossless GmbH", + "license": "MIT", + "bugs": { + "url": "https://gitlab.com/pushrocks/smartinteract/issues" + }, + "homepage": "https://gitlab.com/pushrocks/smartinteract#README", + "dependencies": { + "@types/node": "^6.0.48", + "@types/q": "0.0.32", + "@types/should": "^8.1.30", + "lik": "^1.0.27", + "q": "^1.4.1", + "should": "^11.1.1", + "typings-global": "^1.0.14" + }, + "devDependencies": { + "typings-test": "^1.0.3" + } +} diff --git a/test/test.d.ts b/test/test.d.ts new file mode 100644 index 0000000..2fd432a --- /dev/null +++ b/test/test.d.ts @@ -0,0 +1 @@ +import 'typings-test'; diff --git a/test/test.js b/test/test.js new file mode 100644 index 0000000..bb61c80 --- /dev/null +++ b/test/test.js @@ -0,0 +1,14 @@ +"use strict"; +require("typings-test"); +const should = require("should"); +const smartinteract = require("../dist/index"); +describe('smartinteract', function () { + let testInteract; + it('should create a valid new instance', function () { + testInteract = new smartinteract.SmartInteract(); + should(testInteract).be.instanceOf(smartinteract.SmartInteract); + }); + it('should add question to SmartInteract instance', function () { + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQixpQ0FBZ0M7QUFFaEMsK0NBQThDO0FBRTlDLFFBQVEsQ0FBQyxlQUFlLEVBQUU7SUFDdEIsSUFBSSxZQUFZLENBQUE7SUFDaEIsRUFBRSxDQUFDLG9DQUFvQyxFQUFFO1FBQ3JDLFlBQVksR0FBRyxJQUFJLGFBQWEsQ0FBQyxhQUFhLEVBQUUsQ0FBQTtRQUNoRCxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDbkUsQ0FBQyxDQUFDLENBQUE7SUFDRixFQUFFLENBQUMsK0NBQStDLEVBQUU7SUFFcEQsQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDLENBQUMsQ0FBQSJ9 \ No newline at end of file diff --git a/test/test.ts b/test/test.ts new file mode 100644 index 0000000..f86f99f --- /dev/null +++ b/test/test.ts @@ -0,0 +1,16 @@ +import 'typings-test' +import * as should from 'should' + +import * as smartinteract from '../dist/index' + +describe('smartinteract', function(){ + let testInteract + it('should create a valid new instance', function(){ + testInteract = new smartinteract.SmartInteract() + should(testInteract).be.instanceOf(smartinteract.SmartInteract) + }) + it('should add question to SmartInteract instance', function() { + + }) +}) + diff --git a/ts/index.ts b/ts/index.ts new file mode 100644 index 0000000..e2e696b --- /dev/null +++ b/ts/index.ts @@ -0,0 +1 @@ +export * from './smartinteract.classes.smartinteract' \ No newline at end of file diff --git a/ts/smartinteract.classes.smartinteract.ts b/ts/smartinteract.classes.smartinteract.ts new file mode 100644 index 0000000..6327e90 --- /dev/null +++ b/ts/smartinteract.classes.smartinteract.ts @@ -0,0 +1,94 @@ +import * as plugins from './smartinteract.plugins' +import * as q from 'q' +import { Objectmap } from 'lik' + +export type questionType = 'input' | 'confirm' | 'list' | 'rawlist' | 'expand' | 'checkbox' | 'password' | 'editor' + +export interface IChoiceObject { + name: string + value: any +} + +export interface IQuestionObject { + name: string + type: questionType + message: string + default: any + choices: string[] | IChoiceObject[] + validate: IValidateFunction +} + +export interface IAnswerObject { + +} + +export interface IValidateFunction { + (anyObject: any): boolean +} + +/** + * class SmartInteract - allows to specify an user interaction during runtime + */ +export class SmartInteract { + + /** + * holds the qestion queue, that is emptied once you call + */ + private questionMap = new Objectmap() + + /** + * constructor of class SmartInteract + */ + constructor(questionArrayArg?: IQuestionObject[]) { + if (questionArrayArg) { + this.addQuestions(questionArrayArg) + } + } + /** + * allows you to ask a single question and returns the answer in a promise + * skips the queue + */ + askQuestion(optionsArg: IQuestionObject): q.Promise { + let done = q.defer() + plugins.inquirer.prompt([{ + name: optionsArg.name, + type: optionsArg.type, + message: optionsArg.message, + default: optionsArg.default, + choices: optionsArg.choices, + validate: optionsArg.validate + }]).then((answers: IAnswerObject[]) => { + console.log(answers) + done.resolve(answers) + }) + return done.promise + } + + /** + * add questions to queue + */ + addQuestions(questionArrayArg: IQuestionObject[]) { + this.questionMap.addArray(questionArrayArg) + } + + /** + * run the question queue + */ + runQueue() { + let done = q.defer() + let answerMap = new Objectmap() + let handleQuestion = () => { + let oneQuestion = this.questionMap.getOneAndRemove() + this.askQuestion(oneQuestion).then(x => { + answerMap.addArray(x) + if (!this.questionMap.isEmpty()) { + handleQuestion() // recursion: as questions until empty + } else { + done.resolve(answerMap.getArray()) // when empty, then resolve promise + } + }) + } + handleQuestion() + return done.promise + } +} diff --git a/ts/smartinteract.plugins.ts b/ts/smartinteract.plugins.ts new file mode 100644 index 0000000..8318286 --- /dev/null +++ b/ts/smartinteract.plugins.ts @@ -0,0 +1,6 @@ +import 'typings-global' +import * as inquirer from 'inquirer' + +export { + inquirer +} \ No newline at end of file diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..45052ad --- /dev/null +++ b/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "tslint-config-standard" +}