New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@mobify/generator

Package Overview
Dependencies
Maintainers
7
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mobify/generator - npm Package Compare versions

Comparing version

to
0.5.0

lib/generator/auth-questions.js

3

config/default.json
{
"API_URL": "http://generator.mobify.net/api",
"API_TOKEN": "v0eXzwEPl2e4@Y%ewJKW"
"API_URL": "http://generator.mobify.net/api"
}

@@ -9,3 +9,3 @@ 'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _buffer = require('buffer');

@@ -16,55 +16,51 @@ var _requestPromiseNative = require('request-promise-native');

var _nconf = require('nconf');
var _nconf2 = _interopRequireDefault(_nconf);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var b64Encode = function b64Encode(s) {
return _buffer.Buffer.from(s).toString('base64');
};
var ApiClient = function () {
function ApiClient() {
_classCallCheck(this, ApiClient);
var createAPI = function createAPI(username, apiKey, apiURL) {
var opts = {
headers: { Authorization: 'Basic ' + b64Encode(username + ':' + apiKey) },
json: true
};
_nconf2.default.argv().env().file({ file: __dirname + '/../../config/default.json' }); // eslint-disable-line no-undef
return {
checkCredentials: function checkCredentials() {
return (0, _requestPromiseNative2.default)(_extends({
url: apiURL + '/verify_credentials',
method: 'GET'
}, opts)).then(function (responseJson) {
return responseJson.authorized;
}).catch(function () {
return false;
});
},
this.apiURL = _nconf2.default.get('API_URL');
this.apiToken = _nconf2.default.get('API_TOKEN');
}
_createClass(ApiClient, [{
key: '_clientOptions',
value: function _clientOptions(path) {
return {
url: this.apiURL + '/' + path,
headers: {
Authorization: this.apiToken
},
json: true
};
}
}, {
key: 'getQuestions',
value: function getQuestions() {
var options = _extends({
getQuestions: function getQuestions() {
return (0, _requestPromiseNative2.default)(_extends({
url: apiURL + '/questions',
method: 'GET'
}, this._clientOptions('questions'));
}, opts));
},
return (0, _requestPromiseNative2.default)(options);
}
}, {
key: 'generateProject',
value: function generateProject(params) {
var options = _extends({
generateProject: function generateProject(params) {
return (0, _requestPromiseNative2.default)(_extends({
url: apiURL + '/project',
method: 'POST',
body: params
}, this._clientOptions('project'));
}, opts));
},
return (0, _requestPromiseNative2.default)(options);
checkRepoAvailability: function checkRepoAvailability(repo) {
return (0, _requestPromiseNative2.default)(_extends({
url: apiURL + '/repo_name_available',
method: 'GET',
body: { repository_name: repo }
}, opts));
}
}]);
};
};
return ApiClient;
}();
exports.default = ApiClient;
exports.default = createAPI;

@@ -7,4 +7,2 @@ 'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // eslint-disable-line no-unused-vars
var _inquirer = require('inquirer');

@@ -18,2 +16,20 @@

var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _os = require('os');
var _os2 = _interopRequireDefault(_os);
var _nconf = require('nconf');
var _nconf2 = _interopRequireDefault(_nconf);
var _questions = require('./questions');
var _authQuestions = require('./auth-questions');
var _authQuestions2 = _interopRequireDefault(_authQuestions);
var _api = require('./api');

@@ -23,107 +39,146 @@

var _questions = require('./questions');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
// eslint-disable-line no-unused-vars
var defaultFeatures = ['web', 'native', 'amp'];
var transformedAuthQuestions = (0, _questions.transform)(_authQuestions2.default);
var CliSession = function () {
function CliSession(dryRun) {
_classCallCheck(this, CliSession);
var initialPrompt = function initialPrompt() {
/* eslint-disable prefer-template */
console.log(' `:-.');
console.log(' -yyyyys+:`');
console.log(' /yyyyyyyyy` +o+/:-.');
console.log(' `oyyyyyyyyy- :hhhhhhhs');
console.log(' `syyyyyyyyy+ yhhhhhhhy');
console.log(' `-/oyyyyyyyyyyo :hhhhhhhhs');
console.log(' -/oyyyyyyyyyyyyyo` shhhhhhhhs');
console.log(' +yyyyyyyyyyyyyyyy+ `hhhhhhhhho');
console.log(' +yyyyyyyyyyyyyy+. .hhhhhhhhho');
console.log(' `yyyyyyyyys+/. yhhhhhhhhhs`');
console.log(' -yso+/-.` .yhhhhhhhhhy.');
console.log(' ```.....` `shhhhhhhhhy.');
console.log(' -://++++++++++++/-` /yhhhhhhhhy.');
console.log(' /++++++++++++++++++/. `ohhhhhhy+`');
console.log(' :++++++++++++++++++++/-` -shhs:`');
console.log(' `+++++++++++++++++++++++-` -`');
console.log(' `......-...-/+++++++++++/`');
console.log(' `-/+++++++:`');
console.log(' `.:/+:`');
console.log('');
console.log('Hey, you\'re about to create a new Mobify platform project!');
console.log('We\'ll generate Progressive Web App with various components like Native Apps, Push Notifications, eCommerce connectors, Analytics and more.');
console.log('You can find more info here: ' + 'https://docs.mobify.com'.underline);
console.log('');
console.log('Before you get started:'.bold.bgYellow + ' make sure you\'ve created a new project in Mobify Cloud. ' + 'To create a Cloud project, visit this link: ' + 'https://cloud.mobify.com/projects/new/'.underline);
console.log('');
/* eslint-enable prefer-template */
};
this.defaultFeatures = ['web', 'native'];
var transformQuestions = function transformQuestions(questionsDefinition, api) {
return new Promise(function (resolve) {
resolve((0, _questions.transform)(questionsDefinition, api));
});
};
this.dryRun = dryRun;
this.apiClient = new _api2.default();
/**
* Prompts the user for their Cloud API key and email address and creates a .mobify file in their home directory.
*/
var captureAndSaveMobifyCredentials = function captureAndSaveMobifyCredentials() {
console.log('Either this is your first time generating a Mobify project OR the Mobify credentials we found are invalid.');
console.log('In order to generate projects, you must have a valid Mobify API key saved on your computer. Let\'s set that up now.');
console.log('');
return _inquirer2.default.prompt(transformedAuthQuestions).then(function (answers) {
var mobifyCredentialsPath = _os2.default.homedir() + '/.mobify';
try {
_fs2.default.writeFileSync(mobifyCredentialsPath, JSON.stringify({ username: answers.email, api_key: answers.cloudAPIKey }, null, 4));
console.log('Saved Mobify Cloud credentials to "' + mobifyCredentialsPath + '".\n');
} catch (e) {
console.error(e);
console.error('Failed to save credentials. Please try again.\n'.red);
}
});
};
var generateProject = function generateProject(answers, api, dryRun) {
if (dryRun) {
return console.log(JSON.stringify(answers, null, ' '));
}
_createClass(CliSession, [{
key: 'transformQuestions',
value: function transformQuestions(questionsDefinition) {
var _this = this;
return new Promise(function (resolve) {
_this.questions = (0, _questions.transform)(questionsDefinition);
resolve();
});
console.log('Generating...');
var githubPush = answers['github-push'];
return api.generateProject({
repository_name: answers['repository-name'],
project_url: answers['project-url'],
project_name: answers['project-name'],
mobify_project_id: answers['mobify-project-id'],
features: defaultFeatures,
bundle_identifier: answers['apps-bundle-id'],
github_push: githubPush,
// All the answers are included in the POST so that
// new questions can be added without having to
// overload the schema.
answers: answers
}).then(function (response) {
if (githubPush) {
console.log('That\'s it, your project has been created!\nGo to this URL to explore and clone the project: ' + response.url.underline);
} else {
console.log('That\'s it, your project has been created!\nUse this URL (valid for one week) to download your project: ' + response.url.underline);
}
}, {
key: 'askQuestions',
value: function askQuestions() {
var _this2 = this;
});
};
return _inquirer2.default.prompt(this.questions).then(function (answers) {
if (_this2.dryRun) {
return JSON.stringify(answers, null, ' ');
} else {
console.log('Generating...');
return _this2.apiClient.generateProject({
project_id: answers['project-id'],
project_url: answers['project-url'],
mobify_id: answers['mobify-id'],
features: _this2.defaultFeatures,
bundle_identifier: answers['apps-bundle-id']
}).then(function (response) {
return 'That\'s it, your project has been created!\nGo to this URL to explore and clone the project: ' + response.url.underline;
});
}
});
var run = function run(api, dryRun) {
return api.getQuestions().then(function (questions) {
return transformQuestions(questions, api);
}).then(function (transformedQuestions) {
return _inquirer2.default.prompt(transformedQuestions);
}).then(function (answers) {
return generateProject(answers, api, dryRun);
}).catch(function (error) {
console.error('Generator failed :-('.red);
// Error format expected from the API
if (error.error && error.error.message) {
console.error(('Error! ' + error.error.message).red);
// Something else...
} else {
console.error(error);
}
}, {
key: 'prompt',
value: function prompt() {
var _this3 = this;
});
};
/* eslint-disable prefer-template */
console.log(' `:-.');
console.log(' -yyyyys+:`');
console.log(' /yyyyyyyyy` +o+/:-.');
console.log(' `oyyyyyyyyy- :hhhhhhhs');
console.log(' `syyyyyyyyy+ yhhhhhhhy');
console.log(' `-/oyyyyyyyyyyo :hhhhhhhhs');
console.log(' -/oyyyyyyyyyyyyyo` shhhhhhhhs');
console.log(' +yyyyyyyyyyyyyyyy+ `hhhhhhhhho');
console.log(' +yyyyyyyyyyyyyy+. .hhhhhhhhho');
console.log(' `yyyyyyyyys+/. yhhhhhhhhhs`');
console.log(' -yso+/-.` .yhhhhhhhhhy.');
console.log(' ```.....` `shhhhhhhhhy.');
console.log(' -://++++++++++++/-` /yhhhhhhhhy.');
console.log(' /++++++++++++++++++/. `ohhhhhhy+`');
console.log(' :++++++++++++++++++++/-` -shhs:`');
console.log(' `+++++++++++++++++++++++-` -`');
console.log(' `......-...-/+++++++++++/`');
console.log(' `-/+++++++:`');
console.log(' `.:/+:`');
console.log('');
console.log('Hey, you\'re about to create a new Mobify Platform project!');
console.log('We\'ll generate Progressive Web App with various components like Native Apps, Push messages, Analytics and more.');
console.log('You can find more info here: ' + 'https://docs.mobify.com'.underline);
console.log('');
console.log('Before you get started:'.bold.bgYellow + ' make sure you\'ve created a new project in Mobify Cloud. ' + 'To create a Cloud project, visit this link: ' + 'https://cloud.mobify.com/projects/new/'.underline);
console.log('');
/* eslint-disable prefer-template */
var main = function main(dryRun) {
var showWelcome = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
this.apiClient.getQuestions().then(function (questions) {
return _this3.transformQuestions(questions);
}).then(function () {
return _this3.askQuestions();
}).then(function (message) {
return console.log(message);
}).catch(function (error) {
console.error('Generator failed :-('.red);
if (showWelcome) {
initialPrompt();
}
// Error format expected from the API
if (error.error && error.error.message) {
console.error(('Error! ' + error.error.message).red);
// Something else...
} else {
console.error(error);
}
});
_nconf2.default.argv().env().file('mobify-config', { file: _os2.default.homedir() + '/.mobify' }).file('defaults', { file: __dirname + '/../../config/default.json' }); // eslint-disable-line no-undef
// API URL should come from a bundled file. Fatal error if not found.
var apiURL = _nconf2.default.get('API_URL');
if (!apiURL) {
console.error('ERROR: API URL not found. Please contact Mobify support.'.red);
process.exit(1); // eslint-disable-line no-undef
}
var api = (0, _api2.default)(_nconf2.default.get('username'), _nconf2.default.get('api_key'), apiURL);
// Loop in main until credentials look good
return api.checkCredentials().then(function (valid) {
if (valid) {
return run(api, dryRun);
}
}]);
return captureAndSaveMobifyCredentials().then(function () {
return main(dryRun, false);
});
}).catch(function () {
return captureAndSaveMobifyCredentials().then(function () {
return main(dryRun, false);
});
});
};
return CliSession;
}();
exports.default = CliSession;
exports.default = main;

@@ -6,3 +6,3 @@ 'use strict';

});
exports.transform = exports.transformDefaultApply = exports.transformDefaultValue = exports.transformTitle = exports.transformValidation = exports.Converters = exports.Validators = undefined;
exports.transform = exports.transformWhen = exports.transformDefaultApply = exports.transformDefaultValue = exports.transformTitle = exports.transformValidation = exports.Converters = exports.Validators = undefined;

@@ -21,7 +21,9 @@ var _url = require('url');

var _cliSpinner = require('cli-spinner');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// eslint-disable-line no-unused-vars
var ANSWERS_PREFIX = 'answers.'; // eslint-disable-line no-unused-vars
var ANSWERS_PREFIX = 'answers.';
var spinner = (0, _cliSpinner.Spinner)();

@@ -50,2 +52,25 @@ // Export almost everything below for testing

return valid || 'Please enter a valid alphanumeric value. Hyphens (-), underscores (_) and dots (.) are allowed';
},
boolean: function boolean(value) {
var valid = value === true || value === false;
return valid || 'Please enter either \'yes\' or \'no\'';
},
repo: function repo(value, api) {
return new Promise(function (resolve) {
spinner.start(); // show the cli spinner!
// Request for availability of the provided repo name
api.checkRepoAvailability(value).then(function (response) {
spinner.stop(true);
if (response.available) {
resolve(true);
} else {
resolve('Oops! The repository name "' + value + '" is not available. Please submit another');
}
}).catch(function (e) {
spinner.stop(true);
console.error('ERROR: Failed to check repo availability. Error message received: ' + e.message);
process.exit(1); // eslint-disable-line no-undef
});
});
}

@@ -86,3 +111,3 @@ };

var isNotAnswerValue = function isNotAnswerValue(value) {
return value.indexOf(ANSWERS_PREFIX) === -1;
return typeof value !== 'string' || value.indexOf(ANSWERS_PREFIX) === -1;
};

@@ -94,3 +119,6 @@

var transformValidation = exports.transformValidation = function transformValidation(question) {
// We supply `api` here so that our validators can make api calls
// to perform validations if need be. This allows us to provide immediate
// feedback and request corrected input.
var transformValidation = exports.transformValidation = function transformValidation(question, api) {
if (Array.isArray(question.validation)) {

@@ -114,3 +142,3 @@ // closure to memorize the value

var check = validation(value);
var check = validation(value, api);
if (check !== true) {

@@ -142,3 +170,5 @@ return check;

if (validation) {
question.validate = validation;
question.validate = function (value) {
return validation(value, api);
};
}

@@ -163,4 +193,6 @@ }

var transformDefaultValue = exports.transformDefaultValue = function transformDefaultValue(question) {
if (question.defaultValue) {
// simple text value - just use it
// question.defaultValue could be `false`. Must check if the key
// exists, not if it's value is truthy
if ('defaultValue' in question) {
// simple value - just use it
if (isNotAnswerValue(question.defaultValue)) {

@@ -192,3 +224,4 @@ question.default = question.defaultValue;

// process all arguments, find actual values for pointers
var args = current.args.map(function (value) {
var currentArgs = current.args || [];
var args = currentArgs.map(function (value) {
if (isNotAnswerValue(value)) {

@@ -212,12 +245,54 @@ return value;

var transform = exports.transform = function transform(questionsDefinition) {
/**
* Return true iff the messaging-enabled question was answered with 'yes'
* @param answers
*/
var isMessagingEnabled = function isMessagingEnabled(answers) {
return !!answers['messaging-enabled'];
};
var isWelcomeMessageEnabled = function isWelcomeMessageEnabled(answers) {
return !!answers['send-welcome-message'];
};
var isUniqueAmpGaEnabled = function isUniqueAmpGaEnabled(answers) {
return !!answers['add-amp-ga'];
};
var isGitHubPushEnabled = function isGitHubPushEnabled(answers) {
return !!answers['github-push'];
};
var whenFunctions = {
isMessagingEnabled: isMessagingEnabled,
isWelcomeMessageEnabled: isWelcomeMessageEnabled,
isUniqueAmpGaEnabled: isUniqueAmpGaEnabled,
isGitHubPushEnabled: isGitHubPushEnabled
};
var transformWhen = exports.transformWhen = function transformWhen(question) {
if (question.when) {
// Because the questions file is JSON, not JS, the when value
// cannot be a function - it can only be the name of one of our
// predefined functions.
var whenFunction = whenFunctions[question.when];
if (whenFunction) {
question.when = whenFunction;
} else {
console.log('Unknown \'when\' value \'' + question.when + '\' - ignored');
delete question.when;
}
}
return question;
};
var transform = exports.transform = function transform(questionsDefinition, api) {
var size = questionsDefinition.length;
return questionsDefinition.map(function (question, i) {
question = transformValidation(question);
question = transformValidation(question, api);
question = transformTitle(question, i, size);
question = transformDefaultValue(question);
question = transformDefaultApply(question);
question = transformWhen(question);
return question;
});
};

@@ -17,4 +17,3 @@ 'use strict';

_commander2.default.command('create').description('Generate new Mobify Platform project').action(function () {
var session = new _cli2.default(_commander2.default.dryRun);
session.prompt();
(0, _cli2.default)(_commander2.default.dryRun);
});

@@ -21,0 +20,0 @@

{
"name": "@mobify/generator",
"version": "0.4.0",
"version": "0.5.0",
"description": "Mobify Platform Generator",

@@ -58,2 +58,3 @@ "main": "./lib/mobify.js",

"dependencies": {
"cli-spinner": "0.2.6",
"colors": "^1.1.2",

@@ -60,0 +61,0 @@ "commander": "^2.9.0",

@@ -1,71 +0,74 @@

# Platform Generator CLI
# Platform Generator Client
# How to install
Node CLI for generating projects with the use of (but not limited to) the following libraries:
## Prerequisites
* [`commander`](https://www.npmjs.com/package/commander) parses command line arguments, support options and powers the help page.
* [`inquirer`](https://www.npmjs.com/package/inquirer) is used to support rich interactive cli prompts.
- Node 6.x
Published as a private package [`@mobify/generator`](https://www.npmjs.com/package/@mobify/generator) on npm. You can see if you have access to the private package by running...
## Installation
```bash
# 🔒 Check your access to the private package:
npm view @mobify/generator
Make sure you have access to the Mobify [Platform Generator npm repo](https://www.npmjs.com/package/@mobify/generator). For that:
# 💥 If you can't access it, get #engineering to help:
npm login mobify
npm owner add jb
```
- `npm login` with your credentials
- Ask Mobify to invite you as a collaborator to `@mobify/generator`
Then simply run:
## 🏃 Usage
```
npm install -g @mobify/generator
```
1. In a terminal, run the docker image from the project root
# How to run
```
// From the repo root...
Docker/run-sshd.sh
```
```
mobify create
```
2. In another terminal, ssh into the docker image and run the server
```bash
Docker/ssh.sh
will run a globally installed `mobify` command.
// In the ssh'ed terminal
cd server
export GITHUB_ACCESS_TOKEN=<mobifygenerator access token>
make run
```
You may find the access token in Last Pass (**Use Generator GitHub bot - mobifygenerator**)
If you want to run your local setup:
3. In another terminal, ssh into the docker image and run the client
```bash
Docker/ssh.sh
```
# Make sure you have the server running, 'make run' in 'server' folder
export API_TOKEN=123
export API_URL=http://localhost:5000/api
npm start -- create
```
// In the ssh'ed terminal
cd client
export API_TOKEN=123
export API_URL=http://localhost:5000/api
npm start -- create
```
Running the last command will run thru the generator questions and create a gitHub repo with generated project
# How to test
**Any changes you make locally will be reflected on the docker image.**
```
## 🐛 Testing
```bash
npm test
```
# How to deploy
## 🚀 Deployment
Increase the version in the `package.json`, then run:
Bump the version in the `package.json` and run:
```
```bash
npm publish
```
# Owner
## 👷‍️ Development
Platform team.
Use double dash (`--`) to pass parameters to the cli command using `npm start`. For example:
# Development
We use [commander](https://www.npmjs.com/package/commander) to parse command line arguments, support options and show help page for the cli command.
When you develop you can use the double dash (`--`) to pass parameters to the cli command using `npm start`. For example:
```
```bash
npm start -- create
```
```
npm start -- -h
```
[inquirer](https://www.npmjs.com/package/inquirer) is used to support rich interactive cli prompts.