@mobify/generator
Advanced tools
Comparing version
{ | ||
"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. |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
24911
21.2%473
34.76%75
4.17%8
14.29%11
-8.33%1
Infinity%1
Infinity%+ Added
+ Added