Comparing version 5.3.1 to 6.0.0
{ | ||
"name": "forceios", | ||
"version": "5.3.1", | ||
"version": "6.0.0", | ||
"description": "Utilities for creating mobile apps based on the Salesforce Mobile SDK for iOS", | ||
@@ -5,0 +5,0 @@ "keywords": [ "mobilesdk", "ios", "salesforce", "mobile", "sdk" ], |
# Salesforce Mobile SDK for iOS Package | ||
The **forceios** npm package allows users to create iOS mobile applications to interface with the [Salesforce Platform](http://www.salesforce.com/platform/overview/), leveraging the [Salesforce Mobile SDK for iOS](https://github.com/forcedotcom/SalesforceMobileSDK-iOS). | ||
The **forceios** npm package allows users to create iOS mobile applications to interface with the [Salesforce Platform](http://www.salesforce.com/platform/overview/), leveraging [Salesforce Mobile SDK for iOS](https://github.com/forcedotcom/SalesforceMobileSDK-iOS). | ||
## Getting Started | ||
If you're new to mobile development, or the force.com platform, you may want to start at the [Mobile SDK landing page](http://wiki.developerforce.com/page/Mobile_SDK). This page offers a variety of resources to help you determine the best technology path for creating your app, as well as many guides and blog posts detailing how to work with the Mobile SDK. | ||
If you're new to mobile development or the force.com platform, you may want to start at the [Mobile SDK landing page](http://wiki.developerforce.com/page/Mobile_SDK). This page offers a variety of resources to help you determine the best technology path for creating your app, as well as many guides and blog posts detailing how to work with the Mobile SDK. | ||
@@ -21,3 +21,3 @@ But assuming you're all read up, here's how to get started with the **forceios** package to create the starting point for your mobile application. | ||
In this case, you can access the forceios app at `[Install Directory]/node_modules/.bin/forceios`. | ||
In local installations, you can access the forceios app at `[Install Directory]/node_modules/.bin/forceios`. | ||
@@ -30,29 +30,36 @@ ## Using forceios | ||
forceios | ||
Usage: | ||
forceios create | ||
--apptype=<Application Type> (native, native_swift, hybrid_local, hybrid_remote) | ||
--appname=<Application Name> | ||
--packagename=<App Package Identifier> (com.mycompany.myapp) | ||
--organization=<Organization Name> (Your company\'s/organization\'s name) | ||
--startpage=<App Start Page> (The start page of your remote app. Only required for hybrid_remote) | ||
[--outputdir=<Output directory> (Leave empty for current directory)] | ||
``` | ||
-> forceios | ||
forceios: Tool for building an iOS native mobile application using Salesforce Mobile SDK | ||
OR | ||
Usage: | ||
forceios createWithTemplate | ||
--templaterepouri=<Template repo URI> | ||
--appname=<Application Name> | ||
--packagename=<App Package Identifier> (com.mycompany.myapp) | ||
--organization=<Organization Name> (Your company\'s/organization\'s name) | ||
[--outputdir=<Output directory> (Leave empty for current directory)] | ||
# create an iOS native mobile application | ||
forceios create | ||
--apptype=application type (native, native_swift) | ||
--appname=application name | ||
--packagename=app package identifier (e.g. com.mycompany.myapp) | ||
--organization=organization name (your company's/organization's name) | ||
[--outputdir=output directory (leave empty for current directory)] | ||
OR | ||
OR | ||
forceios version | ||
# create an iOS native mobile application from a template | ||
forceios createwithtemplate | ||
--templaterepouri=template repo URI | ||
--appname=application name | ||
--packagename=app package identifier (e.g. com.mycompany.myapp) | ||
--organization=organization name (your company's/organization's name) | ||
[--outputdir=output directory (leave empty for current directory)] | ||
OR | ||
OR | ||
forceios | ||
# show version of Mobile SDK | ||
forceios version | ||
OR | ||
forceios | ||
``` | ||
**Note:** You can specify any or all of the arguments as command line options as specified in the usage. If you run `forceios create` with missing arguments, it prompts you for each missing option interactively. | ||
@@ -68,4 +75,2 @@ | ||
- **native\_swift** — A fully native iOS application written in Swift | ||
- **hybrid\_local** — A hybrid application, based on the Cordova framework, that runs in a native container. The app contents are developed locally in the Xcode project, and are deployed to the device itself when the app is built | ||
- **hybrid\_remote** — A hybrid application, based on the [Cordova](http://cordova.apache.org/) framework, that runs in a native container. The app contents live in the cloud as a [Visualforce](http://wiki.developerforce.com/page/An_Introduction_to_Visualforce) application | ||
@@ -78,4 +83,2 @@ **App Name:** The name of your application | ||
**Start Page:** \( *Required for hybrid\_remote apps only* \) The starting page of your application on salesforce.com. This is the entry point of your remote application, though it's only the path, not the server portion of the URL. For instance, `/apex/MyVisualforceStartPage`. | ||
**Output Directory:** \( *Optional* \) The folder where you want your app to be created. | ||
@@ -87,4 +90,8 @@ | ||
- You can find the `forcedroid` npm package [here](https://npmjs.org/package/forcedroid), to develop Mobile SDK apps for Android. | ||
- You can find the `forcedroid` npm package [here](https://npmjs.org/package/forcedroid) to develop Mobile SDK apps for Android. | ||
- You can find the `forcehybrid` npm package [here](https://npmjs.org/package/forcehybrid) to develop Mobile SDK hybrid apps for iOS and Android. | ||
- You can find the `forcereact` npm package [here](https://npmjs.org/package/forcereact) to develop Mobile SDK react native apps for iOS and Android. | ||
- The Salesforce Mobile SDK for iOS source repository lives [here](https://github.com/forcedotcom/SalesforceMobileSDK-iOS). | ||
@@ -94,4 +101,4 @@ | ||
- See [our developerforce site](http://wiki.developerforce.com/page/Mobile_SDK) for more information about how you can leverage the Salesforce Mobile SDK with the force.com platform. | ||
- See [our developerforce site](http://wiki.developerforce.com/page/Mobile_SDK) for more information about how you can leverage Salesforce Mobile SDK with the force.com platform. | ||
- If you would like to make suggestions, have questions, or encounter any issues, we'd love to hear from you. Post any feedback you have on our [Google+ Community](https://plus.google.com/communities/114225252149514546445). |
@@ -36,21 +36,57 @@ /* | ||
function readConfig(args, forcecli, handler) { | ||
function applyCli(f, cli) { | ||
return typeof f === 'function' ? f(cli): f; | ||
} | ||
function getArgsExpanded(cli, commandName) { | ||
var argNames = applyCli(SDK.commands[commandName].args, cli); | ||
return argNames | ||
.map(argName => SDK.args[argName]) | ||
.map(arg => | ||
({ | ||
name: arg.name, | ||
'char': arg.char, | ||
description: applyCli(arg.description, cli), | ||
longDescription: applyCli(arg.longDescription, cli), | ||
prompt: applyCli(arg.prompt, cli), | ||
error: applyCli(arg.error, cli), | ||
validate: applyCli(arg.validate, cli), | ||
promptIf: arg.promptIf, | ||
required: arg.required === undefined ? true : arg.required, | ||
hasValue: arg.hasValue === undefined ? true : arg.hasValue, | ||
hidden: arg.description == null | ||
}) | ||
); | ||
} | ||
function getCommandExpanded(cli, commandName) { | ||
var command = SDK.commands[commandName]; | ||
return { | ||
name: command.name, | ||
args: getArgsExpanded(cli, commandName), | ||
description: applyCli(command.description, cli), | ||
longDescription: applyCli(command.longDescription, cli), | ||
help: applyCli(command.help, cli) | ||
}; | ||
} | ||
function readConfig(args, cli, handler) { | ||
var commandLineArgs = args.slice(2, args.length); | ||
var command = commandLineArgs.shift(); | ||
var commandName = commandLineArgs.shift(); | ||
commandName = commandName ? commandName.toLowerCase() : commandName; | ||
var processorList = null; | ||
switch (command || '') { | ||
case 'version': | ||
logInfo(forcecli.name + ' version ' + SDK.version); | ||
switch (commandName || '') { | ||
case SDK.commands.version.name: | ||
printVersion(cli); | ||
process.exit(0); | ||
break; | ||
case 'create': | ||
processorList = createArgsProcessorList(forcecli, false); | ||
case SDK.commands.create.name: | ||
case SDK.commands.createwithtemplate.name: | ||
processorList = createArgsProcessorList(cli, commandName); | ||
break; | ||
case 'createWithTemplate': | ||
processorList = createArgsProcessorList(forcecli, true); | ||
break; | ||
default: | ||
usage(forcecli); | ||
usage(cli); | ||
process.exit(1); | ||
@@ -62,42 +98,37 @@ }; | ||
function usage(forcecli) { | ||
var forcecliName = forcecli.name; | ||
var forcecliVersion = SDK.version; | ||
var appTypes = forcecli.appTypes; | ||
var platforms = forcecli.platforms; | ||
function printVersion(cli) { | ||
logInfo(cli.name + ' version ' + SDK.version); | ||
} | ||
function printArgs(cli, commandName) { | ||
getArgsExpanded(cli, commandName) | ||
.filter(arg => !arg.hidden) | ||
.forEach(arg => logInfo(' ' + (!arg.required ? '[' : '') + '--' + arg.name + '=' + arg.description + (!arg.required ? ']' : ''), COLOR.magenta)); | ||
} | ||
function usage(cli) { | ||
var cliName = cli.name; | ||
var cliVersion = SDK.version; | ||
var appTypes = cli.appTypes; | ||
var platforms = cli.platforms; | ||
logInfo('\n' + forcecliName + ': ' + forcecli.description, COLOR.cyan); | ||
logInfo('\n' + cliName + ': Tool for building ' + cli.purpose + ' using Salesforce Mobile SDK', COLOR.cyan); | ||
logInfo('\nUsage:\n', COLOR.cyan); | ||
logInfo(forcecliName + ' create', COLOR.magenta); | ||
if (appTypes.length > 1) { | ||
logInfo(' --apptype=<Application Type> (' + appTypes.join(', ') + ')', COLOR.magenta); | ||
for (var i=0; i<cli.commands.length; i++) { | ||
if (i>0) { | ||
logInfo('\n OR \n', COLOR.cyan); | ||
} | ||
var commandName = cli.commands[i]; | ||
var command = getCommandExpanded(cli, commandName); | ||
logInfo('# ' + command.description, COLOR.magenta); | ||
logInfo(cliName + ' ' + commandName, COLOR.magenta); | ||
printArgs(cli, commandName); | ||
} | ||
if (platforms.length > 1) { | ||
logInfo(' --platform=<Comma separated plaforms> (' + platforms.join(', ') + ')', COLOR.magenta); | ||
} | ||
logInfo(' --appname=<Application Name>', COLOR.magenta); | ||
logInfo(' --packagename=<App Package Identifier> (e.g. com.mycompany.myapp)', COLOR.magenta); | ||
logInfo(' --organization=<Organization Name> (Your company\'s/organization\'s name)', COLOR.magenta); | ||
if (appTypes.indexOf('hybrid_remote') >= 0) { | ||
logInfo(' --startpage=<App Start Page> (The start page of your remote app. Only required for hybrid_remote)', COLOR.magenta); | ||
} | ||
logInfo(' [--outputdir=<Output directory> (Leave empty for current directory)]', COLOR.magenta); | ||
logInfo('\n OR \n', COLOR.cyan); | ||
logInfo(forcecliName + ' createWithTemplate', COLOR.magenta); | ||
if (platforms.length > 1) { | ||
logInfo(' --platform=<Comma separated plaforms> (' + platforms.join(', ') + ')', COLOR.magenta); | ||
} | ||
logInfo(' --templaterepouri=<Template repo URI> (e.g. https://github.com/forcedotcom/SmartSyncExplorerReactNative)]', COLOR.magenta); | ||
logInfo(' --appname=<Application Name>', COLOR.magenta); | ||
logInfo(' --packagename=<App Package Identifier> (e.g. com.mycompany.myapp)', COLOR.magenta); | ||
logInfo(' --organization=<Organization Name> (Your company\'s/organization\'s name)', COLOR.magenta); | ||
logInfo(' [--outputdir=<Output directory> (Leave empty for current directory)]', COLOR.magenta); | ||
logInfo('\n OR \n', COLOR.cyan); | ||
logInfo(forcecliName + ' version', COLOR.magenta); | ||
logInfo('\n OR \n', COLOR.cyan); | ||
logInfo(forcecliName, COLOR.magenta); | ||
logInfo(cliName, COLOR.magenta); | ||
logInfo('\nWe also offer:', COLOR.cyan); | ||
for (var cli of Object.values(SDK.forceclis)) { | ||
if (cli.name != forcecli.name) { | ||
logInfo('- ' + cli.name + ': ' + cli.description, COLOR.cyan); | ||
for (var otherCliName in SDK.forceclis) { | ||
var otherCli = SDK.forceclis[otherCliName]; | ||
if (otherCli.name != cli.name) { | ||
logInfo('- ' + otherCli.name + ': Tool for building ' + otherCli.purpose + ' using Salesforce Mobile SDK', COLOR.cyan); | ||
} | ||
@@ -109,66 +140,11 @@ } | ||
// | ||
// Processor list for 'create' command | ||
// Processor list | ||
// | ||
function createArgsProcessorList(forcecli, isCreateWithTemplate) { | ||
var appTypes = forcecli.appTypes; | ||
var platforms = forcecli.platforms; | ||
function createArgsProcessorList(cli, commandName) { | ||
var argProcessorList = new commandLineUtils.ArgProcessorList(); | ||
if (platforms.length > 1) { | ||
// Platforms | ||
addProcessorFor(argProcessorList, 'platform', 'Enter the target platform(s) separated by commas (' + platforms.join(', ') + '):', | ||
'Platform(s) must be in ' + platforms.join(', ') + '.', | ||
function(val) { return !val.split(",").some(p=>platforms.indexOf(p) == -1); }); | ||
for (var arg of getArgsExpanded(cli, commandName)) { | ||
addProcessorFor(argProcessorList, arg.name, arg.prompt, arg.error, arg.validate, arg.promptIf); | ||
} | ||
if (isCreateWithTemplate) { | ||
// Template Repo URI | ||
addProcessorFor(argProcessorList, 'templaterepouri', 'Enter URI of repo containing template application:', | ||
'Invalid value for template repo uri: \'$val\'.', /^\S+$/); | ||
} | ||
else { | ||
if (appTypes.length > 1) { | ||
// App type | ||
addProcessorFor(argProcessorList, 'apptype', 'Enter your application type (' + appTypes.join(', ') + '):', | ||
'App type must be ' + appTypes.join(', ') + '.', | ||
function(val) { return appTypes.indexOf(val) >= 0; }); | ||
} | ||
} | ||
// App name | ||
addProcessorFor(argProcessorList, 'appname', 'Enter your application name:', | ||
'Invalid value for application name: \'$val\'.', /^\S+$/); | ||
// Package name | ||
addProcessorFor(argProcessorList, 'packagename', 'Enter the package name for your app (com.mycompany.myapp):', | ||
'\'$val\' is not a valid package name.', /^[a-z]+[a-z0-9_]*(\.[a-z]+[a-z0-9_]*)*$/); | ||
// Organization | ||
addProcessorFor(argProcessorList, 'organization', 'Enter your organization name (Acme, Inc.):', | ||
'Invalid value for organization: \'$val\'.', /\S+/); | ||
// Start page | ||
addProcessorFor(argProcessorList, 'startpage', 'Enter the start page for your app:', | ||
'Invalid value for start page: \'$val\'.', /\S+/, | ||
function(argsMap) { return (argsMap['apptype'] === 'hybrid_remote'); }); | ||
// Output dir | ||
addProcessorFor(argProcessorList, 'outputdir', 'Enter output directory for your app (leave empty for the current directory):', | ||
'Invalid value for output directory (directory must not already exist): \'$val\'.', | ||
function(val) { return val === '' || !shelljs.test('-e', path.resolve(val)); }); | ||
// Template Path - private param (not documented in usage, user is never prompted) | ||
addProcessorFor(argProcessorList, 'templatepath', null, | ||
'Invalid value for template path: \'$val\'.', /.*/); | ||
// Plugin URI - private param (not documented in usage, user is never prompted) | ||
addProcessorFor(argProcessorList, 'pluginrepouri', null, | ||
'Invalid value for plugin repo uri: \'$val\'.', /.*/); | ||
// Verbose - private param (not documented in usage, user is never prompted) | ||
addProcessorFor(argProcessorList, 'verbose', null, | ||
'Invalid value for verbose: \'$val\'.', /.*/); | ||
return argProcessorList; | ||
@@ -182,20 +158,17 @@ } | ||
// * prompt: string for prompt | ||
// * error: string for error (can contain $val to print the value typed by the user in the error message) | ||
// * validation: function or regexp or null (no validation) | ||
// * error: function | ||
// * validation: function or null (no validation) | ||
// * preprocessor: function or null | ||
// * postprocessor: function or null | ||
// | ||
function addProcessorFor(argProcessorList, argName, prompt, error, validation, preprocessor, postprocessor) { | ||
function addProcessorFor(argProcessorList, argName, prompt, error, validation, preprocessor) { | ||
argProcessorList.addArgProcessor(argName, prompt, function(val) { | ||
val = val.trim(); | ||
// validation is either a function or a regexp | ||
if (typeof validation === 'function' && validation(val) | ||
|| typeof validation === 'object' && typeof validation.test === 'function' && validation.test(val)) | ||
{ | ||
return new commandLineUtils.ArgProcessorOutput(true, typeof postprocessor === 'function' ? postprocessor(val) : val); | ||
} | ||
else { | ||
return new commandLineUtils.ArgProcessorOutput(false, error.replace('$val', val)); | ||
} | ||
// validation is either a function or null | ||
if (validation == null || validation(val)) { | ||
return new commandLineUtils.ArgProcessorOutput(true, val); | ||
} | ||
else { | ||
return new commandLineUtils.ArgProcessorOutput(false, error(val)); | ||
} | ||
@@ -205,2 +178,7 @@ }, preprocessor); | ||
module.exports.readConfig = readConfig; | ||
module.exports = { | ||
readConfig: readConfig, | ||
printVersion: printVersion, | ||
getArgsExpanded: getArgsExpanded, | ||
getCommandExpanded: getCommandExpanded | ||
}; |
@@ -28,73 +28,232 @@ /* | ||
var VERSION = '5.3.0'; | ||
var path = require('path'), | ||
shelljs = require('shelljs'); | ||
var VERSION = '6.0.0'; | ||
module.exports = { | ||
version: VERSION, | ||
//templatesRepoUri: 'https://github.com/forcedotcom/SalesforceMobileSDK-Templates#dev53', // dev | ||
templatesRepoUri: 'https://github.com/forcedotcom/SalesforceMobileSDK-Templates#v' + '5.3.1', // GA | ||
tools: { | ||
git: { | ||
checkCmd: 'git --version', | ||
minVersion: '2.13' | ||
}, | ||
npm: { | ||
checkCmd: 'npm -v', | ||
minVersion: '3.10' | ||
}, | ||
pod: { | ||
checkCmd: 'pod --version', | ||
minVersion: '1.2' | ||
}, | ||
cordova: { | ||
checkCmd: 'cordova -v', | ||
minVersion: '7.0.0', | ||
//pluginRepoUri: 'https://github.com/forcedotcom/SalesforceMobileSDK-CordovaPlugin#dev', // dev | ||
pluginRepoUri: 'https://github.com/forcedotcom/SalesforceMobileSDK-CordovaPlugin#v' + VERSION, // GA | ||
platformVersion: { | ||
ios: '4.5.4', | ||
android: '7.0.0' | ||
} | ||
} | ||
}, | ||
ides: { | ||
ios: 'XCode', | ||
android: 'Android Studio' | ||
}, | ||
//templatesRepoUri: 'https://github.com/forcedotcom/SalesforceMobileSDK-Templates#dev', // dev | ||
templatesRepoUri: 'https://github.com/forcedotcom/SalesforceMobileSDK-Templates#v' + VERSION, // GA | ||
forceclis: { | ||
forceios: { | ||
name: 'forceios', | ||
description: 'command line utility for building iOS mobile applications using Salesforce Mobile SDK', | ||
topic: 'ios', | ||
purpose: 'an iOS native mobile application', | ||
dir: 'ios', | ||
platforms: ['ios'], | ||
toolNames: ['git', 'npm', 'pod'], | ||
appTypes: ['native', 'native_swift', 'react_native', 'hybrid_local', 'hybrid_remote'], | ||
appTypes: ['native', 'native_swift'], | ||
appTypesToPath: { | ||
'native': 'iOSNativeTemplate', | ||
'native_swift': 'iOSNativeSwiftTemplate', | ||
'react_native': 'ReactNativeTemplate', | ||
'hybrid_local': 'HybridLocalTemplate', | ||
'hybrid_remote': 'HybridRemoteTemplate' | ||
} | ||
'native_swift': 'iOSNativeSwiftTemplate' | ||
}, | ||
commands: ['create', 'createwithtemplate', 'version'] | ||
}, | ||
forcedroid: { | ||
name: 'forcedroid', | ||
description: 'command line utility for building Android mobile applications using Salesforce Mobile SDK', | ||
topic: 'android', | ||
purpose: 'an Android native mobile application', | ||
dir: 'android', | ||
platforms: ['android'], | ||
toolNames: ['git', 'npm'], | ||
appTypes: ['native', 'native_kotlin', 'react_native', 'hybrid_local', 'hybrid_remote'], | ||
appTypes: ['native', 'native_kotlin'], | ||
appTypesToPath: { | ||
'native': 'AndroidNativeTemplate', | ||
'native_kotlin': 'AndroidNativeKotlinTemplate', | ||
'react_native': 'ReactNativeTemplate', | ||
'native_kotlin': 'AndroidNativeKotlinTemplate' | ||
}, | ||
commands: ['create', 'createwithtemplate', 'version'] | ||
}, | ||
forcehybrid: { | ||
name: 'forcehybrid', | ||
topic: 'hybrid', | ||
purpose: 'a hybrid mobile application', | ||
dir: 'hybrid', | ||
platforms: ['ios', 'android'], | ||
toolNames: ['git', 'npm', 'cordova'], | ||
appTypes: ['hybrid_local', 'hybrid_remote'], | ||
appTypesToPath: { | ||
'hybrid_local': 'HybridLocalTemplate', | ||
'hybrid_remote': 'HybridRemoteTemplate' | ||
} | ||
}, | ||
commands: ['create', 'createwithtemplate', 'version'] | ||
}, | ||
forcereact: { | ||
name: 'forcereact', | ||
topic: 'reactnative', | ||
purpose: 'a React Native mobile application', | ||
dir: 'react', | ||
platforms: ['ios', 'android'], | ||
toolNames: ['git', 'npm', 'pod'], | ||
appTypes: ['react_native'], | ||
appTypesToPath: { | ||
'react_native': 'ReactNativeTemplate' | ||
}, | ||
commands: ['create', 'createwithtemplate', 'version'] | ||
} | ||
}, | ||
tools: { | ||
git: { | ||
checkCmd: 'git --version', | ||
minVersion: '2.13' | ||
args: { | ||
platform: { | ||
name: 'platform', | ||
'char': 'p', | ||
description: cli => 'comma-separated list of platforms (' + cli.platforms.join(', ') + ')', | ||
longDescription: cli => 'A comma-separated list of one or more platforms you support. The script creates a project for each platform you select. Available options are ' + cli.platforms.join(', ') + '.', | ||
prompt: cli => 'Enter the target platform(s) separated by commas (' + cli.platforms.join(', ') + '):', | ||
error: cli => val => 'Platform(s) must be in ' + cli.platforms.join(', '), | ||
validate: cli => val => !val.split(",").some(p=>cli.platforms.indexOf(p) == -1) | ||
}, | ||
npm: { | ||
checkCmd: 'npm -v', | ||
minVersion: '3.10' | ||
appType: { | ||
name:'apptype', | ||
'char':'t', | ||
description: cli => 'application type (' + cli.appTypes.join(', ') + ')', | ||
longDescription: cli => 'You can choose one of the following types of applications: ' + cli.appTypes.join(', ') + '.', | ||
prompt: cli => 'Enter your application type (' + cli.appTypes.join(', ') + '):', | ||
error: cli => val => 'App type must be ' + cli.appTypes.join(' or ') + '.', | ||
validate: cli => val => cli.appTypes.indexOf(val) >=0 | ||
}, | ||
pod: { | ||
checkCmd: 'pod --version', | ||
minVersion: '1.2' | ||
templateRepoUri: { | ||
name:'templaterepouri', | ||
'char': 'r', | ||
description:'template repo URI', | ||
longDescription: 'The URI of a repository that contains the template application to be used as the basis of your new app. See https://developer.salesforce.com/docs/atlas.en-us.mobile_sdk.meta/mobile_sdk/ios_new_project_template.htm for information on creating templates.', | ||
prompt: 'Enter URI of repo containing template application:', | ||
error: cli => val => 'Invalid value for template repo uri: \'' + val + '\'.', | ||
validate: cli => val => /^\S+$/.test(val) | ||
}, | ||
cordova: { | ||
checkCmd: 'cordova -v', | ||
minVersion: '7.0.0', | ||
//pluginRepoUri: 'https://github.com/forcedotcom/SalesforceMobileSDK-CordovaPlugin#dev53', // dev | ||
pluginRepoUri: 'https://github.com/forcedotcom/SalesforceMobileSDK-CordovaPlugin#v' + VERSION, // GA | ||
platformVersion: { | ||
ios: '4.4.0', | ||
android: '6.2.3' | ||
} | ||
} | ||
appName: { | ||
name: 'appname', | ||
'char': 'n', | ||
description: 'application name', | ||
longDescription: 'A name for the app that conforms to the naming requirements for the platform.', | ||
prompt: 'Enter your application name:', | ||
error: cli => val => 'Invalid value for application name: \'' + val + '\'.', | ||
validate: cli => val => /^\S+$/.test(val) | ||
}, | ||
packageName: { | ||
name: 'packagename', | ||
'char': 'k', | ||
description: 'app package identifier (e.g. com.mycompany.myapp)', | ||
longDescription: 'A string in reverse internet domain format that identifies your app\'s package or bundle. For example, "com.mycompany.myapp".', | ||
prompt: 'Enter your package name:', | ||
error: cli => val => '\'' + val + '\' is not a valid package name.', | ||
validate: cli => val => /^[a-z]+[a-z0-9_]*(\.[a-z]+[a-z0-9_]*)*$/.test(val), | ||
}, | ||
organization: { | ||
name: 'organization', | ||
'char': 'o', | ||
description: 'organization name (your company\'s/organization\'s name)', | ||
longDescription: 'The name of your company or organization. This string is user-defined and may contain spaces and punctuation.', | ||
prompt: 'Enter your organization name (Acme, Inc.):', | ||
error: cli => val => 'Invalid value for organization: \'' + val + '\'.', | ||
validate: cli => val => /\S+/.test(val) | ||
}, | ||
outputDir: { | ||
name:'outputdir', | ||
'char':'d', | ||
description:'output directory (leave empty for current directory)', | ||
longDescription: 'The local path for your new project. If this path points to an existing directory, that directory must be empty. If you don\'t specify a value, the script creates the app in the current directory.', | ||
prompt: 'Enter output directory for your app (leave empty for the current directory):', | ||
error: cli => val => 'Invalid value for output directory (directory must not already exist): \'' + val + '\'.', | ||
validate: cli => val => val === undefined || val === '' || !shelljs.test('-e', path.resolve(val)), | ||
required:false | ||
}, | ||
startPage: { | ||
name:'startpage', | ||
'char':'s', | ||
description:'app start page (the start page of your remote app; required for hybrid_remote apps only)', | ||
longDescription: 'For hybrid remote apps only, specify the relative server path to your Visualforce start page. This relative path always discards the Salesforce instance and domain name and starts with "apex/".', | ||
prompt: 'Enter the start page for your app:', | ||
error: cli => val => 'Invalid value for start page: \'' + val + '\'.', | ||
validate: cli => val => /\S+/.test(val), | ||
required: false, | ||
promptIf: otherArgs => otherArgs.apptype === 'hybrid_remote' | ||
}, | ||
// Private args | ||
verbose: { | ||
name:'verbose', | ||
'char':'v', | ||
hasValue:false, | ||
required:false | ||
}, | ||
pluginRepoUri: { | ||
name:'pluginrepouri', | ||
'char':'v', | ||
error: cli => val => 'Invalid value for plugin repo uri: \'' + val + '\'.', | ||
validate: cli => val => /.*/.test(val), | ||
required:false | ||
} | ||
}, | ||
ides: { | ||
ios: 'XCode', | ||
android: 'Android Studio' | ||
commands: { | ||
create: { | ||
name: 'create', | ||
args: cli => [cli.platforms.length > 1 ? 'platform' : null, | ||
cli.appTypes.length > 1 ? 'appType' : null, | ||
'appName', | ||
'packageName', | ||
'organization', | ||
cli.appTypes.indexOf('hybrid_remote') >=0 ? 'startPage' : null, | ||
'outputDir', | ||
'verbose', | ||
cli.name === 'forcehybrid' ? 'pluginRepoUri' : null | ||
].filter(x=>x!=null), | ||
description: cli => 'create ' + cli.purpose, | ||
longDescription: cli => 'Create ' + cli.purpose + '.', | ||
help: 'This command initiates creation of a new app based on the standard Mobile SDK template.' | ||
}, | ||
createwithtemplate: { | ||
name: 'createwithtemplate', | ||
args: cli => [cli.platforms.length > 1 ? 'platform' : null, | ||
'templateRepoUri', | ||
'appName', | ||
'packageName', | ||
'organization', | ||
'outputDir', | ||
'verbose' | ||
].filter(x=>x!=null), | ||
description: cli => 'create ' + cli.purpose + ' from a template', | ||
longDescription: cli => 'Create ' + cli.purpose + ' from a template.', | ||
help: 'This command initiates creation of a new app based on the Mobile SDK template that you specify. The template can be a specialized app for your app type that Mobile SDK provides, or your own custom app that you\'ve configured to use as a template. See https://developer.salesforce.com/docs/atlas.en-us.mobile_sdk.meta/mobile_sdk/ios_new_project_template.htm for information on custom templates.' | ||
}, | ||
version: { | ||
name: 'version', | ||
args: [], | ||
description: 'show version of Mobile SDK', | ||
longDescription: 'Show version of Mobile SDK.', | ||
help: 'This command displays to the console the version of Mobile SDK that the script uses to create apps.' | ||
} | ||
} | ||
}; |
@@ -171,3 +171,3 @@ /* | ||
// | ||
function createApp(forcecli) { | ||
function createApp(forcecli, config) { | ||
@@ -188,12 +188,10 @@ // Can't target ios or run pod if not on a mac | ||
// Read parameters from command line | ||
configHelper.readConfig(process.argv, forcecli, function(config) { | ||
try { | ||
actuallyCreateApp(forcecli, config); | ||
} | ||
catch (error) { | ||
utils.logError(forcecli.name + ' failed\n', error); | ||
process.exit(1); | ||
} | ||
}); | ||
if (config === undefined) { | ||
// Read parameters from command line | ||
configHelper.readConfig(process.argv, forcecli, function(config) { actuallyCreateApp(forcecli, config); }); | ||
} | ||
else { | ||
// Use parameters passed through | ||
actuallyCreateApp(forcecli, config); | ||
} | ||
} | ||
@@ -205,63 +203,76 @@ | ||
function actuallyCreateApp(forcecli, config) { | ||
// Adding platform | ||
if (forcecli.platforms.length == 1) { | ||
config.platform = forcecli.platforms[0]; | ||
} | ||
try { | ||
// Adding platform | ||
if (forcecli.platforms.length == 1) { | ||
config.platform = forcecli.platforms[0]; | ||
} | ||
// Adding app type | ||
if (forcecli.appTypes.length == 1) { | ||
config.apptype = forcecli.appTypes[0]; | ||
} | ||
// Adding app type | ||
if (forcecli.appTypes.length == 1) { | ||
config.apptype = forcecli.appTypes[0]; | ||
} | ||
// Setting log level | ||
if (config.verbose) { | ||
utils.setLogLevel(utils.LOG_LEVELS.DEBUG); | ||
} | ||
else { | ||
utils.setLogLevel(utils.LOG_LEVELS.INFO); | ||
} | ||
// Setting log level | ||
if (config.verbose) { | ||
utils.setLogLevel(utils.LOG_LEVELS.DEBUG); | ||
} | ||
else { | ||
utils.setLogLevel(utils.LOG_LEVELS.INFO); | ||
} | ||
// Computing projectDir | ||
config.projectDir = config.outputdir ? path.resolve(config.outputdir) : path.join(process.cwd(),config.appname) | ||
config.projectPath = path.relative(process.cwd(), config.projectDir); | ||
// Computing projectDir | ||
config.projectDir = config.outputdir ? path.resolve(config.outputdir) : path.join(process.cwd(),config.appname) | ||
config.projectPath = path.relative(process.cwd(), config.projectDir); | ||
// Adding version | ||
config.version = SDK.version; | ||
// Adding template repo uri and path if none provided | ||
config.templaterepouri = config.templaterepouri || SDK.templatesRepoUri; | ||
config.templatepath = config.templatepath || (config.templaterepouri == SDK.templatesRepoUri ? forcecli.appTypesToPath[config.apptype] : ''); | ||
// Adding version | ||
config.version = SDK.version; | ||
// Figuring out template repo uri and path | ||
if (config.templaterepouri) { | ||
var templateUriParsed = utils.separateRepoUrlPathBranch(config.templaterepouri); | ||
config.templaterepouri = templateUriParsed.repo + '#' + templateUriParsed.branch; | ||
config.templatepath = templateUriParsed.path; | ||
} | ||
else { | ||
config.templaterepouri = SDK.templatesRepoUri; | ||
config.templatepath = forcecli.appTypesToPath[config.apptype]; | ||
} | ||
// Creating tmp dir for template clone | ||
var tmpDir = utils.mkTmpDir(); | ||
// Creating tmp dir for template clone | ||
var tmpDir = utils.mkTmpDir(); | ||
// Cloning template repo | ||
var repoDir = utils.cloneRepo(tmpDir, config.templaterepouri); | ||
config.templateLocalPath = path.join(repoDir, config.templatepath); | ||
// Cloning template repo | ||
var repoDir = utils.cloneRepo(tmpDir, config.templaterepouri); | ||
config.templateLocalPath = path.join(repoDir, config.templatepath); | ||
// Getting apptype from template | ||
config.apptype = require(path.join(config.templateLocalPath, 'template.js')).appType; | ||
// Getting apptype from template | ||
config.apptype = require(path.join(config.templateLocalPath, 'template.js')).appType; | ||
var isNative = config.apptype.indexOf('native') >= 0; | ||
var isNative = config.apptype.indexOf('native') >= 0; | ||
// Adding hybrid only config | ||
if (!isNative) { | ||
config.cordovaPluginRepoUri = config.pluginrepouri || SDK.tools.cordova.pluginRepoUri; | ||
} | ||
// Adding hybrid only config | ||
if (!isNative) { | ||
config.cordovaPluginRepoUri = config.pluginrepouri || SDK.tools.cordova.pluginRepoUri; | ||
} | ||
// Print details | ||
printDetails(config); | ||
// Print details | ||
printDetails(config); | ||
// Creating application | ||
var results = isNative ? createNativeApp(config) : createHybridApp(config); | ||
// Creating application | ||
var results = isNative ? createNativeApp(config) : createHybridApp(config); | ||
// Cleanup | ||
utils.removeFile(tmpDir); | ||
// Printing next steps | ||
if (!(results instanceof Array)) { results = [results] }; | ||
for (var result of results) { | ||
var ide = SDK.ides[result.platform || config.platform.split(',')[0]]; | ||
printNextSteps(ide, config.projectPath, result); | ||
// Cleanup | ||
utils.removeFile(tmpDir); | ||
// Printing next steps | ||
if (!(results instanceof Array)) { results = [results] }; | ||
for (var result of results) { | ||
var ide = SDK.ides[result.platform || config.platform.split(',')[0]]; | ||
printNextSteps(ide, config.projectPath, result); | ||
} | ||
} | ||
catch (error) { | ||
utils.logError(forcecli.name + ' failed\n', error); | ||
process.exit(1); | ||
} | ||
} | ||
@@ -268,0 +279,0 @@ |
@@ -269,2 +269,16 @@ /* | ||
/** | ||
* Separate repo url / path / branch from url of the form https://server/org/repo/path#branch or https://server/org/repo#branch or https://server/org/repo | ||
* @param {String} Full url | ||
* @return map with repo / path /branch {repo:https://server/org/repo, branch:branch, path:path} | ||
*/ | ||
function separateRepoUrlPathBranch(fullUrl) { | ||
var parts = fullUrl.split('#'); | ||
var repoWithPath = parts[0]; | ||
var branch = parts.length > 1 ? parts[1] : 'master'; | ||
var repo = repoWithPath.split('/').splice(0,5).join('/'); | ||
var path = repoWithPath.split('/').splice(5).join('/'); | ||
return {repo:repo, branch:branch, path:path}; | ||
} | ||
/** | ||
* Clone repo. | ||
@@ -379,3 +393,4 @@ * | ||
runProcessCatchError, | ||
runProcessThrowError | ||
runProcessThrowError, | ||
separateRepoUrlPathBranch | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
60159
1264
99