Skip to content

Commit 529b37e

Browse files
Merge pull request #4 from redvanworkshop/feature/live-reload
Feature - Adds support for Browser Extension
2 parents e14f22e + 77110c6 commit 529b37e

24 files changed

+1232
-45
lines changed

.eslintrc.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module.exports = {
77
env: {
88
es6: true,
99
node: true,
10-
browser: false
10+
browser: true
1111
},
1212
plugins: [
1313
'prettier'
@@ -35,5 +35,8 @@ module.exports = {
3535
}
3636
],
3737
'no-console': 0
38+
},
39+
globals: {
40+
'io': true
3841
}
3942
}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.DS_Store
22
node_modules
33
npm-debug.log
4+
remote/ssl/sfcc-cli-localhost.*

README.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ SFCC CLI
55

66
> Command Line Interface for Salesforce Commerce Cloud Sandbox Development
77
8-
![demo](https://sfcc-cli.s3.amazonaws.com/watch.gif)
9-
![demo](https://sfcc-cli.s3.amazonaws.com/log.gif)
8+
![demo](https://sfcc-cli.s3.amazonaws.com/demo.gif)
9+
1010

1111
Introduction
1212
---
@@ -15,7 +15,10 @@ Make developing for Salesforce Commerce Cloud work with any IDE on MacOS, Window
1515

1616
- [X] Easily Manage Multiple Clients & Instances
1717
- [X] Watch for code changes and upload in background ( without being prompted for passwords )
18+
- [X] Support for Eclipse Build Processes
1819
- [X] Log Viewing with Advanced Search & Filter Capabilities
20+
- [X] SFCC CLI integration via [Browser Extension](https://github.com/redvanworkshop/sfcc-remote)
21+
1922

2023
Developer Overview
2124
---
@@ -27,6 +30,7 @@ Developer Overview
2730
* [`sfcc delete`](docs/cmd-delete.md) - Delete Config for Client
2831
* [`sfcc watch`](docs/cmd-watch.md) - Watch for Changes and Push Updates
2932
* [`sfcc log`](docs/cmd-log.md) - View Logs with Advanced Search & Filter Capabilities
33+
* [`sfcc remote`](docs/cmd-remote.md) - Remote Control for your Sandbox Storefront
3034
* [`sfcc help`](docs/cmd-help.md) - Get Help when you need it
3135

3236
#### Additional Information
@@ -38,20 +42,20 @@ Developer Overview
3842
Install
3943
---
4044

41-
#### Install via Clone
45+
#### Install via NPM
4246

4347
```bash
44-
cd ~
45-
git clone https://github.com/redvanworkshop/sfcc-cli.git
46-
cd sfcc-cli
47-
npm install -g
48+
npm install -g sfcc-cli --no-optional
4849
sfcc setup
4950
```
5051

51-
#### Install via NPM
52+
#### Install via Clone
5253

5354
```bash
54-
npm install -g sfcc-cli
55+
cd ~
56+
git clone https://github.com/redvanworkshop/sfcc-cli.git
57+
cd sfcc-cli
58+
npm install -g --no-optional
5559
sfcc setup
5660
```
5761

bin/cli.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ const argv = yargs
4747
})
4848
.command('list', 'List Configured SFCC Clients')
4949
.command('delete <client> [instance]', 'Delete Config for Client')
50-
.command('watch [client] [instance]', 'Watch for Code Changes and Push Updates', {
50+
.command('watch [client] [instance]', 'Watch for Changes and Push Updates', {
5151
log: {
52-
describe: 'Pipe Output to Log File ~/.sffc-cli.log',
52+
describe: 'Pipe Output to ~/.sffc-cli.log',
5353
type: 'boolean',
5454
default: false
5555
},
@@ -112,9 +112,17 @@ const argv = yargs
112112
default: false
113113
}
114114
})
115+
.command('remote [client] [instance]', 'Enable Support for Browser Extension')
116+
.example('sfcc setup', 'Setup SFCC Development')
117+
.example('sfcc list', 'List Configured SFCC Clients')
115118
.example('sfcc delete my-client sandbox', 'Delete my-client sandbox config')
116119
.example('sfcc watch my-client sandbox', 'Watch for my-client sandbox changes')
117120
.example('sfcc log -i customerror --latest', 'Watch Latest Custom Error Logs')
121+
.example('sfcc remote', 'Live Reload Sandbox Storefront on Changes')
122+
.example(' ', ' ')
123+
.example('----------------------------------', '------------------------------------------')
124+
.example('NEED MORE HELP ?', 'https://bit.ly/sfcc-cli-help')
125+
.example('----------------------------------', '------------------------------------------')
118126
.demand(1)
119127
.help()
120128
.version().argv

commands/delete.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ module.exports = async () => {
3232
}
3333

3434
if (found) {
35+
console.log('')
3536
const prompt = new confirm('Confirm Delete?')
3637
prompt.ask(function(confirmed) {
3738
if (confirmed) {

commands/log.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ const keys = require('lodash/keys')
66
const pickBy = require('lodash/pickBy')
77
const sortBy = require('lodash/sortBy')
88

9+
const config = require('../lib/config')()
910
const find = require('../lib/find')
1011
const search = require('../lib/search')
1112
const tail = require('../lib/tail')
12-
const config = require('../lib/config')()
1313

1414
module.exports = async options => {
1515
let client = argv['_'][1] || null
@@ -98,7 +98,9 @@ module.exports = async options => {
9898

9999
try {
100100
// Start log output
101-
options.search ? search(selected, groups, options) : tail(selected, logs, groups, options)
101+
options.search
102+
? search(selected, client, instance, groups, options)
103+
: tail(selected, client, instance, logs, groups, options)
102104
} catch (err) {
103105
console.log(err)
104106
}

commands/remote.js

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
const argv = require('minimist')(process.argv.slice(2))
2+
const chalk = require('chalk')
3+
const express = require('express')
4+
const fs = require('fs')
5+
const https = require('https')
6+
const ipc = require('node-ipc')
7+
const ora = require('ora')
8+
const path = require('path')
9+
10+
const config = require('../lib/config')()
11+
12+
const port = 8443
13+
14+
module.exports = async () => {
15+
let client = argv['_'][1] || null
16+
let instance = argv['_'][2] || null
17+
let selected = null
18+
let remote
19+
let spinner
20+
21+
const output = fn => {
22+
spinner.stop()
23+
fn()
24+
spinner.start()
25+
}
26+
27+
// Get Client & Instance, or check for Default
28+
if (client && instance) {
29+
selected = config.get(client, instance)
30+
} else {
31+
const defaultConfig = config.get(client, instance, true)
32+
33+
if (defaultConfig) {
34+
client = defaultConfig.client
35+
instance = defaultConfig.instance
36+
selected = defaultConfig.config
37+
}
38+
}
39+
40+
if (selected) {
41+
const sslKey = path.resolve(__dirname, '../remote/ssl/sfcc-cli-ca.pvk')
42+
const sslCrt = path.resolve(__dirname, '../remote/ssl/sfcc-cli-ca.cer')
43+
44+
// Start Message Bus
45+
ipc.config.id = 'remote'
46+
ipc.config.retry = 1500
47+
ipc.config.silent = true
48+
ipc.serve(() => {
49+
ipc.server.on('message', data => {
50+
if (remote && typeof remote.emit !== 'undefined') {
51+
remote.emit('message', data)
52+
} else {
53+
output(() => console.log(chalk.red.bold(`✖ Failed Remote Message`, data)))
54+
}
55+
})
56+
ipc.server.on('watch', data => {
57+
if (remote && typeof remote.emit !== 'undefined') {
58+
remote.emit('watch', data)
59+
} else {
60+
output(() => console.log(chalk.red.bold(`✖ Failed Remote Watch`, data)))
61+
}
62+
})
63+
ipc.server.on('log', data => {
64+
if (remote && typeof remote.emit !== 'undefined') {
65+
remote.emit('log', data)
66+
} else {
67+
output(() => console.log(chalk.red.bold(`✖ Failed Remote Log`, data)))
68+
}
69+
})
70+
})
71+
72+
ipc.server.start()
73+
74+
// Check that SSL files exist
75+
if (!fs.existsSync(sslKey)) {
76+
console.log(chalk.red.bold(`✖ Missing ${sslKey}`))
77+
console.log('See ./docs/cmd-remote.md for setup instructions.')
78+
process.exit()
79+
}
80+
81+
if (!fs.existsSync(sslCrt)) {
82+
console.log(chalk.red.bold(`✖ Missing ${sslCrt}`))
83+
console.log('See ./docs/cmd-remote.md for setup instructions.')
84+
process.exit()
85+
}
86+
87+
// Start Socket Server
88+
const app = express()
89+
const server = https.createServer(
90+
{
91+
key: fs.readFileSync(sslKey),
92+
cert: fs.readFileSync(sslCrt)
93+
},
94+
app
95+
)
96+
97+
const io = require('socket.io')(server)
98+
99+
// Handle connections from remote script
100+
io.on('connection', socket => {
101+
remote = socket
102+
103+
socket.on('message', message => {
104+
console.log('MESSAGE', message)
105+
})
106+
107+
socket.on('get-config', () => {
108+
io.emit('set-config', config.getAll())
109+
})
110+
})
111+
112+
server.listen(port, function() {
113+
spinner = ora(
114+
`${chalk.bold('REMOTE')} ${chalk.cyan.bold(client)} ${chalk.magenta.bold(instance)} [Ctrl-C to Cancel]\n`
115+
).start()
116+
})
117+
}
118+
}

commands/setup.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
const argv = require('minimist')(process.argv.slice(2))
22
const chalk = require('chalk')
33
const fs = require('fs')
4+
const path = require('path')
45
const prompt = require('prompt')
56
const slug = require('slug')
67

7-
const config = require('../lib/config')()
88
const builds = require('../lib/builds')
9+
const config = require('../lib/config')()
910

1011
module.exports = async () => {
1112
const setDefaults =
@@ -29,6 +30,9 @@ module.exports = async () => {
2930
prompt.delimiter = ''
3031
prompt.override = argv
3132

33+
// Intentional Blank Line
34+
console.log('')
35+
3236
prompt.start()
3337
prompt.get(
3438
[
@@ -85,6 +89,7 @@ module.exports = async () => {
8589
required: true,
8690
message: 'Directory does not exist. ( e.g. /Users/RVW/Projects/mysandbox )',
8791
conform: function(directory) {
92+
directory = path.normalize(path.resolve(directory.replace(/^\/[a-z]\//, '/')))
8893
return fs.existsSync(directory)
8994
}
9095
},
@@ -130,22 +135,26 @@ module.exports = async () => {
130135
newConfig[client] = {}
131136
}
132137

138+
const directory = path.normalize(path.resolve(result.d.replace(/^\/[a-z]\//, '/')))
139+
133140
// Fetch Build Scripts from Project Directory
134-
const builders = builds(result.d)
141+
const builders = builds(directory)
135142

136143
// Create / Overwrite SFCC Instance for Client
137144
newConfig[client][alias] = {
138145
h: result.h,
139146
v: result.v,
140147
a: result.a,
141-
d: result.d,
148+
d: directory,
142149
u: result.u,
143150
p: result.p,
144151
b: builders
145152
}
146153

147154
// Write Config File
148155
config.set(newConfig, isUpdate)
156+
157+
process.exit()
149158
}
150159
}
151160
)

0 commit comments

Comments
 (0)