Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 5f830b5
Showing
16 changed files
with
354 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules | ||
.env | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: node app.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# node-nforce-demo | ||
|
||
Simple node.js application for CRUDing salesforce.com Accounts using nforce and async. | ||
|
||
## Installation Instructions | ||
|
||
From the command line type in: | ||
|
||
``` | ||
npm install | ||
``` | ||
|
||
|
||
### Node Module Dependencies | ||
|
||
These will be automatically installed when you use any of the above *npm* installation methods above. | ||
|
||
1. [express](http://expressjs.com/) - framework | ||
2. [nforce](https://github.com/kevinohara80/nforce) - REST wrapper for force.com | ||
3. [async](https://github.com/caolan/async/) - asynchronous utility module | ||
4. [jade](http://jade-lang.com/) - the view engine | ||
|
||
### Running the Application Locally | ||
|
||
1. Open terminal and change directory to node-nforce-demo root | ||
2. `node app.js` | ||
3. Point your browser to: [http://localhost:3001](http://localhost:3001) | ||
|
||
### Deploying to Heroku | ||
|
||
``` | ||
heroku create | ||
heroku config:add CLIENT_ID=YOUR-SALESFORCE-CLIENT-ID | ||
heroku config:add CLIENT_SECRET=YOUR-SALESFORCE-SECRET | ||
heroku config:add USERNAME=YOUR-SALESFORCE-USERNAME | ||
heroku config:add PASSWORD=YOUR-SALESFORCE-PASSWORD-AND-TOKEN | ||
heroku open | ||
``` | ||
|
||
### Demo on Heroku | ||
|
||
This application is running on heroku at: [http://node-nforce-demo.herokuapp.com/](http://node-nforce-demo.herokuapp.com/) | ||
|
||
## Contributors | ||
* Jeff Douglas -> [jeffdonthemic](https://github.com/jeffdonthemic) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
var express = require('express'); | ||
var path = require('path'); | ||
var favicon = require('serve-favicon'); | ||
var logger = require('morgan'); | ||
var cookieParser = require('cookie-parser'); | ||
var bodyParser = require('body-parser'); | ||
var async = require('async'); | ||
var nforce = require('nforce'); | ||
|
||
var app = express(); | ||
app.set('port', process.env.PORT || 3000); | ||
|
||
// use the nforce package to create a connection to salesforce.com | ||
var org = nforce.createConnection({ | ||
clientId: process.env.CLIENT_ID, | ||
clientSecret: process.env.CLIENT_SECRET, | ||
redirectUri: 'http://localhost:' + app.get('port') + '/oauth/_callback', | ||
mode: 'single' | ||
}); | ||
|
||
// authenticate using username-password oauth flow | ||
org.authenticate({ username: process.env.USERNAME, password: process.env.PASSWORD }, function(err, resp){ | ||
if(err) { | ||
console.log('Error: ' + err.message); | ||
} else { | ||
console.log('Successfully connected to salesforce'); | ||
console.log('Access Token: ' + resp.access_token); | ||
oauth = resp; | ||
} | ||
}); | ||
|
||
// view engine setup | ||
app.set('views', path.join(__dirname, 'views')); | ||
app.set('view engine', 'jade'); | ||
|
||
// uncomment after placing your favicon in /public | ||
//app.use(favicon(__dirname + '/public/favicon.ico')); | ||
app.use(logger('dev')); | ||
app.use(bodyParser.json()); | ||
app.use(bodyParser.urlencoded({ extended: false })); | ||
app.use(cookieParser()); | ||
app.use(express.static(path.join(__dirname, 'public'))); | ||
|
||
app.get('/', function(req, res) { | ||
res.render('index', { title: 'Express' }); | ||
}); | ||
|
||
// display a list of 10 accounts | ||
app.get('/accounts', function(req, res) { | ||
var q = 'select id, name from account limit 10'; | ||
org.query({ query: q }, function(err, resp){ | ||
res.render("accounts", { title: 'Accounts', data: resp.records } ); | ||
}); | ||
}); | ||
|
||
// display form to create a new account | ||
app.get('/accounts/new', function(req, res) { | ||
// call describe to dynamically generate the form fields | ||
org.getDescribe({type: 'Account'}, function(err, resp) { | ||
res.render('new', { title: 'New Account', data: resp }); | ||
}); | ||
}); | ||
|
||
// create the account in salesforce | ||
app.post('/accounts/create', function(req, res) { | ||
var obj = nforce.createSObject('Account', req.body); | ||
org.insert({sobject: obj}, function(err, resp){ | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
if (resp.success === true) { | ||
res.redirect('/accounts/'+resp.id); | ||
res.end(); | ||
} | ||
} | ||
}); | ||
}); | ||
|
||
// display the account | ||
app.get('/accounts/:id', function(req, res) { | ||
var async = require('async'); | ||
var obj = nforce.createSObject('Account', {id: req.params.id}); | ||
|
||
async.parallel([ | ||
function(callback){ | ||
var q = "select count() from contact where accountid = '" + req.params.id + "'"; | ||
org.query({query: q}, function(err, resp){ | ||
callback(null, resp); | ||
}); | ||
}, | ||
function(callback){ | ||
org.getRecord({sobject: obj}, function(err, resp) { | ||
callback(null, resp); | ||
}); | ||
}, | ||
], | ||
// optional callback | ||
function(err, results){ | ||
// returns the responses in an array | ||
res.render('show', { title: 'Account Details', data: results }); | ||
}); | ||
|
||
}); | ||
|
||
// display form to update an existing account | ||
app.get('/accounts/:id/edit', function(req, res) { | ||
var obj = nforce.createSObject('Account', {id: req.params.id}); | ||
org.getRecord({sobject: obj}, function(err, resp) { | ||
res.render('edit', { title: 'Edit Account', data: resp }); | ||
}); | ||
}); | ||
|
||
// update the account in salesforce | ||
app.post('/accounts/:id/update', function(req, res) { | ||
var obj = nforce.createSObject('Account', req.body); | ||
org.update({sobject: obj}, function(results) { | ||
res.redirect('/accounts/'+req.params.id); | ||
res.end(); | ||
}); | ||
}); | ||
|
||
// catch 404 and forward to error handler | ||
app.use(function(req, res, next) { | ||
var err = new Error('Not Found'); | ||
err.status = 404; | ||
next(err); | ||
}); | ||
|
||
// error handlers | ||
|
||
// development error handler | ||
// will print stacktrace | ||
if (app.get('env') === 'development') { | ||
app.use(function(err, req, res, next) { | ||
res.status(err.status || 500); | ||
res.render('error', { | ||
message: err.message, | ||
error: err | ||
}); | ||
}); | ||
} | ||
|
||
// production error handler | ||
// no stacktraces leaked to user | ||
app.use(function(err, req, res, next) { | ||
res.status(err.status || 500); | ||
res.render('error', { | ||
message: err.message, | ||
error: {} | ||
}); | ||
}); | ||
|
||
var server = app.listen(app.get('port'), function() { | ||
console.log('Express server listening on port ' + server.address().port); | ||
}); | ||
|
||
module.exports = app; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"name": "NodeJS Demo for Saleforce with nforce and async", | ||
"description": "Simple node.js application for CRUDing salesforce.com Accounts using nforce and async.", | ||
"repository": "https://github.com/jeffdonthemic/node-nforce-demo", | ||
"logo": "", | ||
"keywords": ["node", "salesforce", "nforce"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"name": "node-nforce-demo", | ||
"version": "0.0.1", | ||
"private": true, | ||
"scripts": { | ||
"start": "node app.js" | ||
}, | ||
"engines": { | ||
"node": "0.10.x" | ||
}, | ||
"dependencies": { | ||
"express": "~4.9.0", | ||
"body-parser": "~1.8.1", | ||
"cookie-parser": "~1.3.3", | ||
"morgan": "~1.3.0", | ||
"serve-favicon": "~2.1.3", | ||
"debug": "~2.0.0", | ||
"jade": "~1.6.0", | ||
"nforce": "0.10.0", | ||
"async": "*" | ||
} | ||
} |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
body { | ||
padding: 50px; | ||
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; | ||
} | ||
|
||
a { | ||
color: #00B7FF; | ||
} | ||
|
||
.info, .success, .warning, .error, .validation { | ||
border: 1px solid; | ||
margin: 10px 0px; | ||
padding:15px 10px 15px 50px; | ||
background-repeat: no-repeat; | ||
background-position: 10px center; | ||
} | ||
.info { | ||
color: #00529B; | ||
background-color: #BDE5F8; | ||
background-image: url('info.png'); | ||
} | ||
.success { | ||
color: #4F8A10; | ||
background-color: #DFF2BF; | ||
background-image:url('success.png'); | ||
} | ||
.warning { | ||
color: #9F6000; | ||
background-color: #FEEFB3; | ||
background-image: url('warning.png'); | ||
} | ||
.error { | ||
color: #D8000C; | ||
background-color: #FFBABA; | ||
background-image: url('error.png'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
var express = require('express'); | ||
var router = express.Router(); | ||
|
||
/* GET home page. */ | ||
router.get('/', function(req, res) { | ||
res.render('index', { title: 'Express' }); | ||
}); | ||
|
||
module.exports = router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
extends layout | ||
|
||
block content | ||
|
||
h1= title | ||
a(href='/accounts/new') Create a new Account | ||
p Existing Accounts | ||
ul | ||
each item in data | ||
li: a(href='/accounts/#{item.getId()}') #{item.get('Name')} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
extends layout | ||
|
||
block content | ||
|
||
// form fields to be displayed | ||
- var formFields = ['name','billingcity']; | ||
h1= title | ||
form(method='post', action='/accounts/#{data.getId()}/update') | ||
input(name='id', value='#{data.getId()}', type='hidden') | ||
each val, key in data._fields | ||
- if (formFields.indexOf(key) != -1) | ||
div | ||
label #{key}: | ||
input(name='#{key}', value=val || '', type='text') | ||
div | ||
input(type='submit', value='Save') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
extends layout | ||
|
||
block content | ||
h1= message | ||
h2= error.status | ||
pre #{error.stack} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
extends layout | ||
|
||
block content | ||
h1= title | ||
p This is a simple node.js application for CRUDing salesforce.com Accounts using the nforce package and async. | ||
ul | ||
li: a(href='/accounts') Get a list of 10 Accounts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
doctype html | ||
html | ||
head | ||
title= title | ||
link(rel='stylesheet', href='/stylesheets/style.css') | ||
body | ||
block content |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
extends layout | ||
|
||
block content | ||
|
||
// generate a form based upon metadata & display the following field | ||
- var formFields = ['Name','BillingCity']; | ||
h1= title | ||
form(method='post', action='/accounts/create') | ||
each field in data.fields | ||
- if (formFields.indexOf(field.name) != -1) | ||
div | ||
label #{field.label}: | ||
input(name='#{field.name}', value='', type='text') | ||
div | ||
input(type='submit', value='Save') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
extends layout | ||
|
||
block content | ||
|
||
// fields NOT to be displayed | ||
- var skipFields = ['attributes','isdeleted','setexternalid']; | ||
h1= title | ||
p Number of contacts: #{data[0].totalSize} | ||
a(href='/accounts/#{data[1].getId()}/edit') Edit this record | ||
ul | ||
each val, key in data[1]._fields | ||
- if (skipFields.indexOf(key) == -1) | ||
li #{key}: #{val} |