sfdx-hardis 6.9.1-alpha202510262348.0 → 6.9.1-alpha202510270034.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5539,12 +5539,15 @@
5539
5539
  "import:data:org:hardis"
5540
5540
  ]
5541
5541
  },
5542
- "hardis:org:files:export": {
5542
+ "hardis:org:diagnose:audittrail": {
5543
5543
  "aliases": [],
5544
5544
  "args": {},
5545
- "description": "\n## Command Behavior\n\n**Exports file attachments (ContentVersion, Attachment) from a Salesforce org based on a predefined configuration.**\n\nThis command enables the mass download of files associated with Salesforce records, providing a robust solution for backing up files, migrating them to other systems, or integrating them with external document management solutions.\n\nKey functionalities:\n\n- **Configuration-Driven Export:** Relies on an `export.json` file within a designated file export project to define the export criteria, including the SOQL query for parent records, file types to export, output naming conventions, and file size filtering.\n- **File Size Filtering:** Supports minimum file size filtering via the `fileSizeMin` configuration parameter (in KB). Files smaller than the specified size will be skipped during export.\n- **File Validation:** After downloading each file, validates the integrity by:\n - **Checksum Validation:** For ContentVersion files, compares MD5 checksum with Salesforce's stored checksum\n - **Size Validation:** For both ContentVersion and Attachment files, verifies actual file size matches expected size\n - **Status Tracking:** Files are categorized with specific statuses: `success` (valid files), `failed` (download errors), `skipped` (filtered files), `invalid` (downloaded but failed validation)\n - All validation results are logged in the CSV export log for audit purposes\n- **Resume/Restart Capability:** \n - **Resume Mode:** When `--resume` flag is used (default in CI environments), checks existing downloaded files for validity. Valid files are skipped, invalid files are re-downloaded.\n - **Restart Mode:** When resume is disabled, clears the output folder and starts a fresh export.\n - **Interactive Mode:** When existing files are found and `--resume` is not explicitly specified (non-CI environments), prompts the user to choose between resume or restart.\n- **Interactive Project Selection:** If the file export project path is not provided via the `--path` flag, it interactively prompts the user to select one.\n- **Configurable Export Options:** Allows overriding default export settings such as `chunksize` (number of records processed in a batch), `polltimeout` (timeout for Bulk API calls), and `startchunknumber` (to resume a failed export).\n- **Support for ContentVersion and Attachment:** Handles both modern Salesforce Files (ContentVersion) and older Attachments.\n\nSee this article for a practical example:\n\n[![How to mass download notes and attachments files from a Salesforce org](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-mass-download.jpg)](https://nicolas.vuillamy.fr/how-to-mass-download-notes-and-attachments-files-from-a-salesforce-org-83a028824afd)\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **FilesExporter Class:** The core logic is encapsulated within the `FilesExporter` class, which orchestrates the entire export process.\n- **SOQL Queries (Bulk API):** It uses Salesforce Bulk API queries to efficiently retrieve large volumes of parent record IDs and file metadata, including checksums and file sizes.\n- **File Download:** Downloads the actual file content from Salesforce.\n- **File Validation:** After each successful download, validates file integrity by comparing checksums (ContentVersion) and file sizes (both ContentVersion and Attachment) against Salesforce metadata.\n- **Resume Logic:** In resume mode, checks for existing files before downloading, validates their integrity, and only re-downloads invalid or missing files. This enables efficient recovery from interrupted exports.\n- **File System Operations:** Writes the downloaded files to the local file system, organizing them into folders based on the configured naming conventions.\n- **Configuration Loading:** Reads the `export.json` file to get the export configuration. It also allows for interactive overriding of these settings.\n- **Interactive Prompts:** Uses `selectFilesWorkspace` to allow the user to choose a file export project, `promptFilesExportConfiguration` for customizing export options, and prompts for resume/restart choice when existing files are found.\n- **Error Handling:** Includes mechanisms to handle potential errors during the export process, such as network issues, API limits, and file validation failures. Each file is assigned a specific status (`success`, `failed`, `skipped`, `invalid`) for comprehensive tracking and troubleshooting.\n</details>\n",
5545
+ "description": "Export Audit trail into a CSV file with selected criteria, and highlight suspect actions\n\nAlso detects updates of Custom Settings values (disable by defining `SKIP_AUDIT_TRAIL_CUSTOM_SETTINGS=true`)\n\nRegular setup actions performed in major orgs are filtered.\n\n- \"\"\n - createScratchOrg\n - changedsenderemail\n - deleteScratchOrg\n - loginasgrantedtopartnerbt\n- Certificate and Key Management\n - insertCertificate\n- Custom App Licenses\n - addeduserpackagelicense\n - granteduserpackagelicense\n - revokeduserpackagelicense\n- Customer Portal\n - createdcustomersuccessuser\n - CSPUserDisabled\n- Currency\n - updateddatedexchrate\n- Data Management\n - queueMembership\n- Email Administration\n - dkimRotationPreparationSuccessful\n - dkimRotationSuccessful\n- External Objects\n - xdsEncryptedFieldChange\n- Groups\n - groupMembership\n- Holidays\n - holiday_insert\n- Inbox mobile and legacy desktop apps\n - enableSIQUserNonEAC\n - siqUserAcceptedTOS\n- Manage Users\n - activateduser\n - createduser\n - changedcommunitynickname\n - changedemail\n - changedfederationid\n - changedpassword\n - changedinteractionuseroffon\n - changedinteractionuseronoff\n - changedmarketinguseroffon\n - changedmarketinguseronoff\n - changedofflineuseroffon\n - changedprofileforuserstdtostd\n - changedprofileforuser\n - changedprofileforusercusttostd\n - changedprofileforuserstdtocust\n - changedroleforusertonone\n - changedroleforuser\n - changedroleforuserfromnone\n - changedUserAdminVerifiedStatusVerified\n - changedUserEmailVerifiedStatusUnverified\n - changedUserEmailVerifiedStatusVerified\n - changedknowledgeuseroffon\n - changedsfcontentuseroffon\n - changedsupportuseroffon\n - changedusername\n - changedUserPhoneNumber\n - changedUserPhoneVerifiedStatusUnverified\n - changedUserPhoneVerifiedStatusVerified\n - deactivateduser\n - deleteAuthenticatorPairing\n - deleteTwoFactorInfo2\n - deleteTwoFactorTempCode\n - frozeuser\n - insertAuthenticatorPairing\n - insertTwoFactorInfo2\n - insertTwoFactorTempCode\n - lightningloginenroll\n - PermSetAssign\n - PermSetGroupAssign\n - PermSetGroupUnassign\n - PermSetLicenseAssign\n - PermSetUnassign\n - PermSetLicenseUnassign\n - registeredUserPhoneNumber\n - resetpassword\n - suNetworkAdminLogin\n - suNetworkAdminLogout\n - suOrgAdminLogin\n - suOrgAdminLogout\n - unfrozeuser\n - useremailchangesent\n- Mobile Administration\n - assigneduserstomobileconfig\n- Reporting Snapshots\n - createdReportJob\n - deletedReportJob\n- Sandboxes\n - DeleteSandbox\n\nBy default, deployment user defined in .sfdx-hardis.yml targetUsername property will be excluded.\n\nYou can define additional users to exclude in .sfdx-hardis.yml **monitoringExcludeUsernames** property.\n\nYou can also add more sections / actions considered as not suspect using property **monitoringAllowedSectionsActions**\n\nExample:\n\n```yaml\nmonitoringExcludeUsernames:\n - deploymentuser@cloudity.com\n - marketingcloud@cloudity.com\n - integration-user@cloudity.com\n\nmonitoringAllowedSectionsActions:\n \"Some section\": [] // Will ignore all actions from such section\n \"Some other section\": [\"actionType1\",\"actionType2\",\"actionType3\"] // Will ignore only those 3 actions from section \"Some other section\". Other actions in the same section will be considered as suspect.\n```\n\n## Excel output example\n\n![](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/screenshot-monitoring-audittrail-excel.jpg)\n\n## Local output example\n\n![](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/screenshot-monitoring-audittrail-local.jpg)\n\nThis command is part of [sfdx-hardis Monitoring](https://sfdx-hardis.cloudity.com/salesforce-monitoring-suspect-audit-trail/) and can output Grafana, Slack and MsTeams Notifications.\n",
5546
5546
  "examples": [
5547
- "$ sf hardis:org:files:export"
5547
+ "$ sf hardis:org:diagnose:audittrail",
5548
+ "$ sf hardis:org:diagnose:audittrail --excludeusers baptiste@titi.com",
5549
+ "$ sf hardis:org:diagnose:audittrail --excludeusers baptiste@titi.com,bertrand@titi.com",
5550
+ "$ sf hardis:org:diagnose:audittrail --lastndays 5"
5548
5551
  ],
5549
5552
  "flags": {
5550
5553
  "json": {
@@ -5562,48 +5565,30 @@
5562
5565
  "multiple": false,
5563
5566
  "type": "option"
5564
5567
  },
5565
- "path": {
5566
- "char": "p",
5567
- "description": "Path to the file export project",
5568
- "name": "path",
5569
- "hasDynamicHelp": false,
5570
- "multiple": false,
5571
- "type": "option"
5572
- },
5573
- "chunksize": {
5574
- "char": "c",
5575
- "description": "Number of records to add in a chunk before it is processed",
5576
- "name": "chunksize",
5577
- "default": 1000,
5568
+ "excludeusers": {
5569
+ "char": "e",
5570
+ "description": "Comma-separated list of usernames to exclude",
5571
+ "name": "excludeusers",
5578
5572
  "hasDynamicHelp": false,
5579
5573
  "multiple": false,
5580
5574
  "type": "option"
5581
5575
  },
5582
- "polltimeout": {
5576
+ "lastndays": {
5583
5577
  "char": "t",
5584
- "description": "Timeout in MS for Bulk API calls",
5585
- "name": "polltimeout",
5586
- "default": 300000,
5578
+ "description": "Number of days to extract from today (included)",
5579
+ "name": "lastndays",
5587
5580
  "hasDynamicHelp": false,
5588
5581
  "multiple": false,
5589
5582
  "type": "option"
5590
5583
  },
5591
- "startchunknumber": {
5592
- "char": "s",
5593
- "description": "Chunk number to start from",
5594
- "name": "startchunknumber",
5595
- "default": 0,
5584
+ "outputfile": {
5585
+ "char": "f",
5586
+ "description": "Force the path and name of output report file. Must end with .csv",
5587
+ "name": "outputfile",
5596
5588
  "hasDynamicHelp": false,
5597
5589
  "multiple": false,
5598
5590
  "type": "option"
5599
5591
  },
5600
- "resume": {
5601
- "char": "r",
5602
- "description": "Resume previous export by checking existing files (default in CI)",
5603
- "name": "resume",
5604
- "allowNo": false,
5605
- "type": "boolean"
5606
- },
5607
5592
  "debug": {
5608
5593
  "char": "d",
5609
5594
  "description": "Activate debug mode (more logs)",
@@ -5642,13 +5627,13 @@
5642
5627
  },
5643
5628
  "hasDynamicHelp": true,
5644
5629
  "hiddenAliases": [],
5645
- "id": "hardis:org:files:export",
5630
+ "id": "hardis:org:diagnose:audittrail",
5646
5631
  "pluginAlias": "sfdx-hardis",
5647
5632
  "pluginName": "sfdx-hardis",
5648
5633
  "pluginType": "core",
5649
5634
  "strict": true,
5650
5635
  "enableJsonFlag": true,
5651
- "title": "Export files",
5636
+ "title": "Diagnose content of Setup Audit Trail",
5652
5637
  "requiresProject": false,
5653
5638
  "isESM": true,
5654
5639
  "relativePath": [
@@ -5656,43 +5641,43 @@
5656
5641
  "commands",
5657
5642
  "hardis",
5658
5643
  "org",
5659
- "files",
5660
- "export.js"
5644
+ "diagnose",
5645
+ "audittrail.js"
5661
5646
  ],
5662
5647
  "aliasPermutations": [],
5663
5648
  "permutations": [
5664
- "hardis:org:files:export",
5665
- "org:hardis:files:export",
5666
- "org:files:hardis:export",
5667
- "org:files:export:hardis",
5668
- "hardis:files:org:export",
5669
- "files:hardis:org:export",
5670
- "files:org:hardis:export",
5671
- "files:org:export:hardis",
5672
- "hardis:files:export:org",
5673
- "files:hardis:export:org",
5674
- "files:export:hardis:org",
5675
- "files:export:org:hardis",
5676
- "hardis:org:export:files",
5677
- "org:hardis:export:files",
5678
- "org:export:hardis:files",
5679
- "org:export:files:hardis",
5680
- "hardis:export:org:files",
5681
- "export:hardis:org:files",
5682
- "export:org:hardis:files",
5683
- "export:org:files:hardis",
5684
- "hardis:export:files:org",
5685
- "export:hardis:files:org",
5686
- "export:files:hardis:org",
5687
- "export:files:org:hardis"
5649
+ "hardis:org:diagnose:audittrail",
5650
+ "org:hardis:diagnose:audittrail",
5651
+ "org:diagnose:hardis:audittrail",
5652
+ "org:diagnose:audittrail:hardis",
5653
+ "hardis:diagnose:org:audittrail",
5654
+ "diagnose:hardis:org:audittrail",
5655
+ "diagnose:org:hardis:audittrail",
5656
+ "diagnose:org:audittrail:hardis",
5657
+ "hardis:diagnose:audittrail:org",
5658
+ "diagnose:hardis:audittrail:org",
5659
+ "diagnose:audittrail:hardis:org",
5660
+ "diagnose:audittrail:org:hardis",
5661
+ "hardis:org:audittrail:diagnose",
5662
+ "org:hardis:audittrail:diagnose",
5663
+ "org:audittrail:hardis:diagnose",
5664
+ "org:audittrail:diagnose:hardis",
5665
+ "hardis:audittrail:org:diagnose",
5666
+ "audittrail:hardis:org:diagnose",
5667
+ "audittrail:org:hardis:diagnose",
5668
+ "audittrail:org:diagnose:hardis",
5669
+ "hardis:audittrail:diagnose:org",
5670
+ "audittrail:hardis:diagnose:org",
5671
+ "audittrail:diagnose:hardis:org",
5672
+ "audittrail:diagnose:org:hardis"
5688
5673
  ]
5689
5674
  },
5690
- "hardis:org:files:import": {
5675
+ "hardis:org:diagnose:instanceupgrade": {
5691
5676
  "aliases": [],
5692
5677
  "args": {},
5693
- "description": "\nThis command facilitates the mass upload of files into Salesforce, allowing you to populate records with associated documents, images, or other file types. It's a crucial tool for data migration, content seeding, or synchronizing external file repositories with Salesforce.\n\nKey functionalities:\n\n- **Configuration-Driven Import:** Relies on an `export.json` file within a designated file export project (created using `sf hardis:org:configure:files`) to determine which files to import and how they should be associated with Salesforce records.\n- **Interactive Project Selection:** If the file import project path is not provided via the `--path` flag, it interactively prompts the user to select one.\n- **Overwrite Option:** The `--overwrite` flag allows you to replace existing files in Salesforce with local versions that have the same name. Be aware that this option doubles the number of API calls used.\n- **Support for ContentVersion and Attachment:** Handles both modern Salesforce Files (ContentVersion) and older Attachments.\n\nSee this article for how to export files, which is often a prerequisite for importing:\n\n[![How to mass download notes and attachments files from a Salesforce org](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-mass-download.jpg)](https://nicolas.vuillamy.fr/how-to-mass-download-notes-and-attachments-files-from-a-salesforce-org-83a028824afd)\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **FilesImporter Class:** The core logic is encapsulated within the `FilesImporter` class, which orchestrates the entire import process.\n- **File System Scan:** Scans the local file system within the configured project directory to identify files for import.\n- **Salesforce API Interaction:** Uses Salesforce APIs (e.g., ContentVersion, Attachment) to upload files and associate them with records.\n- **Configuration Loading:** Reads the `export.json` file to get the import configuration, including SOQL queries to identify parent records for file association.\n- **Interactive Prompts:** Uses `selectFilesWorkspace` to allow the user to choose a file import project and `prompts` for confirming the overwrite behavior.\n- **Error Handling:** Includes mechanisms to handle potential errors during the import process, such as API limits or file upload failures.\n</details>\n",
5678
+ "description": "\n## Command Behavior\n\n**Retrieves and displays the scheduled upgrade date for a Salesforce org's instance.**\n\nThis command provides crucial information about when your Salesforce instance will be upgraded to the next major release (Spring, Summer, or Winter). This is vital for release planning, testing, and ensuring compatibility with upcoming Salesforce features.\n\nKey functionalities:\n\n- **Instance Identification:** Determines the Salesforce instance name of your target org.\n- **Upgrade Date Retrieval:** Fetches the planned start time of the next major core service upgrade for that instance from the Salesforce Status API.\n- **Days Until Upgrade:** Calculates and displays the number of days remaining until the next major upgrade.\n- **Severity-Based Logging:** Adjusts the log severity (info, warning) based on the proximity of the upgrade date, providing a visual cue for urgency.\n- **Notifications:** Sends notifications to configured channels (e.g., Slack, MS Teams, Grafana) with the upgrade information, making it suitable for automated monitoring.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **Salesforce SOQL Query:** It first queries the `Organization` object in Salesforce to get the `InstanceName` of the target org.\n- **Salesforce Status API Integration:** It makes an HTTP GET request to the Salesforce Status API (`https://api.status.salesforce.com/v1/instances/{instanceName}/status`) to retrieve detailed information about the instance, including scheduled maintenances.\n- **Data Parsing:** It parses the JSON response from the Status API to extract the relevant major release upgrade information.\n- **Date Calculation:** Uses the `moment` library to calculate the difference in days between the current date and the planned upgrade date.\n- **Notification Integration:** It integrates with the `NotifProvider` to send notifications, including the instance name, upgrade date, and days remaining, along with relevant metrics for monitoring dashboards.\n- **User Feedback:** Provides clear messages to the user about the upgrade status and proximity.\n</details>\n",
5694
5679
  "examples": [
5695
- "$ sf hardis:org:files:import"
5680
+ "$ sf hardis:org:diagnose:instanceupgrade"
5696
5681
  ],
5697
5682
  "flags": {
5698
5683
  "json": {
@@ -5710,21 +5695,6 @@
5710
5695
  "multiple": false,
5711
5696
  "type": "option"
5712
5697
  },
5713
- "path": {
5714
- "char": "p",
5715
- "description": "Path to the file export project",
5716
- "name": "path",
5717
- "hasDynamicHelp": false,
5718
- "multiple": false,
5719
- "type": "option"
5720
- },
5721
- "overwrite": {
5722
- "char": "f",
5723
- "description": "Override existing files (doubles the number of API calls)",
5724
- "name": "overwrite",
5725
- "allowNo": false,
5726
- "type": "boolean"
5727
- },
5728
5698
  "debug": {
5729
5699
  "char": "d",
5730
5700
  "description": "Activate debug mode (more logs)",
@@ -5763,13 +5733,13 @@
5763
5733
  },
5764
5734
  "hasDynamicHelp": true,
5765
5735
  "hiddenAliases": [],
5766
- "id": "hardis:org:files:import",
5736
+ "id": "hardis:org:diagnose:instanceupgrade",
5767
5737
  "pluginAlias": "sfdx-hardis",
5768
5738
  "pluginName": "sfdx-hardis",
5769
5739
  "pluginType": "core",
5770
5740
  "strict": true,
5771
5741
  "enableJsonFlag": true,
5772
- "title": "Import files",
5742
+ "title": "Get Instance Upgrade date",
5773
5743
  "requiresProject": false,
5774
5744
  "isESM": true,
5775
5745
  "relativePath": [
@@ -5777,46 +5747,46 @@
5777
5747
  "commands",
5778
5748
  "hardis",
5779
5749
  "org",
5780
- "files",
5781
- "import.js"
5750
+ "diagnose",
5751
+ "instanceupgrade.js"
5782
5752
  ],
5783
5753
  "aliasPermutations": [],
5784
5754
  "permutations": [
5785
- "hardis:org:files:import",
5786
- "org:hardis:files:import",
5787
- "org:files:hardis:import",
5788
- "org:files:import:hardis",
5789
- "hardis:files:org:import",
5790
- "files:hardis:org:import",
5791
- "files:org:hardis:import",
5792
- "files:org:import:hardis",
5793
- "hardis:files:import:org",
5794
- "files:hardis:import:org",
5795
- "files:import:hardis:org",
5796
- "files:import:org:hardis",
5797
- "hardis:org:import:files",
5798
- "org:hardis:import:files",
5799
- "org:import:hardis:files",
5800
- "org:import:files:hardis",
5801
- "hardis:import:org:files",
5802
- "import:hardis:org:files",
5803
- "import:org:hardis:files",
5804
- "import:org:files:hardis",
5805
- "hardis:import:files:org",
5806
- "import:hardis:files:org",
5807
- "import:files:hardis:org",
5808
- "import:files:org:hardis"
5755
+ "hardis:org:diagnose:instanceupgrade",
5756
+ "org:hardis:diagnose:instanceupgrade",
5757
+ "org:diagnose:hardis:instanceupgrade",
5758
+ "org:diagnose:instanceupgrade:hardis",
5759
+ "hardis:diagnose:org:instanceupgrade",
5760
+ "diagnose:hardis:org:instanceupgrade",
5761
+ "diagnose:org:hardis:instanceupgrade",
5762
+ "diagnose:org:instanceupgrade:hardis",
5763
+ "hardis:diagnose:instanceupgrade:org",
5764
+ "diagnose:hardis:instanceupgrade:org",
5765
+ "diagnose:instanceupgrade:hardis:org",
5766
+ "diagnose:instanceupgrade:org:hardis",
5767
+ "hardis:org:instanceupgrade:diagnose",
5768
+ "org:hardis:instanceupgrade:diagnose",
5769
+ "org:instanceupgrade:hardis:diagnose",
5770
+ "org:instanceupgrade:diagnose:hardis",
5771
+ "hardis:instanceupgrade:org:diagnose",
5772
+ "instanceupgrade:hardis:org:diagnose",
5773
+ "instanceupgrade:org:hardis:diagnose",
5774
+ "instanceupgrade:org:diagnose:hardis",
5775
+ "hardis:instanceupgrade:diagnose:org",
5776
+ "instanceupgrade:hardis:diagnose:org",
5777
+ "instanceupgrade:diagnose:hardis:org",
5778
+ "instanceupgrade:diagnose:org:hardis"
5809
5779
  ]
5810
5780
  },
5811
- "hardis:org:diagnose:audittrail": {
5781
+ "hardis:org:diagnose:legacyapi": {
5812
5782
  "aliases": [],
5813
5783
  "args": {},
5814
- "description": "Export Audit trail into a CSV file with selected criteria, and highlight suspect actions\n\nAlso detects updates of Custom Settings values (disable by defining `SKIP_AUDIT_TRAIL_CUSTOM_SETTINGS=true`)\n\nRegular setup actions performed in major orgs are filtered.\n\n- \"\"\n - createScratchOrg\n - changedsenderemail\n - deleteScratchOrg\n - loginasgrantedtopartnerbt\n- Certificate and Key Management\n - insertCertificate\n- Custom App Licenses\n - addeduserpackagelicense\n - granteduserpackagelicense\n - revokeduserpackagelicense\n- Customer Portal\n - createdcustomersuccessuser\n - CSPUserDisabled\n- Currency\n - updateddatedexchrate\n- Data Management\n - queueMembership\n- Email Administration\n - dkimRotationPreparationSuccessful\n - dkimRotationSuccessful\n- External Objects\n - xdsEncryptedFieldChange\n- Groups\n - groupMembership\n- Holidays\n - holiday_insert\n- Inbox mobile and legacy desktop apps\n - enableSIQUserNonEAC\n - siqUserAcceptedTOS\n- Manage Users\n - activateduser\n - createduser\n - changedcommunitynickname\n - changedemail\n - changedfederationid\n - changedpassword\n - changedinteractionuseroffon\n - changedinteractionuseronoff\n - changedmarketinguseroffon\n - changedmarketinguseronoff\n - changedofflineuseroffon\n - changedprofileforuserstdtostd\n - changedprofileforuser\n - changedprofileforusercusttostd\n - changedprofileforuserstdtocust\n - changedroleforusertonone\n - changedroleforuser\n - changedroleforuserfromnone\n - changedUserAdminVerifiedStatusVerified\n - changedUserEmailVerifiedStatusUnverified\n - changedUserEmailVerifiedStatusVerified\n - changedknowledgeuseroffon\n - changedsfcontentuseroffon\n - changedsupportuseroffon\n - changedusername\n - changedUserPhoneNumber\n - changedUserPhoneVerifiedStatusUnverified\n - changedUserPhoneVerifiedStatusVerified\n - deactivateduser\n - deleteAuthenticatorPairing\n - deleteTwoFactorInfo2\n - deleteTwoFactorTempCode\n - frozeuser\n - insertAuthenticatorPairing\n - insertTwoFactorInfo2\n - insertTwoFactorTempCode\n - lightningloginenroll\n - PermSetAssign\n - PermSetGroupAssign\n - PermSetGroupUnassign\n - PermSetLicenseAssign\n - PermSetUnassign\n - PermSetLicenseUnassign\n - registeredUserPhoneNumber\n - resetpassword\n - suNetworkAdminLogin\n - suNetworkAdminLogout\n - suOrgAdminLogin\n - suOrgAdminLogout\n - unfrozeuser\n - useremailchangesent\n- Mobile Administration\n - assigneduserstomobileconfig\n- Reporting Snapshots\n - createdReportJob\n - deletedReportJob\n- Sandboxes\n - DeleteSandbox\n\nBy default, deployment user defined in .sfdx-hardis.yml targetUsername property will be excluded.\n\nYou can define additional users to exclude in .sfdx-hardis.yml **monitoringExcludeUsernames** property.\n\nYou can also add more sections / actions considered as not suspect using property **monitoringAllowedSectionsActions**\n\nExample:\n\n```yaml\nmonitoringExcludeUsernames:\n - deploymentuser@cloudity.com\n - marketingcloud@cloudity.com\n - integration-user@cloudity.com\n\nmonitoringAllowedSectionsActions:\n \"Some section\": [] // Will ignore all actions from such section\n \"Some other section\": [\"actionType1\",\"actionType2\",\"actionType3\"] // Will ignore only those 3 actions from section \"Some other section\". Other actions in the same section will be considered as suspect.\n```\n\n## Excel output example\n\n![](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/screenshot-monitoring-audittrail-excel.jpg)\n\n## Local output example\n\n![](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/screenshot-monitoring-audittrail-local.jpg)\n\nThis command is part of [sfdx-hardis Monitoring](https://sfdx-hardis.cloudity.com/salesforce-monitoring-suspect-audit-trail/) and can output Grafana, Slack and MsTeams Notifications.\n",
5784
+ "description": "Checks if an org uses retired or someday retired API version\n\n\nSee article below\n\n[![Handle Salesforce API versions Deprecation like a pro](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-deprecated-api.jpg)](https://nicolas.vuillamy.fr/handle-salesforce-api-versions-deprecation-like-a-pro-335065f52238)\n\nThis command is part of [sfdx-hardis Monitoring](https://sfdx-hardis.cloudity.com/salesforce-monitoring-deprecated-api-calls/) and can output Grafana, Slack and MsTeams Notifications.\n",
5815
5785
  "examples": [
5816
- "$ sf hardis:org:diagnose:audittrail",
5817
- "$ sf hardis:org:diagnose:audittrail --excludeusers baptiste@titi.com",
5818
- "$ sf hardis:org:diagnose:audittrail --excludeusers baptiste@titi.com,bertrand@titi.com",
5819
- "$ sf hardis:org:diagnose:audittrail --lastndays 5"
5786
+ "$ sf hardis:org:diagnose:legacyapi",
5787
+ "$ sf hardis:org:diagnose:legacyapi -u hardis@myclient.com",
5788
+ "$ sf hardis:org:diagnose:legacyapi --outputfile 'c:/path/to/folder/legacyapi.csv'",
5789
+ "$ sf hardis:org:diagnose:legacyapi -u hardis@myclient.com --outputfile ./tmp/legacyapi.csv"
5820
5790
  ],
5821
5791
  "flags": {
5822
5792
  "json": {
@@ -5834,18 +5804,20 @@
5834
5804
  "multiple": false,
5835
5805
  "type": "option"
5836
5806
  },
5837
- "excludeusers": {
5807
+ "eventtype": {
5838
5808
  "char": "e",
5839
- "description": "Comma-separated list of usernames to exclude",
5840
- "name": "excludeusers",
5809
+ "description": "Type of EventLogFile event to analyze",
5810
+ "name": "eventtype",
5811
+ "default": "ApiTotalUsage",
5841
5812
  "hasDynamicHelp": false,
5842
5813
  "multiple": false,
5843
5814
  "type": "option"
5844
5815
  },
5845
- "lastndays": {
5846
- "char": "t",
5847
- "description": "Number of days to extract from today (included)",
5848
- "name": "lastndays",
5816
+ "limit": {
5817
+ "char": "l",
5818
+ "description": "Number of latest EventLogFile events to analyze",
5819
+ "name": "limit",
5820
+ "default": 999,
5849
5821
  "hasDynamicHelp": false,
5850
5822
  "multiple": false,
5851
5823
  "type": "option"
@@ -5896,13 +5868,13 @@
5896
5868
  },
5897
5869
  "hasDynamicHelp": true,
5898
5870
  "hiddenAliases": [],
5899
- "id": "hardis:org:diagnose:audittrail",
5871
+ "id": "hardis:org:diagnose:legacyapi",
5900
5872
  "pluginAlias": "sfdx-hardis",
5901
5873
  "pluginName": "sfdx-hardis",
5902
5874
  "pluginType": "core",
5903
5875
  "strict": true,
5904
5876
  "enableJsonFlag": true,
5905
- "title": "Diagnose content of Setup Audit Trail",
5877
+ "title": "Check for legacy API use",
5906
5878
  "requiresProject": false,
5907
5879
  "isESM": true,
5908
5880
  "relativePath": [
@@ -5911,248 +5883,7 @@
5911
5883
  "hardis",
5912
5884
  "org",
5913
5885
  "diagnose",
5914
- "audittrail.js"
5915
- ],
5916
- "aliasPermutations": [],
5917
- "permutations": [
5918
- "hardis:org:diagnose:audittrail",
5919
- "org:hardis:diagnose:audittrail",
5920
- "org:diagnose:hardis:audittrail",
5921
- "org:diagnose:audittrail:hardis",
5922
- "hardis:diagnose:org:audittrail",
5923
- "diagnose:hardis:org:audittrail",
5924
- "diagnose:org:hardis:audittrail",
5925
- "diagnose:org:audittrail:hardis",
5926
- "hardis:diagnose:audittrail:org",
5927
- "diagnose:hardis:audittrail:org",
5928
- "diagnose:audittrail:hardis:org",
5929
- "diagnose:audittrail:org:hardis",
5930
- "hardis:org:audittrail:diagnose",
5931
- "org:hardis:audittrail:diagnose",
5932
- "org:audittrail:hardis:diagnose",
5933
- "org:audittrail:diagnose:hardis",
5934
- "hardis:audittrail:org:diagnose",
5935
- "audittrail:hardis:org:diagnose",
5936
- "audittrail:org:hardis:diagnose",
5937
- "audittrail:org:diagnose:hardis",
5938
- "hardis:audittrail:diagnose:org",
5939
- "audittrail:hardis:diagnose:org",
5940
- "audittrail:diagnose:hardis:org",
5941
- "audittrail:diagnose:org:hardis"
5942
- ]
5943
- },
5944
- "hardis:org:diagnose:instanceupgrade": {
5945
- "aliases": [],
5946
- "args": {},
5947
- "description": "\n## Command Behavior\n\n**Retrieves and displays the scheduled upgrade date for a Salesforce org's instance.**\n\nThis command provides crucial information about when your Salesforce instance will be upgraded to the next major release (Spring, Summer, or Winter). This is vital for release planning, testing, and ensuring compatibility with upcoming Salesforce features.\n\nKey functionalities:\n\n- **Instance Identification:** Determines the Salesforce instance name of your target org.\n- **Upgrade Date Retrieval:** Fetches the planned start time of the next major core service upgrade for that instance from the Salesforce Status API.\n- **Days Until Upgrade:** Calculates and displays the number of days remaining until the next major upgrade.\n- **Severity-Based Logging:** Adjusts the log severity (info, warning) based on the proximity of the upgrade date, providing a visual cue for urgency.\n- **Notifications:** Sends notifications to configured channels (e.g., Slack, MS Teams, Grafana) with the upgrade information, making it suitable for automated monitoring.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **Salesforce SOQL Query:** It first queries the `Organization` object in Salesforce to get the `InstanceName` of the target org.\n- **Salesforce Status API Integration:** It makes an HTTP GET request to the Salesforce Status API (`https://api.status.salesforce.com/v1/instances/{instanceName}/status`) to retrieve detailed information about the instance, including scheduled maintenances.\n- **Data Parsing:** It parses the JSON response from the Status API to extract the relevant major release upgrade information.\n- **Date Calculation:** Uses the `moment` library to calculate the difference in days between the current date and the planned upgrade date.\n- **Notification Integration:** It integrates with the `NotifProvider` to send notifications, including the instance name, upgrade date, and days remaining, along with relevant metrics for monitoring dashboards.\n- **User Feedback:** Provides clear messages to the user about the upgrade status and proximity.\n</details>\n",
5948
- "examples": [
5949
- "$ sf hardis:org:diagnose:instanceupgrade"
5950
- ],
5951
- "flags": {
5952
- "json": {
5953
- "description": "Format output as json.",
5954
- "helpGroup": "GLOBAL",
5955
- "name": "json",
5956
- "allowNo": false,
5957
- "type": "boolean"
5958
- },
5959
- "flags-dir": {
5960
- "helpGroup": "GLOBAL",
5961
- "name": "flags-dir",
5962
- "summary": "Import flag values from a directory.",
5963
- "hasDynamicHelp": false,
5964
- "multiple": false,
5965
- "type": "option"
5966
- },
5967
- "debug": {
5968
- "char": "d",
5969
- "description": "Activate debug mode (more logs)",
5970
- "name": "debug",
5971
- "allowNo": false,
5972
- "type": "boolean"
5973
- },
5974
- "websocket": {
5975
- "description": "Websocket host:port for VsCode SFDX Hardis UI integration",
5976
- "name": "websocket",
5977
- "hasDynamicHelp": false,
5978
- "multiple": false,
5979
- "type": "option"
5980
- },
5981
- "skipauth": {
5982
- "description": "Skip authentication check when a default username is required",
5983
- "name": "skipauth",
5984
- "allowNo": false,
5985
- "type": "boolean"
5986
- },
5987
- "target-org": {
5988
- "aliases": [
5989
- "targetusername",
5990
- "u"
5991
- ],
5992
- "char": "o",
5993
- "deprecateAliases": true,
5994
- "name": "target-org",
5995
- "noCacheDefault": true,
5996
- "required": true,
5997
- "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
5998
- "hasDynamicHelp": true,
5999
- "multiple": false,
6000
- "type": "option"
6001
- }
6002
- },
6003
- "hasDynamicHelp": true,
6004
- "hiddenAliases": [],
6005
- "id": "hardis:org:diagnose:instanceupgrade",
6006
- "pluginAlias": "sfdx-hardis",
6007
- "pluginName": "sfdx-hardis",
6008
- "pluginType": "core",
6009
- "strict": true,
6010
- "enableJsonFlag": true,
6011
- "title": "Get Instance Upgrade date",
6012
- "requiresProject": false,
6013
- "isESM": true,
6014
- "relativePath": [
6015
- "lib",
6016
- "commands",
6017
- "hardis",
6018
- "org",
6019
- "diagnose",
6020
- "instanceupgrade.js"
6021
- ],
6022
- "aliasPermutations": [],
6023
- "permutations": [
6024
- "hardis:org:diagnose:instanceupgrade",
6025
- "org:hardis:diagnose:instanceupgrade",
6026
- "org:diagnose:hardis:instanceupgrade",
6027
- "org:diagnose:instanceupgrade:hardis",
6028
- "hardis:diagnose:org:instanceupgrade",
6029
- "diagnose:hardis:org:instanceupgrade",
6030
- "diagnose:org:hardis:instanceupgrade",
6031
- "diagnose:org:instanceupgrade:hardis",
6032
- "hardis:diagnose:instanceupgrade:org",
6033
- "diagnose:hardis:instanceupgrade:org",
6034
- "diagnose:instanceupgrade:hardis:org",
6035
- "diagnose:instanceupgrade:org:hardis",
6036
- "hardis:org:instanceupgrade:diagnose",
6037
- "org:hardis:instanceupgrade:diagnose",
6038
- "org:instanceupgrade:hardis:diagnose",
6039
- "org:instanceupgrade:diagnose:hardis",
6040
- "hardis:instanceupgrade:org:diagnose",
6041
- "instanceupgrade:hardis:org:diagnose",
6042
- "instanceupgrade:org:hardis:diagnose",
6043
- "instanceupgrade:org:diagnose:hardis",
6044
- "hardis:instanceupgrade:diagnose:org",
6045
- "instanceupgrade:hardis:diagnose:org",
6046
- "instanceupgrade:diagnose:hardis:org",
6047
- "instanceupgrade:diagnose:org:hardis"
6048
- ]
6049
- },
6050
- "hardis:org:diagnose:legacyapi": {
6051
- "aliases": [],
6052
- "args": {},
6053
- "description": "Checks if an org uses retired or someday retired API version\n\n\nSee article below\n\n[![Handle Salesforce API versions Deprecation like a pro](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-deprecated-api.jpg)](https://nicolas.vuillamy.fr/handle-salesforce-api-versions-deprecation-like-a-pro-335065f52238)\n\nThis command is part of [sfdx-hardis Monitoring](https://sfdx-hardis.cloudity.com/salesforce-monitoring-deprecated-api-calls/) and can output Grafana, Slack and MsTeams Notifications.\n",
6054
- "examples": [
6055
- "$ sf hardis:org:diagnose:legacyapi",
6056
- "$ sf hardis:org:diagnose:legacyapi -u hardis@myclient.com",
6057
- "$ sf hardis:org:diagnose:legacyapi --outputfile 'c:/path/to/folder/legacyapi.csv'",
6058
- "$ sf hardis:org:diagnose:legacyapi -u hardis@myclient.com --outputfile ./tmp/legacyapi.csv"
6059
- ],
6060
- "flags": {
6061
- "json": {
6062
- "description": "Format output as json.",
6063
- "helpGroup": "GLOBAL",
6064
- "name": "json",
6065
- "allowNo": false,
6066
- "type": "boolean"
6067
- },
6068
- "flags-dir": {
6069
- "helpGroup": "GLOBAL",
6070
- "name": "flags-dir",
6071
- "summary": "Import flag values from a directory.",
6072
- "hasDynamicHelp": false,
6073
- "multiple": false,
6074
- "type": "option"
6075
- },
6076
- "eventtype": {
6077
- "char": "e",
6078
- "description": "Type of EventLogFile event to analyze",
6079
- "name": "eventtype",
6080
- "default": "ApiTotalUsage",
6081
- "hasDynamicHelp": false,
6082
- "multiple": false,
6083
- "type": "option"
6084
- },
6085
- "limit": {
6086
- "char": "l",
6087
- "description": "Number of latest EventLogFile events to analyze",
6088
- "name": "limit",
6089
- "default": 999,
6090
- "hasDynamicHelp": false,
6091
- "multiple": false,
6092
- "type": "option"
6093
- },
6094
- "outputfile": {
6095
- "char": "f",
6096
- "description": "Force the path and name of output report file. Must end with .csv",
6097
- "name": "outputfile",
6098
- "hasDynamicHelp": false,
6099
- "multiple": false,
6100
- "type": "option"
6101
- },
6102
- "debug": {
6103
- "char": "d",
6104
- "description": "Activate debug mode (more logs)",
6105
- "name": "debug",
6106
- "allowNo": false,
6107
- "type": "boolean"
6108
- },
6109
- "websocket": {
6110
- "description": "Websocket host:port for VsCode SFDX Hardis UI integration",
6111
- "name": "websocket",
6112
- "hasDynamicHelp": false,
6113
- "multiple": false,
6114
- "type": "option"
6115
- },
6116
- "skipauth": {
6117
- "description": "Skip authentication check when a default username is required",
6118
- "name": "skipauth",
6119
- "allowNo": false,
6120
- "type": "boolean"
6121
- },
6122
- "target-org": {
6123
- "aliases": [
6124
- "targetusername",
6125
- "u"
6126
- ],
6127
- "char": "o",
6128
- "deprecateAliases": true,
6129
- "name": "target-org",
6130
- "noCacheDefault": true,
6131
- "required": true,
6132
- "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
6133
- "hasDynamicHelp": true,
6134
- "multiple": false,
6135
- "type": "option"
6136
- }
6137
- },
6138
- "hasDynamicHelp": true,
6139
- "hiddenAliases": [],
6140
- "id": "hardis:org:diagnose:legacyapi",
6141
- "pluginAlias": "sfdx-hardis",
6142
- "pluginName": "sfdx-hardis",
6143
- "pluginType": "core",
6144
- "strict": true,
6145
- "enableJsonFlag": true,
6146
- "title": "Check for legacy API use",
6147
- "requiresProject": false,
6148
- "isESM": true,
6149
- "relativePath": [
6150
- "lib",
6151
- "commands",
6152
- "hardis",
6153
- "org",
6154
- "diagnose",
6155
- "legacyapi.js"
5886
+ "legacyapi.js"
6156
5887
  ],
6157
5888
  "aliasPermutations": [],
6158
5889
  "permutations": [
@@ -7071,13 +6802,12 @@
7071
6802
  "unusedusers:diagnose:org:hardis"
7072
6803
  ]
7073
6804
  },
7074
- "hardis:org:fix:listviewmine": {
6805
+ "hardis:org:files:export": {
7075
6806
  "aliases": [],
7076
6807
  "args": {},
7077
- "description": "Fix listviews whose scope Mine has been replaced by Everything\n\n[![Invalid scope:Mine, not allowed ? Deploy your ListViews anyway !](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-invalid-scope-mine.jpg)](https://nicolas.vuillamy.fr/invalid-scope-mine-not-allowed-deploy-your-listviews-anyway-443aceca8ac7)\n\nList of ListViews can be:\n\n- read from .sfdx-hardis.yml file in property **listViewsToSetToMine**\n- sent in argument listviews\n\nNote: property **listViewsToSetToMine** can be auto-generated by command hardis:work:save if .sfdx-hardis.yml contains the following configuration\n\n```yaml\nautoCleanTypes:\n - listViewsMine\n```\n\n- Example of sfdx-hardis.yml property `listViewsToSetToMine`:\n\n```yaml\nlistViewsToSetToMine:\n - \"force-app/main/default/objects/Operation__c/listViews/MyCurrentOperations.listView-meta.xml\"\n - \"force-app/main/default/objects/Operation__c/listViews/MyFinalizedOperations.listView-meta.xml\"\n - \"force-app/main/default/objects/Opportunity/listViews/Default_Opportunity_Pipeline.listView-meta.xml\"\n - \"force-app/main/default/objects/Opportunity/listViews/MyCurrentSubscriptions.listView-meta.xml\"\n - \"force-app/main/default/objects/Opportunity/listViews/MySubscriptions.listView-meta.xml\"\n - \"force-app/main/default/objects/Account/listViews/MyActivePartners.listView-meta.xml\"\n```\n\n- If manually written, this could also be:\n\n```yaml\nlistViewsToSetToMine:\n - \"Operation__c:MyCurrentOperations\"\n - \"Operation__c:MyFinalizedOperations\"\n - \"Opportunity:Default_Opportunity_Pipeline\"\n - \"Opportunity:MyCurrentSubscriptions\"\n - \"Opportunity:MySubscriptions\"\n - \"Account:MyActivePartners\"\n```\n\nTroubleshooting: if you need to run this command from an alpine-linux based docker image, use this workaround in your dockerfile:\n\n```dockerfile\n# Do not use puppeteer embedded chromium\nRUN apk add --update --no-cache chromium\nENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=\"true\"\nENV CHROMIUM_PATH=\"/usr/bin/chromium-browser\"\nENV PUPPETEER_EXECUTABLE_PATH=\"$\\{CHROMIUM_PATH}\" // remove \\ before {\n```\n",
6808
+ "description": "\n## Command Behavior\n\n**Exports file attachments (ContentVersion, Attachment) from a Salesforce org based on a predefined configuration.**\n\nThis command enables the mass download of files associated with Salesforce records, providing a robust solution for backing up files, migrating them to other systems, or integrating them with external document management solutions.\n\nKey functionalities:\n\n- **Configuration-Driven Export:** Relies on an `export.json` file within a designated file export project to define the export criteria, including the SOQL query for parent records, file types to export, output naming conventions, and file size filtering.\n- **File Size Filtering:** Supports minimum file size filtering via the `fileSizeMin` configuration parameter (in KB). Files smaller than the specified size will be skipped during export.\n- **File Validation:** After downloading each file, validates the integrity by:\n - **Checksum Validation:** For ContentVersion files, compares MD5 checksum with Salesforce's stored checksum\n - **Size Validation:** For both ContentVersion and Attachment files, verifies actual file size matches expected size\n - **Status Tracking:** Files are categorized with specific statuses: `success` (valid files), `failed` (download errors), `skipped` (filtered files), `invalid` (downloaded but failed validation)\n - All validation results are logged in the CSV export log for audit purposes\n- **Resume/Restart Capability:** \n - **Resume Mode:** When `--resume` flag is used (default in CI environments), checks existing downloaded files for validity. Valid files are skipped, invalid files are re-downloaded.\n - **Restart Mode:** When resume is disabled, clears the output folder and starts a fresh export.\n - **Interactive Mode:** When existing files are found and `--resume` is not explicitly specified (non-CI environments), prompts the user to choose between resume or restart.\n- **Interactive Project Selection:** If the file export project path is not provided via the `--path` flag, it interactively prompts the user to select one.\n- **Configurable Export Options:** Allows overriding default export settings such as `chunksize` (number of records processed in a batch), `polltimeout` (timeout for Bulk API calls), and `startchunknumber` (to resume a failed export).\n- **Support for ContentVersion and Attachment:** Handles both modern Salesforce Files (ContentVersion) and older Attachments.\n\nSee this article for a practical example:\n\n[![How to mass download notes and attachments files from a Salesforce org](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-mass-download.jpg)](https://nicolas.vuillamy.fr/how-to-mass-download-notes-and-attachments-files-from-a-salesforce-org-83a028824afd)\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **FilesExporter Class:** The core logic is encapsulated within the `FilesExporter` class, which orchestrates the entire export process.\n- **SOQL Queries (Bulk API):** It uses Salesforce Bulk API queries to efficiently retrieve large volumes of parent record IDs and file metadata, including checksums and file sizes.\n- **File Download:** Downloads the actual file content from Salesforce.\n- **File Validation:** After each successful download, validates file integrity by comparing checksums (ContentVersion) and file sizes (both ContentVersion and Attachment) against Salesforce metadata.\n- **Resume Logic:** In resume mode, checks for existing files before downloading, validates their integrity, and only re-downloads invalid or missing files. This enables efficient recovery from interrupted exports.\n- **File System Operations:** Writes the downloaded files to the local file system, organizing them into folders based on the configured naming conventions.\n- **Configuration Loading:** Reads the `export.json` file to get the export configuration. It also allows for interactive overriding of these settings.\n- **Interactive Prompts:** Uses `selectFilesWorkspace` to allow the user to choose a file export project, `promptFilesExportConfiguration` for customizing export options, and prompts for resume/restart choice when existing files are found.\n- **Error Handling:** Includes mechanisms to handle potential errors during the export process, such as network issues, API limits, and file validation failures. Each file is assigned a specific status (`success`, `failed`, `skipped`, `invalid`) for comprehensive tracking and troubleshooting.\n</details>\n",
7078
6809
  "examples": [
7079
- "$ sf hardis:org:fix:listviewmine",
7080
- "$ sf hardis:org:fix:listviewmine --listviews Opportunity:MySubscriptions,Account:MyActivePartners"
6810
+ "$ sf hardis:org:files:export"
7081
6811
  ],
7082
6812
  "flags": {
7083
6813
  "json": {
@@ -7095,14 +6825,48 @@
7095
6825
  "multiple": false,
7096
6826
  "type": "option"
7097
6827
  },
7098
- "listviews": {
7099
- "char": "l",
7100
- "description": "Comma-separated list of listviews following format Object:ListViewName\nExample: Contact:MyContacts,Contact:MyActiveContacts,Opportunity:MYClosedOpportunities",
7101
- "name": "listviews",
6828
+ "path": {
6829
+ "char": "p",
6830
+ "description": "Path to the file export project",
6831
+ "name": "path",
6832
+ "hasDynamicHelp": false,
6833
+ "multiple": false,
6834
+ "type": "option"
6835
+ },
6836
+ "chunksize": {
6837
+ "char": "c",
6838
+ "description": "Number of records to add in a chunk before it is processed",
6839
+ "name": "chunksize",
6840
+ "default": 1000,
6841
+ "hasDynamicHelp": false,
6842
+ "multiple": false,
6843
+ "type": "option"
6844
+ },
6845
+ "polltimeout": {
6846
+ "char": "t",
6847
+ "description": "Timeout in MS for Bulk API calls",
6848
+ "name": "polltimeout",
6849
+ "default": 300000,
6850
+ "hasDynamicHelp": false,
6851
+ "multiple": false,
6852
+ "type": "option"
6853
+ },
6854
+ "startchunknumber": {
6855
+ "char": "s",
6856
+ "description": "Chunk number to start from",
6857
+ "name": "startchunknumber",
6858
+ "default": 0,
7102
6859
  "hasDynamicHelp": false,
7103
6860
  "multiple": false,
7104
6861
  "type": "option"
7105
6862
  },
6863
+ "resume": {
6864
+ "char": "r",
6865
+ "description": "Resume previous export by checking existing files (default in CI)",
6866
+ "name": "resume",
6867
+ "allowNo": false,
6868
+ "type": "boolean"
6869
+ },
7106
6870
  "debug": {
7107
6871
  "char": "d",
7108
6872
  "description": "Activate debug mode (more logs)",
@@ -7141,14 +6905,250 @@
7141
6905
  },
7142
6906
  "hasDynamicHelp": true,
7143
6907
  "hiddenAliases": [],
7144
- "id": "hardis:org:fix:listviewmine",
6908
+ "id": "hardis:org:files:export",
7145
6909
  "pluginAlias": "sfdx-hardis",
7146
6910
  "pluginName": "sfdx-hardis",
7147
6911
  "pluginType": "core",
7148
6912
  "strict": true,
7149
6913
  "enableJsonFlag": true,
7150
- "title": "Fix listviews with ",
7151
- "requiresProject": true,
6914
+ "title": "Export files",
6915
+ "requiresProject": false,
6916
+ "isESM": true,
6917
+ "relativePath": [
6918
+ "lib",
6919
+ "commands",
6920
+ "hardis",
6921
+ "org",
6922
+ "files",
6923
+ "export.js"
6924
+ ],
6925
+ "aliasPermutations": [],
6926
+ "permutations": [
6927
+ "hardis:org:files:export",
6928
+ "org:hardis:files:export",
6929
+ "org:files:hardis:export",
6930
+ "org:files:export:hardis",
6931
+ "hardis:files:org:export",
6932
+ "files:hardis:org:export",
6933
+ "files:org:hardis:export",
6934
+ "files:org:export:hardis",
6935
+ "hardis:files:export:org",
6936
+ "files:hardis:export:org",
6937
+ "files:export:hardis:org",
6938
+ "files:export:org:hardis",
6939
+ "hardis:org:export:files",
6940
+ "org:hardis:export:files",
6941
+ "org:export:hardis:files",
6942
+ "org:export:files:hardis",
6943
+ "hardis:export:org:files",
6944
+ "export:hardis:org:files",
6945
+ "export:org:hardis:files",
6946
+ "export:org:files:hardis",
6947
+ "hardis:export:files:org",
6948
+ "export:hardis:files:org",
6949
+ "export:files:hardis:org",
6950
+ "export:files:org:hardis"
6951
+ ]
6952
+ },
6953
+ "hardis:org:files:import": {
6954
+ "aliases": [],
6955
+ "args": {},
6956
+ "description": "\nThis command facilitates the mass upload of files into Salesforce, allowing you to populate records with associated documents, images, or other file types. It's a crucial tool for data migration, content seeding, or synchronizing external file repositories with Salesforce.\n\nKey functionalities:\n\n- **Configuration-Driven Import:** Relies on an `export.json` file within a designated file export project (created using `sf hardis:org:configure:files`) to determine which files to import and how they should be associated with Salesforce records.\n- **Interactive Project Selection:** If the file import project path is not provided via the `--path` flag, it interactively prompts the user to select one.\n- **Overwrite Option:** The `--overwrite` flag allows you to replace existing files in Salesforce with local versions that have the same name. Be aware that this option doubles the number of API calls used.\n- **Support for ContentVersion and Attachment:** Handles both modern Salesforce Files (ContentVersion) and older Attachments.\n\nSee this article for how to export files, which is often a prerequisite for importing:\n\n[![How to mass download notes and attachments files from a Salesforce org](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-mass-download.jpg)](https://nicolas.vuillamy.fr/how-to-mass-download-notes-and-attachments-files-from-a-salesforce-org-83a028824afd)\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **FilesImporter Class:** The core logic is encapsulated within the `FilesImporter` class, which orchestrates the entire import process.\n- **File System Scan:** Scans the local file system within the configured project directory to identify files for import.\n- **Salesforce API Interaction:** Uses Salesforce APIs (e.g., ContentVersion, Attachment) to upload files and associate them with records.\n- **Configuration Loading:** Reads the `export.json` file to get the import configuration, including SOQL queries to identify parent records for file association.\n- **Interactive Prompts:** Uses `selectFilesWorkspace` to allow the user to choose a file import project and `prompts` for confirming the overwrite behavior.\n- **Error Handling:** Includes mechanisms to handle potential errors during the import process, such as API limits or file upload failures.\n</details>\n",
6957
+ "examples": [
6958
+ "$ sf hardis:org:files:import"
6959
+ ],
6960
+ "flags": {
6961
+ "json": {
6962
+ "description": "Format output as json.",
6963
+ "helpGroup": "GLOBAL",
6964
+ "name": "json",
6965
+ "allowNo": false,
6966
+ "type": "boolean"
6967
+ },
6968
+ "flags-dir": {
6969
+ "helpGroup": "GLOBAL",
6970
+ "name": "flags-dir",
6971
+ "summary": "Import flag values from a directory.",
6972
+ "hasDynamicHelp": false,
6973
+ "multiple": false,
6974
+ "type": "option"
6975
+ },
6976
+ "path": {
6977
+ "char": "p",
6978
+ "description": "Path to the file export project",
6979
+ "name": "path",
6980
+ "hasDynamicHelp": false,
6981
+ "multiple": false,
6982
+ "type": "option"
6983
+ },
6984
+ "overwrite": {
6985
+ "char": "f",
6986
+ "description": "Override existing files (doubles the number of API calls)",
6987
+ "name": "overwrite",
6988
+ "allowNo": false,
6989
+ "type": "boolean"
6990
+ },
6991
+ "debug": {
6992
+ "char": "d",
6993
+ "description": "Activate debug mode (more logs)",
6994
+ "name": "debug",
6995
+ "allowNo": false,
6996
+ "type": "boolean"
6997
+ },
6998
+ "websocket": {
6999
+ "description": "Websocket host:port for VsCode SFDX Hardis UI integration",
7000
+ "name": "websocket",
7001
+ "hasDynamicHelp": false,
7002
+ "multiple": false,
7003
+ "type": "option"
7004
+ },
7005
+ "skipauth": {
7006
+ "description": "Skip authentication check when a default username is required",
7007
+ "name": "skipauth",
7008
+ "allowNo": false,
7009
+ "type": "boolean"
7010
+ },
7011
+ "target-org": {
7012
+ "aliases": [
7013
+ "targetusername",
7014
+ "u"
7015
+ ],
7016
+ "char": "o",
7017
+ "deprecateAliases": true,
7018
+ "name": "target-org",
7019
+ "noCacheDefault": true,
7020
+ "required": true,
7021
+ "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
7022
+ "hasDynamicHelp": true,
7023
+ "multiple": false,
7024
+ "type": "option"
7025
+ }
7026
+ },
7027
+ "hasDynamicHelp": true,
7028
+ "hiddenAliases": [],
7029
+ "id": "hardis:org:files:import",
7030
+ "pluginAlias": "sfdx-hardis",
7031
+ "pluginName": "sfdx-hardis",
7032
+ "pluginType": "core",
7033
+ "strict": true,
7034
+ "enableJsonFlag": true,
7035
+ "title": "Import files",
7036
+ "requiresProject": false,
7037
+ "isESM": true,
7038
+ "relativePath": [
7039
+ "lib",
7040
+ "commands",
7041
+ "hardis",
7042
+ "org",
7043
+ "files",
7044
+ "import.js"
7045
+ ],
7046
+ "aliasPermutations": [],
7047
+ "permutations": [
7048
+ "hardis:org:files:import",
7049
+ "org:hardis:files:import",
7050
+ "org:files:hardis:import",
7051
+ "org:files:import:hardis",
7052
+ "hardis:files:org:import",
7053
+ "files:hardis:org:import",
7054
+ "files:org:hardis:import",
7055
+ "files:org:import:hardis",
7056
+ "hardis:files:import:org",
7057
+ "files:hardis:import:org",
7058
+ "files:import:hardis:org",
7059
+ "files:import:org:hardis",
7060
+ "hardis:org:import:files",
7061
+ "org:hardis:import:files",
7062
+ "org:import:hardis:files",
7063
+ "org:import:files:hardis",
7064
+ "hardis:import:org:files",
7065
+ "import:hardis:org:files",
7066
+ "import:org:hardis:files",
7067
+ "import:org:files:hardis",
7068
+ "hardis:import:files:org",
7069
+ "import:hardis:files:org",
7070
+ "import:files:hardis:org",
7071
+ "import:files:org:hardis"
7072
+ ]
7073
+ },
7074
+ "hardis:org:fix:listviewmine": {
7075
+ "aliases": [],
7076
+ "args": {},
7077
+ "description": "Fix listviews whose scope Mine has been replaced by Everything\n\n[![Invalid scope:Mine, not allowed ? Deploy your ListViews anyway !](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-invalid-scope-mine.jpg)](https://nicolas.vuillamy.fr/invalid-scope-mine-not-allowed-deploy-your-listviews-anyway-443aceca8ac7)\n\nList of ListViews can be:\n\n- read from .sfdx-hardis.yml file in property **listViewsToSetToMine**\n- sent in argument listviews\n\nNote: property **listViewsToSetToMine** can be auto-generated by command hardis:work:save if .sfdx-hardis.yml contains the following configuration\n\n```yaml\nautoCleanTypes:\n - listViewsMine\n```\n\n- Example of sfdx-hardis.yml property `listViewsToSetToMine`:\n\n```yaml\nlistViewsToSetToMine:\n - \"force-app/main/default/objects/Operation__c/listViews/MyCurrentOperations.listView-meta.xml\"\n - \"force-app/main/default/objects/Operation__c/listViews/MyFinalizedOperations.listView-meta.xml\"\n - \"force-app/main/default/objects/Opportunity/listViews/Default_Opportunity_Pipeline.listView-meta.xml\"\n - \"force-app/main/default/objects/Opportunity/listViews/MyCurrentSubscriptions.listView-meta.xml\"\n - \"force-app/main/default/objects/Opportunity/listViews/MySubscriptions.listView-meta.xml\"\n - \"force-app/main/default/objects/Account/listViews/MyActivePartners.listView-meta.xml\"\n```\n\n- If manually written, this could also be:\n\n```yaml\nlistViewsToSetToMine:\n - \"Operation__c:MyCurrentOperations\"\n - \"Operation__c:MyFinalizedOperations\"\n - \"Opportunity:Default_Opportunity_Pipeline\"\n - \"Opportunity:MyCurrentSubscriptions\"\n - \"Opportunity:MySubscriptions\"\n - \"Account:MyActivePartners\"\n```\n\nTroubleshooting: if you need to run this command from an alpine-linux based docker image, use this workaround in your dockerfile:\n\n```dockerfile\n# Do not use puppeteer embedded chromium\nRUN apk add --update --no-cache chromium\nENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=\"true\"\nENV CHROMIUM_PATH=\"/usr/bin/chromium-browser\"\nENV PUPPETEER_EXECUTABLE_PATH=\"$\\{CHROMIUM_PATH}\" // remove \\ before {\n```\n",
7078
+ "examples": [
7079
+ "$ sf hardis:org:fix:listviewmine",
7080
+ "$ sf hardis:org:fix:listviewmine --listviews Opportunity:MySubscriptions,Account:MyActivePartners"
7081
+ ],
7082
+ "flags": {
7083
+ "json": {
7084
+ "description": "Format output as json.",
7085
+ "helpGroup": "GLOBAL",
7086
+ "name": "json",
7087
+ "allowNo": false,
7088
+ "type": "boolean"
7089
+ },
7090
+ "flags-dir": {
7091
+ "helpGroup": "GLOBAL",
7092
+ "name": "flags-dir",
7093
+ "summary": "Import flag values from a directory.",
7094
+ "hasDynamicHelp": false,
7095
+ "multiple": false,
7096
+ "type": "option"
7097
+ },
7098
+ "listviews": {
7099
+ "char": "l",
7100
+ "description": "Comma-separated list of listviews following format Object:ListViewName\nExample: Contact:MyContacts,Contact:MyActiveContacts,Opportunity:MYClosedOpportunities",
7101
+ "name": "listviews",
7102
+ "hasDynamicHelp": false,
7103
+ "multiple": false,
7104
+ "type": "option"
7105
+ },
7106
+ "debug": {
7107
+ "char": "d",
7108
+ "description": "Activate debug mode (more logs)",
7109
+ "name": "debug",
7110
+ "allowNo": false,
7111
+ "type": "boolean"
7112
+ },
7113
+ "websocket": {
7114
+ "description": "Websocket host:port for VsCode SFDX Hardis UI integration",
7115
+ "name": "websocket",
7116
+ "hasDynamicHelp": false,
7117
+ "multiple": false,
7118
+ "type": "option"
7119
+ },
7120
+ "skipauth": {
7121
+ "description": "Skip authentication check when a default username is required",
7122
+ "name": "skipauth",
7123
+ "allowNo": false,
7124
+ "type": "boolean"
7125
+ },
7126
+ "target-org": {
7127
+ "aliases": [
7128
+ "targetusername",
7129
+ "u"
7130
+ ],
7131
+ "char": "o",
7132
+ "deprecateAliases": true,
7133
+ "name": "target-org",
7134
+ "noCacheDefault": true,
7135
+ "required": true,
7136
+ "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
7137
+ "hasDynamicHelp": true,
7138
+ "multiple": false,
7139
+ "type": "option"
7140
+ }
7141
+ },
7142
+ "hasDynamicHelp": true,
7143
+ "hiddenAliases": [],
7144
+ "id": "hardis:org:fix:listviewmine",
7145
+ "pluginAlias": "sfdx-hardis",
7146
+ "pluginName": "sfdx-hardis",
7147
+ "pluginType": "core",
7148
+ "strict": true,
7149
+ "enableJsonFlag": true,
7150
+ "title": "Fix listviews with ",
7151
+ "requiresProject": true,
7152
7152
  "isESM": true,
7153
7153
  "relativePath": [
7154
7154
  "lib",
@@ -11407,19 +11407,14 @@
11407
11407
  "xml:clean:project:hardis"
11408
11408
  ]
11409
11409
  },
11410
- "hardis:project:generate:bypass": {
11410
+ "hardis:project:deploy:notify": {
11411
11411
  "aliases": [],
11412
11412
  "args": {},
11413
- "description": "\n## Command Behavior\n\n**Generates custom permissions and permission sets to bypass specified Salesforce automations (Flows, Triggers, and Validation Rules) for specific sObjects.**\n\nThis command provides a controlled mechanism to temporarily or permanently disable automations for certain sObjects, which is invaluable for:\n\n- **Data Loading:** Bypassing validation rules or triggers during large data imports.\n- **Troubleshooting:** Isolating automation issues by temporarily disabling them.\n- **Development:** Allowing developers to work on specific sObjects without triggering complex automations.\n\nKey functionalities:\n\n- **sObject Selection:** You can specify a comma-separated list of sObjects to bypass (e.g., `Account,Contact`). If omitted, an interactive prompt will allow you to select from available sObjects.\n- **Automation Type Selection:** Choose which types of automations to bypass: `Flow`, `Trigger`, or `VR` (Validation Rules). If omitted, an interactive prompt will guide your selection.\n- **Automatic Bypass Application:** Optionally, the command can automatically inject bypass logic into Validation Rules and Triggers. This involves modifying the Apex code for Triggers and the XML for Validation Rules.\n- **Metadata Source:** You can choose to retrieve the metadata elements (Validation Rules, Triggers) from the org (`--metadata-source org`) or use local files (`--metadata-source local`). Retrieving from the org is recommended for accuracy.\n- **Custom Permission and Permission Set Generation:** For each selected sObject and automation type, it generates:\n - A **Custom Permission** (e.g., `BypassAccountFlows`) that acts as the bypass switch.\n - A **Permission Set** (e.g., `BypassAccountFlows`) that grants the generated Custom Permission.\n- **Credits Inclusion:** By default, generated XML files include a comment indicating they were generated by sfdx-hardis. This can be skipped using `--skip-credits`.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **SOQL Queries (Tooling API):** It queries `EntityDefinition` to list customizable sObjects and `ValidationRule` and `ApexTrigger` to find existing automations.\n- **Interactive Prompts:** Uses the `prompts` library to guide the user through selecting sObjects, automation types, and bypass application options.\n- **XML Generation:** Dynamically generates XML content for Custom Permissions and Permission Sets, including descriptions and labels that clearly indicate their purpose.\n- **File System Operations:** Uses `fs-extra` to create directories and write the generated Custom Permission and Permission Set XML files.\n- **Metadata Retrieval (for Bypass Application):** If `apply-to-vrs` or `apply-to-triggers` is used and `metadata-source` is `org`, it retrieves the relevant Validation Rule or Apex Trigger metadata from the org using `sf project retrieve start`.\n- **XML/Apex Code Modification:**\n - For Validation Rules, it modifies the `errorConditionFormula` in the XML to include a check for the bypass Custom Permission.\n - For Apex Triggers, it injects an `if` statement at the beginning of the trigger body to check for the bypass Custom Permission.\n- **`parseXmlFile` and `writeXmlFile`:** Used for reading and writing XML metadata files.\n- **`execCommand`:** Used for executing Salesforce CLI commands, particularly for metadata retrieval.\n- **Error Handling:** Includes checks for invalid sObject or automation selections and provides informative error messages.\n</details>\n",
11413
+ "description": "Post notifications related to:\n\n- **Deployment simulation** _(use with --check-only)_\n\n- **Deployment process** _(to call only if your deployment is successful)_\n\n### Integrations\n\nAccording to the [integrations you configured](https://sfdx-hardis.cloudity.com/salesforce-ci-cd-setup-integrations-home/), notifications can contain deployment information and [Flow Visual Git Diff](https://sfdx-hardis.cloudity.com/salesforce-deployment-assistant-home/#flow-visual-git-diff)\n\n - GitHub, Gitlab, Azure DevOps, Bitbucket comments on Pull Requests (including Flows Visual Git Diff)\n\n - Slack, Microsoft Teams, Email deployment summary after a successful deployment\n\n - JIRA tags and comments on tickets that just has been deployed\n\n![](https://sfdx-hardis.cloudity.com/assets/images/screenshot-jira-gitlab.jpg)\n\n![](https://sfdx-hardis.cloudity.com/assets/images/screenshot-jira-slack.jpg)\n\n### Flows Visual Git Diff\n\n- Visually show you the differences on a diagram\n\n- Display the update details without having to open any XML !\n\n🟩 = added\n\n🟥 = removed\n\n🟧 = updated\n\n![](https://sfdx-hardis.cloudity.com/assets/images/flow-visual-git-diff.jpg)\n\n![](https://sfdx-hardis.cloudity.com/assets/images/flow-visual-git-diff-2.jpg)\n\n### In custom CI/CD workflow\n\nExample of usage in a custom CI/CD pipeline:\n\n```bash\n# Disable exit-on-error temporarily\nset +e\n\n# Run the deploy command\nsf project deploy start [....]\nRET_CODE=$?\n\n# Re-enable exit-on-error\nset -e\n\n# Determine MYSTATUS based on return code\nif [ $RET_CODE -eq 0 ]; then\n MYSTATUS=\"valid\"\nelse\n MYSTATUS=\"invalid\"\nfi\n\n# Run the notify command with MYSTATUS\nsf hardis:project:deploy:notify --check-only --deploy-status \"$MYSTATUS\"\n```\n\n### Other usages\n\nThis command is for custom SF Cli pipelines, if you are a sfdx-hardis user, it is already embedded in sf hardis:deploy:smart.\n\nYou can also use [sfdx-hardis wrapper commands of SF deployment commands](https://sfdx-hardis.cloudity.com/salesforce-deployment-assistant-setup/#using-custom-cicd-pipeline)\n",
11414
11414
  "examples": [
11415
- "$ sf hardis:project:generate:bypass",
11416
- "$ sf hardis:project:generate:bypass --sObjects Account,Contact,Opportunity",
11417
- "$ sf hardis:project:generate:bypass --automations Flow,Trigger,VR",
11418
- "$ sf hardis:project:generate:bypass --sObjects Account,Opportunity --automations Flow,Trigger",
11419
- "$ sf hardis:project:generate:bypass --skipCredits",
11420
- "$ sf hardis:project:generate:bypass --apply-to-vrs",
11421
- "$ sf hardis:project:generate:bypass --apply-to-triggers",
11422
- "$ sf hardis:project:generate:bypass --metadata-source org"
11415
+ "$ sf hardis:project:deploy:notify --check-only --deploy-status valid --message \"This deployment check is valid\\n\\nYahooo !!\"",
11416
+ "$ sf hardis:project:deploy:notify --check-only --deploy-status invalid --message \"This deployment check has failed !\\n\\Oh no !!\"",
11417
+ "$ sf hardis:project:deploy:notify --deploy-status valid --message \"This deployment has been processed !\\n\\nYahooo !!\""
11423
11418
  ],
11424
11419
  "flags": {
11425
11420
  "json": {
@@ -11437,42 +11432,43 @@
11437
11432
  "multiple": false,
11438
11433
  "type": "option"
11439
11434
  },
11440
- "target-org": {
11441
- "aliases": [
11442
- "targetusername",
11443
- "u"
11444
- ],
11445
- "char": "o",
11446
- "deprecateAliases": true,
11447
- "name": "target-org",
11448
- "noCacheDefault": true,
11449
- "required": true,
11450
- "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
11451
- "hasDynamicHelp": true,
11452
- "multiple": false,
11453
- "type": "option"
11435
+ "check-only": {
11436
+ "char": "c",
11437
+ "description": "Use this option to send notifications from a Deployment simulation job",
11438
+ "name": "check-only",
11439
+ "allowNo": false,
11440
+ "type": "boolean"
11454
11441
  },
11455
- "objects": {
11456
- "aliases": [
11457
- "sObjects"
11458
- ],
11442
+ "deploy-status": {
11459
11443
  "char": "s",
11460
- "description": "Comma-separated list of sObjects to bypass (e.g., Account,Contact,Opportunity). If omitted, you will be prompted to select.",
11461
- "name": "objects",
11462
- "required": false,
11444
+ "description": "Send success, failure or unknown (default) to indicate if the deployment or deployment simulation is in success or not",
11445
+ "name": "deploy-status",
11446
+ "default": "unknown",
11463
11447
  "hasDynamicHelp": false,
11464
11448
  "multiple": false,
11449
+ "options": [
11450
+ "valid",
11451
+ "invalid",
11452
+ "unknown"
11453
+ ],
11465
11454
  "type": "option"
11466
11455
  },
11467
- "automations": {
11468
- "char": "a",
11469
- "description": "Comma-separated automations to bypass: Flow, Trigger, VR",
11470
- "name": "automations",
11471
- "required": false,
11456
+ "message": {
11457
+ "char": "m",
11458
+ "description": "Custom message that you want to be added in notifications (string or markdown format)",
11459
+ "name": "message",
11460
+ "default": "",
11472
11461
  "hasDynamicHelp": false,
11473
11462
  "multiple": false,
11474
11463
  "type": "option"
11475
11464
  },
11465
+ "debug": {
11466
+ "char": "d",
11467
+ "description": "Activate debug mode (more logs)",
11468
+ "name": "debug",
11469
+ "allowNo": false,
11470
+ "type": "boolean"
11471
+ },
11476
11472
  "websocket": {
11477
11473
  "description": "Websocket host:port for VsCode SFDX Hardis UI integration",
11478
11474
  "name": "websocket",
@@ -11486,103 +11482,75 @@
11486
11482
  "allowNo": false,
11487
11483
  "type": "boolean"
11488
11484
  },
11489
- "skip-credits": {
11490
- "aliases": [
11491
- "skipCredits"
11492
- ],
11493
- "char": "k",
11494
- "description": "Omit the \"Generated by\" line in the XML files",
11495
- "name": "skip-credits",
11496
- "required": false,
11497
- "allowNo": false,
11498
- "type": "boolean"
11499
- },
11500
- "apply-to-vrs": {
11501
- "aliases": [
11502
- "applyToVrs"
11503
- ],
11504
- "description": "Apply bypass to Validation Rules",
11505
- "name": "apply-to-vrs",
11506
- "required": false,
11507
- "allowNo": false,
11508
- "type": "boolean"
11509
- },
11510
- "apply-to-triggers": {
11511
- "aliases": [
11512
- "applyToTriggers"
11513
- ],
11514
- "description": "Apply bypass to Triggers",
11515
- "name": "apply-to-triggers",
11516
- "required": false,
11517
- "allowNo": false,
11518
- "type": "boolean"
11519
- },
11520
- "metadata-source": {
11485
+ "target-org": {
11521
11486
  "aliases": [
11522
- "metadataSource"
11487
+ "targetusername",
11488
+ "u"
11523
11489
  ],
11524
- "char": "r",
11525
- "description": "Source of metadata elements to apply bypass to. Options: 'org' or 'local'.",
11526
- "name": "metadata-source",
11527
- "required": false,
11528
- "hasDynamicHelp": false,
11490
+ "char": "o",
11491
+ "deprecateAliases": true,
11492
+ "name": "target-org",
11493
+ "noCacheDefault": true,
11494
+ "required": true,
11495
+ "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
11496
+ "hasDynamicHelp": true,
11529
11497
  "multiple": false,
11530
11498
  "type": "option"
11531
11499
  }
11532
11500
  },
11533
11501
  "hasDynamicHelp": true,
11534
11502
  "hiddenAliases": [],
11535
- "id": "hardis:project:generate:bypass",
11503
+ "id": "hardis:project:deploy:notify",
11536
11504
  "pluginAlias": "sfdx-hardis",
11537
11505
  "pluginName": "sfdx-hardis",
11538
11506
  "pluginType": "core",
11539
11507
  "strict": true,
11540
11508
  "enableJsonFlag": true,
11509
+ "title": "Deployment Notifications",
11510
+ "requiresProject": true,
11541
11511
  "isESM": true,
11542
11512
  "relativePath": [
11543
11513
  "lib",
11544
11514
  "commands",
11545
11515
  "hardis",
11546
11516
  "project",
11547
- "generate",
11548
- "bypass.js"
11517
+ "deploy",
11518
+ "notify.js"
11549
11519
  ],
11550
11520
  "aliasPermutations": [],
11551
11521
  "permutations": [
11552
- "hardis:project:generate:bypass",
11553
- "project:hardis:generate:bypass",
11554
- "project:generate:hardis:bypass",
11555
- "project:generate:bypass:hardis",
11556
- "hardis:generate:project:bypass",
11557
- "generate:hardis:project:bypass",
11558
- "generate:project:hardis:bypass",
11559
- "generate:project:bypass:hardis",
11560
- "hardis:generate:bypass:project",
11561
- "generate:hardis:bypass:project",
11562
- "generate:bypass:hardis:project",
11563
- "generate:bypass:project:hardis",
11564
- "hardis:project:bypass:generate",
11565
- "project:hardis:bypass:generate",
11566
- "project:bypass:hardis:generate",
11567
- "project:bypass:generate:hardis",
11568
- "hardis:bypass:project:generate",
11569
- "bypass:hardis:project:generate",
11570
- "bypass:project:hardis:generate",
11571
- "bypass:project:generate:hardis",
11572
- "hardis:bypass:generate:project",
11573
- "bypass:hardis:generate:project",
11574
- "bypass:generate:hardis:project",
11575
- "bypass:generate:project:hardis"
11522
+ "hardis:project:deploy:notify",
11523
+ "project:hardis:deploy:notify",
11524
+ "project:deploy:hardis:notify",
11525
+ "project:deploy:notify:hardis",
11526
+ "hardis:deploy:project:notify",
11527
+ "deploy:hardis:project:notify",
11528
+ "deploy:project:hardis:notify",
11529
+ "deploy:project:notify:hardis",
11530
+ "hardis:deploy:notify:project",
11531
+ "deploy:hardis:notify:project",
11532
+ "deploy:notify:hardis:project",
11533
+ "deploy:notify:project:hardis",
11534
+ "hardis:project:notify:deploy",
11535
+ "project:hardis:notify:deploy",
11536
+ "project:notify:hardis:deploy",
11537
+ "project:notify:deploy:hardis",
11538
+ "hardis:notify:project:deploy",
11539
+ "notify:hardis:project:deploy",
11540
+ "notify:project:hardis:deploy",
11541
+ "notify:project:deploy:hardis",
11542
+ "hardis:notify:deploy:project",
11543
+ "notify:hardis:deploy:project",
11544
+ "notify:deploy:hardis:project",
11545
+ "notify:deploy:project:hardis"
11576
11546
  ]
11577
11547
  },
11578
- "hardis:project:generate:flow-git-diff": {
11579
- "aliases": [],
11580
- "args": {},
11581
- "description": "Generate Flow Visual Git Diff markdown between 2 commits\n\nNote: This command might requires @mermaid-js/mermaid-cli to be installed.\n\nRun `npm install @mermaid-js/mermaid-cli --global`\n ",
11582
- "examples": [
11583
- "$ sf hardis:project:generate:flow-git-diff",
11584
- "$ sf hardis:project:generate:flow-git-diff --flow \"force-app/main/default/flows/Opportunity_AfterUpdate_Cloudity.flow-meta.xml\" --commit-before 8bd290e914c9dbdde859dad7e3c399776160d704 --commit-after e0835251bef6e400fb91e42f3a31022f37840f65"
11548
+ "hardis:project:deploy:quick": {
11549
+ "aliases": [
11550
+ "hardis:deploy:quick"
11585
11551
  ],
11552
+ "args": {},
11553
+ "description": "sfdx-hardis wrapper for **sf project deploy quick** that displays tips to solve deployment errors.\n\nNote: Use **--json** argument to have better results\n\n[![Assisted solving of Salesforce deployments errors](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-deployment-errors.jpg)](https://nicolas.vuillamy.fr/assisted-solving-of-salesforce-deployments-errors-47f3666a9ed0)\n\n[See documentation of Salesforce command](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_project_commands_unified.htm#cli_reference_project_deploy_quick_unified)\n\n### Deployment pre or post commands\n\nYou can define command lines to run before or after a deployment, with parameters:\n\n- **id**: Unique Id for the command\n- **label**: Human readable label for the command\n- **skipIfError**: If defined to \"true\", the post-command won't be run if there is a deployment failure\n- **context**: Defines the context where the command will be run. Can be **all** (default), **check-deployment-only** or **process-deployment-only**\n- **runOnlyOnceByOrg**: If set to true, the command will be run only one time per org. A record of SfdxHardisTrace__c is stored to make that possible (it needs to be existing in target org)\n\nIf the commands are not the same depending on the target org, you can define them into **config/branches/.sfdx-hardis-BRANCHNAME.yml** instead of root **config/.sfdx-hardis.yml**\n\nExample:\n\n```yaml\ncommandsPreDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to the deployment user\n command: sf data update record --sobject User --where \"Username='deploy.github@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n\ncommandsPostDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to desired username\n command: sf data update record --sobject User --where \"Username='admin-yser@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n - id: someActionToRunJustOneTime\n label: And to run only if deployment is success\n command: sf sfdmu:run ...\n skipIfError: true\n context: process-deployment-only\n runOnlyOnceByOrg: true\n```\n",
11586
11554
  "flags": {
11587
11555
  "json": {
11588
11556
  "description": "Format output as json.",
@@ -11599,59 +11567,82 @@
11599
11567
  "multiple": false,
11600
11568
  "type": "option"
11601
11569
  },
11602
- "flow": {
11603
- "description": "Path to flow file (will be prompted if not set)",
11604
- "name": "flow",
11570
+ "api-version": {
11571
+ "char": "a",
11572
+ "description": "api-version",
11573
+ "name": "api-version",
11605
11574
  "hasDynamicHelp": false,
11606
11575
  "multiple": false,
11607
11576
  "type": "option"
11608
11577
  },
11609
- "commit-before": {
11610
- "description": "Hash of the commit of the previous flow state, or \"allStates\" (will be prompted if not set)",
11611
- "name": "commit-before",
11612
- "default": "",
11578
+ "async": {
11579
+ "description": "async",
11580
+ "exclusive": [
11581
+ "wait"
11582
+ ],
11583
+ "name": "async",
11584
+ "allowNo": false,
11585
+ "type": "boolean"
11586
+ },
11587
+ "target-org": {
11588
+ "char": "o",
11589
+ "name": "target-org",
11590
+ "noCacheDefault": true,
11591
+ "required": true,
11592
+ "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
11593
+ "hasDynamicHelp": true,
11594
+ "multiple": false,
11595
+ "type": "option"
11596
+ },
11597
+ "tests": {
11598
+ "description": "tests",
11599
+ "name": "tests",
11613
11600
  "hasDynamicHelp": false,
11614
11601
  "multiple": false,
11615
11602
  "type": "option"
11616
11603
  },
11617
- "commit-after": {
11618
- "description": "Hash of the commit of the new flow state (will be prompted if not set)",
11619
- "name": "commit-after",
11620
- "default": "",
11604
+ "--job-id": {
11605
+ "char": "i",
11606
+ "description": "job-id",
11607
+ "name": "--job-id",
11621
11608
  "hasDynamicHelp": false,
11622
11609
  "multiple": false,
11623
11610
  "type": "option"
11624
11611
  },
11625
- "debug": {
11626
- "char": "d",
11627
- "description": "Activate debug mode (more logs)",
11628
- "name": "debug",
11612
+ "--use-most-recent": {
11613
+ "char": "r",
11614
+ "description": "use-most-recent",
11615
+ "name": "--use-most-recent",
11629
11616
  "allowNo": false,
11630
11617
  "type": "boolean"
11631
11618
  },
11632
- "websocket": {
11633
- "description": "Websocket host:port for VsCode SFDX Hardis UI integration",
11634
- "name": "websocket",
11619
+ "wait": {
11620
+ "char": "w",
11621
+ "description": "wait",
11622
+ "exclusive": [
11623
+ "async"
11624
+ ],
11625
+ "name": "wait",
11626
+ "default": 33,
11635
11627
  "hasDynamicHelp": false,
11636
11628
  "multiple": false,
11637
11629
  "type": "option"
11638
11630
  },
11639
- "skipauth": {
11640
- "description": "Skip authentication check when a default username is required",
11641
- "name": "skipauth",
11631
+ "debug": {
11632
+ "description": "debug",
11633
+ "name": "debug",
11642
11634
  "allowNo": false,
11643
11635
  "type": "boolean"
11644
11636
  }
11645
11637
  },
11646
- "hasDynamicHelp": false,
11638
+ "hasDynamicHelp": true,
11647
11639
  "hiddenAliases": [],
11648
- "id": "hardis:project:generate:flow-git-diff",
11640
+ "id": "hardis:project:deploy:quick",
11649
11641
  "pluginAlias": "sfdx-hardis",
11650
11642
  "pluginName": "sfdx-hardis",
11651
11643
  "pluginType": "core",
11652
11644
  "strict": true,
11653
11645
  "enableJsonFlag": true,
11654
- "title": "Generate Flow Visual Gif Diff",
11655
11646
  "requiresProject": true,
11656
11647
  "isESM": true,
11657
11648
  "relativePath": [
@@ -11659,43 +11650,50 @@
11659
11650
  "commands",
11660
11651
  "hardis",
11661
11652
  "project",
11662
- "generate",
11663
- "flow-git-diff.js"
11653
+ "deploy",
11654
+ "quick.js"
11655
+ ],
11656
+ "aliasPermutations": [
11657
+ "hardis:deploy:quick",
11658
+ "deploy:hardis:quick",
11659
+ "deploy:quick:hardis",
11660
+ "hardis:quick:deploy",
11661
+ "quick:hardis:deploy",
11662
+ "quick:deploy:hardis"
11664
11663
  ],
11665
- "aliasPermutations": [],
11666
11664
  "permutations": [
11667
- "hardis:project:generate:flow-git-diff",
11668
- "project:hardis:generate:flow-git-diff",
11669
- "project:generate:hardis:flow-git-diff",
11670
- "project:generate:flow-git-diff:hardis",
11671
- "hardis:generate:project:flow-git-diff",
11672
- "generate:hardis:project:flow-git-diff",
11673
- "generate:project:hardis:flow-git-diff",
11674
- "generate:project:flow-git-diff:hardis",
11675
- "hardis:generate:flow-git-diff:project",
11676
- "generate:hardis:flow-git-diff:project",
11677
- "generate:flow-git-diff:hardis:project",
11678
- "generate:flow-git-diff:project:hardis",
11679
- "hardis:project:flow-git-diff:generate",
11680
- "project:hardis:flow-git-diff:generate",
11681
- "project:flow-git-diff:hardis:generate",
11682
- "project:flow-git-diff:generate:hardis",
11683
- "hardis:flow-git-diff:project:generate",
11684
- "flow-git-diff:hardis:project:generate",
11685
- "flow-git-diff:project:hardis:generate",
11686
- "flow-git-diff:project:generate:hardis",
11687
- "hardis:flow-git-diff:generate:project",
11688
- "flow-git-diff:hardis:generate:project",
11689
- "flow-git-diff:generate:hardis:project",
11690
- "flow-git-diff:generate:project:hardis"
11665
+ "hardis:project:deploy:quick",
11666
+ "project:hardis:deploy:quick",
11667
+ "project:deploy:hardis:quick",
11668
+ "project:deploy:quick:hardis",
11669
+ "hardis:deploy:project:quick",
11670
+ "deploy:hardis:project:quick",
11671
+ "deploy:project:hardis:quick",
11672
+ "deploy:project:quick:hardis",
11673
+ "hardis:deploy:quick:project",
11674
+ "deploy:hardis:quick:project",
11675
+ "deploy:quick:hardis:project",
11676
+ "deploy:quick:project:hardis",
11677
+ "hardis:project:quick:deploy",
11678
+ "project:hardis:quick:deploy",
11679
+ "project:quick:hardis:deploy",
11680
+ "project:quick:deploy:hardis",
11681
+ "hardis:quick:project:deploy",
11682
+ "quick:hardis:project:deploy",
11683
+ "quick:project:hardis:deploy",
11684
+ "quick:project:deploy:hardis",
11685
+ "hardis:quick:deploy:project",
11686
+ "quick:hardis:deploy:project",
11687
+ "quick:deploy:hardis:project",
11688
+ "quick:deploy:project:hardis"
11691
11689
  ]
11692
11690
  },
11693
- "hardis:project:generate:gitdelta": {
11691
+ "hardis:project:deploy:simulate": {
11694
11692
  "aliases": [],
11695
11693
  "args": {},
11696
- "description": "\n## Command Behavior\n\n**Generates a `package.xml` and `destructiveChanges.xml` representing the metadata differences between two Git commits.**\n\nThis command is a powerful tool for managing Salesforce metadata deployments by focusing only on the changes between specific points in your version control history. It leverages `sfdx-git-delta` to accurately identify added, modified, and deleted metadata components.\n\nKey functionalities:\n\n- **Commit-Based Comparison:** Allows you to specify a starting commit (`--fromcommit`) and an ending commit (`--tocommit`) to define the scope of the delta. If not provided, interactive prompts will guide you through selecting commits from your Git history.\n- **Branch Selection:** You can specify a Git branch (`--branch`) to work with. If not provided, it will prompt you to select one.\n- **`package.xml` Generation:** Creates a `package.xml` file that lists all metadata components that have been added or modified between the specified commits.\n- **`destructiveChanges.xml` Generation:** Creates a `destructiveChanges.xml` file that lists all metadata components that have been deleted between the specified commits.\n- **Temporary File Output:** The generated `package.xml` and `destructiveChanges.xml` files are placed in a temporary directory.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **Git Integration:** Uses `simple-git` (`git()`) to interact with the Git repository, including fetching branches (`git().fetch()`), checking out branches (`git().checkoutBranch()`), and listing commit history (`git().log()`).\n- **Interactive Prompts:** Leverages the `prompts` library to guide the user through selecting a Git branch and specific commits for delta generation if they are not provided as command-line arguments.\n- **`sfdx-git-delta` Integration:** The core of the delta generation is handled by the `callSfdxGitDelta` utility function, which wraps the `sfdx-git-delta` tool. This tool performs the actual Git comparison and generates the `package.xml` and `destructiveChanges.xml` files.\n- **Temporary Directory Management:** Uses `createTempDir` to create a temporary directory for storing the generated XML files, ensuring a clean working environment.\n- **File System Operations:** Uses `fs-extra` to manage temporary files and directories.\n- **User Feedback:** Provides clear messages to the user about the generated files and their locations.\n</details>\n",
11694
+ "description": "\n## Command Behavior\n\n**Simulates the deployment of Salesforce metadata to a target org, primarily used by the VS Code Extension for quick validation.**\n\nThis command allows developers to perform a dry run of a metadata deployment without actually committing changes to the Salesforce org. This is incredibly useful for:\n\n- **Pre-Deployment Validation:** Identifying potential errors, warnings, or conflicts before a full deployment.\n- **Troubleshooting:** Quickly testing metadata changes and debugging issues in a safe environment.\n- **Local Development:** Validating changes to individual metadata components (e.g., a Permission Set) without needing to run a full CI/CD pipeline.\n\nKey functionalities:\n\n- **Source Specification:** Takes a source file or directory (`--source-dir`) containing the metadata to be simulated.\n- **Target Org Selection:** Prompts the user to select a Salesforce org for the simulation. This allows for flexible testing across different environments.\n- **Dry Run Execution:** Executes the Salesforce CLI's `sf project deploy start --dry-run` command, which performs all validation steps but does not save any changes to the org.\n\nThis command is primarily used by the VS Code Extension to provide immediate feedback to developers.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **Interactive Org Prompt:** Uses `promptOrgUsernameDefault` to allow the user to select the target Salesforce org for the deployment simulation.\n- **Salesforce CLI Integration:** It constructs and executes the `sf project deploy start` command with the `--dry-run` and `--ignore-conflicts` flags. The `--source-dir` and `--target-org` flags are dynamically populated based on user input.\n- **`wrapSfdxCoreCommand`:** This utility is used to execute the Salesforce CLI command and capture its output.\n- **Connection Variables:** Ensures Salesforce connection variables are set using `setConnectionVariables`.\n</details>\n",
11697
11695
  "examples": [
11698
- "$ sf hardis:project:generate:gitdelta"
11696
+ "$ sf hardis:project:deploy:simulate --source-dir force-app/defaut/main/permissionset/PS_Admin.permissionset-meta.xml"
11699
11697
  ],
11700
11698
  "flags": {
11701
11699
  "json": {
@@ -11713,25 +11711,13 @@
11713
11711
  "multiple": false,
11714
11712
  "type": "option"
11715
11713
  },
11716
- "branch": {
11717
- "description": "Git branch to use to generate delta",
11718
- "name": "branch",
11719
- "hasDynamicHelp": false,
11720
- "multiple": false,
11721
- "type": "option"
11722
- },
11723
- "fromcommit": {
11724
- "description": "Hash of commit to start from",
11725
- "name": "fromcommit",
11726
- "hasDynamicHelp": false,
11727
- "multiple": false,
11728
- "type": "option"
11729
- },
11730
- "tocommit": {
11731
- "description": "Hash of commit to stop at",
11732
- "name": "tocommit",
11714
+ "source-dir": {
11715
+ "char": "f",
11716
+ "description": "Source file or directory to simulate the deployment",
11717
+ "name": "source-dir",
11718
+ "required": true,
11733
11719
  "hasDynamicHelp": false,
11734
- "multiple": false,
11720
+ "multiple": true,
11735
11721
  "type": "option"
11736
11722
  },
11737
11723
  "debug": {
@@ -11753,63 +11739,87 @@
11753
11739
  "name": "skipauth",
11754
11740
  "allowNo": false,
11755
11741
  "type": "boolean"
11742
+ },
11743
+ "target-org": {
11744
+ "aliases": [
11745
+ "targetusername",
11746
+ "u"
11747
+ ],
11748
+ "char": "o",
11749
+ "deprecateAliases": true,
11750
+ "name": "target-org",
11751
+ "noCacheDefault": true,
11752
+ "required": true,
11753
+ "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
11754
+ "hasDynamicHelp": true,
11755
+ "multiple": false,
11756
+ "type": "option"
11756
11757
  }
11757
11758
  },
11758
- "hasDynamicHelp": false,
11759
+ "hasDynamicHelp": true,
11759
11760
  "hiddenAliases": [],
11760
- "id": "hardis:project:generate:gitdelta",
11761
+ "id": "hardis:project:deploy:simulate",
11761
11762
  "pluginAlias": "sfdx-hardis",
11762
11763
  "pluginName": "sfdx-hardis",
11763
11764
  "pluginType": "core",
11764
11765
  "strict": true,
11765
11766
  "enableJsonFlag": true,
11766
- "title": "Generate Git Delta",
11767
- "requiresProject": false,
11767
+ "title": "Simulate the deployment of metadata in an org prompted to the user.\nUsed by VS Code extension.",
11768
+ "requiresProject": true,
11768
11769
  "isESM": true,
11769
11770
  "relativePath": [
11770
11771
  "lib",
11771
11772
  "commands",
11772
11773
  "hardis",
11773
11774
  "project",
11774
- "generate",
11775
- "gitdelta.js"
11775
+ "deploy",
11776
+ "simulate.js"
11776
11777
  ],
11777
11778
  "aliasPermutations": [],
11778
11779
  "permutations": [
11779
- "hardis:project:generate:gitdelta",
11780
- "project:hardis:generate:gitdelta",
11781
- "project:generate:hardis:gitdelta",
11782
- "project:generate:gitdelta:hardis",
11783
- "hardis:generate:project:gitdelta",
11784
- "generate:hardis:project:gitdelta",
11785
- "generate:project:hardis:gitdelta",
11786
- "generate:project:gitdelta:hardis",
11787
- "hardis:generate:gitdelta:project",
11788
- "generate:hardis:gitdelta:project",
11789
- "generate:gitdelta:hardis:project",
11790
- "generate:gitdelta:project:hardis",
11791
- "hardis:project:gitdelta:generate",
11792
- "project:hardis:gitdelta:generate",
11793
- "project:gitdelta:hardis:generate",
11794
- "project:gitdelta:generate:hardis",
11795
- "hardis:gitdelta:project:generate",
11796
- "gitdelta:hardis:project:generate",
11797
- "gitdelta:project:hardis:generate",
11798
- "gitdelta:project:generate:hardis",
11799
- "hardis:gitdelta:generate:project",
11800
- "gitdelta:hardis:generate:project",
11801
- "gitdelta:generate:hardis:project",
11802
- "gitdelta:generate:project:hardis"
11780
+ "hardis:project:deploy:simulate",
11781
+ "project:hardis:deploy:simulate",
11782
+ "project:deploy:hardis:simulate",
11783
+ "project:deploy:simulate:hardis",
11784
+ "hardis:deploy:project:simulate",
11785
+ "deploy:hardis:project:simulate",
11786
+ "deploy:project:hardis:simulate",
11787
+ "deploy:project:simulate:hardis",
11788
+ "hardis:deploy:simulate:project",
11789
+ "deploy:hardis:simulate:project",
11790
+ "deploy:simulate:hardis:project",
11791
+ "deploy:simulate:project:hardis",
11792
+ "hardis:project:simulate:deploy",
11793
+ "project:hardis:simulate:deploy",
11794
+ "project:simulate:hardis:deploy",
11795
+ "project:simulate:deploy:hardis",
11796
+ "hardis:simulate:project:deploy",
11797
+ "simulate:hardis:project:deploy",
11798
+ "simulate:project:hardis:deploy",
11799
+ "simulate:project:deploy:hardis",
11800
+ "hardis:simulate:deploy:project",
11801
+ "simulate:hardis:deploy:project",
11802
+ "simulate:deploy:hardis:project",
11803
+ "simulate:deploy:project:hardis"
11803
11804
  ]
11804
11805
  },
11805
- "hardis:project:deploy:notify": {
11806
- "aliases": [],
11806
+ "hardis:project:deploy:smart": {
11807
+ "aliases": [
11808
+ "hardis:project:deploy:sources:dx"
11809
+ ],
11807
11810
  "args": {},
11808
- "description": "Post notifications related to:\n\n- **Deployment simulation** _(use with --check-only)_\n\n- **Deployment process** _(to call only if your deployment is successful)_\n\n### Integrations\n\nAccording to the [integrations you configured](https://sfdx-hardis.cloudity.com/salesforce-ci-cd-setup-integrations-home/), notifications can contain deployment information and [Flow Visual Git Diff](https://sfdx-hardis.cloudity.com/salesforce-deployment-assistant-home/#flow-visual-git-diff)\n\n - GitHub, Gitlab, Azure DevOps, Bitbucket comments on Pull Requests (including Flows Visual Git Diff)\n\n - Slack, Microsoft Teams, Email deployment summary after a successful deployment\n\n - JIRA tags and comments on tickets that just has been deployed\n\n![](https://sfdx-hardis.cloudity.com/assets/images/screenshot-jira-gitlab.jpg)\n\n![](https://sfdx-hardis.cloudity.com/assets/images/screenshot-jira-slack.jpg)\n\n### Flows Visual Git Diff\n\n- Visually show you the differences on a diagram\n\n- Display the update details without having to open any XML !\n\n🟩 = added\n\n🟥 = removed\n\n🟧 = updated\n\n![](https://sfdx-hardis.cloudity.com/assets/images/flow-visual-git-diff.jpg)\n\n![](https://sfdx-hardis.cloudity.com/assets/images/flow-visual-git-diff-2.jpg)\n\n### In custom CI/CD workflow\n\nExample of usage in a custom CI/CD pipeline:\n\n```bash\n# Disable exit-on-error temporarily\nset +e\n\n# Run the deploy command\nsf project deploy start [....]\nRET_CODE=$?\n\n# Re-enable exit-on-error\nset -e\n\n# Determine MYSTATUS based on return code\nif [ $RET_CODE -eq 0 ]; then\n MYSTATUS=\"valid\"\nelse\n MYSTATUS=\"invalid\"\nfi\n\n# Run the notify command with MYSTATUS\nsf hardis:project:deploy:notify --check-only --deploy-status \"$MYSTATUS\"\n```\n\n### Other usages\n\nThis command is for custom SF Cli pipelines, if you are a sfdx-hardis user, it is already embedded in sf hardis:deploy:smart.\n\nYou can also use [sfdx-hardis wrapper commands of SF deployment commands](https://sfdx-hardis.cloudity.com/salesforce-deployment-assistant-setup/#using-custom-cicd-pipeline)\n",
11811
+ "description": "Smart deploy of SFDX sources to target org, with many useful options.\n\nIn case of errors, [tips to fix them](https://sfdx-hardis.cloudity.com/deployTips/) will be included within the error messages.\n\n### Quick Deploy\n\nIn case Pull Request comments are configured on the project, Quick Deploy will try to be used (equivalent to button Quick Deploy)\n\nIf you do not want to use QuickDeploy, define variable `SFDX_HARDIS_QUICK_DEPLOY=false`\n\n- [GitHub Pull Requests comments config](https://sfdx-hardis.cloudity.com/salesforce-ci-cd-setup-integration-github/)\n- [Gitlab Merge requests notes config](https://sfdx-hardis.cloudity.com/salesforce-ci-cd-setup-integration-gitlab/)\n- [Azure Pull Requests comments config](https://sfdx-hardis.cloudity.com/salesforce-ci-cd-setup-integration-azure/)\n\n### Delta deployments\n\nTo activate delta deployments, define property `useDeltaDeployment: true` in `config/.sfdx-hardis.yml`.\n\nThis will activate delta deployments only between minor and major branches (major to major remains full deployment mode)\n\nIf you want to force the delta deployment into major orgs (ex: preprod to prod), this is not recommended but you can use env variable ALWAYS_ENABLE_DELTA_DEPLOYMENT=true\n\n### Smart Deployments Tests\n\nNot all metadata updates can break test classes, use Smart Deployment Tests to skip running test classes if ALL the following conditions are met:\n\n- Delta deployment is activated and applicable to the source and target branches\n- Delta deployed metadatas are all matching the list of **NOT_IMPACTING_METADATA_TYPES** (see below)\n- Target org is not a production org\n\nActivate Smart Deployment tests with:\n\n- env variable `USE_SMART_DEPLOYMENT_TESTS=true`\n- .sfdx-hardis.yml config property `useSmartDeploymentTests: true`\n\nDefaut list for **NOT_IMPACTING_METADATA_TYPES** (can be overridden with comma-separated list on env var NOT_IMPACTING_METADATA_TYPES)\n\n- Audience\n- AuraDefinitionBundle\n- Bot\n- BotVersion\n- ContentAsset\n- CustomObjectTranslation\n- CustomSite\n- CustomTab\n- Dashboard\n- ExperienceBundle\n- Flexipage\n- GlobalValueSetTranslation\n- Layout\n- LightningComponentBundle\n- NavigationMenu\n- ReportType\n- Report\n- SiteDotCom\n- StandardValueSetTranslation\n- StaticResource\n- Translations\n\nNote: if you want to disable Smart test classes for a PR, add **nosmart** in the text of the latest commit.\n\n### Dynamic deployment items / Overwrite management\n\nIf necessary,you can define the following files (that supports wildcards <members>*</members>):\n\n- `manifest/package-no-overwrite.xml`: Every element defined in this file will be deployed only if it is not existing yet in the target org (can be useful with ListView for example, if the client wants to update them directly in production org).\n - Can be overridden for a branch using .sfdx-hardis.yml property **packageNoOverwritePath** or environment variable PACKAGE_NO_OVERWRITE_PATH (for example, define: `packageNoOverwritePath: manifest/package-no-overwrite-main.xml` in config file `config/.sfdx-hardis.main.yml`)\n- `manifest/packageXmlOnChange.xml`: Every element defined in this file will not be deployed if it already has a similar definition in target org (can be useful for SharingRules for example)\n\nSee [Overwrite management documentation](https://sfdx-hardis.cloudity.com/salesforce-ci-cd-config-overwrite/)\n\n### Packages installation\n\nYou can define a list of package to install during deployments using property `installedPackages`\n\n- If `INSTALL_PACKAGES_DURING_CHECK_DEPLOY` is defined as `true` (or `installPackagesDuringCheckDeploy: true` in `.sfdx-hardis.yml`), packages will be installed even if the command is called with `--check` mode\n- You can automatically update this property by listing all packages installed on an org using command `sf hardis:org:retrieve:packageconfig`\n\nExample:\n\n```yaml\ninstalledPackages:\n - Id: 0A35r0000009EtECAU\n SubscriberPackageId: 033i0000000LVMYAA4\n SubscriberPackageName: Marketing Cloud\n SubscriberPackageNamespace: et4ae5\n SubscriberPackageVersionId: 04t6S000000l11iQAA\n SubscriberPackageVersionName: Marketing Cloud\n SubscriberPackageVersionNumber: 236.0.0.2\n installOnScratchOrgs: true // true or false depending you want to install this package when creating a new scratch org\n installDuringDeployments: true // set as true to install package during a deployment using sf hardis:project:deploy:smart\n installationkey: xxxxxxxxxxxxxxxxxxxx // if the package has a password, write it in this property\n - Id: 0A35r0000009F9CCAU\n SubscriberPackageId: 033b0000000Pf2AAAS\n SubscriberPackageName: Declarative Lookup Rollup Summaries Tool\n SubscriberPackageNamespace: dlrs\n SubscriberPackageVersionId: 04t5p000001BmLvAAK\n SubscriberPackageVersionName: Release\n SubscriberPackageVersionNumber: 2.15.0.9\n installOnScratchOrgs: true\n installDuringDeployments: true\n```\n\n### Deployment pre or post commands\n\nYou can define command lines to run before or after a deployment, with parameters:\n\n- **id**: Unique Id for the command\n- **label**: Human readable label for the command\n- **skipIfError**: If defined to \"true\", the post-command won't be run if there is a deployment failure\n- **context**: Defines the context where the command will be run. Can be **all** (default), **check-deployment-only** or **process-deployment-only**\n- **runOnlyOnceByOrg**: If set to true, the command will be run only one time per org. A record of SfdxHardisTrace__c is stored to make that possible (it needs to be existing in target org)\n\nIf the commands are not the same depending on the target org, you can define them into **config/branches/.sfdx-hardis-BRANCHNAME.yml** instead of root **config/.sfdx-hardis.yml**\n\nExample:\n\n```yaml\ncommandsPreDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to the deployment user\n command: sf data update record --sobject User --where \"Username='deploy.github@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n\ncommandsPostDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to desired username\n command: sf data update record --sobject User --where \"Username='admin-yser@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n - id: someActionToRunJustOneTime\n label: And to run only if deployment is success\n command: sf sfdmu:run ...\n skipIfError: true\n context: process-deployment-only\n runOnlyOnceByOrg: true\n```\n\n### Pull Requests Custom Behaviors\n\nIf some words are found **in the Pull Request description**, special behaviors will be applied\n\n| Word | Behavior |\n| :--- | :--- |\n| NO_DELTA | Even if delta deployments are activated, a deployment in mode **full** will be performed for this Pull Request |\n| PURGE_FLOW_VERSIONS | After deployment, inactive and obsolete Flow Versions will be deleted (equivalent to command sf hardis:org:purge:flow)<br/>**Caution: This will also purge active Flow Interviews !** |\n| DESTRUCTIVE_CHANGES_AFTER_DEPLOYMENT | If a file manifest/destructiveChanges.xml is found, it will be executed in a separate step, after the deployment of the main package |\n\n> For example, define `PURGE_FLOW_VERSIONS` and `DESTRUCTIVE_CHANGES_AFTER_DEPLOYMENT` in your Pull Request comments if you want to delete fields that are used in an active flow.\n\nNote: it is also possible to define these behaviors as ENV variables:\n\n- For all deployments (example: `PURGE_FLOW_VERSIONS=true`)\n- For a specific branch, by appending the target branch name (example: `PURGE_FLOW_VERSIONS_UAT=true`)\n\n### Deployment plan (deprecated)\n\nIf you need to deploy in multiple steps, you can define a property `deploymentPlan` in `.sfdx-hardis.yml`.\n\n- If a file `manifest/package.xml` is found, it will be placed with order 0 in the deployment plan\n\n- If a file `manifest/destructiveChanges.xml` is found, it will be executed as --postdestructivechanges\n\n- If env var `SFDX_HARDIS_DEPLOY_IGNORE_SPLIT_PACKAGES` is defined as `false` , split of package.xml will be applied\n\nExample:\n\n```yaml\ndeploymentPlan:\n packages:\n - label: Deploy Flow-Workflow\n packageXmlFile: manifest/splits/packageXmlFlowWorkflow.xml\n order: 6\n - label: Deploy SharingRules - Case\n packageXmlFile: manifest/splits/packageXmlSharingRulesCase.xml\n order: 30\n waitAfter: 30\n```\n\n### Automated fixes post deployments\n\n#### List view with scope Mine\n\nIf you defined a property **listViewsToSetToMine** in your .sfdx-hardis.yml, related ListViews will be set to Mine ( see command <https://sfdx-hardis.cloudity.com/hardis/org/fix/listviewmine/> )\n\nExample:\n\n```yaml\nlistViewsToSetToMine:\n - \"Operation__c:MyCurrentOperations\"\n - \"Operation__c:MyFinalizedOperations\"\n - \"Opportunity:Default_Opportunity_Pipeline\"\n - \"Opportunity:MyCurrentSubscriptions\"\n - \"Opportunity:MySubscriptions\"\n - \"Account:MyActivePartners\"\n```\n\nTroubleshooting: if you need to fix ListViews with mine from an alpine-linux based docker image, use this workaround in your dockerfile:\n\n```dockerfile\n# Do not use puppeteer embedded chromium\nRUN apk add --update --no-cache chromium\nENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=\"true\"\nENV CHROMIUM_PATH=\"/usr/bin/chromium-browser\"\nENV PUPPETEER_EXECUTABLE_PATH=\"$\\{CHROMIUM_PATH}\" // remove \\ before {\n```\n\nIf you need to increase the deployment waiting time (sf project deploy start --wait arg), you can define env variable SFDX_DEPLOY_WAIT_MINUTES (default: 120)\n\nIf you need notifications to be sent using the current Pull Request and not the one just merged ([see use case](https://github.com/hardisgroupcom/sfdx-hardis/issues/637#issuecomment-2230798904)), define env variable SFDX_HARDIS_DEPLOY_BEFORE_MERGE=true\n\nIf you want to disable the calculation and display of Flow Visual Git Diff in Pull Request comments, define variable **SFDX_DISABLE_FLOW_DIFF=true**\n",
11809
11812
  "examples": [
11810
- "$ sf hardis:project:deploy:notify --check-only --deploy-status valid --message \"This deployment check is valid\\n\\nYahooo !!\"",
11811
- "$ sf hardis:project:deploy:notify --check-only --deploy-status invalid --message \"This deployment check has failed !\\n\\Oh no !!\"",
11812
- "$ sf hardis:project:deploy:notify --deploy-status valid --message \"This deployment has been processed !\\n\\nYahooo !!\""
11813
+ "$ sf hardis:project:deploy:smart",
11814
+ "$ sf hardis:project:deploy:smart --check",
11815
+ "$ sf hardis:project:deploy:smart --check --testlevel RunRepositoryTests",
11816
+ "$ sf hardis:project:deploy:smart --check --testlevel RunRepositoryTests --runtests '^(?!FLI|MyPrefix).*'",
11817
+ "$ sf hardis:project:deploy:smart --check --testlevel RunRepositoryTestsExceptSeeAllData",
11818
+ "$ sf hardis:project:deploy:smart",
11819
+ "$ FORCE_TARGET_BRANCH=preprod NODE_OPTIONS=--inspect-brk sf hardis:project:deploy:smart --check --websocket localhost:2702 --skipauth --target-org nicolas.vuillamy@myclient.com.preprod",
11820
+ "$ SYSTEM_ACCESSTOKEN=xxxxxx SYSTEM_COLLECTIONURI=https://dev.azure.com/xxxxxxx/ SYSTEM_TEAMPROJECT=\"xxxxxxx\" BUILD_REPOSITORY_ID=xxxxx SYSTEM_PULLREQUEST_PULLREQUESTID=1418 FORCE_TARGET_BRANCH=uat NODE_OPTIONS=--inspect-brk sf hardis:project:deploy:smart --check --websocket localhost:2702 --skipauth --target-org my.salesforce@org.com",
11821
+ "$ CI_SFDX_HARDIS_BITBUCKET_TOKEN=xxxxxx BITBUCKET_WORKSPACE=sfdxhardis-demo BITBUCKET_REPO_SLUG=test BITBUCKET_BUILD_NUMBER=1 BITBUCKET_BRANCH=uat BITBUCKET_PR_ID=2 FORCE_TARGET_BRANCH=uat NODE_OPTIONS=--inspect-brk sf hardis:project:deploy:smart --check --websocket localhost:2702 --skipauth --target-org my-salesforce-org@client.com",
11822
+ "$ GITHUB_TOKEN=xxxx GITHUB_REPOSITORY=my-user/my-repo FORCE_TARGET_BRANCH=uat NODE_OPTIONS=--inspect-brk sf hardis:project:deploy:smart --check --websocket localhost:2702 --skipauth --target-org my-salesforce-org@client.com"
11813
11823
  ],
11814
11824
  "flags": {
11815
11825
  "json": {
@@ -11827,36 +11837,51 @@
11827
11837
  "multiple": false,
11828
11838
  "type": "option"
11829
11839
  },
11830
- "check-only": {
11840
+ "check": {
11831
11841
  "char": "c",
11832
- "description": "Use this option to send notifications from a Deployment simulation job",
11833
- "name": "check-only",
11842
+ "description": "Only checks the deployment, there is no impact on target org",
11843
+ "name": "check",
11834
11844
  "allowNo": false,
11835
11845
  "type": "boolean"
11836
11846
  },
11837
- "deploy-status": {
11838
- "char": "s",
11839
- "description": "Send success, failure or unknown (default) to indicate if the deployment or deployment simulation is in success or not",
11840
- "name": "deploy-status",
11841
- "default": "unknown",
11847
+ "testlevel": {
11848
+ "char": "l",
11849
+ "description": "Level of tests to validate deployment. RunRepositoryTests auto-detect and run all repository test classes",
11850
+ "name": "testlevel",
11842
11851
  "hasDynamicHelp": false,
11843
11852
  "multiple": false,
11844
11853
  "options": [
11845
- "valid",
11846
- "invalid",
11847
- "unknown"
11854
+ "NoTestRun",
11855
+ "RunSpecifiedTests",
11856
+ "RunRepositoryTests",
11857
+ "RunRepositoryTestsExceptSeeAllData",
11858
+ "RunLocalTests",
11859
+ "RunAllTestsInOrg"
11848
11860
  ],
11849
11861
  "type": "option"
11850
11862
  },
11851
- "message": {
11852
- "char": "m",
11853
- "description": "Custom message that you want to be added in notifications (string or markdown format)",
11854
- "name": "message",
11855
- "default": "",
11863
+ "runtests": {
11864
+ "char": "r",
11865
+ "description": "If testlevel=RunSpecifiedTests, please provide a list of classes.\nIf testlevel=RunRepositoryTests, can contain a regular expression to keep only class names matching it. If not set, will run all test classes found in the repo.",
11866
+ "name": "runtests",
11867
+ "hasDynamicHelp": false,
11868
+ "multiple": false,
11869
+ "type": "option"
11870
+ },
11871
+ "packagexml": {
11872
+ "char": "p",
11873
+ "description": "Path to package.xml containing what you want to deploy in target org",
11874
+ "name": "packagexml",
11856
11875
  "hasDynamicHelp": false,
11857
11876
  "multiple": false,
11858
11877
  "type": "option"
11859
11878
  },
11879
+ "delta": {
11880
+ "description": "Applies sfdx-git-delta to package.xml before other deployment processes",
11881
+ "name": "delta",
11882
+ "allowNo": false,
11883
+ "type": "boolean"
11884
+ },
11860
11885
  "debug": {
11861
11886
  "char": "d",
11862
11887
  "description": "Activate debug mode (more logs)",
@@ -11895,13 +11920,13 @@
11895
11920
  },
11896
11921
  "hasDynamicHelp": true,
11897
11922
  "hiddenAliases": [],
11898
- "id": "hardis:project:deploy:notify",
11923
+ "id": "hardis:project:deploy:smart",
11899
11924
  "pluginAlias": "sfdx-hardis",
11900
11925
  "pluginName": "sfdx-hardis",
11901
11926
  "pluginType": "core",
11902
11927
  "strict": true,
11903
11928
  "enableJsonFlag": true,
11904
- "title": "Deployment Notifications",
11929
+ "title": "Smart Deploy sfdx sources to org",
11905
11930
  "requiresProject": true,
11906
11931
  "isESM": true,
11907
11932
  "relativePath": [
@@ -11910,45 +11935,166 @@
11910
11935
  "hardis",
11911
11936
  "project",
11912
11937
  "deploy",
11913
- "notify.js"
11914
- ],
11915
- "aliasPermutations": [],
11916
- "permutations": [
11917
- "hardis:project:deploy:notify",
11918
- "project:hardis:deploy:notify",
11919
- "project:deploy:hardis:notify",
11920
- "project:deploy:notify:hardis",
11921
- "hardis:deploy:project:notify",
11922
- "deploy:hardis:project:notify",
11923
- "deploy:project:hardis:notify",
11924
- "deploy:project:notify:hardis",
11925
- "hardis:deploy:notify:project",
11926
- "deploy:hardis:notify:project",
11927
- "deploy:notify:hardis:project",
11928
- "deploy:notify:project:hardis",
11929
- "hardis:project:notify:deploy",
11930
- "project:hardis:notify:deploy",
11931
- "project:notify:hardis:deploy",
11932
- "project:notify:deploy:hardis",
11933
- "hardis:notify:project:deploy",
11934
- "notify:hardis:project:deploy",
11935
- "notify:project:hardis:deploy",
11936
- "notify:project:deploy:hardis",
11937
- "hardis:notify:deploy:project",
11938
- "notify:hardis:deploy:project",
11939
- "notify:deploy:hardis:project",
11940
- "notify:deploy:project:hardis"
11941
- ]
11942
- },
11943
- "hardis:project:deploy:quick": {
11944
- "aliases": [
11945
- "hardis:deploy:quick"
11938
+ "smart.js"
11946
11939
  ],
11947
- "args": {},
11948
- "description": "sfdx-hardis wrapper for **sf project deploy quick** that displays tips to solve deployment errors.\n\nNote: Use **--json** argument to have better results\n\n[![Assisted solving of Salesforce deployments errors](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-deployment-errors.jpg)](https://nicolas.vuillamy.fr/assisted-solving-of-salesforce-deployments-errors-47f3666a9ed0)\n\n[See documentation of Salesforce command](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_project_commands_unified.htm#cli_reference_project_deploy_quick_unified)\n\n### Deployment pre or post commands\n\nYou can define command lines to run before or after a deployment, with parameters:\n\n- **id**: Unique Id for the command\n- **label**: Human readable label for the command\n- **skipIfError**: If defined to \"true\", the post-command won't be run if there is a deployment failure\n- **context**: Defines the context where the command will be run. Can be **all** (default), **check-deployment-only** or **process-deployment-only**\n- **runOnlyOnceByOrg**: If set to true, the command will be run only one time per org. A record of SfdxHardisTrace__c is stored to make that possible (it needs to be existing in target org)\n\nIf the commands are not the same depending on the target org, you can define them into **config/branches/.sfdx-hardis-BRANCHNAME.yml** instead of root **config/.sfdx-hardis.yml**\n\nExample:\n\n```yaml\ncommandsPreDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to the deployment user\n command: sf data update record --sobject User --where \"Username='deploy.github@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n\ncommandsPostDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to desired username\n command: sf data update record --sobject User --where \"Username='admin-yser@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n - id: someActionToRunJustOneTime\n label: And to run only if deployment is success\n command: sf sfdmu:run ...\n skipIfError: true\n context: process-deployment-only\n runOnlyOnceByOrg: true\n```\n",
11949
- "flags": {
11950
- "json": {
11951
- "description": "Format output as json.",
11940
+ "aliasPermutations": [
11941
+ "hardis:project:deploy:sources:dx",
11942
+ "project:hardis:deploy:sources:dx",
11943
+ "project:deploy:hardis:sources:dx",
11944
+ "project:deploy:sources:hardis:dx",
11945
+ "project:deploy:sources:dx:hardis",
11946
+ "hardis:deploy:project:sources:dx",
11947
+ "deploy:hardis:project:sources:dx",
11948
+ "deploy:project:hardis:sources:dx",
11949
+ "deploy:project:sources:hardis:dx",
11950
+ "deploy:project:sources:dx:hardis",
11951
+ "hardis:deploy:sources:project:dx",
11952
+ "deploy:hardis:sources:project:dx",
11953
+ "deploy:sources:hardis:project:dx",
11954
+ "deploy:sources:project:hardis:dx",
11955
+ "deploy:sources:project:dx:hardis",
11956
+ "hardis:deploy:sources:dx:project",
11957
+ "deploy:hardis:sources:dx:project",
11958
+ "deploy:sources:hardis:dx:project",
11959
+ "deploy:sources:dx:hardis:project",
11960
+ "deploy:sources:dx:project:hardis",
11961
+ "hardis:project:sources:deploy:dx",
11962
+ "project:hardis:sources:deploy:dx",
11963
+ "project:sources:hardis:deploy:dx",
11964
+ "project:sources:deploy:hardis:dx",
11965
+ "project:sources:deploy:dx:hardis",
11966
+ "hardis:sources:project:deploy:dx",
11967
+ "sources:hardis:project:deploy:dx",
11968
+ "sources:project:hardis:deploy:dx",
11969
+ "sources:project:deploy:hardis:dx",
11970
+ "sources:project:deploy:dx:hardis",
11971
+ "hardis:sources:deploy:project:dx",
11972
+ "sources:hardis:deploy:project:dx",
11973
+ "sources:deploy:hardis:project:dx",
11974
+ "sources:deploy:project:hardis:dx",
11975
+ "sources:deploy:project:dx:hardis",
11976
+ "hardis:sources:deploy:dx:project",
11977
+ "sources:hardis:deploy:dx:project",
11978
+ "sources:deploy:hardis:dx:project",
11979
+ "sources:deploy:dx:hardis:project",
11980
+ "sources:deploy:dx:project:hardis",
11981
+ "hardis:project:sources:dx:deploy",
11982
+ "project:hardis:sources:dx:deploy",
11983
+ "project:sources:hardis:dx:deploy",
11984
+ "project:sources:dx:hardis:deploy",
11985
+ "project:sources:dx:deploy:hardis",
11986
+ "hardis:sources:project:dx:deploy",
11987
+ "sources:hardis:project:dx:deploy",
11988
+ "sources:project:hardis:dx:deploy",
11989
+ "sources:project:dx:hardis:deploy",
11990
+ "sources:project:dx:deploy:hardis",
11991
+ "hardis:sources:dx:project:deploy",
11992
+ "sources:hardis:dx:project:deploy",
11993
+ "sources:dx:hardis:project:deploy",
11994
+ "sources:dx:project:hardis:deploy",
11995
+ "sources:dx:project:deploy:hardis",
11996
+ "hardis:sources:dx:deploy:project",
11997
+ "sources:hardis:dx:deploy:project",
11998
+ "sources:dx:hardis:deploy:project",
11999
+ "sources:dx:deploy:hardis:project",
12000
+ "sources:dx:deploy:project:hardis",
12001
+ "hardis:project:deploy:dx:sources",
12002
+ "project:hardis:deploy:dx:sources",
12003
+ "project:deploy:hardis:dx:sources",
12004
+ "project:deploy:dx:hardis:sources",
12005
+ "project:deploy:dx:sources:hardis",
12006
+ "hardis:deploy:project:dx:sources",
12007
+ "deploy:hardis:project:dx:sources",
12008
+ "deploy:project:hardis:dx:sources",
12009
+ "deploy:project:dx:hardis:sources",
12010
+ "deploy:project:dx:sources:hardis",
12011
+ "hardis:deploy:dx:project:sources",
12012
+ "deploy:hardis:dx:project:sources",
12013
+ "deploy:dx:hardis:project:sources",
12014
+ "deploy:dx:project:hardis:sources",
12015
+ "deploy:dx:project:sources:hardis",
12016
+ "hardis:deploy:dx:sources:project",
12017
+ "deploy:hardis:dx:sources:project",
12018
+ "deploy:dx:hardis:sources:project",
12019
+ "deploy:dx:sources:hardis:project",
12020
+ "deploy:dx:sources:project:hardis",
12021
+ "hardis:project:dx:deploy:sources",
12022
+ "project:hardis:dx:deploy:sources",
12023
+ "project:dx:hardis:deploy:sources",
12024
+ "project:dx:deploy:hardis:sources",
12025
+ "project:dx:deploy:sources:hardis",
12026
+ "hardis:dx:project:deploy:sources",
12027
+ "dx:hardis:project:deploy:sources",
12028
+ "dx:project:hardis:deploy:sources",
12029
+ "dx:project:deploy:hardis:sources",
12030
+ "dx:project:deploy:sources:hardis",
12031
+ "hardis:dx:deploy:project:sources",
12032
+ "dx:hardis:deploy:project:sources",
12033
+ "dx:deploy:hardis:project:sources",
12034
+ "dx:deploy:project:hardis:sources",
12035
+ "dx:deploy:project:sources:hardis",
12036
+ "hardis:dx:deploy:sources:project",
12037
+ "dx:hardis:deploy:sources:project",
12038
+ "dx:deploy:hardis:sources:project",
12039
+ "dx:deploy:sources:hardis:project",
12040
+ "dx:deploy:sources:project:hardis",
12041
+ "hardis:project:dx:sources:deploy",
12042
+ "project:hardis:dx:sources:deploy",
12043
+ "project:dx:hardis:sources:deploy",
12044
+ "project:dx:sources:hardis:deploy",
12045
+ "project:dx:sources:deploy:hardis",
12046
+ "hardis:dx:project:sources:deploy",
12047
+ "dx:hardis:project:sources:deploy",
12048
+ "dx:project:hardis:sources:deploy",
12049
+ "dx:project:sources:hardis:deploy",
12050
+ "dx:project:sources:deploy:hardis",
12051
+ "hardis:dx:sources:project:deploy",
12052
+ "dx:hardis:sources:project:deploy",
12053
+ "dx:sources:hardis:project:deploy",
12054
+ "dx:sources:project:hardis:deploy",
12055
+ "dx:sources:project:deploy:hardis",
12056
+ "hardis:dx:sources:deploy:project",
12057
+ "dx:hardis:sources:deploy:project",
12058
+ "dx:sources:hardis:deploy:project",
12059
+ "dx:sources:deploy:hardis:project",
12060
+ "dx:sources:deploy:project:hardis"
12061
+ ],
12062
+ "permutations": [
12063
+ "hardis:project:deploy:smart",
12064
+ "project:hardis:deploy:smart",
12065
+ "project:deploy:hardis:smart",
12066
+ "project:deploy:smart:hardis",
12067
+ "hardis:deploy:project:smart",
12068
+ "deploy:hardis:project:smart",
12069
+ "deploy:project:hardis:smart",
12070
+ "deploy:project:smart:hardis",
12071
+ "hardis:deploy:smart:project",
12072
+ "deploy:hardis:smart:project",
12073
+ "deploy:smart:hardis:project",
12074
+ "deploy:smart:project:hardis",
12075
+ "hardis:project:smart:deploy",
12076
+ "project:hardis:smart:deploy",
12077
+ "project:smart:hardis:deploy",
12078
+ "project:smart:deploy:hardis",
12079
+ "hardis:smart:project:deploy",
12080
+ "smart:hardis:project:deploy",
12081
+ "smart:project:hardis:deploy",
12082
+ "smart:project:deploy:hardis",
12083
+ "hardis:smart:deploy:project",
12084
+ "smart:hardis:deploy:project",
12085
+ "smart:deploy:hardis:project",
12086
+ "smart:deploy:project:hardis"
12087
+ ]
12088
+ },
12089
+ "hardis:project:deploy:start": {
12090
+ "aliases": [
12091
+ "hardis:deploy:start"
12092
+ ],
12093
+ "args": {},
12094
+ "description": "sfdx-hardis wrapper for **sf project deploy start** that displays tips to solve deployment errors.\n\nNote: Use **--json** argument to have better results\n\n[![Assisted solving of Salesforce deployments errors](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-deployment-errors.jpg)](https://nicolas.vuillamy.fr/assisted-solving-of-salesforce-deployments-errors-47f3666a9ed0)\n\n[See documentation of Salesforce command](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_project_commands_unified.htm#cli_reference_project_deploy_start_unified)\n\n### Deployment pre or post commands\n\nYou can define command lines to run before or after a deployment, with parameters:\n\n- **id**: Unique Id for the command\n- **label**: Human readable label for the command\n- **skipIfError**: If defined to \"true\", the post-command won't be run if there is a deployment failure\n- **context**: Defines the context where the command will be run. Can be **all** (default), **check-deployment-only** or **process-deployment-only**\n- **runOnlyOnceByOrg**: If set to true, the command will be run only one time per org. A record of SfdxHardisTrace__c is stored to make that possible (it needs to be existing in target org)\n\nIf the commands are not the same depending on the target org, you can define them into **config/branches/.sfdx-hardis-BRANCHNAME.yml** instead of root **config/.sfdx-hardis.yml**\n\nExample:\n\n```yaml\ncommandsPreDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to the deployment user\n command: sf data update record --sobject User --where \"Username='deploy.github@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n\ncommandsPostDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to desired username\n command: sf data update record --sobject User --where \"Username='admin-yser@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n - id: someActionToRunJustOneTime\n label: And to run only if deployment is success\n command: sf sfdmu:run ...\n skipIfError: true\n context: process-deployment-only\n runOnlyOnceByOrg: true\n```\n",
12095
+ "flags": {
12096
+ "json": {
12097
+ "description": "Format output as json.",
11952
12098
  "helpGroup": "GLOBAL",
11953
12099
  "name": "json",
11954
12100
  "allowNo": false,
@@ -11979,6 +12125,73 @@
11979
12125
  "allowNo": false,
11980
12126
  "type": "boolean"
11981
12127
  },
12128
+ "dry-run": {
12129
+ "description": "dry-run",
12130
+ "name": "dry-run",
12131
+ "allowNo": false,
12132
+ "type": "boolean"
12133
+ },
12134
+ "ignore-conflicts": {
12135
+ "char": "c",
12136
+ "description": "ignore-conflicts",
12137
+ "name": "ignore-conflicts",
12138
+ "allowNo": false,
12139
+ "type": "boolean"
12140
+ },
12141
+ "ignore-errors": {
12142
+ "char": "r",
12143
+ "description": "ignore-errors",
12144
+ "name": "ignore-errors",
12145
+ "allowNo": false,
12146
+ "type": "boolean"
12147
+ },
12148
+ "ignore-warnings": {
12149
+ "char": "g",
12150
+ "description": "ignore-warnings",
12151
+ "name": "ignore-warnings",
12152
+ "allowNo": false,
12153
+ "type": "boolean"
12154
+ },
12155
+ "manifest": {
12156
+ "char": "x",
12157
+ "description": "manifest",
12158
+ "name": "manifest",
12159
+ "hasDynamicHelp": false,
12160
+ "multiple": false,
12161
+ "type": "option"
12162
+ },
12163
+ "metadata": {
12164
+ "char": "m",
12165
+ "description": "metadata",
12166
+ "name": "metadata",
12167
+ "hasDynamicHelp": false,
12168
+ "multiple": true,
12169
+ "type": "option"
12170
+ },
12171
+ "metadata-dir": {
12172
+ "description": "metadata-dir",
12173
+ "name": "metadata-dir",
12174
+ "hasDynamicHelp": false,
12175
+ "multiple": false,
12176
+ "type": "option"
12177
+ },
12178
+ "single-package": {
12179
+ "dependsOn": [
12180
+ "metadata-dir"
12181
+ ],
12182
+ "description": "single-package",
12183
+ "name": "single-package",
12184
+ "allowNo": false,
12185
+ "type": "boolean"
12186
+ },
12187
+ "source-dir": {
12188
+ "char": "d",
12189
+ "description": "source-dir",
12190
+ "name": "source-dir",
12191
+ "hasDynamicHelp": false,
12192
+ "multiple": true,
12193
+ "type": "option"
12194
+ },
11982
12195
  "target-org": {
11983
12196
  "char": "o",
11984
12197
  "name": "target-org",
@@ -11996,21 +12209,13 @@
11996
12209
  "multiple": false,
11997
12210
  "type": "option"
11998
12211
  },
11999
- "--job-id": {
12000
- "char": "i",
12001
- "description": "job-id",
12002
- "name": "--job-id",
12212
+ "test-level": {
12213
+ "description": "test-level",
12214
+ "name": "test-level",
12003
12215
  "hasDynamicHelp": false,
12004
12216
  "multiple": false,
12005
12217
  "type": "option"
12006
12218
  },
12007
- "--use-most-recent": {
12008
- "char": "r",
12009
- "description": "use-most-recent",
12010
- "name": "--use-most-recent",
12011
- "allowNo": false,
12012
- "type": "boolean"
12013
- },
12014
12219
  "wait": {
12015
12220
  "char": "w",
12016
12221
  "description": "wait",
@@ -12023,143 +12228,67 @@
12023
12228
  "multiple": false,
12024
12229
  "type": "option"
12025
12230
  },
12026
- "debug": {
12027
- "description": "debug",
12028
- "name": "debug",
12029
- "allowNo": false,
12030
- "type": "boolean"
12031
- }
12032
- },
12033
- "hasDynamicHelp": true,
12034
- "hiddenAliases": [],
12035
- "id": "hardis:project:deploy:quick",
12036
- "pluginAlias": "sfdx-hardis",
12037
- "pluginName": "sfdx-hardis",
12038
- "pluginType": "core",
12039
- "strict": true,
12040
- "enableJsonFlag": true,
12041
- "requiresProject": true,
12042
- "isESM": true,
12043
- "relativePath": [
12044
- "lib",
12045
- "commands",
12046
- "hardis",
12047
- "project",
12048
- "deploy",
12049
- "quick.js"
12050
- ],
12051
- "aliasPermutations": [
12052
- "hardis:deploy:quick",
12053
- "deploy:hardis:quick",
12054
- "deploy:quick:hardis",
12055
- "hardis:quick:deploy",
12056
- "quick:hardis:deploy",
12057
- "quick:deploy:hardis"
12058
- ],
12059
- "permutations": [
12060
- "hardis:project:deploy:quick",
12061
- "project:hardis:deploy:quick",
12062
- "project:deploy:hardis:quick",
12063
- "project:deploy:quick:hardis",
12064
- "hardis:deploy:project:quick",
12065
- "deploy:hardis:project:quick",
12066
- "deploy:project:hardis:quick",
12067
- "deploy:project:quick:hardis",
12068
- "hardis:deploy:quick:project",
12069
- "deploy:hardis:quick:project",
12070
- "deploy:quick:hardis:project",
12071
- "deploy:quick:project:hardis",
12072
- "hardis:project:quick:deploy",
12073
- "project:hardis:quick:deploy",
12074
- "project:quick:hardis:deploy",
12075
- "project:quick:deploy:hardis",
12076
- "hardis:quick:project:deploy",
12077
- "quick:hardis:project:deploy",
12078
- "quick:project:hardis:deploy",
12079
- "quick:project:deploy:hardis",
12080
- "hardis:quick:deploy:project",
12081
- "quick:hardis:deploy:project",
12082
- "quick:deploy:hardis:project",
12083
- "quick:deploy:project:hardis"
12084
- ]
12085
- },
12086
- "hardis:project:deploy:simulate": {
12087
- "aliases": [],
12088
- "args": {},
12089
- "description": "\n## Command Behavior\n\n**Simulates the deployment of Salesforce metadata to a target org, primarily used by the VS Code Extension for quick validation.**\n\nThis command allows developers to perform a dry run of a metadata deployment without actually committing changes to the Salesforce org. This is incredibly useful for:\n\n- **Pre-Deployment Validation:** Identifying potential errors, warnings, or conflicts before a full deployment.\n- **Troubleshooting:** Quickly testing metadata changes and debugging issues in a safe environment.\n- **Local Development:** Validating changes to individual metadata components (e.g., a Permission Set) without needing to run a full CI/CD pipeline.\n\nKey functionalities:\n\n- **Source Specification:** Takes a source file or directory (`--source-dir`) containing the metadata to be simulated.\n- **Target Org Selection:** Prompts the user to select a Salesforce org for the simulation. This allows for flexible testing across different environments.\n- **Dry Run Execution:** Executes the Salesforce CLI's `sf project deploy start --dry-run` command, which performs all validation steps but does not save any changes to the org.\n\nThis command is primarily used by the VS Code Extension to provide immediate feedback to developers.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **Interactive Org Prompt:** Uses `promptOrgUsernameDefault` to allow the user to select the target Salesforce org for the deployment simulation.\n- **Salesforce CLI Integration:** It constructs and executes the `sf project deploy start` command with the `--dry-run` and `--ignore-conflicts` flags. The `--source-dir` and `--target-org` flags are dynamically populated based on user input.\n- **`wrapSfdxCoreCommand`:** This utility is used to execute the Salesforce CLI command and capture its output.\n- **Connection Variables:** Ensures Salesforce connection variables are set using `setConnectionVariables`.\n</details>\n",
12090
- "examples": [
12091
- "$ sf hardis:project:deploy:simulate --source-dir force-app/defaut/main/permissionset/PS_Admin.permissionset-meta.xml"
12092
- ],
12093
- "flags": {
12094
- "json": {
12095
- "description": "Format output as json.",
12096
- "helpGroup": "GLOBAL",
12097
- "name": "json",
12231
+ "purge-on-delete": {
12232
+ "description": "purge-on-delete",
12233
+ "name": "purge-on-delete",
12098
12234
  "allowNo": false,
12099
12235
  "type": "boolean"
12100
12236
  },
12101
- "flags-dir": {
12102
- "helpGroup": "GLOBAL",
12103
- "name": "flags-dir",
12104
- "summary": "Import flag values from a directory.",
12237
+ "pre-destructive-changes": {
12238
+ "dependsOn": [
12239
+ "manifest"
12240
+ ],
12241
+ "description": "pre-destructive-changes",
12242
+ "name": "pre-destructive-changes",
12105
12243
  "hasDynamicHelp": false,
12106
12244
  "multiple": false,
12107
12245
  "type": "option"
12108
12246
  },
12109
- "source-dir": {
12110
- "char": "f",
12111
- "description": "Source file or directory to simulate the deployment",
12112
- "name": "source-dir",
12113
- "required": true,
12247
+ "post-destructive-changes": {
12248
+ "dependsOn": [
12249
+ "manifest"
12250
+ ],
12251
+ "description": "post-destructive-changes",
12252
+ "name": "post-destructive-changes",
12114
12253
  "hasDynamicHelp": false,
12115
- "multiple": true,
12254
+ "multiple": false,
12116
12255
  "type": "option"
12117
12256
  },
12118
- "debug": {
12119
- "char": "d",
12120
- "description": "Activate debug mode (more logs)",
12121
- "name": "debug",
12122
- "allowNo": false,
12123
- "type": "boolean"
12124
- },
12125
- "websocket": {
12126
- "description": "Websocket host:port for VsCode SFDX Hardis UI integration",
12127
- "name": "websocket",
12257
+ "coverage-formatters": {
12258
+ "description": "coverage-formatters",
12259
+ "name": "coverage-formatters",
12128
12260
  "hasDynamicHelp": false,
12129
12261
  "multiple": false,
12130
12262
  "type": "option"
12131
12263
  },
12132
- "skipauth": {
12133
- "description": "Skip authentication check when a default username is required",
12134
- "name": "skipauth",
12264
+ "junit": {
12265
+ "description": "junit",
12266
+ "name": "junit",
12135
12267
  "allowNo": false,
12136
12268
  "type": "boolean"
12137
12269
  },
12138
- "target-org": {
12139
- "aliases": [
12140
- "targetusername",
12141
- "u"
12142
- ],
12143
- "char": "o",
12144
- "deprecateAliases": true,
12145
- "name": "target-org",
12146
- "noCacheDefault": true,
12147
- "required": true,
12148
- "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
12149
- "hasDynamicHelp": true,
12270
+ "results-dir": {
12271
+ "description": "results-dir",
12272
+ "name": "results-dir",
12273
+ "hasDynamicHelp": false,
12150
12274
  "multiple": false,
12151
12275
  "type": "option"
12276
+ },
12277
+ "debug": {
12278
+ "description": "debug",
12279
+ "name": "debug",
12280
+ "allowNo": false,
12281
+ "type": "boolean"
12152
12282
  }
12153
12283
  },
12154
12284
  "hasDynamicHelp": true,
12155
12285
  "hiddenAliases": [],
12156
- "id": "hardis:project:deploy:simulate",
12286
+ "id": "hardis:project:deploy:start",
12157
12287
  "pluginAlias": "sfdx-hardis",
12158
12288
  "pluginName": "sfdx-hardis",
12159
12289
  "pluginType": "core",
12160
12290
  "strict": true,
12161
12291
  "enableJsonFlag": true,
12162
- "title": "Simulate the deployment of metadata in an org prompted to the user.\nUsed by VS Code extension.",
12163
12292
  "requiresProject": true,
12164
12293
  "isESM": true,
12165
12294
  "relativePath": [
@@ -12168,54 +12297,49 @@
12168
12297
  "hardis",
12169
12298
  "project",
12170
12299
  "deploy",
12171
- "simulate.js"
12300
+ "start.js"
12301
+ ],
12302
+ "aliasPermutations": [
12303
+ "hardis:deploy:start",
12304
+ "deploy:hardis:start",
12305
+ "deploy:start:hardis",
12306
+ "hardis:start:deploy",
12307
+ "start:hardis:deploy",
12308
+ "start:deploy:hardis"
12172
12309
  ],
12173
- "aliasPermutations": [],
12174
12310
  "permutations": [
12175
- "hardis:project:deploy:simulate",
12176
- "project:hardis:deploy:simulate",
12177
- "project:deploy:hardis:simulate",
12178
- "project:deploy:simulate:hardis",
12179
- "hardis:deploy:project:simulate",
12180
- "deploy:hardis:project:simulate",
12181
- "deploy:project:hardis:simulate",
12182
- "deploy:project:simulate:hardis",
12183
- "hardis:deploy:simulate:project",
12184
- "deploy:hardis:simulate:project",
12185
- "deploy:simulate:hardis:project",
12186
- "deploy:simulate:project:hardis",
12187
- "hardis:project:simulate:deploy",
12188
- "project:hardis:simulate:deploy",
12189
- "project:simulate:hardis:deploy",
12190
- "project:simulate:deploy:hardis",
12191
- "hardis:simulate:project:deploy",
12192
- "simulate:hardis:project:deploy",
12193
- "simulate:project:hardis:deploy",
12194
- "simulate:project:deploy:hardis",
12195
- "hardis:simulate:deploy:project",
12196
- "simulate:hardis:deploy:project",
12197
- "simulate:deploy:hardis:project",
12198
- "simulate:deploy:project:hardis"
12311
+ "hardis:project:deploy:start",
12312
+ "project:hardis:deploy:start",
12313
+ "project:deploy:hardis:start",
12314
+ "project:deploy:start:hardis",
12315
+ "hardis:deploy:project:start",
12316
+ "deploy:hardis:project:start",
12317
+ "deploy:project:hardis:start",
12318
+ "deploy:project:start:hardis",
12319
+ "hardis:deploy:start:project",
12320
+ "deploy:hardis:start:project",
12321
+ "deploy:start:hardis:project",
12322
+ "deploy:start:project:hardis",
12323
+ "hardis:project:start:deploy",
12324
+ "project:hardis:start:deploy",
12325
+ "project:start:hardis:deploy",
12326
+ "project:start:deploy:hardis",
12327
+ "hardis:start:project:deploy",
12328
+ "start:hardis:project:deploy",
12329
+ "start:project:hardis:deploy",
12330
+ "start:project:deploy:hardis",
12331
+ "hardis:start:deploy:project",
12332
+ "start:hardis:deploy:project",
12333
+ "start:deploy:hardis:project",
12334
+ "start:deploy:project:hardis"
12199
12335
  ]
12200
12336
  },
12201
- "hardis:project:deploy:smart": {
12337
+ "hardis:project:deploy:validate": {
12202
12338
  "aliases": [
12203
- "hardis:project:deploy:sources:dx"
12339
+ "hardis:deploy:validate"
12204
12340
  ],
12205
12341
  "args": {},
12206
- "description": "Smart deploy of SFDX sources to target org, with many useful options.\n\nIn case of errors, [tips to fix them](https://sfdx-hardis.cloudity.com/deployTips/) will be included within the error messages.\n\n### Quick Deploy\n\nIn case Pull Request comments are configured on the project, Quick Deploy will try to be used (equivalent to button Quick Deploy)\n\nIf you do not want to use QuickDeploy, define variable `SFDX_HARDIS_QUICK_DEPLOY=false`\n\n- [GitHub Pull Requests comments config](https://sfdx-hardis.cloudity.com/salesforce-ci-cd-setup-integration-github/)\n- [Gitlab Merge requests notes config](https://sfdx-hardis.cloudity.com/salesforce-ci-cd-setup-integration-gitlab/)\n- [Azure Pull Requests comments config](https://sfdx-hardis.cloudity.com/salesforce-ci-cd-setup-integration-azure/)\n\n### Delta deployments\n\nTo activate delta deployments, define property `useDeltaDeployment: true` in `config/.sfdx-hardis.yml`.\n\nThis will activate delta deployments only between minor and major branches (major to major remains full deployment mode)\n\nIf you want to force the delta deployment into major orgs (ex: preprod to prod), this is not recommended but you can use env variable ALWAYS_ENABLE_DELTA_DEPLOYMENT=true\n\n### Smart Deployments Tests\n\nNot all metadata updates can break test classes, use Smart Deployment Tests to skip running test classes if ALL the following conditions are met:\n\n- Delta deployment is activated and applicable to the source and target branches\n- Delta deployed metadatas are all matching the list of **NOT_IMPACTING_METADATA_TYPES** (see below)\n- Target org is not a production org\n\nActivate Smart Deployment tests with:\n\n- env variable `USE_SMART_DEPLOYMENT_TESTS=true`\n- .sfdx-hardis.yml config property `useSmartDeploymentTests: true`\n\nDefaut list for **NOT_IMPACTING_METADATA_TYPES** (can be overridden with comma-separated list on env var NOT_IMPACTING_METADATA_TYPES)\n\n- Audience\n- AuraDefinitionBundle\n- Bot\n- BotVersion\n- ContentAsset\n- CustomObjectTranslation\n- CustomSite\n- CustomTab\n- Dashboard\n- ExperienceBundle\n- Flexipage\n- GlobalValueSetTranslation\n- Layout\n- LightningComponentBundle\n- NavigationMenu\n- ReportType\n- Report\n- SiteDotCom\n- StandardValueSetTranslation\n- StaticResource\n- Translations\n\nNote: if you want to disable Smart test classes for a PR, add **nosmart** in the text of the latest commit.\n\n### Dynamic deployment items / Overwrite management\n\nIf necessary,you can define the following files (that supports wildcards <members>*</members>):\n\n- `manifest/package-no-overwrite.xml`: Every element defined in this file will be deployed only if it is not existing yet in the target org (can be useful with ListView for example, if the client wants to update them directly in production org).\n - Can be overridden for a branch using .sfdx-hardis.yml property **packageNoOverwritePath** or environment variable PACKAGE_NO_OVERWRITE_PATH (for example, define: `packageNoOverwritePath: manifest/package-no-overwrite-main.xml` in config file `config/.sfdx-hardis.main.yml`)\n- `manifest/packageXmlOnChange.xml`: Every element defined in this file will not be deployed if it already has a similar definition in target org (can be useful for SharingRules for example)\n\nSee [Overwrite management documentation](https://sfdx-hardis.cloudity.com/salesforce-ci-cd-config-overwrite/)\n\n### Packages installation\n\nYou can define a list of package to install during deployments using property `installedPackages`\n\n- If `INSTALL_PACKAGES_DURING_CHECK_DEPLOY` is defined as `true` (or `installPackagesDuringCheckDeploy: true` in `.sfdx-hardis.yml`), packages will be installed even if the command is called with `--check` mode\n- You can automatically update this property by listing all packages installed on an org using command `sf hardis:org:retrieve:packageconfig`\n\nExample:\n\n```yaml\ninstalledPackages:\n - Id: 0A35r0000009EtECAU\n SubscriberPackageId: 033i0000000LVMYAA4\n SubscriberPackageName: Marketing Cloud\n SubscriberPackageNamespace: et4ae5\n SubscriberPackageVersionId: 04t6S000000l11iQAA\n SubscriberPackageVersionName: Marketing Cloud\n SubscriberPackageVersionNumber: 236.0.0.2\n installOnScratchOrgs: true // true or false depending you want to install this package when creating a new scratch org\n installDuringDeployments: true // set as true to install package during a deployment using sf hardis:project:deploy:smart\n installationkey: xxxxxxxxxxxxxxxxxxxx // if the package has a password, write it in this property\n - Id: 0A35r0000009F9CCAU\n SubscriberPackageId: 033b0000000Pf2AAAS\n SubscriberPackageName: Declarative Lookup Rollup Summaries Tool\n SubscriberPackageNamespace: dlrs\n SubscriberPackageVersionId: 04t5p000001BmLvAAK\n SubscriberPackageVersionName: Release\n SubscriberPackageVersionNumber: 2.15.0.9\n installOnScratchOrgs: true\n installDuringDeployments: true\n```\n\n### Deployment pre or post commands\n\nYou can define command lines to run before or after a deployment, with parameters:\n\n- **id**: Unique Id for the command\n- **label**: Human readable label for the command\n- **skipIfError**: If defined to \"true\", the post-command won't be run if there is a deployment failure\n- **context**: Defines the context where the command will be run. Can be **all** (default), **check-deployment-only** or **process-deployment-only**\n- **runOnlyOnceByOrg**: If set to true, the command will be run only one time per org. A record of SfdxHardisTrace__c is stored to make that possible (it needs to be existing in target org)\n\nIf the commands are not the same depending on the target org, you can define them into **config/branches/.sfdx-hardis-BRANCHNAME.yml** instead of root **config/.sfdx-hardis.yml**\n\nExample:\n\n```yaml\ncommandsPreDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to the deployment user\n command: sf data update record --sobject User --where \"Username='deploy.github@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n\ncommandsPostDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to desired username\n command: sf data update record --sobject User --where \"Username='admin-yser@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n - id: someActionToRunJustOneTime\n label: And to run only if deployment is success\n command: sf sfdmu:run ...\n skipIfError: true\n context: process-deployment-only\n runOnlyOnceByOrg: true\n```\n\n### Pull Requests Custom Behaviors\n\nIf some words are found **in the Pull Request description**, special behaviors will be applied\n\n| Word | Behavior |\n| :--- | :--- |\n| NO_DELTA | Even if delta deployments are activated, a deployment in mode **full** will be performed for this Pull Request |\n| PURGE_FLOW_VERSIONS | After deployment, inactive and obsolete Flow Versions will be deleted (equivalent to command sf hardis:org:purge:flow)<br/>**Caution: This will also purge active Flow Interviews !** |\n| DESTRUCTIVE_CHANGES_AFTER_DEPLOYMENT | If a file manifest/destructiveChanges.xml is found, it will be executed in a separate step, after the deployment of the main package |\n\n> For example, define `PURGE_FLOW_VERSIONS` and `DESTRUCTIVE_CHANGES_AFTER_DEPLOYMENT` in your Pull Request comments if you want to delete fields that are used in an active flow.\n\nNote: it is also possible to define these behaviors as ENV variables:\n\n- For all deployments (example: `PURGE_FLOW_VERSIONS=true`)\n- For a specific branch, by appending the target branch name (example: `PURGE_FLOW_VERSIONS_UAT=true`)\n\n### Deployment plan (deprecated)\n\nIf you need to deploy in multiple steps, you can define a property `deploymentPlan` in `.sfdx-hardis.yml`.\n\n- If a file `manifest/package.xml` is found, it will be placed with order 0 in the deployment plan\n\n- If a file `manifest/destructiveChanges.xml` is found, it will be executed as --postdestructivechanges\n\n- If env var `SFDX_HARDIS_DEPLOY_IGNORE_SPLIT_PACKAGES` is defined as `false` , split of package.xml will be applied\n\nExample:\n\n```yaml\ndeploymentPlan:\n packages:\n - label: Deploy Flow-Workflow\n packageXmlFile: manifest/splits/packageXmlFlowWorkflow.xml\n order: 6\n - label: Deploy SharingRules - Case\n packageXmlFile: manifest/splits/packageXmlSharingRulesCase.xml\n order: 30\n waitAfter: 30\n```\n\n### Automated fixes post deployments\n\n#### List view with scope Mine\n\nIf you defined a property **listViewsToSetToMine** in your .sfdx-hardis.yml, related ListViews will be set to Mine ( see command <https://sfdx-hardis.cloudity.com/hardis/org/fix/listviewmine/> )\n\nExample:\n\n```yaml\nlistViewsToSetToMine:\n - \"Operation__c:MyCurrentOperations\"\n - \"Operation__c:MyFinalizedOperations\"\n - \"Opportunity:Default_Opportunity_Pipeline\"\n - \"Opportunity:MyCurrentSubscriptions\"\n - \"Opportunity:MySubscriptions\"\n - \"Account:MyActivePartners\"\n```\n\nTroubleshooting: if you need to fix ListViews with mine from an alpine-linux based docker image, use this workaround in your dockerfile:\n\n```dockerfile\n# Do not use puppeteer embedded chromium\nRUN apk add --update --no-cache chromium\nENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=\"true\"\nENV CHROMIUM_PATH=\"/usr/bin/chromium-browser\"\nENV PUPPETEER_EXECUTABLE_PATH=\"$\\{CHROMIUM_PATH}\" // remove \\ before {\n```\n\nIf you need to increase the deployment waiting time (sf project deploy start --wait arg), you can define env variable SFDX_DEPLOY_WAIT_MINUTES (default: 120)\n\nIf you need notifications to be sent using the current Pull Request and not the one just merged ([see use case](https://github.com/hardisgroupcom/sfdx-hardis/issues/637#issuecomment-2230798904)), define env variable SFDX_HARDIS_DEPLOY_BEFORE_MERGE=true\n\nIf you want to disable the calculation and display of Flow Visual Git Diff in Pull Request comments, define variable **SFDX_DISABLE_FLOW_DIFF=true**\n",
12207
- "examples": [
12208
- "$ sf hardis:project:deploy:smart",
12209
- "$ sf hardis:project:deploy:smart --check",
12210
- "$ sf hardis:project:deploy:smart --check --testlevel RunRepositoryTests",
12211
- "$ sf hardis:project:deploy:smart --check --testlevel RunRepositoryTests --runtests '^(?!FLI|MyPrefix).*'",
12212
- "$ sf hardis:project:deploy:smart --check --testlevel RunRepositoryTestsExceptSeeAllData",
12213
- "$ sf hardis:project:deploy:smart",
12214
- "$ FORCE_TARGET_BRANCH=preprod NODE_OPTIONS=--inspect-brk sf hardis:project:deploy:smart --check --websocket localhost:2702 --skipauth --target-org nicolas.vuillamy@myclient.com.preprod",
12215
- "$ SYSTEM_ACCESSTOKEN=xxxxxx SYSTEM_COLLECTIONURI=https://dev.azure.com/xxxxxxx/ SYSTEM_TEAMPROJECT=\"xxxxxxx\" BUILD_REPOSITORY_ID=xxxxx SYSTEM_PULLREQUEST_PULLREQUESTID=1418 FORCE_TARGET_BRANCH=uat NODE_OPTIONS=--inspect-brk sf hardis:project:deploy:smart --check --websocket localhost:2702 --skipauth --target-org my.salesforce@org.com",
12216
- "$ CI_SFDX_HARDIS_BITBUCKET_TOKEN=xxxxxx BITBUCKET_WORKSPACE=sfdxhardis-demo BITBUCKET_REPO_SLUG=test BITBUCKET_BUILD_NUMBER=1 BITBUCKET_BRANCH=uat BITBUCKET_PR_ID=2 FORCE_TARGET_BRANCH=uat NODE_OPTIONS=--inspect-brk sf hardis:project:deploy:smart --check --websocket localhost:2702 --skipauth --target-org my-salesforce-org@client.com",
12217
- "$ GITHUB_TOKEN=xxxx GITHUB_REPOSITORY=my-user/my-repo FORCE_TARGET_BRANCH=uat NODE_OPTIONS=--inspect-brk sf hardis:project:deploy:smart --check --websocket localhost:2702 --skipauth --target-org my-salesforce-org@client.com"
12218
- ],
12342
+ "description": "sfdx-hardis wrapper for **sf project deploy validate** that displays tips to solve deployment errors.\n\nNote: Use **--json** argument to have better results\n\n[![Assisted solving of Salesforce deployments errors](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-deployment-errors.jpg)](https://nicolas.vuillamy.fr/assisted-solving-of-salesforce-deployments-errors-47f3666a9ed0)\n\n[See documentation of Salesforce command](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_project_commands_unified.htm#cli_reference_project_deploy_validate_unified)\n\n### Deployment pre or post commands\n\nYou can define command lines to run before or after a deployment, with parameters:\n\n- **id**: Unique Id for the command\n- **label**: Human readable label for the command\n- **skipIfError**: If defined to \"true\", the post-command won't be run if there is a deployment failure\n- **context**: Defines the context where the command will be run. Can be **all** (default), **check-deployment-only** or **process-deployment-only**\n- **runOnlyOnceByOrg**: If set to true, the command will be run only one time per org. A record of SfdxHardisTrace__c is stored to make that possible (it needs to be existing in target org)\n\nIf the commands are not the same depending on the target org, you can define them into **config/branches/.sfdx-hardis-BRANCHNAME.yml** instead of root **config/.sfdx-hardis.yml**\n\nExample:\n\n```yaml\ncommandsPreDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to the deployment user\n command: sf data update record --sobject User --where \"Username='deploy.github@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n\ncommandsPostDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to desired username\n command: sf data update record --sobject User --where \"Username='admin-yser@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n - id: someActionToRunJustOneTime\n label: And to run only if deployment is success\n command: sf sfdmu:run ...\n skipIfError: true\n context: process-deployment-only\n runOnlyOnceByOrg: true\n```\n",
12219
12343
  "flags": {
12220
12344
  "json": {
12221
12345
  "description": "Format output as json.",
@@ -12232,297 +12356,26 @@
12232
12356
  "multiple": false,
12233
12357
  "type": "option"
12234
12358
  },
12235
- "check": {
12236
- "char": "c",
12237
- "description": "Only checks the deployment, there is no impact on target org",
12238
- "name": "check",
12239
- "allowNo": false,
12240
- "type": "boolean"
12241
- },
12242
- "testlevel": {
12243
- "char": "l",
12244
- "description": "Level of tests to validate deployment. RunRepositoryTests auto-detect and run all repository test classes",
12245
- "name": "testlevel",
12246
- "hasDynamicHelp": false,
12247
- "multiple": false,
12248
- "options": [
12249
- "NoTestRun",
12250
- "RunSpecifiedTests",
12251
- "RunRepositoryTests",
12252
- "RunRepositoryTestsExceptSeeAllData",
12253
- "RunLocalTests",
12254
- "RunAllTestsInOrg"
12255
- ],
12256
- "type": "option"
12257
- },
12258
- "runtests": {
12259
- "char": "r",
12260
- "description": "If testlevel=RunSpecifiedTests, please provide a list of classes.\nIf testlevel=RunRepositoryTests, can contain a regular expression to keep only class names matching it. If not set, will run all test classes found in the repo.",
12261
- "name": "runtests",
12359
+ "api-version": {
12360
+ "char": "a",
12361
+ "description": "api-version",
12362
+ "name": "api-version",
12262
12363
  "hasDynamicHelp": false,
12263
12364
  "multiple": false,
12264
12365
  "type": "option"
12265
12366
  },
12266
- "packagexml": {
12267
- "char": "p",
12268
- "description": "Path to package.xml containing what you want to deploy in target org",
12269
- "name": "packagexml",
12270
- "hasDynamicHelp": false,
12271
- "multiple": false,
12272
- "type": "option"
12367
+ "async": {
12368
+ "description": "async",
12369
+ "exclusive": [
12370
+ "wait"
12371
+ ],
12372
+ "name": "async",
12373
+ "allowNo": false,
12374
+ "type": "boolean"
12273
12375
  },
12274
- "delta": {
12275
- "description": "Applies sfdx-git-delta to package.xml before other deployment processes",
12276
- "name": "delta",
12277
- "allowNo": false,
12278
- "type": "boolean"
12279
- },
12280
- "debug": {
12281
- "char": "d",
12282
- "description": "Activate debug mode (more logs)",
12283
- "name": "debug",
12284
- "allowNo": false,
12285
- "type": "boolean"
12286
- },
12287
- "websocket": {
12288
- "description": "Websocket host:port for VsCode SFDX Hardis UI integration",
12289
- "name": "websocket",
12290
- "hasDynamicHelp": false,
12291
- "multiple": false,
12292
- "type": "option"
12293
- },
12294
- "skipauth": {
12295
- "description": "Skip authentication check when a default username is required",
12296
- "name": "skipauth",
12297
- "allowNo": false,
12298
- "type": "boolean"
12299
- },
12300
- "target-org": {
12301
- "aliases": [
12302
- "targetusername",
12303
- "u"
12304
- ],
12305
- "char": "o",
12306
- "deprecateAliases": true,
12307
- "name": "target-org",
12308
- "noCacheDefault": true,
12309
- "required": true,
12310
- "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
12311
- "hasDynamicHelp": true,
12312
- "multiple": false,
12313
- "type": "option"
12314
- }
12315
- },
12316
- "hasDynamicHelp": true,
12317
- "hiddenAliases": [],
12318
- "id": "hardis:project:deploy:smart",
12319
- "pluginAlias": "sfdx-hardis",
12320
- "pluginName": "sfdx-hardis",
12321
- "pluginType": "core",
12322
- "strict": true,
12323
- "enableJsonFlag": true,
12324
- "title": "Smart Deploy sfdx sources to org",
12325
- "requiresProject": true,
12326
- "isESM": true,
12327
- "relativePath": [
12328
- "lib",
12329
- "commands",
12330
- "hardis",
12331
- "project",
12332
- "deploy",
12333
- "smart.js"
12334
- ],
12335
- "aliasPermutations": [
12336
- "hardis:project:deploy:sources:dx",
12337
- "project:hardis:deploy:sources:dx",
12338
- "project:deploy:hardis:sources:dx",
12339
- "project:deploy:sources:hardis:dx",
12340
- "project:deploy:sources:dx:hardis",
12341
- "hardis:deploy:project:sources:dx",
12342
- "deploy:hardis:project:sources:dx",
12343
- "deploy:project:hardis:sources:dx",
12344
- "deploy:project:sources:hardis:dx",
12345
- "deploy:project:sources:dx:hardis",
12346
- "hardis:deploy:sources:project:dx",
12347
- "deploy:hardis:sources:project:dx",
12348
- "deploy:sources:hardis:project:dx",
12349
- "deploy:sources:project:hardis:dx",
12350
- "deploy:sources:project:dx:hardis",
12351
- "hardis:deploy:sources:dx:project",
12352
- "deploy:hardis:sources:dx:project",
12353
- "deploy:sources:hardis:dx:project",
12354
- "deploy:sources:dx:hardis:project",
12355
- "deploy:sources:dx:project:hardis",
12356
- "hardis:project:sources:deploy:dx",
12357
- "project:hardis:sources:deploy:dx",
12358
- "project:sources:hardis:deploy:dx",
12359
- "project:sources:deploy:hardis:dx",
12360
- "project:sources:deploy:dx:hardis",
12361
- "hardis:sources:project:deploy:dx",
12362
- "sources:hardis:project:deploy:dx",
12363
- "sources:project:hardis:deploy:dx",
12364
- "sources:project:deploy:hardis:dx",
12365
- "sources:project:deploy:dx:hardis",
12366
- "hardis:sources:deploy:project:dx",
12367
- "sources:hardis:deploy:project:dx",
12368
- "sources:deploy:hardis:project:dx",
12369
- "sources:deploy:project:hardis:dx",
12370
- "sources:deploy:project:dx:hardis",
12371
- "hardis:sources:deploy:dx:project",
12372
- "sources:hardis:deploy:dx:project",
12373
- "sources:deploy:hardis:dx:project",
12374
- "sources:deploy:dx:hardis:project",
12375
- "sources:deploy:dx:project:hardis",
12376
- "hardis:project:sources:dx:deploy",
12377
- "project:hardis:sources:dx:deploy",
12378
- "project:sources:hardis:dx:deploy",
12379
- "project:sources:dx:hardis:deploy",
12380
- "project:sources:dx:deploy:hardis",
12381
- "hardis:sources:project:dx:deploy",
12382
- "sources:hardis:project:dx:deploy",
12383
- "sources:project:hardis:dx:deploy",
12384
- "sources:project:dx:hardis:deploy",
12385
- "sources:project:dx:deploy:hardis",
12386
- "hardis:sources:dx:project:deploy",
12387
- "sources:hardis:dx:project:deploy",
12388
- "sources:dx:hardis:project:deploy",
12389
- "sources:dx:project:hardis:deploy",
12390
- "sources:dx:project:deploy:hardis",
12391
- "hardis:sources:dx:deploy:project",
12392
- "sources:hardis:dx:deploy:project",
12393
- "sources:dx:hardis:deploy:project",
12394
- "sources:dx:deploy:hardis:project",
12395
- "sources:dx:deploy:project:hardis",
12396
- "hardis:project:deploy:dx:sources",
12397
- "project:hardis:deploy:dx:sources",
12398
- "project:deploy:hardis:dx:sources",
12399
- "project:deploy:dx:hardis:sources",
12400
- "project:deploy:dx:sources:hardis",
12401
- "hardis:deploy:project:dx:sources",
12402
- "deploy:hardis:project:dx:sources",
12403
- "deploy:project:hardis:dx:sources",
12404
- "deploy:project:dx:hardis:sources",
12405
- "deploy:project:dx:sources:hardis",
12406
- "hardis:deploy:dx:project:sources",
12407
- "deploy:hardis:dx:project:sources",
12408
- "deploy:dx:hardis:project:sources",
12409
- "deploy:dx:project:hardis:sources",
12410
- "deploy:dx:project:sources:hardis",
12411
- "hardis:deploy:dx:sources:project",
12412
- "deploy:hardis:dx:sources:project",
12413
- "deploy:dx:hardis:sources:project",
12414
- "deploy:dx:sources:hardis:project",
12415
- "deploy:dx:sources:project:hardis",
12416
- "hardis:project:dx:deploy:sources",
12417
- "project:hardis:dx:deploy:sources",
12418
- "project:dx:hardis:deploy:sources",
12419
- "project:dx:deploy:hardis:sources",
12420
- "project:dx:deploy:sources:hardis",
12421
- "hardis:dx:project:deploy:sources",
12422
- "dx:hardis:project:deploy:sources",
12423
- "dx:project:hardis:deploy:sources",
12424
- "dx:project:deploy:hardis:sources",
12425
- "dx:project:deploy:sources:hardis",
12426
- "hardis:dx:deploy:project:sources",
12427
- "dx:hardis:deploy:project:sources",
12428
- "dx:deploy:hardis:project:sources",
12429
- "dx:deploy:project:hardis:sources",
12430
- "dx:deploy:project:sources:hardis",
12431
- "hardis:dx:deploy:sources:project",
12432
- "dx:hardis:deploy:sources:project",
12433
- "dx:deploy:hardis:sources:project",
12434
- "dx:deploy:sources:hardis:project",
12435
- "dx:deploy:sources:project:hardis",
12436
- "hardis:project:dx:sources:deploy",
12437
- "project:hardis:dx:sources:deploy",
12438
- "project:dx:hardis:sources:deploy",
12439
- "project:dx:sources:hardis:deploy",
12440
- "project:dx:sources:deploy:hardis",
12441
- "hardis:dx:project:sources:deploy",
12442
- "dx:hardis:project:sources:deploy",
12443
- "dx:project:hardis:sources:deploy",
12444
- "dx:project:sources:hardis:deploy",
12445
- "dx:project:sources:deploy:hardis",
12446
- "hardis:dx:sources:project:deploy",
12447
- "dx:hardis:sources:project:deploy",
12448
- "dx:sources:hardis:project:deploy",
12449
- "dx:sources:project:hardis:deploy",
12450
- "dx:sources:project:deploy:hardis",
12451
- "hardis:dx:sources:deploy:project",
12452
- "dx:hardis:sources:deploy:project",
12453
- "dx:sources:hardis:deploy:project",
12454
- "dx:sources:deploy:hardis:project",
12455
- "dx:sources:deploy:project:hardis"
12456
- ],
12457
- "permutations": [
12458
- "hardis:project:deploy:smart",
12459
- "project:hardis:deploy:smart",
12460
- "project:deploy:hardis:smart",
12461
- "project:deploy:smart:hardis",
12462
- "hardis:deploy:project:smart",
12463
- "deploy:hardis:project:smart",
12464
- "deploy:project:hardis:smart",
12465
- "deploy:project:smart:hardis",
12466
- "hardis:deploy:smart:project",
12467
- "deploy:hardis:smart:project",
12468
- "deploy:smart:hardis:project",
12469
- "deploy:smart:project:hardis",
12470
- "hardis:project:smart:deploy",
12471
- "project:hardis:smart:deploy",
12472
- "project:smart:hardis:deploy",
12473
- "project:smart:deploy:hardis",
12474
- "hardis:smart:project:deploy",
12475
- "smart:hardis:project:deploy",
12476
- "smart:project:hardis:deploy",
12477
- "smart:project:deploy:hardis",
12478
- "hardis:smart:deploy:project",
12479
- "smart:hardis:deploy:project",
12480
- "smart:deploy:hardis:project",
12481
- "smart:deploy:project:hardis"
12482
- ]
12483
- },
12484
- "hardis:project:deploy:start": {
12485
- "aliases": [
12486
- "hardis:deploy:start"
12487
- ],
12488
- "args": {},
12489
- "description": "sfdx-hardis wrapper for **sf project deploy start** that displays tips to solve deployment errors.\n\nNote: Use **--json** argument to have better results\n\n[![Assisted solving of Salesforce deployments errors](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-deployment-errors.jpg)](https://nicolas.vuillamy.fr/assisted-solving-of-salesforce-deployments-errors-47f3666a9ed0)\n\n[See documentation of Salesforce command](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_project_commands_unified.htm#cli_reference_project_deploy_start_unified)\n\n### Deployment pre or post commands\n\nYou can define command lines to run before or after a deployment, with parameters:\n\n- **id**: Unique Id for the command\n- **label**: Human readable label for the command\n- **skipIfError**: If defined to \"true\", the post-command won't be run if there is a deployment failure\n- **context**: Defines the context where the command will be run. Can be **all** (default), **check-deployment-only** or **process-deployment-only**\n- **runOnlyOnceByOrg**: If set to true, the command will be run only one time per org. A record of SfdxHardisTrace__c is stored to make that possible (it needs to be existing in target org)\n\nIf the commands are not the same depending on the target org, you can define them into **config/branches/.sfdx-hardis-BRANCHNAME.yml** instead of root **config/.sfdx-hardis.yml**\n\nExample:\n\n```yaml\ncommandsPreDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to the deployment user\n command: sf data update record --sobject User --where \"Username='deploy.github@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n\ncommandsPostDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to desired username\n command: sf data update record --sobject User --where \"Username='admin-yser@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n - id: someActionToRunJustOneTime\n label: And to run only if deployment is success\n command: sf sfdmu:run ...\n skipIfError: true\n context: process-deployment-only\n runOnlyOnceByOrg: true\n```\n",
12490
- "flags": {
12491
- "json": {
12492
- "description": "Format output as json.",
12493
- "helpGroup": "GLOBAL",
12494
- "name": "json",
12495
- "allowNo": false,
12496
- "type": "boolean"
12497
- },
12498
- "flags-dir": {
12499
- "helpGroup": "GLOBAL",
12500
- "name": "flags-dir",
12501
- "summary": "Import flag values from a directory.",
12502
- "hasDynamicHelp": false,
12503
- "multiple": false,
12504
- "type": "option"
12505
- },
12506
- "api-version": {
12507
- "char": "a",
12508
- "description": "api-version",
12509
- "name": "api-version",
12510
- "hasDynamicHelp": false,
12511
- "multiple": false,
12512
- "type": "option"
12513
- },
12514
- "async": {
12515
- "description": "async",
12516
- "exclusive": [
12517
- "wait"
12518
- ],
12519
- "name": "async",
12520
- "allowNo": false,
12521
- "type": "boolean"
12522
- },
12523
- "dry-run": {
12524
- "description": "dry-run",
12525
- "name": "dry-run",
12376
+ "dry-run": {
12377
+ "description": "dry-run",
12378
+ "name": "dry-run",
12526
12379
  "allowNo": false,
12527
12380
  "type": "boolean"
12528
12381
  },
@@ -12678,7 +12531,7 @@
12678
12531
  },
12679
12532
  "hasDynamicHelp": true,
12680
12533
  "hiddenAliases": [],
12681
- "id": "hardis:project:deploy:start",
12534
+ "id": "hardis:project:deploy:validate",
12682
12535
  "pluginAlias": "sfdx-hardis",
12683
12536
  "pluginName": "sfdx-hardis",
12684
12537
  "pluginType": "core",
@@ -12692,49 +12545,50 @@
12692
12545
  "hardis",
12693
12546
  "project",
12694
12547
  "deploy",
12695
- "start.js"
12548
+ "validate.js"
12696
12549
  ],
12697
12550
  "aliasPermutations": [
12698
- "hardis:deploy:start",
12699
- "deploy:hardis:start",
12700
- "deploy:start:hardis",
12701
- "hardis:start:deploy",
12702
- "start:hardis:deploy",
12703
- "start:deploy:hardis"
12551
+ "hardis:deploy:validate",
12552
+ "deploy:hardis:validate",
12553
+ "deploy:validate:hardis",
12554
+ "hardis:validate:deploy",
12555
+ "validate:hardis:deploy",
12556
+ "validate:deploy:hardis"
12704
12557
  ],
12705
12558
  "permutations": [
12706
- "hardis:project:deploy:start",
12707
- "project:hardis:deploy:start",
12708
- "project:deploy:hardis:start",
12709
- "project:deploy:start:hardis",
12710
- "hardis:deploy:project:start",
12711
- "deploy:hardis:project:start",
12712
- "deploy:project:hardis:start",
12713
- "deploy:project:start:hardis",
12714
- "hardis:deploy:start:project",
12715
- "deploy:hardis:start:project",
12716
- "deploy:start:hardis:project",
12717
- "deploy:start:project:hardis",
12718
- "hardis:project:start:deploy",
12719
- "project:hardis:start:deploy",
12720
- "project:start:hardis:deploy",
12721
- "project:start:deploy:hardis",
12722
- "hardis:start:project:deploy",
12723
- "start:hardis:project:deploy",
12724
- "start:project:hardis:deploy",
12725
- "start:project:deploy:hardis",
12726
- "hardis:start:deploy:project",
12727
- "start:hardis:deploy:project",
12728
- "start:deploy:hardis:project",
12729
- "start:deploy:project:hardis"
12559
+ "hardis:project:deploy:validate",
12560
+ "project:hardis:deploy:validate",
12561
+ "project:deploy:hardis:validate",
12562
+ "project:deploy:validate:hardis",
12563
+ "hardis:deploy:project:validate",
12564
+ "deploy:hardis:project:validate",
12565
+ "deploy:project:hardis:validate",
12566
+ "deploy:project:validate:hardis",
12567
+ "hardis:deploy:validate:project",
12568
+ "deploy:hardis:validate:project",
12569
+ "deploy:validate:hardis:project",
12570
+ "deploy:validate:project:hardis",
12571
+ "hardis:project:validate:deploy",
12572
+ "project:hardis:validate:deploy",
12573
+ "project:validate:hardis:deploy",
12574
+ "project:validate:deploy:hardis",
12575
+ "hardis:validate:project:deploy",
12576
+ "validate:hardis:project:deploy",
12577
+ "validate:project:hardis:deploy",
12578
+ "validate:project:deploy:hardis",
12579
+ "hardis:validate:deploy:project",
12580
+ "validate:hardis:deploy:project",
12581
+ "validate:deploy:hardis:project",
12582
+ "validate:deploy:project:hardis"
12730
12583
  ]
12731
12584
  },
12732
- "hardis:project:deploy:validate": {
12733
- "aliases": [
12734
- "hardis:deploy:validate"
12735
- ],
12585
+ "hardis:project:fix:profiletabs": {
12586
+ "aliases": [],
12736
12587
  "args": {},
12737
- "description": "sfdx-hardis wrapper for **sf project deploy validate** that displays tips to solve deployment errors.\n\nNote: Use **--json** argument to have better results\n\n[![Assisted solving of Salesforce deployments errors](https://github.com/hardisgroupcom/sfdx-hardis/raw/main/docs/assets/images/article-deployment-errors.jpg)](https://nicolas.vuillamy.fr/assisted-solving-of-salesforce-deployments-errors-47f3666a9ed0)\n\n[See documentation of Salesforce command](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_project_commands_unified.htm#cli_reference_project_deploy_validate_unified)\n\n### Deployment pre or post commands\n\nYou can define command lines to run before or after a deployment, with parameters:\n\n- **id**: Unique Id for the command\n- **label**: Human readable label for the command\n- **skipIfError**: If defined to \"true\", the post-command won't be run if there is a deployment failure\n- **context**: Defines the context where the command will be run. Can be **all** (default), **check-deployment-only** or **process-deployment-only**\n- **runOnlyOnceByOrg**: If set to true, the command will be run only one time per org. A record of SfdxHardisTrace__c is stored to make that possible (it needs to be existing in target org)\n\nIf the commands are not the same depending on the target org, you can define them into **config/branches/.sfdx-hardis-BRANCHNAME.yml** instead of root **config/.sfdx-hardis.yml**\n\nExample:\n\n```yaml\ncommandsPreDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to the deployment user\n command: sf data update record --sobject User --where \"Username='deploy.github@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n\ncommandsPostDeploy:\n - id: knowledgeUnassign\n label: Remove KnowledgeUser right to the user who has it\n command: sf data update record --sobject User --where \"UserPermissionsKnowledgeUser='true'\" --values \"UserPermissionsKnowledgeUser='false'\" --json\n - id: knowledgeAssign\n label: Assign Knowledge user to desired username\n command: sf data update record --sobject User --where \"Username='admin-yser@myclient.com'\" --values \"UserPermissionsKnowledgeUser='true'\" --json\n - id: someActionToRunJustOneTime\n label: And to run only if deployment is success\n command: sf sfdmu:run ...\n skipIfError: true\n context: process-deployment-only\n runOnlyOnceByOrg: true\n```\n",
12588
+ "description": "\n## Command Behavior\n\n**Interactively updates tab visibility settings in Salesforce profiles, addressing a common issue where tab visibilities are not correctly retrieved by `sf project retrieve start`.**\n\nThis command provides a user-friendly interface to manage tab settings within your profile XML files, ensuring that your local project accurately reflects the intended tab configurations in your Salesforce org.\n\nKey functionalities:\n\n- **Interactive Tab Selection:** Displays a multi-select menu of all available tabs in your org, allowing you to choose which tabs to update.\n- **Visibility Control:** Lets you set the visibility for the selected tabs to either `DefaultOn` (Visible) or `Hidden`.\n- **Profile Selection:** Presents a multi-select menu of all .profile-meta.xml files in your project, allowing you to apply the tab visibility changes to specific profiles.\n- **XML Updates:** Modifies the <tabVisibilities> section of the selected profile XML files to reflect the chosen tab settings. If a tab visibility setting already exists for a selected tab, it will be updated; otherwise, a new one will be added.\n- **Sorted Output:** The <tabVisibilities> in the updated profile XML files are sorted alphabetically for consistency and readability.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **SOQL Queries (Tooling API):** It queries the `TabDefinition` object using `soqlQueryTooling` to retrieve a list of all available tabs in the target org.\n- **File Discovery:** Uses `glob` to find all .profile-meta.xml files within the specified project path.\n- **Interactive Prompts:** Leverages the `prompts` library to create interactive menus for selecting tabs, visibility settings, and profiles.\n- **XML Parsing and Manipulation:** Uses `parseXmlFile` to read the content of profile XML files and `writeXmlFile` to write the modified content back. It manipulates the `tabVisibilities` array within the parsed XML to add or update tab settings.\n- **Array Sorting:** Employs the `sort-array` library to sort the `tabVisibilities` alphabetically by tab name.\n- **Logging:** Provides feedback to the user about which profiles have been updated and a summary of the changes.\n</details>\n",
12589
+ "examples": [
12590
+ "$ sf hardis:project:fix:profiletabs"
12591
+ ],
12738
12592
  "flags": {
12739
12593
  "json": {
12740
12594
  "description": "Format output as json.",
@@ -12751,92 +12605,235 @@
12751
12605
  "multiple": false,
12752
12606
  "type": "option"
12753
12607
  },
12754
- "api-version": {
12755
- "char": "a",
12756
- "description": "api-version",
12757
- "name": "api-version",
12608
+ "path": {
12609
+ "char": "p",
12610
+ "description": "Root folder",
12611
+ "name": "path",
12612
+ "default": "/home/runner/work/sfdx-hardis/sfdx-hardis",
12758
12613
  "hasDynamicHelp": false,
12759
12614
  "multiple": false,
12760
12615
  "type": "option"
12761
12616
  },
12762
- "async": {
12763
- "description": "async",
12764
- "exclusive": [
12765
- "wait"
12766
- ],
12767
- "name": "async",
12768
- "allowNo": false,
12769
- "type": "boolean"
12770
- },
12771
- "dry-run": {
12772
- "description": "dry-run",
12773
- "name": "dry-run",
12617
+ "debug": {
12618
+ "char": "d",
12619
+ "description": "Activate debug mode (more logs)",
12620
+ "name": "debug",
12774
12621
  "allowNo": false,
12775
12622
  "type": "boolean"
12776
12623
  },
12777
- "ignore-conflicts": {
12778
- "char": "c",
12779
- "description": "ignore-conflicts",
12780
- "name": "ignore-conflicts",
12781
- "allowNo": false,
12782
- "type": "boolean"
12624
+ "websocket": {
12625
+ "description": "Websocket host:port for VsCode SFDX Hardis UI integration",
12626
+ "name": "websocket",
12627
+ "hasDynamicHelp": false,
12628
+ "multiple": false,
12629
+ "type": "option"
12783
12630
  },
12784
- "ignore-errors": {
12785
- "char": "r",
12786
- "description": "ignore-errors",
12787
- "name": "ignore-errors",
12631
+ "skipauth": {
12632
+ "description": "Skip authentication check when a default username is required",
12633
+ "name": "skipauth",
12788
12634
  "allowNo": false,
12789
12635
  "type": "boolean"
12790
12636
  },
12791
- "ignore-warnings": {
12792
- "char": "g",
12793
- "description": "ignore-warnings",
12794
- "name": "ignore-warnings",
12637
+ "target-org": {
12638
+ "aliases": [
12639
+ "targetusername",
12640
+ "u"
12641
+ ],
12642
+ "char": "o",
12643
+ "deprecateAliases": true,
12644
+ "name": "target-org",
12645
+ "noCacheDefault": true,
12646
+ "required": true,
12647
+ "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
12648
+ "hasDynamicHelp": true,
12649
+ "multiple": false,
12650
+ "type": "option"
12651
+ }
12652
+ },
12653
+ "hasDynamicHelp": true,
12654
+ "hiddenAliases": [],
12655
+ "id": "hardis:project:fix:profiletabs",
12656
+ "pluginAlias": "sfdx-hardis",
12657
+ "pluginName": "sfdx-hardis",
12658
+ "pluginType": "core",
12659
+ "strict": true,
12660
+ "enableJsonFlag": true,
12661
+ "title": "Fix profiles to add tabs that are not retrieved by SF CLI",
12662
+ "requiresProject": true,
12663
+ "isESM": true,
12664
+ "relativePath": [
12665
+ "lib",
12666
+ "commands",
12667
+ "hardis",
12668
+ "project",
12669
+ "fix",
12670
+ "profiletabs.js"
12671
+ ],
12672
+ "aliasPermutations": [],
12673
+ "permutations": [
12674
+ "hardis:project:fix:profiletabs",
12675
+ "project:hardis:fix:profiletabs",
12676
+ "project:fix:hardis:profiletabs",
12677
+ "project:fix:profiletabs:hardis",
12678
+ "hardis:fix:project:profiletabs",
12679
+ "fix:hardis:project:profiletabs",
12680
+ "fix:project:hardis:profiletabs",
12681
+ "fix:project:profiletabs:hardis",
12682
+ "hardis:fix:profiletabs:project",
12683
+ "fix:hardis:profiletabs:project",
12684
+ "fix:profiletabs:hardis:project",
12685
+ "fix:profiletabs:project:hardis",
12686
+ "hardis:project:profiletabs:fix",
12687
+ "project:hardis:profiletabs:fix",
12688
+ "project:profiletabs:hardis:fix",
12689
+ "project:profiletabs:fix:hardis",
12690
+ "hardis:profiletabs:project:fix",
12691
+ "profiletabs:hardis:project:fix",
12692
+ "profiletabs:project:hardis:fix",
12693
+ "profiletabs:project:fix:hardis",
12694
+ "hardis:profiletabs:fix:project",
12695
+ "profiletabs:hardis:fix:project",
12696
+ "profiletabs:fix:hardis:project",
12697
+ "profiletabs:fix:project:hardis"
12698
+ ]
12699
+ },
12700
+ "hardis:project:fix:v53flexipages": {
12701
+ "aliases": [],
12702
+ "args": {},
12703
+ "description": "\n## Command Behavior\n\n**Fixes Salesforce FlexiPages for compatibility with API Version 53.0 (Winter '22 release) by adding missing identifiers to component instances.**\n\nSalesforce introduced a change in API Version 53.0 that requires `identifier` tags within `componentInstance` and `fieldInstance` elements in FlexiPage metadata. If these identifiers are missing, deployments to orgs with API version 53.0 or higher will fail. This command automates the process of adding these missing identifiers, ensuring your FlexiPages remain deployable.\n\nKey functionalities:\n\n- **Targeted FlexiPage Processing:** Scans all .flexipage-meta.xml files within the specified root folder (defaults to current working directory).\n- **Identifier Injection:** Inserts a unique `identifier` tag (e.g., `SFDX_HARDIS_REPLACEMENT_ID`) into `componentInstance` and `fieldInstance` elements that lack one.\n\n**Important Note:** After running this command, ensure you update your `apiVersion` to `53.0` (or higher) in your `package.xml` and `sfdx-project.json` files.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **File Discovery:** Uses `glob` to find all .flexipage-meta.xml files.\n- **Content Reading:** Reads the XML content of each FlexiPage file.\n- **Regular Expression Replacement:** Employs a set of regular expressions to identify specific XML patterns (componentName.../componentName.../componentInstance, componentName.../componentName.../visibilityRule, fieldItem.../fieldItem.../fieldInstance) that are missing the `identifier` tag.\n- **Dynamic ID Generation:** For each match, it generates a unique identifier (e.g., `sfdxHardisIdX`) and injects it into the XML structure.\n- **File Writing:** If changes are made, the modified XML content is written back to the FlexiPage file using `fs.writeFile`.\n- **Logging:** Provides messages about which FlexiPages are being processed and a summary of the total number of identifiers added.\n</details>\n",
12704
+ "examples": [
12705
+ "$ sf hardis:project:fix:v53flexipages"
12706
+ ],
12707
+ "flags": {
12708
+ "json": {
12709
+ "description": "Format output as json.",
12710
+ "helpGroup": "GLOBAL",
12711
+ "name": "json",
12795
12712
  "allowNo": false,
12796
12713
  "type": "boolean"
12797
12714
  },
12798
- "manifest": {
12799
- "char": "x",
12800
- "description": "manifest",
12801
- "name": "manifest",
12715
+ "flags-dir": {
12716
+ "helpGroup": "GLOBAL",
12717
+ "name": "flags-dir",
12718
+ "summary": "Import flag values from a directory.",
12802
12719
  "hasDynamicHelp": false,
12803
12720
  "multiple": false,
12804
12721
  "type": "option"
12805
12722
  },
12806
- "metadata": {
12807
- "char": "m",
12808
- "description": "metadata",
12809
- "name": "metadata",
12723
+ "path": {
12724
+ "char": "p",
12725
+ "description": "Root folder",
12726
+ "name": "path",
12727
+ "default": "/home/runner/work/sfdx-hardis/sfdx-hardis",
12810
12728
  "hasDynamicHelp": false,
12811
- "multiple": true,
12729
+ "multiple": false,
12812
12730
  "type": "option"
12813
12731
  },
12814
- "metadata-dir": {
12815
- "description": "metadata-dir",
12816
- "name": "metadata-dir",
12732
+ "debug": {
12733
+ "char": "d",
12734
+ "description": "Activate debug mode (more logs)",
12735
+ "name": "debug",
12736
+ "allowNo": false,
12737
+ "type": "boolean"
12738
+ },
12739
+ "websocket": {
12740
+ "description": "Websocket host:port for VsCode SFDX Hardis UI integration",
12741
+ "name": "websocket",
12817
12742
  "hasDynamicHelp": false,
12818
12743
  "multiple": false,
12819
12744
  "type": "option"
12820
12745
  },
12821
- "single-package": {
12822
- "dependsOn": [
12823
- "metadata-dir"
12824
- ],
12825
- "description": "single-package",
12826
- "name": "single-package",
12746
+ "skipauth": {
12747
+ "description": "Skip authentication check when a default username is required",
12748
+ "name": "skipauth",
12749
+ "allowNo": false,
12750
+ "type": "boolean"
12751
+ }
12752
+ },
12753
+ "hasDynamicHelp": false,
12754
+ "hiddenAliases": [],
12755
+ "id": "hardis:project:fix:v53flexipages",
12756
+ "pluginAlias": "sfdx-hardis",
12757
+ "pluginName": "sfdx-hardis",
12758
+ "pluginType": "core",
12759
+ "strict": true,
12760
+ "enableJsonFlag": true,
12761
+ "title": "Fix flexipages for v53",
12762
+ "requiresProject": true,
12763
+ "isESM": true,
12764
+ "relativePath": [
12765
+ "lib",
12766
+ "commands",
12767
+ "hardis",
12768
+ "project",
12769
+ "fix",
12770
+ "v53flexipages.js"
12771
+ ],
12772
+ "aliasPermutations": [],
12773
+ "permutations": [
12774
+ "hardis:project:fix:v53flexipages",
12775
+ "project:hardis:fix:v53flexipages",
12776
+ "project:fix:hardis:v53flexipages",
12777
+ "project:fix:v53flexipages:hardis",
12778
+ "hardis:fix:project:v53flexipages",
12779
+ "fix:hardis:project:v53flexipages",
12780
+ "fix:project:hardis:v53flexipages",
12781
+ "fix:project:v53flexipages:hardis",
12782
+ "hardis:fix:v53flexipages:project",
12783
+ "fix:hardis:v53flexipages:project",
12784
+ "fix:v53flexipages:hardis:project",
12785
+ "fix:v53flexipages:project:hardis",
12786
+ "hardis:project:v53flexipages:fix",
12787
+ "project:hardis:v53flexipages:fix",
12788
+ "project:v53flexipages:hardis:fix",
12789
+ "project:v53flexipages:fix:hardis",
12790
+ "hardis:v53flexipages:project:fix",
12791
+ "v53flexipages:hardis:project:fix",
12792
+ "v53flexipages:project:hardis:fix",
12793
+ "v53flexipages:project:fix:hardis",
12794
+ "hardis:v53flexipages:fix:project",
12795
+ "v53flexipages:hardis:fix:project",
12796
+ "v53flexipages:fix:hardis:project",
12797
+ "v53flexipages:fix:project:hardis"
12798
+ ]
12799
+ },
12800
+ "hardis:project:generate:bypass": {
12801
+ "aliases": [],
12802
+ "args": {},
12803
+ "description": "\n## Command Behavior\n\n**Generates custom permissions and permission sets to bypass specified Salesforce automations (Flows, Triggers, and Validation Rules) for specific sObjects.**\n\nThis command provides a controlled mechanism to temporarily or permanently disable automations for certain sObjects, which is invaluable for:\n\n- **Data Loading:** Bypassing validation rules or triggers during large data imports.\n- **Troubleshooting:** Isolating automation issues by temporarily disabling them.\n- **Development:** Allowing developers to work on specific sObjects without triggering complex automations.\n\nKey functionalities:\n\n- **sObject Selection:** You can specify a comma-separated list of sObjects to bypass (e.g., `Account,Contact`). If omitted, an interactive prompt will allow you to select from available sObjects.\n- **Automation Type Selection:** Choose which types of automations to bypass: `Flow`, `Trigger`, or `VR` (Validation Rules). If omitted, an interactive prompt will guide your selection.\n- **Automatic Bypass Application:** Optionally, the command can automatically inject bypass logic into Validation Rules and Triggers. This involves modifying the Apex code for Triggers and the XML for Validation Rules.\n- **Metadata Source:** You can choose to retrieve the metadata elements (Validation Rules, Triggers) from the org (`--metadata-source org`) or use local files (`--metadata-source local`). Retrieving from the org is recommended for accuracy.\n- **Custom Permission and Permission Set Generation:** For each selected sObject and automation type, it generates:\n - A **Custom Permission** (e.g., `BypassAccountFlows`) that acts as the bypass switch.\n - A **Permission Set** (e.g., `BypassAccountFlows`) that grants the generated Custom Permission.\n- **Credits Inclusion:** By default, generated XML files include a comment indicating they were generated by sfdx-hardis. This can be skipped using `--skip-credits`.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **SOQL Queries (Tooling API):** It queries `EntityDefinition` to list customizable sObjects and `ValidationRule` and `ApexTrigger` to find existing automations.\n- **Interactive Prompts:** Uses the `prompts` library to guide the user through selecting sObjects, automation types, and bypass application options.\n- **XML Generation:** Dynamically generates XML content for Custom Permissions and Permission Sets, including descriptions and labels that clearly indicate their purpose.\n- **File System Operations:** Uses `fs-extra` to create directories and write the generated Custom Permission and Permission Set XML files.\n- **Metadata Retrieval (for Bypass Application):** If `apply-to-vrs` or `apply-to-triggers` is used and `metadata-source` is `org`, it retrieves the relevant Validation Rule or Apex Trigger metadata from the org using `sf project retrieve start`.\n- **XML/Apex Code Modification:**\n - For Validation Rules, it modifies the `errorConditionFormula` in the XML to include a check for the bypass Custom Permission.\n - For Apex Triggers, it injects an `if` statement at the beginning of the trigger body to check for the bypass Custom Permission.\n- **`parseXmlFile` and `writeXmlFile`:** Used for reading and writing XML metadata files.\n- **`execCommand`:** Used for executing Salesforce CLI commands, particularly for metadata retrieval.\n- **Error Handling:** Includes checks for invalid sObject or automation selections and provides informative error messages.\n</details>\n",
12804
+ "examples": [
12805
+ "$ sf hardis:project:generate:bypass",
12806
+ "$ sf hardis:project:generate:bypass --sObjects Account,Contact,Opportunity",
12807
+ "$ sf hardis:project:generate:bypass --automations Flow,Trigger,VR",
12808
+ "$ sf hardis:project:generate:bypass --sObjects Account,Opportunity --automations Flow,Trigger",
12809
+ "$ sf hardis:project:generate:bypass --skipCredits",
12810
+ "$ sf hardis:project:generate:bypass --apply-to-vrs",
12811
+ "$ sf hardis:project:generate:bypass --apply-to-triggers",
12812
+ "$ sf hardis:project:generate:bypass --metadata-source org"
12813
+ ],
12814
+ "flags": {
12815
+ "json": {
12816
+ "description": "Format output as json.",
12817
+ "helpGroup": "GLOBAL",
12818
+ "name": "json",
12827
12819
  "allowNo": false,
12828
12820
  "type": "boolean"
12829
12821
  },
12830
- "source-dir": {
12831
- "char": "d",
12832
- "description": "source-dir",
12833
- "name": "source-dir",
12822
+ "flags-dir": {
12823
+ "helpGroup": "GLOBAL",
12824
+ "name": "flags-dir",
12825
+ "summary": "Import flag values from a directory.",
12834
12826
  "hasDynamicHelp": false,
12835
- "multiple": true,
12827
+ "multiple": false,
12836
12828
  "type": "option"
12837
12829
  },
12838
12830
  "target-org": {
12831
+ "aliases": [
12832
+ "targetusername",
12833
+ "u"
12834
+ ],
12839
12835
  "char": "o",
12836
+ "deprecateAliases": true,
12840
12837
  "name": "target-org",
12841
12838
  "noCacheDefault": true,
12842
12839
  "required": true,
@@ -12845,144 +12842,136 @@
12845
12842
  "multiple": false,
12846
12843
  "type": "option"
12847
12844
  },
12848
- "tests": {
12849
- "description": "tests",
12850
- "name": "tests",
12845
+ "objects": {
12846
+ "aliases": [
12847
+ "sObjects"
12848
+ ],
12849
+ "char": "s",
12850
+ "description": "Comma-separated list of sObjects to bypass (e.g., Account,Contact,Opportunity). If omitted, you will be prompted to select.",
12851
+ "name": "objects",
12852
+ "required": false,
12851
12853
  "hasDynamicHelp": false,
12852
12854
  "multiple": false,
12853
12855
  "type": "option"
12854
12856
  },
12855
- "test-level": {
12856
- "description": "test-level",
12857
- "name": "test-level",
12857
+ "automations": {
12858
+ "char": "a",
12859
+ "description": "Comma-separated automations to bypass: Flow, Trigger, VR",
12860
+ "name": "automations",
12861
+ "required": false,
12858
12862
  "hasDynamicHelp": false,
12859
12863
  "multiple": false,
12860
12864
  "type": "option"
12861
12865
  },
12862
- "wait": {
12863
- "char": "w",
12864
- "description": "wait",
12865
- "exclusive": [
12866
- "async"
12867
- ],
12868
- "name": "wait",
12869
- "default": 33,
12866
+ "websocket": {
12867
+ "description": "Websocket host:port for VsCode SFDX Hardis UI integration",
12868
+ "name": "websocket",
12870
12869
  "hasDynamicHelp": false,
12871
12870
  "multiple": false,
12872
12871
  "type": "option"
12873
12872
  },
12874
- "purge-on-delete": {
12875
- "description": "purge-on-delete",
12876
- "name": "purge-on-delete",
12873
+ "skipauth": {
12874
+ "description": "Skip authentication check when a default username is required",
12875
+ "name": "skipauth",
12877
12876
  "allowNo": false,
12878
12877
  "type": "boolean"
12879
12878
  },
12880
- "pre-destructive-changes": {
12881
- "dependsOn": [
12882
- "manifest"
12879
+ "skip-credits": {
12880
+ "aliases": [
12881
+ "skipCredits"
12883
12882
  ],
12884
- "description": "pre-destructive-changes",
12885
- "name": "pre-destructive-changes",
12886
- "hasDynamicHelp": false,
12887
- "multiple": false,
12888
- "type": "option"
12883
+ "char": "k",
12884
+ "description": "Omit the \"Generated by\" line in the XML files",
12885
+ "name": "skip-credits",
12886
+ "required": false,
12887
+ "allowNo": false,
12888
+ "type": "boolean"
12889
12889
  },
12890
- "post-destructive-changes": {
12891
- "dependsOn": [
12892
- "manifest"
12890
+ "apply-to-vrs": {
12891
+ "aliases": [
12892
+ "applyToVrs"
12893
12893
  ],
12894
- "description": "post-destructive-changes",
12895
- "name": "post-destructive-changes",
12896
- "hasDynamicHelp": false,
12897
- "multiple": false,
12898
- "type": "option"
12899
- },
12900
- "coverage-formatters": {
12901
- "description": "coverage-formatters",
12902
- "name": "coverage-formatters",
12903
- "hasDynamicHelp": false,
12904
- "multiple": false,
12905
- "type": "option"
12906
- },
12907
- "junit": {
12908
- "description": "junit",
12909
- "name": "junit",
12894
+ "description": "Apply bypass to Validation Rules",
12895
+ "name": "apply-to-vrs",
12896
+ "required": false,
12910
12897
  "allowNo": false,
12911
12898
  "type": "boolean"
12912
12899
  },
12913
- "results-dir": {
12914
- "description": "results-dir",
12915
- "name": "results-dir",
12916
- "hasDynamicHelp": false,
12917
- "multiple": false,
12918
- "type": "option"
12919
- },
12920
- "debug": {
12921
- "description": "debug",
12922
- "name": "debug",
12900
+ "apply-to-triggers": {
12901
+ "aliases": [
12902
+ "applyToTriggers"
12903
+ ],
12904
+ "description": "Apply bypass to Triggers",
12905
+ "name": "apply-to-triggers",
12906
+ "required": false,
12923
12907
  "allowNo": false,
12924
12908
  "type": "boolean"
12909
+ },
12910
+ "metadata-source": {
12911
+ "aliases": [
12912
+ "metadataSource"
12913
+ ],
12914
+ "char": "r",
12915
+ "description": "Source of metadata elements to apply bypass to. Options: 'org' or 'local'.",
12916
+ "name": "metadata-source",
12917
+ "required": false,
12918
+ "hasDynamicHelp": false,
12919
+ "multiple": false,
12920
+ "type": "option"
12925
12921
  }
12926
12922
  },
12927
12923
  "hasDynamicHelp": true,
12928
12924
  "hiddenAliases": [],
12929
- "id": "hardis:project:deploy:validate",
12925
+ "id": "hardis:project:generate:bypass",
12930
12926
  "pluginAlias": "sfdx-hardis",
12931
12927
  "pluginName": "sfdx-hardis",
12932
12928
  "pluginType": "core",
12933
12929
  "strict": true,
12934
12930
  "enableJsonFlag": true,
12935
- "requiresProject": true,
12936
12931
  "isESM": true,
12937
12932
  "relativePath": [
12938
12933
  "lib",
12939
12934
  "commands",
12940
12935
  "hardis",
12941
12936
  "project",
12942
- "deploy",
12943
- "validate.js"
12944
- ],
12945
- "aliasPermutations": [
12946
- "hardis:deploy:validate",
12947
- "deploy:hardis:validate",
12948
- "deploy:validate:hardis",
12949
- "hardis:validate:deploy",
12950
- "validate:hardis:deploy",
12951
- "validate:deploy:hardis"
12937
+ "generate",
12938
+ "bypass.js"
12952
12939
  ],
12940
+ "aliasPermutations": [],
12953
12941
  "permutations": [
12954
- "hardis:project:deploy:validate",
12955
- "project:hardis:deploy:validate",
12956
- "project:deploy:hardis:validate",
12957
- "project:deploy:validate:hardis",
12958
- "hardis:deploy:project:validate",
12959
- "deploy:hardis:project:validate",
12960
- "deploy:project:hardis:validate",
12961
- "deploy:project:validate:hardis",
12962
- "hardis:deploy:validate:project",
12963
- "deploy:hardis:validate:project",
12964
- "deploy:validate:hardis:project",
12965
- "deploy:validate:project:hardis",
12966
- "hardis:project:validate:deploy",
12967
- "project:hardis:validate:deploy",
12968
- "project:validate:hardis:deploy",
12969
- "project:validate:deploy:hardis",
12970
- "hardis:validate:project:deploy",
12971
- "validate:hardis:project:deploy",
12972
- "validate:project:hardis:deploy",
12973
- "validate:project:deploy:hardis",
12974
- "hardis:validate:deploy:project",
12975
- "validate:hardis:deploy:project",
12976
- "validate:deploy:hardis:project",
12977
- "validate:deploy:project:hardis"
12942
+ "hardis:project:generate:bypass",
12943
+ "project:hardis:generate:bypass",
12944
+ "project:generate:hardis:bypass",
12945
+ "project:generate:bypass:hardis",
12946
+ "hardis:generate:project:bypass",
12947
+ "generate:hardis:project:bypass",
12948
+ "generate:project:hardis:bypass",
12949
+ "generate:project:bypass:hardis",
12950
+ "hardis:generate:bypass:project",
12951
+ "generate:hardis:bypass:project",
12952
+ "generate:bypass:hardis:project",
12953
+ "generate:bypass:project:hardis",
12954
+ "hardis:project:bypass:generate",
12955
+ "project:hardis:bypass:generate",
12956
+ "project:bypass:hardis:generate",
12957
+ "project:bypass:generate:hardis",
12958
+ "hardis:bypass:project:generate",
12959
+ "bypass:hardis:project:generate",
12960
+ "bypass:project:hardis:generate",
12961
+ "bypass:project:generate:hardis",
12962
+ "hardis:bypass:generate:project",
12963
+ "bypass:hardis:generate:project",
12964
+ "bypass:generate:hardis:project",
12965
+ "bypass:generate:project:hardis"
12978
12966
  ]
12979
12967
  },
12980
- "hardis:project:fix:profiletabs": {
12968
+ "hardis:project:generate:flow-git-diff": {
12981
12969
  "aliases": [],
12982
12970
  "args": {},
12983
- "description": "\n## Command Behavior\n\n**Interactively updates tab visibility settings in Salesforce profiles, addressing a common issue where tab visibilities are not correctly retrieved by `sf project retrieve start`.**\n\nThis command provides a user-friendly interface to manage tab settings within your profile XML files, ensuring that your local project accurately reflects the intended tab configurations in your Salesforce org.\n\nKey functionalities:\n\n- **Interactive Tab Selection:** Displays a multi-select menu of all available tabs in your org, allowing you to choose which tabs to update.\n- **Visibility Control:** Lets you set the visibility for the selected tabs to either `DefaultOn` (Visible) or `Hidden`.\n- **Profile Selection:** Presents a multi-select menu of all .profile-meta.xml files in your project, allowing you to apply the tab visibility changes to specific profiles.\n- **XML Updates:** Modifies the <tabVisibilities> section of the selected profile XML files to reflect the chosen tab settings. If a tab visibility setting already exists for a selected tab, it will be updated; otherwise, a new one will be added.\n- **Sorted Output:** The <tabVisibilities> in the updated profile XML files are sorted alphabetically for consistency and readability.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **SOQL Queries (Tooling API):** It queries the `TabDefinition` object using `soqlQueryTooling` to retrieve a list of all available tabs in the target org.\n- **File Discovery:** Uses `glob` to find all .profile-meta.xml files within the specified project path.\n- **Interactive Prompts:** Leverages the `prompts` library to create interactive menus for selecting tabs, visibility settings, and profiles.\n- **XML Parsing and Manipulation:** Uses `parseXmlFile` to read the content of profile XML files and `writeXmlFile` to write the modified content back. It manipulates the `tabVisibilities` array within the parsed XML to add or update tab settings.\n- **Array Sorting:** Employs the `sort-array` library to sort the `tabVisibilities` alphabetically by tab name.\n- **Logging:** Provides feedback to the user about which profiles have been updated and a summary of the changes.\n</details>\n",
12971
+ "description": "Generate Flow Visual Git Diff markdown between 2 commits\n\nNote: This command might requires @mermaid-js/mermaid-cli to be installed.\n\nRun `npm install @mermaid-js/mermaid-cli --global`\n ",
12984
12972
  "examples": [
12985
- "$ sf hardis:project:fix:profiletabs"
12973
+ "$ sf hardis:project:generate:flow-git-diff",
12974
+ "$ sf hardis:project:generate:flow-git-diff --flow \"force-app/main/default/flows/Opportunity_AfterUpdate_Cloudity.flow-meta.xml\" --commit-before 8bd290e914c9dbdde859dad7e3c399776160d704 --commit-after e0835251bef6e400fb91e42f3a31022f37840f65"
12986
12975
  ],
12987
12976
  "flags": {
12988
12977
  "json": {
@@ -13000,11 +12989,25 @@
13000
12989
  "multiple": false,
13001
12990
  "type": "option"
13002
12991
  },
13003
- "path": {
13004
- "char": "p",
13005
- "description": "Root folder",
13006
- "name": "path",
13007
- "default": "/home/runner/work/sfdx-hardis/sfdx-hardis",
12992
+ "flow": {
12993
+ "description": "Path to flow file (will be prompted if not set)",
12994
+ "name": "flow",
12995
+ "hasDynamicHelp": false,
12996
+ "multiple": false,
12997
+ "type": "option"
12998
+ },
12999
+ "commit-before": {
13000
+ "description": "Hash of the commit of the previous flow state, or \"allStates\" (will be prompted if not set)",
13001
+ "name": "commit-before",
13002
+ "default": "",
13003
+ "hasDynamicHelp": false,
13004
+ "multiple": false,
13005
+ "type": "option"
13006
+ },
13007
+ "commit-after": {
13008
+ "description": "Hash of the commit of the new flow state (will be prompted if not set)",
13009
+ "name": "commit-after",
13010
+ "default": "",
13008
13011
  "hasDynamicHelp": false,
13009
13012
  "multiple": false,
13010
13013
  "type": "option"
@@ -13028,32 +13031,17 @@
13028
13031
  "name": "skipauth",
13029
13032
  "allowNo": false,
13030
13033
  "type": "boolean"
13031
- },
13032
- "target-org": {
13033
- "aliases": [
13034
- "targetusername",
13035
- "u"
13036
- ],
13037
- "char": "o",
13038
- "deprecateAliases": true,
13039
- "name": "target-org",
13040
- "noCacheDefault": true,
13041
- "required": true,
13042
- "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
13043
- "hasDynamicHelp": true,
13044
- "multiple": false,
13045
- "type": "option"
13046
13034
  }
13047
13035
  },
13048
- "hasDynamicHelp": true,
13036
+ "hasDynamicHelp": false,
13049
13037
  "hiddenAliases": [],
13050
- "id": "hardis:project:fix:profiletabs",
13038
+ "id": "hardis:project:generate:flow-git-diff",
13051
13039
  "pluginAlias": "sfdx-hardis",
13052
13040
  "pluginName": "sfdx-hardis",
13053
13041
  "pluginType": "core",
13054
13042
  "strict": true,
13055
13043
  "enableJsonFlag": true,
13056
- "title": "Fix profiles to add tabs that are not retrieved by SF CLI",
13044
+ "title": "Generate Flow Visual Gif Diff",
13057
13045
  "requiresProject": true,
13058
13046
  "isESM": true,
13059
13047
  "relativePath": [
@@ -13061,43 +13049,43 @@
13061
13049
  "commands",
13062
13050
  "hardis",
13063
13051
  "project",
13064
- "fix",
13065
- "profiletabs.js"
13052
+ "generate",
13053
+ "flow-git-diff.js"
13066
13054
  ],
13067
13055
  "aliasPermutations": [],
13068
13056
  "permutations": [
13069
- "hardis:project:fix:profiletabs",
13070
- "project:hardis:fix:profiletabs",
13071
- "project:fix:hardis:profiletabs",
13072
- "project:fix:profiletabs:hardis",
13073
- "hardis:fix:project:profiletabs",
13074
- "fix:hardis:project:profiletabs",
13075
- "fix:project:hardis:profiletabs",
13076
- "fix:project:profiletabs:hardis",
13077
- "hardis:fix:profiletabs:project",
13078
- "fix:hardis:profiletabs:project",
13079
- "fix:profiletabs:hardis:project",
13080
- "fix:profiletabs:project:hardis",
13081
- "hardis:project:profiletabs:fix",
13082
- "project:hardis:profiletabs:fix",
13083
- "project:profiletabs:hardis:fix",
13084
- "project:profiletabs:fix:hardis",
13085
- "hardis:profiletabs:project:fix",
13086
- "profiletabs:hardis:project:fix",
13087
- "profiletabs:project:hardis:fix",
13088
- "profiletabs:project:fix:hardis",
13089
- "hardis:profiletabs:fix:project",
13090
- "profiletabs:hardis:fix:project",
13091
- "profiletabs:fix:hardis:project",
13092
- "profiletabs:fix:project:hardis"
13057
+ "hardis:project:generate:flow-git-diff",
13058
+ "project:hardis:generate:flow-git-diff",
13059
+ "project:generate:hardis:flow-git-diff",
13060
+ "project:generate:flow-git-diff:hardis",
13061
+ "hardis:generate:project:flow-git-diff",
13062
+ "generate:hardis:project:flow-git-diff",
13063
+ "generate:project:hardis:flow-git-diff",
13064
+ "generate:project:flow-git-diff:hardis",
13065
+ "hardis:generate:flow-git-diff:project",
13066
+ "generate:hardis:flow-git-diff:project",
13067
+ "generate:flow-git-diff:hardis:project",
13068
+ "generate:flow-git-diff:project:hardis",
13069
+ "hardis:project:flow-git-diff:generate",
13070
+ "project:hardis:flow-git-diff:generate",
13071
+ "project:flow-git-diff:hardis:generate",
13072
+ "project:flow-git-diff:generate:hardis",
13073
+ "hardis:flow-git-diff:project:generate",
13074
+ "flow-git-diff:hardis:project:generate",
13075
+ "flow-git-diff:project:hardis:generate",
13076
+ "flow-git-diff:project:generate:hardis",
13077
+ "hardis:flow-git-diff:generate:project",
13078
+ "flow-git-diff:hardis:generate:project",
13079
+ "flow-git-diff:generate:hardis:project",
13080
+ "flow-git-diff:generate:project:hardis"
13093
13081
  ]
13094
13082
  },
13095
- "hardis:project:fix:v53flexipages": {
13083
+ "hardis:project:generate:gitdelta": {
13096
13084
  "aliases": [],
13097
13085
  "args": {},
13098
- "description": "\n## Command Behavior\n\n**Fixes Salesforce FlexiPages for compatibility with API Version 53.0 (Winter '22 release) by adding missing identifiers to component instances.**\n\nSalesforce introduced a change in API Version 53.0 that requires `identifier` tags within `componentInstance` and `fieldInstance` elements in FlexiPage metadata. If these identifiers are missing, deployments to orgs with API version 53.0 or higher will fail. This command automates the process of adding these missing identifiers, ensuring your FlexiPages remain deployable.\n\nKey functionalities:\n\n- **Targeted FlexiPage Processing:** Scans all .flexipage-meta.xml files within the specified root folder (defaults to current working directory).\n- **Identifier Injection:** Inserts a unique `identifier` tag (e.g., `SFDX_HARDIS_REPLACEMENT_ID`) into `componentInstance` and `fieldInstance` elements that lack one.\n\n**Important Note:** After running this command, ensure you update your `apiVersion` to `53.0` (or higher) in your `package.xml` and `sfdx-project.json` files.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **File Discovery:** Uses `glob` to find all .flexipage-meta.xml files.\n- **Content Reading:** Reads the XML content of each FlexiPage file.\n- **Regular Expression Replacement:** Employs a set of regular expressions to identify specific XML patterns (componentName.../componentName.../componentInstance, componentName.../componentName.../visibilityRule, fieldItem.../fieldItem.../fieldInstance) that are missing the `identifier` tag.\n- **Dynamic ID Generation:** For each match, it generates a unique identifier (e.g., `sfdxHardisIdX`) and injects it into the XML structure.\n- **File Writing:** If changes are made, the modified XML content is written back to the FlexiPage file using `fs.writeFile`.\n- **Logging:** Provides messages about which FlexiPages are being processed and a summary of the total number of identifiers added.\n</details>\n",
13086
+ "description": "\n## Command Behavior\n\n**Generates a `package.xml` and `destructiveChanges.xml` representing the metadata differences between two Git commits.**\n\nThis command is a powerful tool for managing Salesforce metadata deployments by focusing only on the changes between specific points in your version control history. It leverages `sfdx-git-delta` to accurately identify added, modified, and deleted metadata components.\n\nKey functionalities:\n\n- **Commit-Based Comparison:** Allows you to specify a starting commit (`--fromcommit`) and an ending commit (`--tocommit`) to define the scope of the delta. If not provided, interactive prompts will guide you through selecting commits from your Git history.\n- **Branch Selection:** You can specify a Git branch (`--branch`) to work with. If not provided, it will prompt you to select one.\n- **`package.xml` Generation:** Creates a `package.xml` file that lists all metadata components that have been added or modified between the specified commits.\n- **`destructiveChanges.xml` Generation:** Creates a `destructiveChanges.xml` file that lists all metadata components that have been deleted between the specified commits.\n- **Temporary File Output:** The generated `package.xml` and `destructiveChanges.xml` files are placed in a temporary directory.\n\n<details markdown=\"1\">\n<summary>Technical explanations</summary>\n\nThe command's technical implementation involves:\n\n- **Git Integration:** Uses `simple-git` (`git()`) to interact with the Git repository, including fetching branches (`git().fetch()`), checking out branches (`git().checkoutBranch()`), and listing commit history (`git().log()`).\n- **Interactive Prompts:** Leverages the `prompts` library to guide the user through selecting a Git branch and specific commits for delta generation if they are not provided as command-line arguments.\n- **`sfdx-git-delta` Integration:** The core of the delta generation is handled by the `callSfdxGitDelta` utility function, which wraps the `sfdx-git-delta` tool. This tool performs the actual Git comparison and generates the `package.xml` and `destructiveChanges.xml` files.\n- **Temporary Directory Management:** Uses `createTempDir` to create a temporary directory for storing the generated XML files, ensuring a clean working environment.\n- **File System Operations:** Uses `fs-extra` to manage temporary files and directories.\n- **User Feedback:** Provides clear messages to the user about the generated files and their locations.\n</details>\n",
13099
13087
  "examples": [
13100
- "$ sf hardis:project:fix:v53flexipages"
13088
+ "$ sf hardis:project:generate:gitdelta"
13101
13089
  ],
13102
13090
  "flags": {
13103
13091
  "json": {
@@ -13115,11 +13103,23 @@
13115
13103
  "multiple": false,
13116
13104
  "type": "option"
13117
13105
  },
13118
- "path": {
13119
- "char": "p",
13120
- "description": "Root folder",
13121
- "name": "path",
13122
- "default": "/home/runner/work/sfdx-hardis/sfdx-hardis",
13106
+ "branch": {
13107
+ "description": "Git branch to use to generate delta",
13108
+ "name": "branch",
13109
+ "hasDynamicHelp": false,
13110
+ "multiple": false,
13111
+ "type": "option"
13112
+ },
13113
+ "fromcommit": {
13114
+ "description": "Hash of commit to start from",
13115
+ "name": "fromcommit",
13116
+ "hasDynamicHelp": false,
13117
+ "multiple": false,
13118
+ "type": "option"
13119
+ },
13120
+ "tocommit": {
13121
+ "description": "Hash of commit to stop at",
13122
+ "name": "tocommit",
13123
13123
  "hasDynamicHelp": false,
13124
13124
  "multiple": false,
13125
13125
  "type": "option"
@@ -13147,49 +13147,49 @@
13147
13147
  },
13148
13148
  "hasDynamicHelp": false,
13149
13149
  "hiddenAliases": [],
13150
- "id": "hardis:project:fix:v53flexipages",
13150
+ "id": "hardis:project:generate:gitdelta",
13151
13151
  "pluginAlias": "sfdx-hardis",
13152
13152
  "pluginName": "sfdx-hardis",
13153
13153
  "pluginType": "core",
13154
13154
  "strict": true,
13155
13155
  "enableJsonFlag": true,
13156
- "title": "Fix flexipages for v53",
13157
- "requiresProject": true,
13156
+ "title": "Generate Git Delta",
13157
+ "requiresProject": false,
13158
13158
  "isESM": true,
13159
13159
  "relativePath": [
13160
13160
  "lib",
13161
13161
  "commands",
13162
13162
  "hardis",
13163
13163
  "project",
13164
- "fix",
13165
- "v53flexipages.js"
13164
+ "generate",
13165
+ "gitdelta.js"
13166
13166
  ],
13167
13167
  "aliasPermutations": [],
13168
13168
  "permutations": [
13169
- "hardis:project:fix:v53flexipages",
13170
- "project:hardis:fix:v53flexipages",
13171
- "project:fix:hardis:v53flexipages",
13172
- "project:fix:v53flexipages:hardis",
13173
- "hardis:fix:project:v53flexipages",
13174
- "fix:hardis:project:v53flexipages",
13175
- "fix:project:hardis:v53flexipages",
13176
- "fix:project:v53flexipages:hardis",
13177
- "hardis:fix:v53flexipages:project",
13178
- "fix:hardis:v53flexipages:project",
13179
- "fix:v53flexipages:hardis:project",
13180
- "fix:v53flexipages:project:hardis",
13181
- "hardis:project:v53flexipages:fix",
13182
- "project:hardis:v53flexipages:fix",
13183
- "project:v53flexipages:hardis:fix",
13184
- "project:v53flexipages:fix:hardis",
13185
- "hardis:v53flexipages:project:fix",
13186
- "v53flexipages:hardis:project:fix",
13187
- "v53flexipages:project:hardis:fix",
13188
- "v53flexipages:project:fix:hardis",
13189
- "hardis:v53flexipages:fix:project",
13190
- "v53flexipages:hardis:fix:project",
13191
- "v53flexipages:fix:hardis:project",
13192
- "v53flexipages:fix:project:hardis"
13169
+ "hardis:project:generate:gitdelta",
13170
+ "project:hardis:generate:gitdelta",
13171
+ "project:generate:hardis:gitdelta",
13172
+ "project:generate:gitdelta:hardis",
13173
+ "hardis:generate:project:gitdelta",
13174
+ "generate:hardis:project:gitdelta",
13175
+ "generate:project:hardis:gitdelta",
13176
+ "generate:project:gitdelta:hardis",
13177
+ "hardis:generate:gitdelta:project",
13178
+ "generate:hardis:gitdelta:project",
13179
+ "generate:gitdelta:hardis:project",
13180
+ "generate:gitdelta:project:hardis",
13181
+ "hardis:project:gitdelta:generate",
13182
+ "project:hardis:gitdelta:generate",
13183
+ "project:gitdelta:hardis:generate",
13184
+ "project:gitdelta:generate:hardis",
13185
+ "hardis:gitdelta:project:generate",
13186
+ "gitdelta:hardis:project:generate",
13187
+ "gitdelta:project:hardis:generate",
13188
+ "gitdelta:project:generate:hardis",
13189
+ "hardis:gitdelta:generate:project",
13190
+ "gitdelta:hardis:generate:project",
13191
+ "gitdelta:generate:hardis:project",
13192
+ "gitdelta:generate:project:hardis"
13193
13193
  ]
13194
13194
  },
13195
13195
  "hardis:project:metadata:activate-decomposed": {
@@ -15370,5 +15370,5 @@
15370
15370
  ]
15371
15371
  }
15372
15372
  },
15373
- "version": "6.9.1-alpha202510262348.0"
15373
+ "version": "6.9.1-alpha202510270034.0"
15374
15374
  }