Comparing version 2.0.5 to 2.1.0
@@ -1,1 +0,1 @@ | ||
[SalesforceMobileSDK-iOS](https://github.com/forcedotcom/SalesforceMobileSDK-iOS) commit: edb526afee8c8765408ea951337a868b1c21c2ac | ||
[SalesforceMobileSDK-iOS](https://github.com/forcedotcom/SalesforceMobileSDK-iOS) commit: b120a77416fd2fc710ca98b16aacd71a3e6cd7ab |
@@ -1,2 +0,2 @@ | ||
5d392fe039ed4174a1200d4f02124239855ebc72 | ||
b2151f85f15f527c63adb466bd3218c8763fdd1a | ||
357
forceios.js
#!/usr/bin/env node | ||
var exec = require('child_process').exec, | ||
var version = '2.1.0', | ||
exec = require('child_process').exec, | ||
path = require('path'), | ||
@@ -19,3 +20,4 @@ commandLineUtils = require('./HybridShared/node/commandLineUtils'); | ||
'DIR': 1, | ||
'ARCHIVE': 2 | ||
'ARCHIVE': 2, | ||
'DIRCONTENTS': 3 | ||
} | ||
@@ -30,20 +32,34 @@ | ||
var argProcessorList = createArgProcessorList(); | ||
var commandLineArgsMap; | ||
commandLineUtils.processArgsInteractive(commandLineArgs, argProcessorList, function (outputArgsMap) { | ||
commandLineArgsMap = outputArgsMap; | ||
switch (command) { | ||
case 'create': | ||
switch (command) { | ||
case 'version': | ||
console.log('forceios version ' + version); | ||
break; | ||
case 'create': | ||
commandLineUtils.processArgsInteractive(commandLineArgs, createArgProcessorList(), function (outputArgsMap) { | ||
commandLineArgsMap = outputArgsMap; | ||
createApp(); | ||
break; | ||
default: | ||
console.log(outputColors.red + 'Unknown option: \'' + command + '\'.' + outputColors.reset); | ||
usage(); | ||
process.exit(2); | ||
} | ||
}); | ||
}); | ||
break; | ||
case 'update': | ||
commandLineUtils.processArgsInteractive(commandLineArgs, createArgProcessorList(), function (outputArgsMap) { | ||
commandLineArgsMap = outputArgsMap; | ||
updateApp(); | ||
}); | ||
break; | ||
case 'samples': | ||
commandLineUtils.processArgsInteractive(commandLineArgs, samplesArgProcessorList(), function (outputArgsMap) { | ||
commandLineArgsMap = outputArgsMap; | ||
fetchSamples(); | ||
}); | ||
break; | ||
default: | ||
console.log(outputColors.red + 'Unknown option: \'' + command + '\'.' + outputColors.reset); | ||
usage(); | ||
process.exit(2); | ||
} | ||
function usage() { | ||
console.log(outputColors.cyan + 'Usage:'); | ||
console.log(outputColors.magenta + 'forceios create'); | ||
console.log(outputColors.cyan + 'Usage:\n'); | ||
console.log(outputColors.magenta + 'forceios create/update'); | ||
console.log(' --apptype=<Application Type> (native, hybrid_remote, hybrid_local)'); | ||
@@ -56,5 +72,97 @@ console.log(' --appname=<Application Name>'); | ||
console.log(' [--appid=<Salesforce App Identifier> (The Consumer Key for your app. Defaults to the sample app.)]'); | ||
console.log(' [--callbackuri=<Salesforce App Callback URL (The Callback URL for your app. Defaults to the sample app.)]' + outputColors.reset); | ||
console.log(' [--callbackuri=<Salesforce App Callback URL (The Callback URL for your app. Defaults to the sample app.)]'); | ||
console.log(outputColors.cyan + '\n OR \n'); | ||
console.log(outputColors.magenta + 'forceios version' + outputColors.reset); | ||
console.log(outputColors.cyan + '\n OR \n'); | ||
console.log(outputColors.magenta + 'forceios samples'); | ||
console.log(' --outputDir=<Output directory to copy the samples into>' + outputColors.reset); | ||
} | ||
function fetchSamples() { | ||
var srcDir; | ||
createDirectory(commandLineArgsMap.outputdir, function(success, msg) { | ||
if (!success) { | ||
if (msg) { | ||
console.log(msg); | ||
} | ||
process.exit(5); | ||
} | ||
copySampleApp('RestAPIExplorer', 'native', function(success, error) { | ||
copySampleApp('NativeSqlAggregator', 'native', function(success, error) { | ||
copySampleApp('FileExplorer', 'native', function(success, error) { | ||
copySampleApp('VFConnector', 'hybrid_remote', function(success, error) { | ||
copySampleApp('ContactExplorer', 'hybrid_local', function(success, error) { | ||
copySampleApp('SmartStoreExplorer', 'hybrid_local', function(success, error) { | ||
copySampleApp('AccountEditor', 'hybrid_local', function(success, error) { | ||
copySampleApp('HybridFileExplorer', 'hybrid_local', function(success, error) { | ||
if (success) { | ||
console.log(outputColors.green + 'Sample apps copied successfully!' + outputColors.reset); | ||
} else { | ||
if (error) { | ||
console.log(outputColors.red + msg + outputColors.reset); | ||
} | ||
} | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
} | ||
function copySampleApp(appName, appType, callback) { | ||
commandLineArgsMap.appname = appName; | ||
if (appType === 'hybrid_local' || appType === 'hybrid_remote') { | ||
srcDir = path.join(__dirname, 'Samples', 'hybrid', appName); | ||
} else { | ||
srcDir = path.join(__dirname, 'Samples', 'native', appName); | ||
} | ||
copyAppFolder(srcDir, function(success, msg) { | ||
if (!success) { | ||
return callback(false, msg); | ||
} | ||
createDirectory(path.join(commandLineArgsMap.outputdir, appName, appName, 'Dependencies'), function(success, error) { | ||
if (error) { | ||
console.log(outputColors.red + error + outputColors.reset); | ||
} | ||
if (appType === 'hybrid_local' || appType === 'hybrid_remote') { | ||
createDirectory(path.join(commandLineArgsMap.outputdir, appName, appName, 'www'), function(success, error) { | ||
copyDependencies(appType, function(success, error) { | ||
console.log(outputColors.green + 'Dependencies copied successfully!' + outputColors.reset); | ||
return callback(success, error); | ||
}); | ||
}); | ||
} else { | ||
copyDependencies(appType, function(success, error) { | ||
console.log(outputColors.green + 'Dependencies copied successfully!' + outputColors.reset); | ||
return callback(success, error); | ||
}); | ||
} | ||
}); | ||
}); | ||
} | ||
function createDirectory(dirName, callback) { | ||
exec('mkdir "' + dirName + '"', function(error, stdout, stderr) { | ||
if (error) { | ||
return callback(false, 'Error creating directory \'' + dirName + '\'' + ': ' + error); | ||
} else { | ||
return callback(true, null); | ||
} | ||
}); | ||
} | ||
function copyAppFolder(srcDir, callback) { | ||
exec('cp -R "' + srcDir + '" "' + commandLineArgsMap.outputdir + '"', function(error, stdout, stderr) { | ||
if (error) { | ||
return callback(false, 'Error copying directory \'' + srcDir + '\' to \'' + commandLineArgsMap.outputdir + '\': ' + error); | ||
} else { | ||
return callback(true, null); | ||
} | ||
}); | ||
} | ||
function createApp() { | ||
@@ -68,7 +176,7 @@ var appType = commandLineArgsMap.apptype; | ||
var createAppExecutable = (appType === 'native' ? | ||
var createAppExecutable = (appType === 'native' ? | ||
path.join(__dirname, 'Templates', 'NativeAppTemplate', 'createApp.sh') : | ||
path.join(__dirname, 'Templates', 'HybridAppTemplate', 'createApp.sh') | ||
); | ||
// Calling out to the shell, so re-quote the command line arguments. | ||
@@ -97,2 +205,22 @@ var newCommandLineArgs = buildArgsFromArgMap(); | ||
function updateApp() { | ||
var appType = commandLineArgsMap.apptype; | ||
if (appType !== 'native' && appType !== 'hybrid_remote' && appType !== 'hybrid_local') { | ||
console.log(outputColors.red + 'Unrecognized app type: \'' + appType + '\'.' + outputColors.reset + 'App type must be native, hybrid_remote, or hybrid_local.'); | ||
usage(); | ||
process.exit(4); | ||
} | ||
// Copy dependencies | ||
copyDependencies(appType, function(success, msg) { | ||
if (success) { | ||
if (msg) console.log(outputColors.green + msg + outputColors.reset); | ||
console.log(outputColors.green + 'Congratulations! You have successfully updated your app.' + outputColors.reset); | ||
} else { | ||
if (msg) console.log(outputColors.red + msg + outputColors.reset); | ||
console.log(outputColors.red + 'There was an error updating the app.' + outputColors.reset); | ||
} | ||
}); | ||
} | ||
function buildArgsFromArgMap() { | ||
@@ -129,3 +257,4 @@ var argLine = ''; | ||
case 'native': | ||
dependencies.push(dependencyPackages.restkit); | ||
dependencies.push(dependencyPackages.mkNetworkKit); | ||
dependencies.push(dependencyPackages.salesforceNetworkSDK); | ||
dependencies.push(dependencyPackages.nativesdk); | ||
@@ -138,4 +267,14 @@ break; | ||
dependencies.push(dependencyPackages.hybridSmartSync); | ||
dependencies.push(dependencyPackages.hybridSampleAppHtml); | ||
dependencies.push(dependencyPackages.hybridSampleAppJs); | ||
if (command === 'samples') { | ||
if (commandLineArgsMap.appname === 'AccountEditor' || commandLineArgsMap.appname === 'HybridFileExplorer') { | ||
dependencies.push(dependencyPackages.hybridAppWww); | ||
} else { | ||
dependencies.push(dependencyPackages.hybridSampleAppBootConfig); | ||
dependencies.push(dependencyPackages.hybridSampleAppHtml); | ||
dependencies.push(dependencyPackages.hybridSampleAppJs); | ||
} | ||
} else { | ||
dependencies.push(dependencyPackages.hybridSampleAppHtml); | ||
dependencies.push(dependencyPackages.hybridSampleAppJs); | ||
} | ||
dependencies.push(dependencyPackages.jquery); | ||
@@ -165,3 +304,3 @@ dependencies.push(dependencyPackages.backbone); | ||
console.log(outputColors.yellow + 'Uncompressing ' + path.basename(dependencyObj.srcPath) + ' to ' + dependencyObj.destPath + outputColors.reset); | ||
exec('unzip "' + dependencyObj.srcPath + '" -d "' + dependencyObj.destPath + '"', function(error, stdout, stderr) { | ||
exec('unzip -o "' + dependencyObj.srcPath + '" -d "' + dependencyObj.destPath + '"', function(error, stdout, stderr) { | ||
if (error) { | ||
@@ -193,2 +332,12 @@ return callback(false, 'There was an error uncompressing the archive \'' + dependencyObj.srcPath + '\' to \'' + dependencyObj.destPath + '\': ' + error); | ||
break; | ||
case dependencyType.DIRCONTENTS: | ||
// Recursive copy to the contents of the directory. | ||
console.log(outputColors.yellow + 'Copying ' + path.basename(dependencyObj.srcPath) + ' to ' + dependencyObj.destPath + outputColors.reset); | ||
exec('cp -rf "' + dependencyObj.srcPath + '"/ "' + dependencyObj.destPath + '"', function(error, stdout, stderr) { | ||
if (error) { | ||
return callback(false, 'Error copying directory \'' + dependencyObj.srcPath + '\' to \'' + dependencyObj.destPath + '\': ' + error); | ||
} | ||
copyDependenciesHelper(dependencies, callback); | ||
}); | ||
break; | ||
} | ||
@@ -208,2 +357,11 @@ } | ||
outputDirMap.hybridAppWwwDir = path.join(outputDirMap.appBaseContentDir, 'www'); | ||
if (command == 'update') { | ||
outputDirMap.hybridAppWwwDir += ('_' + version); | ||
exec('mkdir "' + outputDirMap.hybridAppWwwDir + '"', function(error, stdout, stderr) { | ||
if (error) { | ||
console.log('Error creating directory: ' + outputDirMap.hybridAppWwwDir); | ||
process.exit(5); | ||
} | ||
}); | ||
} | ||
@@ -215,3 +373,2 @@ return outputDirMap; | ||
var packageMap = {}; | ||
packageMap.sdkresources = makePackageObj(path.join(__dirname, 'Dependencies', 'SalesforceSDKResources.bundle'), outputDirMap.appBaseContentDir, dependencyType.DIR); | ||
@@ -227,4 +384,25 @@ packageMap.cordovaBin = makePackageObj(path.join(__dirname, 'Dependencies', 'Cordova', 'Cordova-Release.zip'), outputDirMap.appDependenciesDir, dependencyType.ARCHIVE); | ||
packageMap.backbone = makePackageObj(path.join(__dirname, 'HybridShared', 'external', 'backbone'), outputDirMap.hybridAppWwwDir, dependencyType.DIR); | ||
packageMap.hybridSampleAppHtml = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'contactexplorer', 'index.html'), outputDirMap.hybridAppWwwDir, dependencyType.FILE); | ||
packageMap.hybridSampleAppJs = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'contactexplorer', 'inline.js'), outputDirMap.hybridAppWwwDir, dependencyType.FILE); | ||
if (command === 'samples') { | ||
if (commandLineArgsMap.appname === 'ContactExplorer') { | ||
packageMap.hybridSampleAppBootConfig = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'contactexplorer', 'bootconfig.json'), outputDirMap.hybridAppWwwDir, dependencyType.FILE); | ||
} else if (commandLineArgsMap.appname === 'SmartStoreExplorer') { | ||
packageMap.hybridSampleAppBootConfig = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'smartstoreexplorer', 'bootconfig.json'), outputDirMap.hybridAppWwwDir, dependencyType.FILE); | ||
} else if (commandLineArgsMap.appname === 'VFConnector') { | ||
packageMap.hybridSampleAppBootConfig = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'vfconnector', 'bootconfig.json'), outputDirMap.hybridAppWwwDir, dependencyType.FILE); | ||
} | ||
if (commandLineArgsMap.appname === 'SmartStoreExplorer') { | ||
packageMap.hybridSampleAppHtml = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'smartstoreexplorer', 'index.html'), outputDirMap.hybridAppWwwDir, dependencyType.FILE); | ||
packageMap.hybridSampleAppJs = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'smartstoreexplorer', 'smartstoreexplorer.js'), outputDirMap.hybridAppWwwDir, dependencyType.FILE); | ||
} else if (commandLineArgsMap.appname === 'AccountEditor') { | ||
packageMap.hybridAppWww = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'smartsync'), outputDirMap.hybridAppWwwDir, dependencyType.DIRCONTENTS); | ||
} else if (commandLineArgsMap.appname === 'HybridFileExplorer') { | ||
packageMap.hybridAppWww = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'fileexplorer'), outputDirMap.hybridAppWwwDir, dependencyType.DIRCONTENTS); | ||
} else { | ||
packageMap.hybridSampleAppHtml = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'contactexplorer', 'index.html'), outputDirMap.hybridAppWwwDir, dependencyType.FILE); | ||
packageMap.hybridSampleAppJs = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'contactexplorer', 'inline.js'), outputDirMap.hybridAppWwwDir, dependencyType.FILE); | ||
} | ||
} else { | ||
packageMap.hybridSampleAppHtml = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'contactexplorer', 'index.html'), outputDirMap.hybridAppWwwDir, dependencyType.FILE); | ||
packageMap.hybridSampleAppJs = makePackageObj(path.join(__dirname, 'HybridShared', 'SampleApps', 'contactexplorer', 'inline.js'), outputDirMap.hybridAppWwwDir, dependencyType.FILE); | ||
} | ||
packageMap.hybridsdk = makePackageObj(path.join(__dirname, 'Dependencies', 'SalesforceHybridSDK-Release.zip'), outputDirMap.appDependenciesDir, dependencyType.ARCHIVE); | ||
@@ -234,7 +412,7 @@ packageMap.nativesdk = makePackageObj(path.join(__dirname, 'Dependencies', 'SalesforceNativeSDK-Release.zip'), outputDirMap.appDependenciesDir, dependencyType.ARCHIVE); | ||
packageMap.sdkcore = makePackageObj(path.join(__dirname, 'Dependencies', 'SalesforceSDKCore-Release.zip'), outputDirMap.appDependenciesDir, dependencyType.ARCHIVE); | ||
packageMap.restkit = makePackageObj(path.join(__dirname, 'Dependencies', 'ThirdParty', 'RestKit'), outputDirMap.appDependenciesDir, dependencyType.DIR); | ||
packageMap.mkNetworkKit = makePackageObj(path.join(__dirname, 'Dependencies', 'MKNetworkKit-iOS-Release.zip'), outputDirMap.appDependenciesDir, dependencyType.ARCHIVE); | ||
packageMap.salesforceNetworkSDK = makePackageObj(path.join(__dirname, 'Dependencies', 'SalesforceNetworkSDK-Release.zip'), outputDirMap.appDependenciesDir, dependencyType.ARCHIVE); | ||
packageMap.commonutils = makePackageObj(path.join(__dirname, 'Dependencies', 'ThirdParty', 'SalesforceCommonUtils'), outputDirMap.appDependenciesDir, dependencyType.DIR); | ||
packageMap.openssl = makePackageObj(path.join(__dirname, 'Dependencies', 'ThirdParty', 'openssl'), outputDirMap.appDependenciesDir, dependencyType.DIR); | ||
packageMap.sqlcipher = makePackageObj(path.join(__dirname, 'Dependencies', 'ThirdParty', 'sqlcipher'), outputDirMap.appDependenciesDir, dependencyType.DIR); | ||
return packageMap; | ||
@@ -267,71 +445,88 @@ } | ||
return new commandLineUtils.ArgProcessorOutput(false, 'Invalid value for app name: \'' + appName + '\''); | ||
return new commandLineUtils.ArgProcessorOutput(true, appName.trim()); | ||
}); | ||
// Company Identifier | ||
argProcessorList.addArgProcessor('companyid', 'Enter your company identifier (com.mycompany):', function(companyId) { | ||
if (companyId.trim() === '') | ||
return new commandLineUtils.ArgProcessorOutput(false, 'Invalid value for company identifier: \'' + companyId + '\''); | ||
// TODO: Update the company ID format as necessary. | ||
return new commandLineUtils.ArgProcessorOutput(true, companyId.trim()); | ||
}); | ||
// Output dir | ||
argProcessorList.addArgProcessor('outputdir', 'Enter the output directory for your app (defaults to the current directory):', function(outputDir) { | ||
if (outputDir.trim() === '') | ||
// Just unset the value. The underlying script will take care of the default. | ||
return new commandLineUtils.ArgProcessorOutput(true, undefined); | ||
// Organization | ||
argProcessorList.addArgProcessor('organization', 'Enter your organization name (Acme, Inc.):', function(org) { | ||
if (org.trim() === '') | ||
return new commandLineUtils.ArgProcessorOutput(false, 'Invalid value for organization: \'' + org + '\''); | ||
return new commandLineUtils.ArgProcessorOutput(true, org.trim()); | ||
return new commandLineUtils.ArgProcessorOutput(true, outputDir.trim()); | ||
}); | ||
// Start page | ||
argProcessorList.addArgProcessor( | ||
'startpage', | ||
'Enter the start page for your app (only applicable for hybrid_remote apps):', | ||
function(startPage, argsMap) { | ||
if (argsMap && argsMap.apptype === 'hybrid_remote') { | ||
if (startPage.trim() === '') | ||
return new commandLineUtils.ArgProcessorOutput(false, 'Invalid value for start page: \'' + startPage + '\''); | ||
// Additional arguments for the create | ||
if (command == 'create') { | ||
// Company Identifier | ||
argProcessorList.addArgProcessor('companyid', 'Enter your company identifier (com.mycompany):', function(companyId) { | ||
if (companyId.trim() === '') | ||
return new commandLineUtils.ArgProcessorOutput(false, 'Invalid value for company identifier: \'' + companyId + '\''); | ||
return new commandLineUtils.ArgProcessorOutput(true, startPage.trim()); | ||
// TODO: Update the company ID format as necessary. | ||
return new commandLineUtils.ArgProcessorOutput(true, companyId.trim()); | ||
}); | ||
// Organization | ||
argProcessorList.addArgProcessor('organization', 'Enter your organization name (Acme, Inc.):', function(org) { | ||
if (org.trim() === '') | ||
return new commandLineUtils.ArgProcessorOutput(false, 'Invalid value for organization: \'' + org + '\''); | ||
return new commandLineUtils.ArgProcessorOutput(true, org.trim()); | ||
}); | ||
// Start page | ||
argProcessorList.addArgProcessor( | ||
'startpage', | ||
'Enter the start page for your app (only applicable for hybrid_remote apps):', | ||
function(startPage, argsMap) { | ||
if (argsMap && argsMap.apptype === 'hybrid_remote') { | ||
if (startPage.trim() === '') | ||
return new commandLineUtils.ArgProcessorOutput(false, 'Invalid value for start page: \'' + startPage + '\''); | ||
return new commandLineUtils.ArgProcessorOutput(true, startPage.trim()); | ||
} | ||
// Unset any value here, as it doesn't apply for non-remote apps. | ||
return new commandLineUtils.ArgProcessorOutput(true, undefined); | ||
}, | ||
function (argsMap) { | ||
return (argsMap['apptype'] === 'hybrid_remote'); | ||
} | ||
); | ||
// Unset any value here, as it doesn't apply for non-remote apps. | ||
return new commandLineUtils.ArgProcessorOutput(true, undefined); | ||
}, | ||
function (argsMap) { | ||
return (argsMap['apptype'] === 'hybrid_remote'); | ||
} | ||
); | ||
// Connected App ID | ||
argProcessorList.addArgProcessor('appid', 'Enter your Connected App ID (defaults to the sample app\'s ID):', function(appId) { | ||
if (appId.trim() === '') | ||
// Just unset the value. The underlying script will take care of the default. | ||
return new commandLineUtils.ArgProcessorOutput(true, undefined); | ||
return new commandLineUtils.ArgProcessorOutput(true, appId.trim()); | ||
}); | ||
// Connected App Callback URI | ||
argProcessorList.addArgProcessor('callbackuri', 'Enter your Connected App Callback URI (defaults to the sample app\'s URI):', function(callbackUri) { | ||
if (callbackUri.trim() === '') | ||
// Just unset the value. The underlying script will take care of the default. | ||
return new commandLineUtils.ArgProcessorOutput(true, undefined); | ||
return new commandLineUtils.ArgProcessorOutput(true, callbackUri.trim()); | ||
}); | ||
} | ||
return argProcessorList; | ||
} | ||
function samplesArgProcessorList() { | ||
var argProcessorList = new commandLineUtils.ArgProcessorList(); | ||
// Output dir | ||
argProcessorList.addArgProcessor('outputdir', 'Enter the output directory for your app (defaults to the current directory):', function(outputDir) { | ||
argProcessorList.addArgProcessor('outputdir', 'Enter the output directory for the samples:', function(outputDir) { | ||
if (outputDir.trim() === '') | ||
// Just unset the value. The underlying script will take care of the default. | ||
return new commandLineUtils.ArgProcessorOutput(true, undefined); | ||
return new commandLineUtils.ArgProcessorOutput(false, 'Invalid value for output dir: \'' + outputDir + '\''); | ||
return new commandLineUtils.ArgProcessorOutput(true, outputDir.trim()); | ||
}); | ||
// Connected App ID | ||
argProcessorList.addArgProcessor('appid', 'Enter your Connected App ID (defaults to the sample app\'s ID):', function(appId) { | ||
if (appId.trim() === '') | ||
// Just unset the value. The underlying script will take care of the default. | ||
return new commandLineUtils.ArgProcessorOutput(true, undefined); | ||
return new commandLineUtils.ArgProcessorOutput(true, appId.trim()); | ||
}); | ||
// Connected App Callback URI | ||
argProcessorList.addArgProcessor('callbackuri', 'Enter your Connected App Callback URI (defaults to the sample app\'s URI):', function(callbackUri) { | ||
if (callbackUri.trim() === '') | ||
// Just unset the value. The underlying script will take care of the default. | ||
return new commandLineUtils.ArgProcessorOutput(true, undefined); | ||
return new commandLineUtils.ArgProcessorOutput(true, callbackUri.trim()); | ||
}); | ||
return argProcessorList; | ||
} |
@@ -28,3 +28,3 @@ /* | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "2.0.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "2.1.0"; | ||
@@ -194,3 +194,3 @@ /** | ||
successCB = typeof successCB !== "function" ? defaultSuccessCB : successCB; | ||
error = typeof errorCB !== "function" ? defaultErrorCB : errorCB; | ||
errorCB = typeof errorCB !== "function" ? defaultErrorCB : errorCB; | ||
args.unshift("pluginSDKVersion:" + pluginVersion); | ||
@@ -197,0 +197,0 @@ var cordovaExec = require('cordova/exec'); |
@@ -27,4 +27,6 @@ /* | ||
(function($j) { | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "2.0.0"; | ||
this.SALESFORCE_MOBILE_SDK_VERSION = "2.1.0"; | ||
@@ -36,3 +38,3 @@ /* | ||
* | ||
* Note that you must add the REST endpoint hostname for your instance (i.e. | ||
* Note that you must add the REST endpoint hostname for your instance (i.e. | ||
* https://na1.salesforce.com/ or similar) as a remote site - in the admin | ||
@@ -42,6 +44,6 @@ * console, go to Your Name | Setup | Security Controls | Remote Site Settings | ||
var forcetk = window.forcetk; | ||
var forcetk = this.forcetk; | ||
if (forcetk === undefined) { | ||
forcetk = {}; | ||
forcetk = this.forcetk = {}; | ||
} | ||
@@ -51,9 +53,4 @@ | ||
// We use $j rather than $ for jQuery so it works in Visualforce | ||
if (window.$j === undefined) { | ||
$j = $; | ||
} | ||
/** | ||
* The Client provides a convenient wrapper for the Force.com REST API, | ||
* The Client provides a convenient wrapper for the Force.com REST API, | ||
* allowing JavaScript in Visualforce pages to use the API via the Ajax | ||
@@ -63,3 +60,3 @@ * Proxy. | ||
* @param [loginUrl='https://login.salesforce.com/'] Login endpoint | ||
* @param [proxyUrl=null] Proxy URL. Omit if running on Visualforce or | ||
* @param [proxyUrl=null] Proxy URL. Omit if running on Visualforce or | ||
* Cordova etc | ||
@@ -73,3 +70,3 @@ * @constructor | ||
/** | ||
* The Client provides a convenient wrapper for the Force.com REST API, | ||
* The Client provides a convenient wrapper for the Force.com REST API, | ||
* allowing JavaScript in Visualforce pages to use the API via the Ajax | ||
@@ -79,3 +76,3 @@ * Proxy. | ||
* @param [loginUrl='https://login.salesforce.com/'] Login endpoint | ||
* @param [proxyUrl=null] Proxy URL. Omit if running on Visualforce or | ||
* @param [proxyUrl=null] Proxy URL. Omit if running on Visualforce or | ||
* Cordova etc | ||
@@ -89,13 +86,6 @@ * @param authCallback Callback method to perform authentication when 401 is received. | ||
if (typeof proxyUrl === 'undefined' || proxyUrl === null) { | ||
if (location.protocol === 'file:') { | ||
// In Cordova | ||
this.proxyUrl = null; | ||
} else { | ||
// In Visualforce | ||
this.proxyUrl = location.protocol + "//" + location.hostname | ||
+ "/services/proxy"; | ||
} | ||
this.proxyUrl = null; | ||
this.authzHeader = "Authorization"; | ||
} else { | ||
// On a server outside VF | ||
// On an external proxy service | ||
this.proxyUrl = proxyUrl; | ||
@@ -188,4 +178,4 @@ this.authzHeader = "X-Authorization"; | ||
switch(match[1]) { | ||
case "iPad": | ||
platform = "iPhone OS"; | ||
case "iPad": | ||
platform = "iPhone OS"; | ||
platformVersion = getIPadVersion(); | ||
@@ -195,5 +185,5 @@ model = "iPad"; | ||
case "iPhone": | ||
case "iPod": | ||
platform = "iPhone OS"; | ||
case "iPhone": | ||
case "iPod": | ||
platform = "iPhone OS"; | ||
platformVersion = getIPhoneVersion(); | ||
@@ -203,22 +193,22 @@ model = match[1]; | ||
case "Android": | ||
platform = "android mobile"; | ||
platformVersion = getAndroidVersion(); | ||
model = getAndroidModel(); | ||
case "Android": | ||
platform = "android mobile"; | ||
platformVersion = getAndroidVersion(); | ||
model = getAndroidModel(); | ||
break; | ||
case "Windows Phone": | ||
platform = "Windows Phone"; | ||
platformVersion = getWindowsPhoneVersion(); | ||
case "Windows Phone": | ||
platform = "Windows Phone"; | ||
platformVersion = getWindowsPhoneVersion(); | ||
model = getWindowsPhoneModel(); | ||
break; | ||
case "Macintosh": | ||
platform = "Mac OS"; | ||
platformVersion = getMacOSVersion(); | ||
case "Macintosh": | ||
platform = "Mac OS"; | ||
platformVersion = getMacOSVersion(); | ||
break; | ||
case "Windows": | ||
platform = "Windows"; | ||
platformVersion = getWindowsVersion(); | ||
case "Windows": | ||
platform = "Windows"; | ||
platformVersion = getWindowsVersion(); | ||
break; | ||
@@ -229,3 +219,3 @@ } | ||
return "SalesforceMobileSDK/" + sdkVersion + " " + platform + "/" + platformVersion + " (" + model + ") " + appName + "/" + appVersion + " Web " + navigatorUserAgent; | ||
} | ||
} | ||
@@ -247,3 +237,3 @@ /** | ||
var that = this; | ||
if (this.authCallback == null) { | ||
if (this.authCallback == null && this.refreshToken) { | ||
var url = this.loginUrl + '/services/oauth2/token'; | ||
@@ -278,3 +268,3 @@ return $j.ajax({ | ||
* @param [apiVersion="28.0"] Force.com API version | ||
* @param [instanceUrl] Omit this if running on Visualforce; otherwise | ||
* @param [instanceUrl] Omit this if running on Visualforce; otherwise | ||
* use the value from the OAuth token. | ||
@@ -288,5 +278,5 @@ */ | ||
// location.hostname can be of the form 'abc.na1.visual.force.com', | ||
// 'na1.salesforce.com' or 'abc.my.salesforce.com' (custom domains). | ||
// 'na1.salesforce.com' or 'abc.my.salesforce.com' (custom domains). | ||
// Split on '.', and take the [1] or [0] element as appropriate | ||
var elements = location.hostname.split("."); | ||
var elements = location.hostname.split("."); | ||
var instance = null; | ||
@@ -306,5 +296,20 @@ if(elements.length == 4 && elements[1] === 'my') { | ||
// Internal method to generate the key/value pairs of all the required headers for xhr. | ||
var getRequestHeaders = function(client) { | ||
var headers = {}; | ||
headers[client.authzHeader] = "Bearer " + client.sessionId; | ||
headers['Cache-Control'] = 'no-store'; | ||
// See http://www.salesforce.com/us/developer/docs/chatterapi/Content/intro_requesting_bearer_token_url.htm#kanchor36 | ||
headers["X-Connect-Bearer-Urls"] = true; | ||
if (client.userAgentString !== null) { | ||
headers['User-Agent'] = client.userAgentString; | ||
headers['X-User-Agent'] = client.userAgentString; | ||
} | ||
return headers; | ||
} | ||
/* | ||
* Low level utility function to call the Salesforce endpoint. | ||
* @param path resource path relative to /services/data | ||
* @param path resource path relative to /services/data or fully qualified url (to Salesforce) | ||
* @param callback function to which response will be passed | ||
@@ -314,6 +319,8 @@ * @param [error=null] function to which jqXHR will be passed in case of error | ||
* @param [payload=null] payload for POST/PATCH etc | ||
* @param [headerParams={headerName:"headerValue",...}] parameters to send as header values for POST/PATCH etc | ||
*/ | ||
forcetk.Client.prototype.ajax = function(path, callback, error, method, payload, retry) { | ||
forcetk.Client.prototype.ajax = function(path, callback, error, method, payload, headerParams) { | ||
var that = this; | ||
var url = this.instanceUrl + '/services/data' + path; | ||
var retryCount = 0; | ||
var url = (path.indexOf(this.instanceUrl) == 0 ? path : this.instanceUrl + '/services/data' + path); | ||
return $j.ajax({ | ||
@@ -326,15 +333,20 @@ type: method || "GET", | ||
processData: false, | ||
dataType: "json", | ||
data: payload, | ||
headers: getRequestHeaders(this), | ||
success: callback, | ||
error: (!this.refreshToken || retry ) ? error : function(jqXHR, textStatus, errorThrown) { | ||
if (jqXHR.status === 401) { | ||
error: function(jqXHR, textStatus, errorThrown) { | ||
var xhr = this; | ||
var errorCallback = function() { | ||
if (typeof error == 'function') { | ||
error(jqXHR, textStatus, errorThrown); | ||
} | ||
} | ||
if (jqXHR.status === 401 && retryCount++ == 0) { | ||
that.refreshAccessToken(function() { | ||
that.ajax(path, callback, error, method, payload, true); | ||
that.replay(xhr); | ||
}, | ||
error); | ||
} else { | ||
error(jqXHR, textStatus, errorThrown); | ||
} | ||
errorCallback); | ||
} else errorCallback(); | ||
}, | ||
dataType: "json", | ||
beforeSend: function(xhr) { | ||
@@ -344,8 +356,6 @@ if (that.proxyUrl !== null) { | ||
} | ||
xhr.setRequestHeader(that.authzHeader, "Bearer " + that.sessionId); | ||
if (that.userAgentString !== null) { | ||
xhr.setRequestHeader('User-Agent', that.userAgentString); | ||
xhr.setRequestHeader('X-User-Agent', that.userAgentString); | ||
//Add any custom headers | ||
for (paramName in (headerParams || {})) { | ||
xhr.setRequestHeader(paramName, headerParams[paramName]); | ||
} | ||
xhr.setRequestHeader('Cache-Control', 'no-store'); | ||
} | ||
@@ -355,6 +365,16 @@ }); | ||
/* | ||
* Low level utility function to replay an ajax request. | ||
* The utility function updates the session id before replaying the request. | ||
* @param xhr xhr request to be replayed. | ||
*/ | ||
forcetk.Client.prototype.replay = function(xhr) { | ||
xhr.headers = getRequestHeaders(this); | ||
$j.ajax(xhr); | ||
} | ||
/** | ||
* Utility function to query the Chatter API and download a file | ||
* Note, raw XMLHttpRequest because JQuery mangles the arraybuffer | ||
* This should work on any browser that supports XMLHttpRequest 2 because arraybuffer is required. | ||
* This should work on any browser that supports XMLHttpRequest 2 because arraybuffer is required. | ||
* For mobile, that means iOS >= 5 and Android >= Honeycomb | ||
@@ -366,7 +386,7 @@ * @author Tom Gersic | ||
* @param [error=null] function to which request will be passed in case of error | ||
* @param rety true if we've already tried refresh token flow once | ||
* @param retry true if we've already tried refresh token flow once | ||
**/ | ||
forcetk.Client.prototype.getChatterFile = function(path,mimeType,callback,error,retry) { | ||
var that = this; | ||
var url = this.instanceUrl + path; | ||
var url = this.instanceUrl + '/services/data' + path; | ||
var request = new XMLHttpRequest(); | ||
@@ -415,55 +435,14 @@ request.open("GET", (this.proxyUrl !== null) ? this.proxyUrl: url, true); | ||
* @param path resource path relative to /services/apexrest | ||
* @param [method="GET"] HTTP method for call | ||
* @param [payload=null] payload for POST/PATCH etc | ||
* @param [headerParams={headerName:"headerValue",...}] parameters to send as header values for POST/PATCH etc | ||
* @param callback function to which response will be passed | ||
* @param [error=null] function to which jqXHR will be passed in case of error | ||
* @param [method="GET"] HTTP method for call | ||
* @param [payload=null] payload for POST/PATCH etc | ||
* @param [paramMap={}] parameters to send as header values for POST/PATCH etc | ||
* @param [retry] specifies whether to retry on error | ||
*/ | ||
forcetk.Client.prototype.apexrest = function(path, callback, error, method, payload, paramMap, retry) { | ||
var that = this; | ||
var url = this.instanceUrl + '/services/apexrest' + path; | ||
return $j.ajax({ | ||
type: method || "GET", | ||
async: this.asyncAjax, | ||
url: (this.proxyUrl !== null) ? this.proxyUrl: url, | ||
contentType: 'application/json', | ||
cache: false, | ||
processData: false, | ||
data: payload, | ||
success: callback, | ||
error: (!this.refreshToken || retry ) ? error : function(jqXHR, textStatus, errorThrown) { | ||
if (jqXHR.status === 401) { | ||
that.refreshAccessToken(function() { | ||
that.apexrest(path, callback, error, method, payload, paramMap, true); | ||
}, | ||
error); | ||
} else { | ||
error(jqXHR, textStatus, errorThrown); | ||
} | ||
}, | ||
dataType: "json", | ||
beforeSend: function(xhr) { | ||
if (that.proxyUrl !== null) { | ||
xhr.setRequestHeader('SalesforceProxy-Endpoint', url); | ||
} | ||
//Add any custom headers | ||
if (paramMap === null) { | ||
paramMap = {}; | ||
} | ||
for (paramName in paramMap) { | ||
xhr.setRequestHeader(paramName, paramMap[paramName]); | ||
} | ||
xhr.setRequestHeader(that.authzHeader, "Bearer " + that.sessionId); | ||
if (that.userAgentString !== null) { | ||
xhr.setRequestHeader('User-Agent', that.userAgentString); | ||
xhr.setRequestHeader('X-User-Agent', that.userAgentString); | ||
} | ||
xhr.setRequestHeader('Cache-Control', 'no-store'); | ||
} | ||
}); | ||
forcetk.Client.prototype.apexrest = function(path, method, payload, headerParams, callback, error) { | ||
return this.ajax(this.instanceUrl + '/services/apexrest' + path, callback, error, method, payload, headerParams); | ||
} | ||
/* | ||
* Lists summary information about each Salesforce.com version currently | ||
* Lists summary information about each Salesforce.com version currently | ||
* available, including the version, label, and a link to each version's | ||
@@ -479,3 +458,3 @@ * root. | ||
/* | ||
* Lists available resources for the client's API version, including | ||
* Lists available resources for the client's API version, including | ||
* resource name and URI. | ||
@@ -490,3 +469,3 @@ * @param callback function to which response will be passed | ||
/* | ||
* Lists the available objects and their metadata for your organization's | ||
* Lists the available objects and their metadata for your organization's | ||
* data. | ||
@@ -512,3 +491,3 @@ * @param callback function to which response will be passed | ||
/* | ||
* Completely describes the individual metadata at all levels for the | ||
* Completely describes the individual metadata at all levels for the | ||
* specified object. | ||
@@ -540,4 +519,4 @@ * @param objtype object type; e.g. "Account" | ||
* @param objtype object type; e.g. "Account" | ||
* @param fields an object containing initial field names and values for | ||
* the record, e.g. {:Name "salesforce.com", :TickerSymbol | ||
* @param fields an object containing initial field names and values for | ||
* the record, e.g. {:Name "salesforce.com", :TickerSymbol | ||
* "CRM"} | ||
@@ -556,3 +535,3 @@ * @param callback function to which response will be passed | ||
* @param id the record's object ID | ||
* @param [fields=null] optional comma-separated list of fields for which | ||
* @param [fields=null] optional comma-separated list of fields for which | ||
* to return values; e.g. Name,Industry,TickerSymbol | ||
@@ -569,3 +548,3 @@ * @param callback function to which response will be passed | ||
var fields = fieldlist ? '?fields=' + fieldlist : ''; | ||
this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + id | ||
return this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + id | ||
+ fields, callback, error); | ||
@@ -575,3 +554,3 @@ } | ||
/* | ||
* Upsert - creates or updates record of the given type, based on the | ||
* Upsert - creates or updates record of the given type, based on the | ||
* given external Id. | ||
@@ -581,4 +560,4 @@ * @param objtype object type; e.g. "Account" | ||
* @param externalId the record's external ID value | ||
* @param fields an object containing field names and values for | ||
* the record, e.g. {:Name "salesforce.com", :TickerSymbol | ||
* @param fields an object containing field names and values for | ||
* the record, e.g. {:Name "salesforce.com", :TickerSymbol | ||
* "CRM"} | ||
@@ -589,3 +568,3 @@ * @param callback function to which response will be passed | ||
forcetk.Client.prototype.upsert = function(objtype, externalIdField, externalId, fields, callback, error) { | ||
return this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + externalIdField + '/' + externalId | ||
return this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + externalIdField + '/' + externalId | ||
+ '?_HttpMethod=PATCH', callback, error, "POST", JSON.stringify(fields)); | ||
@@ -598,4 +577,4 @@ } | ||
* @param id the record's object ID | ||
* @param fields an object containing initial field names and values for | ||
* the record, e.g. {:Name "salesforce.com", :TickerSymbol | ||
* @param fields an object containing initial field names and values for | ||
* the record, e.g. {:Name "salesforce.com", :TickerSymbol | ||
* "CRM"} | ||
@@ -606,3 +585,3 @@ * @param callback function to which response will be passed | ||
forcetk.Client.prototype.update = function(objtype, id, fields, callback, error) { | ||
return this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + id | ||
return this.ajax('/' + this.apiVersion + '/sobjects/' + objtype + '/' + id | ||
+ '?_HttpMethod=PATCH', callback, error, "POST", JSON.stringify(fields)); | ||
@@ -612,3 +591,3 @@ } | ||
/* | ||
* Deletes a record of the given type. Unfortunately, 'delete' is a | ||
* Deletes a record of the given type. Unfortunately, 'delete' is a | ||
* reserved word in JavaScript. | ||
@@ -627,3 +606,3 @@ * @param objtype object type; e.g. "Account" | ||
* Executes the specified SOQL query. | ||
* @param soql a string containing the query to execute - e.g. "SELECT Id, | ||
* @param soql a string containing the query to execute - e.g. "SELECT Id, | ||
* Name from Account ORDER BY Name LIMIT 20" | ||
@@ -634,6 +613,6 @@ * @param callback function to which response will be passed | ||
forcetk.Client.prototype.query = function(soql, callback, error) { | ||
return this.ajax('/' + this.apiVersion + '/query?q=' + escape(soql) | ||
return this.ajax('/' + this.apiVersion + '/query?q=' + encodeURI(soql) | ||
, callback, error); | ||
} | ||
/* | ||
@@ -644,3 +623,3 @@ * Queries the next set of records based on pagination. | ||
* <p>Ex: forcetkClient.queryMore( successResponse.nextRecordsUrl, successHandler, failureHandler )</p> | ||
* | ||
* | ||
* @param url - the url retrieved from nextRecordsUrl or prevRecordsUrl | ||
@@ -651,10 +630,2 @@ * @param callback function to which response will be passed | ||
forcetk.Client.prototype.queryMore = function( url, callback, error ){ | ||
//-- ajax call adds on services/data to the url call, so only send the url after | ||
var serviceData = "services/data"; | ||
var index = url.indexOf( serviceData ); | ||
if( index > -1 ){ | ||
url = url.substr( index + serviceData.length ); | ||
} else { | ||
//-- leave alone | ||
} | ||
return this.ajax( url, callback, error ); | ||
@@ -665,3 +636,3 @@ } | ||
* Executes the specified SOSL search. | ||
* @param sosl a string containing the search to execute - e.g. "FIND | ||
* @param sosl a string containing the search to execute - e.g. "FIND | ||
* {needle}" | ||
@@ -672,5 +643,150 @@ * @param callback function to which response will be passed | ||
forcetk.Client.prototype.search = function(sosl, callback, error) { | ||
return this.ajax('/' + this.apiVersion + '/search?q=' + escape(sosl) | ||
return this.ajax('/' + this.apiVersion + '/search?q=' + encodeURI(sosl) | ||
, callback, error); | ||
} | ||
} | ||
/* | ||
* Returns a page from the list of files owned by the specified user | ||
* @param userId a user id or 'me' - when null uses current user | ||
* @param page page number - when null fetches first page | ||
* @param callback function to which response will be passed | ||
* @param [error=null] function to which jqXHR will be passed in case of error | ||
*/ | ||
forcetk.Client.prototype.ownedFilesList = function(userId, page, callback, error) { | ||
return this.ajax('/' + this.apiVersion + '/chatter/users/' + (userId == null ? 'me' : userId) + '/files' + (page != null ? '?page=' + page : '') | ||
, callback, error); | ||
} | ||
/* | ||
* Returns a page from the list of files from groups that the specified user is a member of | ||
* @param userId a user id or 'me' - when null uses current user | ||
* @param page page number - when null fetches first page | ||
* @param callback function to which response will be passed | ||
* @param [error=null] function to which jqXHR will be passed in case of error | ||
*/ | ||
forcetk.Client.prototype.filesInUsersGroups = function(userId, page, callback, error) { | ||
return this.ajax('/' + this.apiVersion + '/chatter/users/' + (userId == null ? 'me' : userId) + '/files/filter/groups' + (page != null ? '?page=' + page : '') | ||
, callback, error); | ||
} | ||
/* | ||
* Returns a page from the list of files shared with the specified user | ||
* @param userId a user id or 'me' - when null uses current user | ||
* @param page page number - when null fetches first page | ||
* @param callback function to which response will be passed | ||
* @param [error=null] function to which jqXHR will be passed in case of error | ||
*/ | ||
forcetk.Client.prototype.filesSharedWithUser = function(userId, page, callback, error) { | ||
return this.ajax('/' + this.apiVersion + '/chatter/users/' + (userId == null ? 'me' : userId) + '/files/filter/sharedwithme' + (page != null ? '?page=' + page : '') | ||
, callback, error); | ||
} | ||
/* | ||
* Returns file details | ||
* @param fileId file's Id | ||
* @param version - when null fetches details of most recent version | ||
* @param callback function to which response will be passed | ||
* @param [error=null] function to which jqXHR will be passed in case of error | ||
*/ | ||
forcetk.Client.prototype.fileDetails = function(fileId, version, callback, error) { | ||
return this.ajax('/' + this.apiVersion + '/chatter/files/' + fileId + (version != null ? '?versionNumber=' + version : '') | ||
, callback, error); | ||
} | ||
/* | ||
* Returns file details for multiple files | ||
* @param fileIds file ids | ||
* @param callback function to which response will be passed | ||
* @param [error=null] function to which jqXHR will be passed in case of error | ||
*/ | ||
forcetk.Client.prototype.batchFileDetails = function(fileIds, callback, error) { | ||
return this.ajax('/' + this.apiVersion + '/chatter/files/batch/' + fileIds.join(',') | ||
, callback, error); | ||
} | ||
/* | ||
* Returns file rendition | ||
* @param fileId file's Id | ||
* @param version - when null fetches details of most recent version | ||
* @param rentidionType - FLASH, PDF, THUMB120BY90, THUMB240BY180, THUMB720BY480 | ||
* @param page page number - when null fetches first page | ||
* @param callback function to which response will be passed | ||
* @param [error=null] function to which jqXHR will be passed in case of error | ||
*/ | ||
forcetk.Client.prototype.fileRendition = function(fileId, version, renditionType, page, callback, error) { | ||
var mimeType = (renditionType == "FLASH" ? "application/x-shockwave-flash" : (renditionType == "PDF" ? "application/pdf" : "image/jpeg")); | ||
return this.getChatterFile(this.fileRenditionPath(fileId, version, renditionType, page) | ||
, mimeType , callback, error); | ||
} | ||
/* | ||
* Returns file rendition path (relative to service/data) - from html (e.g. img tag), use the bearer token url instead | ||
* @param fileId file's Id | ||
* @param version - when null fetches details of most recent version | ||
* @param rentidionType - FLASH, PDF, THUMB120BY90, THUMB240BY180, THUMB720BY480 | ||
* @param page page number - when null fetches first page | ||
*/ | ||
forcetk.Client.prototype.fileRenditionPath = function(fileId, version, renditionType, page) { | ||
return '/' + this.apiVersion + '/chatter/files/' + fileId + '/rendition?type=' + renditionType + (version != null ? '&versionNumber=' + version : '') + (page != null ? '&page=' + page : ''); | ||
} | ||
/* | ||
* Returns file content | ||
* @param fileId file's Id | ||
* @param version - when null fetches details of most recent version | ||
* @param callback function to which response will be passed | ||
* @param [error=null] function to which jqXHR will be passed in case of error | ||
*/ | ||
forcetk.Client.prototype.fileContents = function(fileId, version, callback, error) { | ||
var mimeType = null; // we don't know | ||
return this.getChatterFile(this.fileContentsPath(fileId, version) | ||
, mimeType , callback, error); | ||
} | ||
/* | ||
* Returns file content path (relative to service/data) - from html (e.g. img tag), use the bearer token url instead | ||
* @param fileId file's Id | ||
* @param version - when null fetches details of most recent version | ||
*/ | ||
forcetk.Client.prototype.fileContentsPath = function(fileId, version) { | ||
return '/' + this.apiVersion + '/chatter/files/' + fileId + '/content' + (version != null ? '?versionNumber=' + version : ''); | ||
} | ||
/** | ||
* Returns a page from the list of entities that this file is shared to | ||
* | ||
* @param fileId file's Id | ||
* @param page page number - when null fetches first page | ||
* @param callback function to which response will be passed | ||
* @param [error=null] function to which jqXHR will be passed in case of error | ||
*/ | ||
forcetk.Client.prototype.fileShares = function(fileId, page, callback, error) { | ||
return this.ajax('/' + this.apiVersion + '/chatter/files/' + fileId + '/file-shares' + (page != null ? '?page=' + page : '') | ||
, callback, error); | ||
} | ||
/** | ||
* Adds a file share for the specified fileId to the specified entityId | ||
* | ||
* @param fileId file's Id | ||
* @param entityId Id of the entity to share the file to (e.g. a user or a group) | ||
* @param shareType the type of share (V - View, C - Collaboration) | ||
* @param callback function to which response will be passed | ||
* @param [error=null] function to which jqXHR will be passed in case of error | ||
*/ | ||
forcetk.Client.prototype.addFileShare = function(fileId, entityId, shareType, callback, error) { | ||
return this.create("ContentDocumentLink", {ContentDocumentId:fileId, LinkedEntityId:entityId, ShareType:shareType}, callback, error); | ||
} | ||
/** | ||
* Deletes the specified file share. | ||
* @param shareId Id of the file share record (aka ContentDocumentLink) | ||
* @param callback function to which response will be passed | ||
* @param [error=null] function to which jqXHR will be passed in case of error | ||
*/ | ||
forcetk.Client.prototype.deleteFileShare = function(sharedId, callback, error) { | ||
return this.del("ContentDocumentLink", sharedId, callback, error); | ||
} | ||
}}) | ||
.call(this, jQuery); |
@@ -59,8 +59,12 @@ # Salesforce.com Mobile SDK Shared | ||
HTML/CSS/JavaScript used by SmartStore Explorer application. | ||
HTML/CSS/JavaScript used by SmartStoreExplorer application. | ||
**vfconnector** | ||
Contains bootconfig.json for VF Connector application. | ||
Contains bootconfig.json for VFConnector application. | ||
**fileexplorer** | ||
HTML/CSS/JavaScript used by HybridFileExplorer application. | ||
# /test | ||
@@ -67,0 +71,0 @@ |
@@ -9,3 +9,4 @@ { | ||
"shouldAuthenticate": true, | ||
"attemptOfflineLoad": false | ||
"attemptOfflineLoad": false, | ||
"androidPushNotificationClientId": "" | ||
} |
@@ -9,3 +9,4 @@ { | ||
"shouldAuthenticate": true, | ||
"attemptOfflineLoad": false | ||
"attemptOfflineLoad": false, | ||
"androidPushNotificationClientId": "" | ||
} |
@@ -18,3 +18,2 @@ // Creating the application namespace | ||
var sdkLikeUserAgent = "SalesforceMobileSDK/2.0 " + partialNavigatorUserAgent + " AccountEditor/1.0 Hybrid" | ||
// Use when testing in browser | ||
@@ -25,3 +24,3 @@ // Also make sure to start browser with same origin policy disable | ||
accessToken: "--will-be-obtained-by-refresh--", | ||
refreshToken: "5Aep861KIwKdekr90KsESmRP6soKuBrQlSV5iTuNdX6UHGbZnbEUug1hvYnrlDYmYFX.g2AaD7vtQ==", | ||
refreshToken: "5Aep861KIwKdekr90KlxVVUI47zdR6dX_VeBWZBgUZuRVDPRFwP3_geyRbJwFUPW7ud7qOkj0jFr70NO7eQVfsP", | ||
clientId: "3MVG9Iu66FKeHhINkB1l7xt7kR8czFcCTUhgoA8Ol2Ltf1eYHOU4SqQRSEitYFDUpqRWcoQ2.dBv_a1Dyu5xa", | ||
@@ -39,3 +38,3 @@ loginUrl: "https://test.salesforce.com", | ||
// Force init | ||
Force.init(creds, null, null, cordova.require("salesforce/plugin/oauth").forcetkRefresh); | ||
Force.init(creds); | ||
@@ -42,0 +41,0 @@ // router |
@@ -9,3 +9,4 @@ { | ||
"shouldAuthenticate": true, | ||
"attemptOfflineLoad": true | ||
"attemptOfflineLoad": true, | ||
"androidPushNotificationClientId": "" | ||
} |
@@ -9,3 +9,4 @@ { | ||
"shouldAuthenticate": true, | ||
"attemptOfflineLoad": false | ||
"attemptOfflineLoad": false, | ||
"androidPushNotificationClientId": "" | ||
} |
@@ -9,3 +9,4 @@ { | ||
"shouldAuthenticate": true, | ||
"attemptOfflineLoad": false | ||
"attemptOfflineLoad": false, | ||
"androidPushNotificationClientId": "" | ||
} |
@@ -48,3 +48,3 @@ /* | ||
cordova.interceptExec(SDKINFO_SERVICE, "getInfo", function (successCB, errorCB, args) { | ||
successCB(new SDKInfo("2.0.0", | ||
successCB(new SDKInfo("2.1.0", | ||
["com.salesforce.oauth", "com.salesforce.sdkinfo", "com.salesforce.testrunner", "com.salesforce.smartstore"], | ||
@@ -51,0 +51,0 @@ "ForcePluginsTest", "1.0")); |
@@ -39,2 +39,3 @@ /* | ||
SFTestSuite.call(this, "forcetk"); | ||
this.apiVersion = "v29.0"; | ||
}; | ||
@@ -112,12 +113,205 @@ | ||
/** | ||
* TEST ownedFilesList | ||
*/ | ||
ForcetkTestSuite.prototype.testOwnedFilesList = function() { | ||
console.log("In SFForcetkTestSuite.testOwnedFilesList"); | ||
var forcetkClient = this.getTestForcetkClientForGet(); | ||
QUnit.equals(forcetkClient.ownedFilesList(), "/" + this.apiVersion + "/chatter/users/me/files"); | ||
QUnit.equals(forcetkClient.ownedFilesList("me"), "/" + this.apiVersion + "/chatter/users/me/files"); | ||
QUnit.equals(forcetkClient.ownedFilesList("someUserId"), "/" + this.apiVersion + "/chatter/users/someUserId/files"); | ||
QUnit.equals(forcetkClient.ownedFilesList(null, 1), "/" + this.apiVersion + "/chatter/users/me/files?page=1"); | ||
QUnit.equals(forcetkClient.ownedFilesList("me", 2), "/" + this.apiVersion + "/chatter/users/me/files?page=2"); | ||
QUnit.equals(forcetkClient.ownedFilesList("someUserId", 3), "/" + this.apiVersion + "/chatter/users/someUserId/files?page=3"); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* TEST filesInUsersGroups | ||
*/ | ||
ForcetkTestSuite.prototype.testFilesInUsersGroups = function() { | ||
console.log("In SFForcetkTestSuite.testFilesInUsersGroups"); | ||
var forcetkClient = this.getTestForcetkClientForGet(); | ||
QUnit.equals(forcetkClient.filesInUsersGroups(), "/" + this.apiVersion + "/chatter/users/me/files/filter/groups"); | ||
QUnit.equals(forcetkClient.filesInUsersGroups("me"), "/" + this.apiVersion + "/chatter/users/me/files/filter/groups"); | ||
QUnit.equals(forcetkClient.filesInUsersGroups("someUserId"), "/" + this.apiVersion + "/chatter/users/someUserId/files/filter/groups"); | ||
QUnit.equals(forcetkClient.filesInUsersGroups(null, 1), "/" + this.apiVersion + "/chatter/users/me/files/filter/groups?page=1"); | ||
QUnit.equals(forcetkClient.filesInUsersGroups("me", 2), "/" + this.apiVersion + "/chatter/users/me/files/filter/groups?page=2"); | ||
QUnit.equals(forcetkClient.filesInUsersGroups("someUserId", 3), "/" + this.apiVersion + "/chatter/users/someUserId/files/filter/groups?page=3"); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* TEST filesSharedWithUser | ||
*/ | ||
ForcetkTestSuite.prototype.testFilesSharedWithUser = function() { | ||
console.log("In SFForcetkTestSuite.testFilesInUsersGroups"); | ||
var forcetkClient = this.getTestForcetkClientForGet(); | ||
QUnit.equals(forcetkClient.filesSharedWithUser(), "/" + this.apiVersion + "/chatter/users/me/files/filter/sharedwithme"); | ||
QUnit.equals(forcetkClient.filesSharedWithUser("me"), "/" + this.apiVersion + "/chatter/users/me/files/filter/sharedwithme"); | ||
QUnit.equals(forcetkClient.filesSharedWithUser("someUserId"), "/" + this.apiVersion + "/chatter/users/someUserId/files/filter/sharedwithme"); | ||
QUnit.equals(forcetkClient.filesSharedWithUser(null, 1), "/" + this.apiVersion + "/chatter/users/me/files/filter/sharedwithme?page=1"); | ||
QUnit.equals(forcetkClient.filesSharedWithUser("me", 2), "/" + this.apiVersion + "/chatter/users/me/files/filter/sharedwithme?page=2"); | ||
QUnit.equals(forcetkClient.filesSharedWithUser("someUserId", 3), "/" + this.apiVersion + "/chatter/users/someUserId/files/filter/sharedwithme?page=3"); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* TEST fileDetails | ||
*/ | ||
ForcetkTestSuite.prototype.testFileDetails = function() { | ||
console.log("In SFForcetkTestSuite.testFileDetails"); | ||
var forcetkClient = this.getTestForcetkClientForGet(); | ||
QUnit.equals(forcetkClient.fileDetails("someFileId"), "/" + this.apiVersion + "/chatter/files/someFileId"); | ||
QUnit.equals(forcetkClient.fileDetails("someFileId", "someVersionNumber"), "/" + this.apiVersion + "/chatter/files/someFileId?versionNumber=someVersionNumber"); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* TEST batchFileDetails | ||
*/ | ||
ForcetkTestSuite.prototype.testBatchFileDetails = function() { | ||
console.log("In SFForcetkTestSuite.testBatchFileDetails"); | ||
var forcetkClient = this.getTestForcetkClientForGet(); | ||
QUnit.equals(forcetkClient.batchFileDetails(["someFileId"]), "/" + this.apiVersion + "/chatter/files/batch/someFileId"); | ||
QUnit.equals(forcetkClient.batchFileDetails(["someFileId", "otherFileId"]), "/" + this.apiVersion + "/chatter/files/batch/someFileId,otherFileId"); | ||
QUnit.equals(forcetkClient.batchFileDetails(["someFileId", "otherFileId", "thirdFileId"]), "/" + this.apiVersion + "/chatter/files/batch/someFileId,otherFileId,thirdFileId"); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* TEST fileRenditionPath | ||
*/ | ||
ForcetkTestSuite.prototype.testFileRenditionPath = function() { | ||
console.log("In SFForcetkTestSuite.testFileRenditionPath"); | ||
var forcetkClient = this.getTestForcetkClientForBinary(); | ||
// only rendition type provided | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", null, "FLASH"), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=FLASH"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", null, "PDF"), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=PDF"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", null, "THUMB120BY90"), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB120BY90"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", null, "THUMB240BY180"), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB240BY180"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", null, "THUMB720BY480"), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB720BY480"); | ||
// rendition type and version provided | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", "someVersionNumber", "FLASH"), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=FLASH&versionNumber=someVersionNumber"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", "someVersionNumber", "PDF"), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=PDF&versionNumber=someVersionNumber"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", "someVersionNumber", "THUMB120BY90"), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB120BY90&versionNumber=someVersionNumber"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", "someVersionNumber", "THUMB240BY180"), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB240BY180&versionNumber=someVersionNumber"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", "someVersionNumber", "THUMB720BY480"), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB720BY480&versionNumber=someVersionNumber"); | ||
// rendition type and page number provided | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", null, "FLASH", 3), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=FLASH&page=3"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", null, "PDF", 3), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=PDF&page=3"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", null, "THUMB120BY90", 3), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB120BY90&page=3"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", null, "THUMB240BY180", 3), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB240BY180&page=3"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", null, "THUMB720BY480", 3), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB720BY480&page=3"); | ||
// rendition type, version and page number provided | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", "someVersionNumber", "FLASH", 3), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=FLASH&versionNumber=someVersionNumber&page=3"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", "someVersionNumber", "PDF", 3), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=PDF&versionNumber=someVersionNumber&page=3"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", "someVersionNumber", "THUMB120BY90", 3), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB120BY90&versionNumber=someVersionNumber&page=3"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", "someVersionNumber", "THUMB240BY180", 3), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB240BY180&versionNumber=someVersionNumber&page=3"); | ||
QUnit.equals(forcetkClient.fileRenditionPath("someFileId", "someVersionNumber", "THUMB720BY480", 3), "/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB720BY480&versionNumber=someVersionNumber&page=3"); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* TEST fileRendition | ||
*/ | ||
ForcetkTestSuite.prototype.testFileRendition = function() { | ||
console.log("In SFForcetkTestSuite.testFileRendition"); | ||
var forcetkClient = this.getTestForcetkClientForBinary(); | ||
// only rendition type provided | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", null, "FLASH"), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=FLASH", "application/x-shockwave-flash"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", null, "PDF"), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=PDF", "application/pdf"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", null, "THUMB120BY90"), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB120BY90", "image/jpeg"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", null, "THUMB240BY180"), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB240BY180", "image/jpeg"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", null, "THUMB720BY480"), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB720BY480", "image/jpeg"]); | ||
// rendition type and version provided | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", "someVersionNumber", "FLASH"), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=FLASH&versionNumber=someVersionNumber", "application/x-shockwave-flash"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", "someVersionNumber", "PDF"), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=PDF&versionNumber=someVersionNumber", "application/pdf"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", "someVersionNumber", "THUMB120BY90"), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB120BY90&versionNumber=someVersionNumber", "image/jpeg"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", "someVersionNumber", "THUMB240BY180"), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB240BY180&versionNumber=someVersionNumber", "image/jpeg"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", "someVersionNumber", "THUMB720BY480"), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB720BY480&versionNumber=someVersionNumber", "image/jpeg"]); | ||
// rendition type and page number provided | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", null, "FLASH", 3), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=FLASH&page=3", "application/x-shockwave-flash"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", null, "PDF", 3), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=PDF&page=3", "application/pdf"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", null, "THUMB120BY90", 3), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB120BY90&page=3", "image/jpeg"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", null, "THUMB240BY180", 3), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB240BY180&page=3", "image/jpeg"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", null, "THUMB720BY480", 3), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB720BY480&page=3", "image/jpeg"]); | ||
// rendition type, version and page number provided | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", "someVersionNumber", "FLASH", 3), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=FLASH&versionNumber=someVersionNumber&page=3", "application/x-shockwave-flash"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", "someVersionNumber", "PDF", 3), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=PDF&versionNumber=someVersionNumber&page=3", "application/pdf"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", "someVersionNumber", "THUMB120BY90", 3), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB120BY90&versionNumber=someVersionNumber&page=3", "image/jpeg"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", "someVersionNumber", "THUMB240BY180", 3), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB240BY180&versionNumber=someVersionNumber&page=3", "image/jpeg"]); | ||
QUnit.deepEqual(forcetkClient.fileRendition("someFileId", "someVersionNumber", "THUMB720BY480", 3), ["/" + this.apiVersion + "/chatter/files/someFileId/rendition?type=THUMB720BY480&versionNumber=someVersionNumber&page=3", "image/jpeg"]); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* TEST fileContentsPath | ||
*/ | ||
ForcetkTestSuite.prototype.testFileContentsPath = function() { | ||
console.log("In SFForcetkTestSuite.testFileContentsPath"); | ||
var forcetkClient = this.getTestForcetkClientForBinary(); | ||
QUnit.equals(forcetkClient.fileContentsPath("someFileId"), "/" + this.apiVersion + "/chatter/files/someFileId/content"); | ||
QUnit.deepEqual(forcetkClient.fileContentsPath("someFileId", "someVersionNumber"), "/" + this.apiVersion + "/chatter/files/someFileId/content?versionNumber=someVersionNumber"); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* TEST fileContents | ||
*/ | ||
ForcetkTestSuite.prototype.testFileContents = function() { | ||
console.log("In SFForcetkTestSuite.testFileContents"); | ||
var forcetkClient = this.getTestForcetkClientForBinary(); | ||
QUnit.deepEqual(forcetkClient.fileContents("someFileId"), ["/" + this.apiVersion + "/chatter/files/someFileId/content", null]); | ||
QUnit.deepEqual(forcetkClient.fileContents("someFileId", "someVersionNumber"), ["/" + this.apiVersion + "/chatter/files/someFileId/content?versionNumber=someVersionNumber", null]); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* TEST fileShares | ||
*/ | ||
ForcetkTestSuite.prototype.testFileShares = function() { | ||
console.log("In SFForcetkTestSuite.testFileShares"); | ||
var forcetkClient = this.getTestForcetkClientForGet(); | ||
QUnit.equals(forcetkClient.fileShares("fileId"), "/" + this.apiVersion + "/chatter/files/fileId/file-shares"); | ||
QUnit.equals(forcetkClient.fileShares("fileId", 2), "/" + this.apiVersion + "/chatter/files/fileId/file-shares?page=2"); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* TEST addFileShare | ||
*/ | ||
ForcetkTestSuite.prototype.testAddFileShare = function() { | ||
console.log("In SFForcetkTestSuite.testAddFileShare"); | ||
var forcetkClient = this.getTestForcetkClient(); | ||
QUnit.deepEqual(forcetkClient.addFileShare("fileId", "entityId", "shareType"), {path:"/" + this.apiVersion + "/sobjects/ContentDocumentLink/", method:"POST", payload:'{"ContentDocumentId":"fileId","LinkedEntityId":"entityId","ShareType":"shareType"}'}); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* TEST deleteFileShare | ||
*/ | ||
ForcetkTestSuite.prototype.testDeleteFileShare = function() { | ||
console.log("In SFForcetkTestSuite.testDeleteFileShare"); | ||
var forcetkClient = this.getTestForcetkClient(); | ||
QUnit.deepEqual(forcetkClient.deleteFileShare("shareId"), {path:"/" + this.apiVersion + "/sobjects/ContentDocumentLink/shareId", method:"DELETE", payload: undefined}); | ||
this.finalizeTest(); | ||
}; | ||
/** | ||
* Helper function for user agent testing | ||
*/ | ||
ForcetkTestSuite.prototype.tryUserAgent = function(expectedPlatform, expectedPlatformVersion, expectedModel, userAgent) { | ||
var forcetkClient = new forcetk.Client(); | ||
var webAppSdkAgent = forcetkClient.computeWebAppSdkAgent(userAgent); | ||
var match = /SalesforceMobileSDK\/2.0.0 ([^\/]*)\/([^\ ]*) \(([^\)]*)\) test.html\/1.0 Web (.*)/.exec(webAppSdkAgent); | ||
if (match != null && match.length == 5) { | ||
var match = /SalesforceMobileSDK\/2.1.0 ([^\/]*)\/([^\ ]*) \(([^\)]*)\) ([^\/]*)\/1.0 Web (.*)/.exec(webAppSdkAgent); | ||
if (match != null && match.length == 6) { | ||
QUnit.equals(match[1], expectedPlatform, "Wrong platform for user agent [" + userAgent + "]"); | ||
QUnit.equals(match[2], expectedPlatformVersion, "Wrong platformVersion for user agent [" + userAgent + "]"); | ||
QUnit.equals(match[3], expectedModel, "Wrong model for user agent [" + userAgent + "]"); | ||
QUnit.equals(match[4], userAgent, "Wrong user agent appended for user agent [" + userAgent + "]"); | ||
QUnit.equals(match[4], window.location.pathname.split("/").pop(), "Wrong appName for user agent [" + userAgent + "]"); | ||
QUnit.equals(match[5], userAgent, "Wrong user agent appended for user agent [" + userAgent + "]"); | ||
} | ||
@@ -129,4 +323,33 @@ else { | ||
/** | ||
* Helper function to get a forcetk client that doesn't actually send requests | ||
*/ | ||
ForcetkTestSuite.prototype.getTestForcetkClient = function() { | ||
var forcetkClient = new forcetk.Client(); | ||
forcetkClient.apiVersion = this.apiVersion; | ||
forcetkClient.ajax = function(path, callback, error, method, payload) { return {path:path, method:method, payload:payload}; } | ||
return forcetkClient; | ||
}; | ||
/** | ||
* Helper function to get a forcetk client that doesn't actually send requests when testing get requests | ||
*/ | ||
ForcetkTestSuite.prototype.getTestForcetkClientForGet = function() { | ||
var forcetkClient = new forcetk.Client(); | ||
forcetkClient.apiVersion = this.apiVersion; | ||
forcetkClient.ajax = function(path) { return path; } | ||
return forcetkClient; | ||
}; | ||
/** | ||
* Helper function to get a forcetk client that doesn't actually send requests when testing requests that fetch binary | ||
*/ | ||
ForcetkTestSuite.prototype.getTestForcetkClientForBinary = function() { | ||
var forcetkClient = new forcetk.Client(); | ||
forcetkClient.apiVersion = this.apiVersion; | ||
forcetkClient.getChatterFile = function(path, mimeType) { return [path, mimeType]; } | ||
return forcetkClient; | ||
}; | ||
} | ||
@@ -60,3 +60,3 @@ /* | ||
.done(function(sdkInfo) { | ||
QUnit.ok(sdkInfo.sdkVersion.indexOf("2.0") == 0, "expected different sdk version"); | ||
QUnit.ok(sdkInfo.sdkVersion.indexOf("2.1") == 0, "expected different sdk version"); | ||
QUnit.ok(sdkInfo.appName == "HybridPluginTestApp" || sdkInfo.appName == "ForcePluginsTest", "expected different app name"); | ||
@@ -63,0 +63,0 @@ QUnit.equal(sdkInfo.appVersion, "1.0", "expected different app version"); |
@@ -28,3 +28,3 @@ /* | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "2.0.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "2.1.0"; | ||
@@ -31,0 +31,0 @@ cordova.define("salesforce/plugin/testrunner", function(require, exports, module) { |
{ | ||
"name": "forceios", | ||
"version": "2.0.5", | ||
"version": "2.1.0", | ||
"description": "Utilities for creating mobile apps based on the Salesforce Mobile SDK for iOS", | ||
@@ -23,2 +23,2 @@ "keywords": [ "mobilesdk", "ios", "salesforce", "mobile", "sdk" ], | ||
] | ||
} | ||
} |
@@ -41,2 +41,11 @@ # Salesforce Mobile SDK for iOS Package | ||
OR | ||
forceios version | ||
OR | ||
forceios samples | ||
--outputDir=<Output directory to copy the samples into> | ||
**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,2 +77,6 @@ | ||
### forceios samples options | ||
**Output Directory:** The output directory where you want the samples to be copied. | ||
## More information | ||
@@ -70,0 +83,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
555
19980
85
5
42578728