Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 25 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,29 @@ Dev Pack for Salesforce is a collection of useful VS Code extensions for Salesfo

## Included Extensions

- [Salesforce Extension Pack](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode)
- [Salesforce Apex](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-apex)
- [Salesforce Lightning Web Components](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-lwc)
- [Salesforce SOQL](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-soql)
- [Salesforce Core](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-core)
- [Agentforce for Developers](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-einstein-gpt)
- [Markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)
- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
- [VSCode Icons](https://marketplace.visualstudio.com/items?itemName=vscode-icons-team.vscode-icons)
- [One Dark Pro Theme](https://marketplace.visualstudio.com/items?itemName=zhuangtongfa.Material-theme)
- [Better Comments](https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments)
- [Indent Rainbow](https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow)
- [Apex Log Analyzer](https://marketplace.visualstudio.com/items?itemName=financialforce.lana)
- [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
- [Lightning Flow Scanner](https://marketplace.visualstudio.com/items?itemName=ForceConfigControl.lightningflowscanner)
- [Salesforce Code Analyzer](https://marketplace.visualstudio.com/items?itemName=salesforce.sfdx-code-analyzer-vscode)
- [Log File Highlighter](https://marketplace.visualstudio.com/items?itemName=emilast.LogFileHighlighter)
- [Salesforce Extension Pack](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-expanded)
- [Salesforce CLI Integration](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-core) - This extension (salesforcedx-vscode-core) interacts with Salesforce CLI to provide core functionality.
- [Salesforce Apex](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-apex) - This extension (salesforcedx-vscode-apex) uses the Apex Language Server to provide features such as syntax highlighting and code completion.
- [Apex Interactive Debugger](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-apex-debugger) - This extension (salesforcedx-vscode-apex-debugger) enables VS Code to use the real-time Apex Debugger with your scratch orgs or to use ISV Customer Debugger for your subscribers’ orgs.
- [Apex Replay Debugger](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-apex-replay-debugger) - This extension (salesforcedx-vscode-apex-replay-debugger) enables VS Code to replay Apex execution from Apex debug logs.
- [Salesforce Lightning Web Components](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-lwc) - This extension supports Lightning web component bundles. It uses the HTML language server from VS Code.
- [Aura Components](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-lightning) - This extension (salesforcedx-vscode-lightning) supports Aura component bundles. It uses the HTML language server from VS Code.
- [Visualforce](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-visualforce) - This extension (salesforcedx-vscode-visualforce) supports Visualforce pages and components. It uses the Visualforce Language Server and the HTML language server from VS Code.
- [SOQL](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-soql) - This extension (salesforcedx-vscode-soql) enables you to interactively build a SOQL query via a form-based visual editor, view the query as you build, and save the output to a .csv or .json file.
- [Salesforce Lightning Design System (SLDS) Validator](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-slds) - This extension (salesforcedx-vscode-slds) simplifies working with the Salesforce Lightning Design System (SLDS). It provides code completion, syntax highlighting, and validation with recommended tokens and utility classes.
- [Agentforce for Developers](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-einstein-gpt) - This extension (salesforcedx-einstein-gpt) uses generative AI to make Salesforce development in Visual Studio Code richer with features such as natural language to code generation, inline autocompletion for Apex and LWC code, and test case generation for Apex classes.
- [Salesforce Code Analyzer](https://marketplace.visualstudio.com/items?itemName=salesforce.sfdx-code-analyzer-vscode) - This extension (sfdx-code-analyzer-vscode) scans your code using multiple rule engines to produce lists of violations that you can use to improve your code.
- [Apex Log Analyzer](https://marketplace.visualstudio.com/items?itemName=financialforce.lana) - This extension helps you analyze Apex logs.
- [One Dark Pro Theme](https://marketplace.visualstudio.com/items?itemName=zhuangtongfa.Material-theme) - A popular dark theme for Visual Studio Code.
- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) - An opinionated code formatter that enforces a consistent style.
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - Integrates ESLint JavaScript into VS Code.
- [VSCode Icons](https://marketplace.visualstudio.com/items?itemName=vscode-icons-team.vscode-icons) - Adds icons to the Visual Studio Code editor.
- [Better Comments](https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments) - Improves your comment annotations with different colors.
- [Indent Rainbow](https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow) - Makes indentation levels more readable with color coding.
- [Markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) - Provides Markdown linting and style checking.
- [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) - A basic spell checker that works well with code.
- [Lightning Flow Scanner](https://marketplace.visualstudio.com/items?itemName=ForceConfigControl.lightningflowscanner) - Scans and validates Salesforce Lightning Flows.
- [Log File Highlighter](https://marketplace.visualstudio.com/items?itemName=emilast.LogFileHighlighter) - Highlights log files to make them easier to read.

## Installation

Expand All @@ -46,7 +51,8 @@ This setup is only done the first time the extension is installed. Feel free to

## Automatic Package Detection and Installation

Dev Pack for Salesforce automatically detects and prompts you to install the following required npm packages if they are not already installed:
The Dev Pack for Salesforce simplifies and automates the setup of your developer environment. Upon installation, the pack automatically detects and installs required npm packages, as long as Node.js is installed in your system. The required npm packages include:


- `@salesforce/cli`
- `prettier`
Expand Down
Binary file removed dev-pack-salesforce-1.0.9.vsix
Binary file not shown.
17 changes: 10 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "dev-pack-salesforce",
"displayName": "Dev Pack for Salesforce",
"description": "A collection of useful VS Code extensions for Salesforce development",
"version": "1.0.9",
"version": "1.1.0",
"publisher": "avidev9",
"scripts": {
"package": "npx vsce package"
Expand All @@ -24,20 +24,18 @@
],
"main": "./src/extension.js",
"extensionPack": [
"salesforce.salesforcedx-vscode",
"salesforce.salesforcedx-einstein-gpt",
"salesforce.salesforcedx-vscode-expanded",
"davidanson.vscode-markdownlint",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"vscode-icons-team.vscode-icons",
"zhuangtongfa.material-theme",
"aaron-bond.better-comments",
"oderwat.indent-rainbow",
"financialforce.lana",
"streetsidesoftware.code-spell-checker",
"ForceConfigControl.lightningflowscanner",
"salesforce.sfdx-code-analyzer-vscode",
"emilast.LogFileHighlighter"
"ForceConfigControl.lightning-flow-scanner-vsx",
"emilast.LogFileHighlighter",
"usernamehw.errorlens"
],
"repository": {
"type": "git",
Expand Down Expand Up @@ -78,6 +76,11 @@
"command": "dev-pack-salesforce.updateBetterCommentsSettings",
"title": "Dev Pack for Salesforce: Update better comments settings",
"shortTitle": "Update better comments settings"
},
{
"command": "dev-pack-salesforce.deleteApexLogs",
"title": "Dev Pack for Salesforce: Delete all apex logs",
"shortTitle": "Delete all apex logs"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const vscode = require("vscode");
const { EXTENSION_NAME, BETTER_COMMENTS_TAG } = require("../utils/constants");
const { BETTER_COMMENTS_TAG } = require("../utils/constants");
const CommonUtils = require("../utils/CommonUtils");

class BetterComments {
static updateSettings() {
Expand All @@ -9,8 +10,8 @@ class BetterComments {
BETTER_COMMENTS_TAG,
vscode.ConfigurationTarget.Global
);
vscode.window.showInformationMessage(
`${EXTENSION_NAME}: Updated Better Comments settings globally.`
CommonUtils.showInformationMessage(
"Updated Better Comments settings globally."
);
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/commands/ForceCheckPackages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const vscode = require("vscode");
const NodePackageManager = require("./NodePackageManager");
const CommonUtils = require("../utils/CommonUtils");

class ForceCheckPackages {
static async checkPackages(context) {
CommonUtils.showInformationMessage(
"Checking and installing required packages and plugins..."
);
context.globalState.update("dev-pack-salesforce.packages-checked", false);
context.globalState.update("dev-pack-salesforce.sf-plugins-checked", false);
await NodePackageManager.managePackages(context);
}
}

module.exports = ForceCheckPackages;
111 changes: 111 additions & 0 deletions src/commands/NodePackageManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
const vscode = require("vscode");
const { EXTENSION_NAME, REQUIRED_PACKAGES } = require("../utils/constants");
const SfdxScannerInstaller = require("./SfdxScannerInstaller");
const CommonUtils = require("../utils/CommonUtils");

class NodePackageManager {
static async managePackages(context) {
try {
await this.checkNodeInstallation();
const missingPackages = await this.checkRequiredPackages(context);
if (missingPackages.length > 0) {
const userConfirmed = await CommonUtils.promptForConfirmation(
`The following node packages will be installed globally: ${missingPackages.join(
", "
)}. Do you want to proceed?`
);
if (userConfirmed) {
await this.installMissingPackages(missingPackages);
} else {
return; // Exit if user doesn't confirm package installation
}
}
// Only install SF plugins after ensuring @salesforce/cli is installed
await SfdxScannerInstaller.install(context);
} catch (error) {
vscode.window.showErrorMessage(error);
}
}

static async checkNodeInstallation() {
try {
await CommonUtils.execCommand("node -v");
} catch (error) {
throw new Error(
`${EXTENSION_NAME}: Node.js is not installed. Please install Node.js to use this extension.`
);
}
}

static async checkRequiredPackages(context) {
try {
const packagesToCheck = REQUIRED_PACKAGES;
const stdout = await CommonUtils.execCommand(
`npm list -g ${packagesToCheck.join(" ")}`
);

if (!context.globalState.get("dev-pack-salesforce.packages-checked")) {
CommonUtils.showInformationMessage(
"Required packages are already installed."
);
context.globalState.update(
"dev-pack-salesforce.packages-checked",
true
);
}

const missingPackages = this.getMissingPackages(stdout, packagesToCheck);
return missingPackages;
} catch (error) {
const stdout = error.message;
const missingPackages = this.getMissingPackages(
stdout,
REQUIRED_PACKAGES
);
if (missingPackages.length === 0) {
if (!context.globalState.get("dev-pack-salesforce.packages-checked")) {
CommonUtils.showInformationMessage(
"All required packages are already installed."
);
context.globalState.update(
"dev-pack-salesforce.packages-checked",
true
);
}
}
return missingPackages;
}
}

static getMissingPackages(stdout, packagesToInstall) {
const missingPackages = packagesToInstall.filter(
(pkg) => !stdout.includes(pkg)
);
const hasPrettierPluginApex = stdout.includes("prettier-plugin-apex");
const hasIlyamatsuevPrettierPluginApex = stdout.includes(
"@ilyamatsuev/prettier-plugin-apex"
);

if (!hasPrettierPluginApex && !hasIlyamatsuevPrettierPluginApex) {
missingPackages.push("prettier-plugin-apex");
}

return missingPackages;
}

static async installMissingPackages(missingPackages) {
try {
const installCommand = `npm install -g ${missingPackages.join(" ")}`;
await CommonUtils.execCommand(installCommand);
CommonUtils.showInformationMessage(
`Successfully installed npm packages: ${missingPackages.join(", ")}`
);
} catch (error) {
throw new Error(
`${EXTENSION_NAME}: Failed to install npm packages: ${error.message}`
);
}
}
}

module.exports = NodePackageManager;
46 changes: 46 additions & 0 deletions src/commands/Sfdx.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const vscode = require("vscode");
const CommonUtils = require("../utils/CommonUtils");
const { EXTENSION_NAME } = require("../utils/constants");

const apexLogFileName = "apexlog-out.csv";

class Sfdx {
static async deleteApexLogs() {
await vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
title: "Deleting Apex Logs",
cancellable: false,
},
async (progress) => {
try {
progress.report({ message: "Querying ApexLog IDs..." });
// Step 1: Query ApexLog IDs and save to apexlog-out.csv
await CommonUtils.execCommand(
`sf data query -q "SELECT Id FROM ApexLog" -r "csv" > ${apexLogFileName}`
);

progress.report({ message: "Deleting ApexLogs..." });
// Step 2: Delete ApexLogs using the apexlog-out.csv file
await CommonUtils.execCommand(
`sf data delete bulk --sobject ApexLog --file ${apexLogFileName} --wait 1000`
);

CommonUtils.showInformationMessage(
"Successfully deleted all Apex logs."
);

// Step 3: Delete the apexlog-out.csv file using vscode API
const file = vscode.Uri.file(apexLogFileName);
await vscode.workspace.fs.delete(file);
} catch (error) {
vscode.window.showErrorMessage(
`${EXTENSION_NAME}: Failed to delete Apex logs: ${error.message}`
);
}
}
);
}
}

module.exports = Sfdx;
72 changes: 72 additions & 0 deletions src/commands/SfdxScannerInstaller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const vscode = require("vscode");
const CommonUtils = require("../utils/CommonUtils");

class SfdxScannerInstaller {
static async install(context) {
try {
// Check if sf command is available
await this.verifySfCliInstalled();

const plugins = await CommonUtils.execCommand("sf plugins");
const pluginsToInstall = [];

if (!plugins.includes("@salesforce/sfdx-scanner")) {
pluginsToInstall.push("@salesforce/sfdx-scanner");
}

if (!plugins.includes("code-analyzer")) {
pluginsToInstall.push("code-analyzer");
}

if (pluginsToInstall.length > 0) {
const userConfirmed = await CommonUtils.promptForConfirmation(
`The following SF plugins will be installed: ${pluginsToInstall.join(
", "
)}. Do you want to proceed?`
);
if (userConfirmed) {
await this.installPlugins(pluginsToInstall);
}
} else {
if (
!context.globalState.get("dev-pack-salesforce.sf-plugins-checked")
) {
CommonUtils.showInformationMessage(
"All required SF plugins are already installed. SF setup is complete."
);
context.globalState.update(
"dev-pack-salesforce.sf-plugins-checked",
true
);
}
}
} catch (error) {
vscode.window.showErrorMessage(error);
}
}

static async verifySfCliInstalled() {
try {
await CommonUtils.execCommand("sf --version");
} catch (error) {
throw new Error(
"Salesforce CLI (sf) is not available. Please ensure @salesforce/cli is installed first."
);
}
}

static async installPlugins(pluginsToInstall) {
try {
for (const plugin of pluginsToInstall) {
await CommonUtils.execCommand(`sf plugins install ${plugin}`);
}
CommonUtils.showInformationMessage(
`Successfully installed SF plugins: ${pluginsToInstall.join(", ")}`
);
} catch (error) {
throw new Error(`Failed to install SF plugins: ${error.message}`);
}
}
}

module.exports = SfdxScannerInstaller;
Loading