This repository has been archived by the owner on Mar 10, 2024. It is now read-only.
forked from amtrack/sfdx-browserforce-plugin
-
Notifications
You must be signed in to change notification settings - Fork 1
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
buildbot
committed
Sep 30, 2023
1 parent
092b743
commit a37fb5f
Showing
8 changed files
with
1,361 additions
and
1,378 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
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 |
---|---|---|
@@ -1,8 +1,7 @@ | ||
# sfdx-browserforce-plugin | ||
# @dxatscale/browserforce | ||
|
||
> sfdx plugin for browser automation | ||
> sf plugin for browser automation | ||
[![Actions Status](https://github.com/amtrack/sfdx-browserforce-plugin/workflows/Test%20and%20Release/badge.svg)](https://github.com/amtrack/sfdx-browserforce-plugin/actions) | ||
|
||
Unlike the [Scratch Org Definition Configuration](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file.htm) which can only be used **on the creation of a scratch org** (`sfdx force:org:create -f config/scratch-def.json`), | ||
the _Browserforce Configuration_ allows to "shape" **any org**, (e.g. scratch org, sandbox or production org) with **similar preferences and unofficial preferences** that are not (yet) available in the _Scratch Org Definition Configuration_ or as _Metadata_ (`sfdx browserforce:apply -f config/setup-admin-login-as-any.json -u [email protected]`). | ||
|
@@ -20,13 +19,8 @@ There are several different methods to install `sfdx-browserforce-plugin`: | |
|
||
```console | ||
# as an sfdx plugin globally | ||
sfdx plugins:install sfdx-browserforce-plugin | ||
sf plugins:install @dxatscale/browserforce | ||
|
||
# or standalone globally | ||
npm install --global sfdx-browserforce-plugin | ||
|
||
# or standalone locally (as a dependency in your Node.js project) | ||
npm install --save-dev sfdx-browserforce-plugin | ||
``` | ||
|
||
# Usage | ||
|
@@ -35,21 +29,16 @@ Depending on your choice of installation, you can find the `browserforce` namesp | |
|
||
```console | ||
# globally in the sfdx cli | ||
sfdx browserforce | ||
|
||
# globally in the sfdx-browserforce-plugin executable | ||
sfdx-browserforce-plugin browserforce | ||
sf browserforce --help | ||
|
||
# locally in the sfdx-browserforce-plugin executable (npx is awesome!) | ||
npx sfdx-browserforce-plugin browserforce | ||
``` | ||
|
||
```console | ||
$ sfdx-browserforce browserforce -h | ||
$ sf browserforce --help | ||
browser automation | ||
|
||
USAGE | ||
$ sfdx-browserforce-plugin browserforce:COMMAND | ||
$ sf browserforce:COMMAND | ||
|
||
COMMANDS | ||
browserforce:apply apply a plan from a definition file | ||
|
@@ -173,4 +162,4 @@ Please see [CONTRIBUTING.md](CONTRIBUTING.md) for getting started. | |
|
||
# License | ||
|
||
MIT © [Matthias Rolke](mailto:[email protected]) | ||
MIT © [dxatscale](@dxatscale) |
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 |
---|---|---|
@@ -1,20 +1,26 @@ | ||
{ | ||
"name": "sfdx-browserforce-plugin", | ||
"version": "0.0.0-development", | ||
"name": "@dxatscale/browserforce", | ||
"version": "0.0.2", | ||
"description": "sfdx plugin for browser automation", | ||
"author": "Matthias Rolke <[email protected]>", | ||
"author": "dxatscale", | ||
"bin": { | ||
"sfdx-browserforce-plugin": "bin/run" | ||
"browserforce": "bin/run" | ||
}, | ||
"dependencies": { | ||
"@mdapi-issues/listmetadata-standardvalueset": "2.0.3", | ||
"@salesforce/command": "5.2.16", | ||
"@oclif/core": "2.11.8", | ||
"@oclif/plugin-help": "5.2.17", | ||
"@salesforce/core": "^5.2.7", | ||
"@salesforce/kit": "^3.0.9", | ||
"@salesforce/sf-plugins-core": "^3.1.22", | ||
"json-merge-patch": "1.0.2", | ||
"p-retry": "4.6.2", | ||
"puppeteer": "19.2.0", | ||
"tslib": "2.4.0" | ||
}, | ||
"devDependencies": { | ||
"@salesforce/ts-types": "2.0.5", | ||
"@salesforce/dev-config": "^4.0.1", | ||
"@types/mocha": "10.0.1", | ||
"@types/node": "18.16.8", | ||
"mocha": "10.2.0", | ||
|
@@ -24,7 +30,7 @@ | |
"typescript": "5.0.4" | ||
}, | ||
"engines": { | ||
"node": ">=14.0.0" | ||
"node": ">=18.0.0" | ||
}, | ||
"files": [ | ||
"/bin", | ||
|
@@ -39,7 +45,7 @@ | |
], | ||
"license": "MIT", | ||
"oclif": { | ||
"bin": "sfdx-browserforce-plugin", | ||
"bin": "browserforce", | ||
"commands": "./lib/commands", | ||
"topics": { | ||
"browserforce": { | ||
|
@@ -50,7 +56,8 @@ | |
"-h" | ||
] | ||
}, | ||
"repository": "amtrack/sfdx-browserforce-plugin", | ||
"publishConfig": { "access": "public" }, | ||
"repository": "dxatscale/browserforce", | ||
"scripts": { | ||
"build": "rm -rf lib && tsc -p . && oclif manifest", | ||
"develop": "bash scripts/develop.sh", | ||
|
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 |
---|---|---|
@@ -1,70 +1,81 @@ | ||
import { flags, SfdxCommand } from '@salesforce/command'; | ||
import { Messages } from '@salesforce/core'; | ||
import { Messages, } from '@salesforce/core'; | ||
import { SfCommand } from '@salesforce/sf-plugins-core'; | ||
import { promises } from 'fs'; | ||
import * as path from 'path'; | ||
import { Browserforce } from './browserforce'; | ||
import { ConfigParser } from './config-parser'; | ||
import * as DRIVERS from './plugins'; | ||
import { ux } from '@oclif/core'; | ||
import { Flags } from '@salesforce/sf-plugins-core'; | ||
|
||
Messages.importMessagesDirectory(__dirname); | ||
const messages = Messages.loadMessages( | ||
'sfdx-browserforce-plugin', | ||
'@dxatscale/browserforce', | ||
'browserforce' | ||
); | ||
|
||
export class BrowserforceCommand extends SfdxCommand { | ||
export class BrowserforceCommand extends SfCommand<void> { | ||
protected static requiresUsername = true; | ||
|
||
protected static flagsConfig = { | ||
definitionfile: flags.string({ | ||
public static readonly flags: { [key: string]: any } = { | ||
'target-org': Flags.requiredOrg( | ||
{ | ||
char: 'o', | ||
} | ||
), | ||
definitionfile: Flags.string({ | ||
char: 'f', | ||
description: messages.getMessage('definitionFileDescription') | ||
}), | ||
planfile: flags.string({ | ||
planfile: Flags.string({ | ||
char: 'p', | ||
name: 'plan', | ||
description: messages.getMessage('planFileDescription') | ||
}), | ||
statefile: flags.string({ | ||
statefile: Flags.string({ | ||
char: 's', | ||
name: 'state', | ||
description: messages.getMessage('stateFileDescription') | ||
}) | ||
|
||
}; | ||
|
||
|
||
|
||
protected bf: Browserforce; | ||
protected settings: any[]; | ||
|
||
public async init(): Promise<void> { | ||
await super.init(); | ||
const { flags } = await this.parse(BrowserforceCommand); | ||
const definitionFileData = await promises.readFile( | ||
path.resolve(this.flags.definitionfile), | ||
path.resolve(flags.definitionfile), | ||
'utf8' | ||
); | ||
let definition; | ||
try { | ||
definition = JSON.parse(definitionFileData); | ||
definition = JSON.parse(definitionFileData); | ||
} catch (err) { | ||
throw new Error('Failed parsing definitionfile'); | ||
} | ||
// TODO: use require.resolve to dynamically load plugins from npm packages | ||
this.settings = ConfigParser.parse(DRIVERS, definition); | ||
this.bf = new Browserforce(this.org, this.ux); | ||
this.ux.startSpinner('logging in'); | ||
this.bf = new Browserforce(flags['target-org'], ux); | ||
this.spinner.start('logging in'); | ||
await this.bf.login(); | ||
this.ux.stopSpinner(); | ||
this.spinner.stop(); | ||
} | ||
|
||
public async run(): Promise<unknown> { | ||
public async run(): Promise<void> { | ||
throw new Error('BrowserforceCommand should not be run directly'); | ||
} | ||
|
||
public async finally(err: Error): Promise<void> { | ||
this.ux.stopSpinner(); | ||
this.spinner.stop(); | ||
if (this.bf) { | ||
this.ux.startSpinner('logging out'); | ||
this.spinner.start('logging out'); | ||
await this.bf.logout(); | ||
this.ux.stopSpinner(); | ||
this.spinner.stop(); | ||
} | ||
} | ||
} |
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 |
---|---|---|
@@ -1,17 +1,43 @@ | ||
import { Messages } from '@salesforce/core'; | ||
import { BrowserforceCommand } from '../../browserforce-command'; | ||
import { Flags } from '@salesforce/sf-plugins-core'; | ||
import { ux } from '@oclif/core'; | ||
|
||
Messages.importMessagesDirectory(__dirname); | ||
const messages = Messages.loadMessages( | ||
'sfdx-browserforce-plugin', | ||
'@dxatscale/browserforce', | ||
'browserforce' | ||
); | ||
|
||
export default class BrowserforceApply extends BrowserforceCommand { | ||
public static description = messages.getMessage('applyCommandDescription'); | ||
|
||
|
||
public static readonly flags: { [key: string]: any } = { | ||
'target-org': Flags.requiredOrg( | ||
{ | ||
char: 'o', | ||
} | ||
), | ||
definitionfile: Flags.string({ | ||
char: 'f', | ||
description: messages.getMessage('definitionFileDescription') | ||
}), | ||
planfile: Flags.string({ | ||
char: 'p', | ||
name: 'plan', | ||
description: messages.getMessage('planFileDescription') | ||
}), | ||
statefile: Flags.string({ | ||
char: 's', | ||
name: 'state', | ||
description: messages.getMessage('stateFileDescription') | ||
}) | ||
|
||
}; | ||
|
||
public static examples = [ | ||
`$ sfdx browserforce:apply -f ./config/setup-admin-login-as-any.json --targetusername [email protected] | ||
`$ sf browserforce:apply -f ./config/setup-admin-login-as-any.json --targetusername [email protected] | ||
logging in... done | ||
Applying definition file ./config/setup-admin-login-as-any.json to org [email protected] | ||
[Security] retrieving state... done | ||
|
@@ -20,28 +46,30 @@ export default class BrowserforceApply extends BrowserforceCommand { | |
` | ||
]; | ||
|
||
public async run(): Promise<unknown> { | ||
this.ux.log( | ||
public async run(): Promise<any> { | ||
const { flags } = await this.parse(BrowserforceApply); | ||
|
||
ux.log( | ||
`Applying definition file ${ | ||
this.flags.definitionfile | ||
} to org ${this.org.getUsername()}` | ||
flags.definitionfile | ||
} to org ${flags['target-org'].getUsername()}` | ||
); | ||
for (const setting of this.settings) { | ||
const driver = setting.Driver; | ||
const instance = new driver(this.bf, this.org); | ||
this.ux.startSpinner(`[${driver.name}] retrieving state`); | ||
const instance = new driver(this.bf, flags['target-org']); | ||
this.spinner.start(`[${driver.name}] retrieving state`); | ||
let state; | ||
try { | ||
state = await instance.retrieve(setting.value); | ||
} catch (err) { | ||
this.ux.stopSpinner('failed'); | ||
this.spinner.stop('failed'); | ||
throw err; | ||
} | ||
this.ux.stopSpinner(); | ||
this.spinner.stop(); | ||
const action = instance.diff(state, setting.value); | ||
this.ux.stopSpinner(); | ||
this.spinner.stop(); | ||
if (action && Object.keys(action).length) { | ||
this.ux.startSpinner( | ||
this.spinner.start( | ||
`[${driver.name}] ${Object.keys(action) | ||
.map((key) => { | ||
return `changing '${key}' to '${JSON.stringify(action[key])}'`; | ||
|
@@ -51,12 +79,12 @@ export default class BrowserforceApply extends BrowserforceCommand { | |
try { | ||
await instance.apply(action); | ||
} catch (err) { | ||
this.ux.stopSpinner('failed'); | ||
this.spinner.stop('failed'); | ||
throw err; | ||
} | ||
this.ux.stopSpinner(); | ||
this.spinner.stop(); | ||
} else { | ||
this.ux.log(`[${driver.name}] no action necessary`); | ||
ux.log(`[${driver.name}] no action necessary`); | ||
} | ||
} | ||
return { success: true }; | ||
|
Oops, something went wrong.