├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── images ├── addChangesets.png ├── apexsave.png ├── aurasave.png ├── autosavedisable.png ├── autosavefeature.png ├── changesetDeploy.png ├── changesetdir.png ├── changesetname.png ├── deploySrc.png ├── deployorgselector.png ├── error_log.png ├── install_plugins.png ├── logo.png ├── logo_revised.png ├── lwcsave.png ├── manageConflictSettings.png ├── manageConflicts.png ├── navigation.png ├── retrieve.png ├── retrievePkg.png ├── retrieve_changeset.png └── switchorg.png ├── package-lock.json ├── package.json ├── src ├── extension.ts ├── providers │ └── ccprovider.ts ├── services │ ├── changeset.ts │ ├── commandBuilder.ts │ ├── config.ts │ ├── deploy.ts │ ├── findMetadataType.ts │ ├── navigation.ts │ ├── osUtils.ts │ ├── retrieve.ts │ ├── sfdcUtils.ts │ ├── switchOrg.ts │ ├── vscodeCore.ts │ └── vscodeUI.ts ├── test │ ├── extension.test.ts │ └── index.ts └── typings │ └── ccdxTypings.ts ├── tsconfig.json ├── tslint.json └── vsc-extension-quickstart.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behavior to automatically normalize line endings. 2 | * text=auto 3 | 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "10:00" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: "@types/node" 11 | versions: 12 | - 14.14.22 13 | - 14.14.25 14 | - 14.14.27 15 | - 14.14.28 16 | - 14.14.30 17 | - 14.14.31 18 | - 14.14.32 19 | - 14.14.33 20 | - 14.14.34 21 | - 14.14.35 22 | - 14.14.36 23 | - 14.14.37 24 | - 14.14.39 25 | - 14.14.41 26 | - 15.0.0 27 | - dependency-name: "@salesforce/core" 28 | versions: 29 | - 2.16.4 30 | - 2.17.0 31 | - 2.18.0 32 | - 2.18.2 33 | - 2.18.3 34 | - 2.18.4 35 | - 2.18.5 36 | - 2.18.6 37 | - 2.19.0 38 | - 2.19.1 39 | - 2.20.0 40 | - 2.20.1 41 | - 2.20.3 42 | - 2.20.4 43 | - 2.20.5 44 | - 2.20.8 45 | - 2.20.9 46 | - dependency-name: typescript 47 | versions: 48 | - 4.1.3 49 | - 4.1.4 50 | - 4.1.5 51 | - 4.2.2 52 | - 4.2.3 53 | - dependency-name: "@types/mocha" 54 | versions: 55 | - 8.2.0 56 | - 8.2.1 57 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | # The branches below must be a subset of the branches above 8 | branches: [master] 9 | schedule: 10 | - cron: '0 15 * * 6' 11 | 12 | jobs: 13 | analyze: 14 | name: Analyze 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | # Override automatic language detection by changing the below list 21 | # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] 22 | language: ['javascript'] 23 | # Learn more... 24 | # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection 25 | 26 | steps: 27 | - name: Checkout repository 28 | uses: actions/checkout@v2 29 | with: 30 | # We must fetch at least the immediate parents so that if this is 31 | # a pull request then we can checkout the head. 32 | fetch-depth: 2 33 | 34 | # If this run was triggered by a pull request event, then checkout 35 | # the head of the pull request instead of the merge commit. 36 | - run: git checkout HEAD^2 37 | if: ${{ github.event_name == 'pull_request' }} 38 | 39 | # Initializes the CodeQL tools for scanning. 40 | - name: Initialize CodeQL 41 | uses: github/codeql-action/init@v1 42 | with: 43 | languages: ${{ matrix.language }} 44 | 45 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 46 | # If this step fails, then you should remove it and run the build manually (see below) 47 | - name: Autobuild 48 | uses: github/codeql-action/autobuild@v1 49 | 50 | # ℹ️ Command-line programs to run using the OS shell. 51 | # 📚 https://git.io/JvXDl 52 | 53 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 54 | # and modify them (or add more) to build your code if your project 55 | # uses a compiled language 56 | 57 | #- run: | 58 | # make bootstrap 59 | # make release 60 | 61 | - name: Perform CodeQL Analysis 62 | uses: github/codeql-action/analyze@v1 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode-test/ 4 | *.vsix 5 | C:Devnodejsnpm-cache 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "salesforce.salesforcedx-vscode" 6 | ] 7 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "--extensionDevelopmentPath=${workspaceFolder}" 15 | ], 16 | "outFiles": [ 17 | "${workspaceFolder}/out/**/*.js" 18 | ], 19 | "preLaunchTask": "npm: watch" 20 | }, 21 | { 22 | "name": "Extension Tests", 23 | "type": "extensionHost", 24 | "request": "launch", 25 | "runtimeExecutable": "${execPath}", 26 | "args": [ 27 | "--extensionDevelopmentPath=${workspaceFolder}", 28 | "--extensionTestsPath=${workspaceFolder}/out/test" 29 | ], 30 | "outFiles": [ 31 | "${workspaceFolder}/out/test/**/*.js" 32 | ], 33 | "preLaunchTask": "npm: watch" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off", 11 | "typescript.tsdk": "/Users/mohith/Desktop/CodeCompanion/dx-code-companion/node_modules/typescript/lib" 12 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | out/**/*.map 5 | src/** 6 | .gitignore 7 | tsconfig.json 8 | vsc-extension-quickstart.md 9 | tslint.json -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to the "dx-code-companion" extension will be documented in this file. 3 | 4 | ### 0.4.8 5 | 6 | 1. Update npm libraries to latest 7 | 8 | ### 0.4.7 9 | 10 | 1. Update npm libraries to latest. 11 | 2. Diff view now respects current UI theme set by user 12 | 13 | ### 0.4.6 14 | 15 | 1.Update npm libraries to latest. 16 | 17 | ### 0.4.1 18 | 1.Update npm libraries to latest. Fixes Security Vulnerabilities 19 | 20 | ### 0.4.0 21 | 1.Fix issues listed [here](https://github.com/msrivastav13/DX-Code-Companion/labels/fixed%20in%200.4.0) 22 | 23 | 2.Install mo-dx-plugin now from the extension context menu directly if you do not have mo-dx-plugin. 24 | 25 | ![Install mo-dx-plugin for extension](./images/install_plugins.png) 26 | 27 | 3.Security patch 28 | 29 | ### 0.3.9 30 | 1.There is a setting provided(dx-code-companion.staticresourcefolder.resourceBundleFoldername) to indicate the resource bundle folder name for single page app development. Default value is "staticresource" but if you prefer to use names like "resourcebundle" or "spa" use the settings to change it. 31 | 2.A static resource folder has a explorer menu to deploy the folder as static resource bundle 32 | 33 | ### 0.3.8 34 | 1.Fix bug for the windows when static resource files are edited 35 | 36 | ### 0.3.7 37 | 1.Added support for saving static resource files to server via tooling api. 38 | 39 | ### 0.3.6 40 | 1.To manage settings you dont need to edit the settings.json and instead has UI 41 | 2.Security patches (discovered via npm audit) 42 | 43 | ### 0.3.3 44 | 45 | 1.Update the sfdx-core to use latest version. 46 | 2.Save to salesforce would automatically kick off when vscode opens a folder. Made sure it happens only when user manually tries to save the file 47 | 3.Remove support for v1.29.0 vscode. Requires v1.30.0 and above 48 | 49 | ### 0.3.0 50 | 51 | Fully support changeset driven development (https://trailhead.salesforce.com/en/content/learn/modules/declarative-change-set-development/develop-and-test-changes-locally) 52 | 53 | This version requires you to upgrade mo-dx-plugin to 0.2.0 version. 54 | 55 | Run `sfdx plugins:update` to update mo-dx-plugin to latest 56 | 57 | With this release,you can use DX Code Companion extension to retrieve source from the changeset created in your sandbox (Assumes you have authorized CLI to sandbox using "SFDX:Authorize and org").Use vscode to edit contents if needed and then deploy to target orgs all from VScode without need to upload the changesets and wait. 58 | 59 | 1) To retrieve source from the changeset use the command pallete and select "CCDX:Retrieve Source From Changeset" 60 | 61 | ![Retrieve source from changeset](./images/retrieve_changeset.png) 62 | 63 | 2) Provide the changeset name in the text box (Avoid creating changesets with same name in sandbox) 64 | 65 | ![changeset name](./images/changesetname.png) 66 | 67 | 3) Once code components are retrieved , Under changeset directory a sub directory will be created with src folder having all the components .You can edit the source code and also save to the authenticated orgs. 68 | 69 | ![changeset dir structure](./images/changesetdir.png) 70 | 71 | 4) Note that the changeset directory has orgs.json to which you can add list of orgs you have authorized salesforce CLI by clicking on the file and using "CCDX:Add Orgs For Changeset Deployment" 72 | 73 | ![Add orgs for depolyments](./images/addChangesets.png) 74 | 75 | ![Select the target org](./images/deployorgselector.png) 76 | 77 | 5.Click on "src" folder for your changeset to deploy them . The interface will ask you to pick org from the list of orgs you have added in previous step 78 | 79 | ![Deploy changeset](./images/changesetDeploy.png) 80 | 81 | ### 0.2.8 82 | 83 | 1. Fixes connection method to use salesforce core library native methods 84 | 2. Adds ability to deploy the src folder for classic metadata directly from explorer menu. Note this expects you have source in classic metadata format 85 | 86 | ![Deploy source from src folder](./images/deploySrc.png) 87 | 88 | ### 0.2.7 89 | 90 | 1. Fixes Manage Conflicts with server is not working for Apex Components and Apex Pages 91 | 92 | ### 0.2.6 93 | 94 | 1. Fix issue by changing the folder name of content provider to use Capital letter. Seems very weird that not doing this breaks the plugin for chrome-os. The issue is described here (https://github.com/msrivastav13/DX-Code-Companion/issues/6) 95 | 96 | ### 0.2.5 97 | 98 | 1. Adds a new Command Compare With Server to view diff between current local and server file. 99 | 100 | 2. By default Manage Conflict is switched off .Turn it on via settings 101 | 102 | ![Manage conflict](./images/manageConflictSettings.png) 103 | 104 | 3. Fixed few bugs related to refresh from server on aura components. 105 | 106 | ### 0.2.4 107 | 108 | 1. Fixes when .xml files would try to save to server .This is not supported at this point and use native salesforce extension to deploy meta.xml files for version changes . 109 | 110 | ### 0.2.0 111 | 112 | 1. Adds ability to manage conflicts with server copy 113 | 114 | 2. Refresh From Server for LWC, Aura files , triggers , vf pages, vf components and classes 115 | 116 | 3. Save now compares file with server copy . 117 | 118 | 4. A new icon on the footer to indicate SalesforceDX Code Companion is active 119 | 120 | 5. Footer now indicates a rocket symbol if extension is active and you can navigate to org clicking on this . 121 | 122 | ### 0.1.10 123 | 124 | 1. Auto populate package list for selection for Retrieve Options 125 | 126 | 2. Retrieve DX Source and metadata options are only available from Command Palette (CMD+ SHIFT + P on MACOSX or CTRL + SHIFT + P on windows) 127 | 128 | 3. Previously the Save To Server tried running command on Non Salesforce files .This update fixes this and only saves if the working directory root has sfdx-project.json file. 129 | 130 | ### 0.1.8 131 | 132 | 1.Switch between authenticated orgs using new Switch Org Command .This opens up to switch and deploy the code between orgs using SFDX:Deploy To Org Command 133 | 134 | ![Navigations](./images/switchorg.png) 135 | 136 | 2.Fix AutoSave to now not run terminal command if file type is not supported 137 | 138 | 3.Better naming and Grouping .All Commands now CCDX as the prefix . 139 | 140 | 4.LWC(Lighnting Web Components) support improved 141 | 142 | 5.Introduces sfdx-core library in the build opening up lot more existing features to come in next release. 143 | 144 | ### 0.1.4 145 | 146 | 1.Auto Save enabled .You can disable using the autosave property 147 | 148 | ![Auto Save Feature](./images/autosavefeature.png) 149 | 150 | Use the settings (Select Code > Preferences > Settings) from the gear icon and modify the usersettings to disable the autosave feature as shown below by setting dx-code-companion.autosave.enabled as false . 151 | 152 | ![Auto Save Feature](./images/autosavedisable.png) 153 | 154 | 2.Save LWC Components(Under preview).Upgrade the mo-dx-plugin using sfdx:plugins:update mo-dx-plugin 155 | 156 | ### 0.1.3 157 | 158 | 1.Add support to retrieve metadata using package name in regular metadata format 159 | 160 | 2.Add some useful link in editor title for vf preview , app builder page ,metadata coverage report and component Library. 161 | 162 | ### 0.0.5 163 | 164 | 1. Fixes issues for keyboard shortcut 165 | 166 | ### 0.0.2 167 | 168 | 1. Provides quick save apex,vf,aura bundles to salesforce server 169 | 2. Retrieve Source from Salesforce using DX Source format. 170 | 3. 3X performant than salesforce deploy command for apex,aura and vf files. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Mohith Shrivastava 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SalesforceDX Code Companion 2 | 3 | [![Logo](./images/logo_revised.png)](https://marketplace.visualstudio.com/items?itemName=MohithShrivastava.dx-code-companion) 4 | 5 | [![Version](https://vsmarketplacebadge.apphb.com/version/MohithShrivastava.dx-code-companion.png)](https://marketplace.visualstudio.com/items?itemName=MohithShrivastava.dx-code-companion) 6 | [![Installs](https://vsmarketplacebadge.apphb.com/installs/MohithShrivastava.dx-code-companion.png)](https://marketplace.visualstudio.com/items?itemName=MohithShrivastava.dx-code-companion) 7 | [![Downloads](https://vsmarketplacebadge.apphb.com/downloads/MohithShrivastava.dx-code-companion.png)](https://marketplace.visualstudio.com/items?itemName=MohithShrivastava.dx-code-companion) 8 | [![Ratings](https://vsmarketplacebadge.apphb.com/rating/MohithShrivastava.dx-code-companion.png)](https://vsmarketplacebadge.apphb.com/rating/MohithShrivastava.dx-code-companion.svg) 9 | 10 | 11 | **Note that this is not official from Salesforce. I created this extension to help my own development workflow for building salesforce apps. This extension supplements Salesforce Official Extension Pack with features like faster save of apex,lwc and vf pages.You can use this to also retrieve package metadata from salesforce orgs in both traditional metadata and SalesforceDX formats. Also supports managing conflicts between salesforce files and salesforce org** 12 | 13 | Provides ability to save Apex Classes,Apex Triggers, Visualforce, AuraBundles, Lightning Web Component Bundles(under preview) and ApexComponents to Salesforce Org at blazing speed without source tracking. Also enables retrieving code from the salesforce unmanaged package/changesets in both DX and NonDX source formats .You can also switch between authenticated orgs easily with CCDX: Switch Command. This extension requires users to have SalesforceDX CLI and also mo-dx-plugin(run **sfdx plugins:install mo-dx-plugin**) for SalesforceDX CLI.This Extension works with both scratch orgs and Non-scratch orgs. 14 | 15 | It is highly recommended to use with Salesforce Extension Pack to get all the other good things salesforce official extension offers (https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode) . 16 | 17 | # Requirements 18 | 19 | This vscode extension works only once you have installed Salesforce CLI and a mo-dx-plugin(run **sfdx plugins:install mo-dx-plugin** on your terminal) that has api for all the commands this extension leverages . 20 | 21 | 1. Install SalesforceDX CLI from https://developer.salesforce.com/tools/sfdxcli based on your operating system. 22 | 2. Install mo-dx-plugin using the command `sfdx plugins:install mo-dx-plugin`.Note if you have already then make sure to update to latest always using `sfdx plugins:update` 23 | 3. VScode version 1.30 and beyond 24 | 4. Salesforce official plugin provides great syntax and language support.Highly recommend to install (https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode) 25 | 5. You have project workspace set up and have sfdx-project.json file in the root folder and you have ran sfdx force:auth:web:login for project folder and authorized your org with Salesforce CLI. 26 | 6. Extension activation is shown in footer with a rocket symbol. Once extension is active authorize the project if you havent and enjoy faster deploys 27 | 28 | # Features 29 | 30 | 1. **Retrieve Source in DX Source format from Managed/Unmamaged package/ChangeSets** 31 | 32 | From the command palette menu select "Retrieve DX Source From Package" . Provide the name of the managed/unmanaged package in input box and press enter .This is the recommended source format. 33 | 34 | The source is in the format specified here (https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_source_file_format.htm) 35 | 36 | You will notice that package.xml is autogenerated in the manifest directory and source code of the package is retrieved in DX source format in force-app folder. 37 | 38 | ![Retrieve Source From Unmanaged/Managed Package In DX Format](./images/retrieve.png) 39 | 40 | 2. **Retrieve Source from Managed/Unmamaged package/Changesets in traditional metadata format** 41 | 42 | From the command palette menu select "Retrieve Source From Package". Provide the name of the managed/unmanaged package and press enter .Projects still not moved to the DX format can benefit from this . 43 | 44 | You will notice that package.xml is autogenerated and source code of the package is retrieved in src folder. Create a folder src if your project does not have one. 45 | 46 | ![Retrieve Source From Unmanaged/Managed Package In DX Format](./images/retrievePkg.png) 47 | 48 | 3. **Save Apex Class,Apex Trigger,Visualforce Page and Visualforce Component To Salesforce Org** 49 | 50 | ![Save Apex](./images/apexsave.png) 51 | 52 | By default autosave is enabled .Hence when you save file the extension will try to save the file to salesforce you have logged in by default. 53 | 54 | If you disable auto save feature you can also Right click on the File and click "Save To Salesforce Menu" 55 | 56 | 4. **Save Lightning Components (Both aura and LWC) To Salesforce Org** 57 | 58 | If you disable auto save feature you can also Right click on the File and click **_"Save To Salesforce"_** 59 | 60 | ![Save AuraBundle Files](./images/aurasave.png) 61 | 62 | Save LWC (Available in Spring 19 pre-release orgs) 63 | 64 | ![Save LWC Bundle Files](./images/lwcsave.png) 65 | 66 | 5. **Manage Conflicts with server** 67 | 68 | This feature is turned off by default .It compares server copy with the local copy before save and if a difference is found you will see a prompt in a diff editor with options to either overwrite or accept change from server. Also you can manually resolve the conflicts and push changes . 69 | 70 | ![Manage conflict](./images/manageConflicts.png) 71 | 72 | If you wish to turn this feature (If you have VCS for your project and do not develop in team) for faster save you can do so by disabling Manageconflict settings found in settings for extension 73 | 74 | ![Manage conflict](./images/manageConflictSettings.png) 75 | 76 | 77 | 6. **Smart Navigations to VF page preview ,Lighnting App Builder Page ,Salesforce Lightning Design System Website ,Salesforce MetadataCoverage Report and Component Library URL** 78 | 79 | Screenshot shows how one can find these smart navigation 80 | 81 | ![Navigations](./images/navigation.png) 82 | 83 | ## Display Status of Save and Success 84 | 85 | 1. When Saving files to Salesforce Status of Success or Failure is always displayed on the Terminal . 86 | 2. Extension relies on Terminal API and hence to see any errors and progress keep the Terminal On. 87 | 88 | Below screenshot shows how the errors are logged 89 | 90 | ![See Errors on Terminal](./images/error_log.png) 91 | 92 | # Video Recordings of all features 93 | 94 | https://www.youtube.com/playlist?list=PLDFd1LjbN883y5IlMuU8BCyGhRO-VMuw9 95 | 96 | # Issue Reporting 97 | 98 | You can join the slack channel for any assistance [here](https://join.slack.com/t/salesforcedxc-ej87847/shared_invite/enQtNTQ4MjM2MTEzNjg2LTg2NzA4YTQ5ZTRkYzZjYTI4MDFhODQ2MDQ1ZjNmNzVmMTg5M2E0NTI2NzE0YWVmZjRjMGIwNmQ5YjkyMWEzZWU). 99 | 100 | If you find any issues feel free to log it on the github page for the project @ https://github.com/msrivastav13/DX-Code-Companion/issues 101 | 102 | You can also reach out to me via my twitter @msrivastav13 or via my MVP email handle mohith.shrivastava@salesforcemvps.com 103 | 104 | ## Extension Shortcut Keys 105 | 106 | To open command pallete and look for all CCDX Commands use below . 107 | 108 | "MACOSX": "cmd+shift+p", 109 | "win": "ctrl+shift+p", 110 | "linux": "ctrl+shift+p", 111 | 112 | # Release Notes 113 | 114 | ### 0.4.8 115 | 1.Update npm libraries to latest. Fixes Security Vulnerabilities 116 | 117 | ### 0.4.7 118 | 1.Update npm libraries to latest. Fixes Security Vulnerabilities 119 | 2.Update mo-dx-plugins using sfdx plugins:update to get latest CLI plugin extension that powers this extension 120 | 3.Diff view now respects current UI theme set by user 121 | 122 | ### 0.4.6 123 | 1.Update npm libraries to latest. Fixes Security Vulnerabilities 124 | 125 | ### 0.4.1 126 | 127 | 1.Update npm libraries to latest. Fixes Security Vulnerabilities 128 | 129 | ### 0.4.0 130 | 1.Fix issues listed [here](https://github.com/msrivastav13/DX-Code-Companion/labels/fixed%20in%200.4.0) 131 | 132 | 2.Install mo-dx-plugin now from the extension context menu directly if you do not have mo-dx-plugin. 133 | 134 | ![Install mo-dx-plugin for extension](./images/install_plugins.png) 135 | 136 | 3.Security patch 137 | 138 | ### 0.3.9 139 | 1.There is a setting provided(dx-code-companion.staticresourcefolder.resourceBundleFoldername) to indicate the resource bundle folder name for single page app development. Default value is "staticresource" but if you prefer to use names like "resourcebundle" or "spa" use the settings to change it 140 | 2.A static resource folder has a explorer menu to deploy the folder as static resource bundle 141 | 142 | ### 0.3.7 143 | 1.Now you can directly edit the static resource file and save to the server.Note that your folders or files should be within folder named "staticresources".If you are building a vf app using vue or React,you can keep your files in folder named staticresources and edit the app and save the file. 144 | 145 | ### 0.3.6 146 | 1.To manage settings you dont need to edit the settings.json and instead has UI 147 | 2.Security path via npm audit 148 | 149 | ### 0.3.3 150 | 151 | 1.Update the sfdx-core to use latest version. 152 | 2.Save to salesforce would automatically kick off when vscode opens a folder. Made sure it happens only when user manually tries to save the file 153 | 3.Remove support for v1.29.0 vscode. Requires v1.30.0 and above 154 | 155 | ### 0.3.0 156 | 157 | Fully support changeset driven development (https://trailhead.salesforce.com/en/content/learn/modules/declarative-change-set-development/develop-and-test-changes-locally) 158 | 159 | This version requires you to upgrade mo-dx-plugin to 0.2.0 version. 160 | 161 | Run `sfdx plugins:update` to update mo-dx-plugin to latest 162 | 163 | With this release,you can use DX Code Companion extension to retrieve source from the changeset created in your sandbox (Assumes you have authorized CLI to sandbox using "SFDX:Authorize and org").Use vscode to edit contents if needed and then deploy to target orgs all from VScode without need to upload the changesets and wait. 164 | 165 | 1) To retrieve source from the changeset use the command pallete and select "CCDX:Retrieve Source From Changeset" 166 | 167 | ![Retrieve source from changeset](./images/retrieve_changeset.png) 168 | 169 | 2) Provide the changeset name in the text box (Avoid creating changesets with same name in sandbox) 170 | 171 | ![changeset name](./images/changesetname.png) 172 | 173 | 3) Once code components are retrieved , Under changeset directory a sub directory will be created with src folder having all the components .You can edit the source code and also save to the authenticated orgs. 174 | 175 | ![changeset dir structure](./images/changesetdir.png) 176 | 177 | 4) Note that the changeset directory has orgs.json to which you can add list of orgs you have authorized salesforce CLI by clicking on the file and using "CCDX:Add Orgs For Changeset Deployment" 178 | 179 | ![Add orgs for depolyments](./images/addChangesets.png) 180 | 181 | ![Select the target org](./images/deployorgselector.png) 182 | 183 | 5.Click on "src" folder for your changeset to deploy them . The interface will ask you to pick orgs from list of orgs you have added in previous step 184 | 185 | ![Deploy changeset](./images/changesetDeploy.png) 186 | 187 | ### 0.2.8 188 | 189 | 1. Fixes connection method to use salesforce core library native methods 190 | 2. Adds ability to deploy the src folder for classic metadata directly from explorer menu 191 | 192 | ![Deploy source from src folder](./images/deploySrc.png) 193 | 194 | ### 0.2.7 195 | 196 | 1. Fixes Manage Conflicts with server is not working for Apex Components and Apex Pages 197 | 198 | ### 0.2.6 199 | 200 | 1. Fix issue by changing the folder name of content provider to use Capital letter. Seems very weird that not doing this breaks the plugin for chrome-os. The issue is described here (https://github.com/msrivastav13/DX-Code-Companion/issues/6) 201 | 202 | ### 0.2.5 203 | 204 | 1. Adds a new Command Compare With Server to view diff between current local and server file. 205 | 206 | 2. By default Manage Conflict is switched off .Turn it on via settings 207 | 208 | ![Manage conflict](./images/manageConflictSettings.png) 209 | 210 | 3. Fixed few bugs related to refresh from server on aura components. 211 | 212 | ### 0.2.4 213 | 214 | 1. Fixes when .xml files would try to save to server .This is not supported at this point and use native salesforce extension to deploy meta.xml files for version changes . 215 | 216 | ### 0.2.0 217 | 218 | 1. Adds ability to manage conflicts with server copy 219 | 220 | 2. Refresh From Server for LWC, Aura files , triggers , vf pages, vf components and classes 221 | 222 | 3. Save now compares file with server copy . 223 | 224 | 4. A new icon on the footer to indicate SalesforceDX Code Companion is active 225 | 226 | 5. Footer now indicates a rocket symbol if extension is active and you can navigate to org clicking on this . 227 | 228 | ### 0.1.10 229 | 230 | 1. Auto populate package list for selection for Retrieve Options 231 | 232 | 2. Retrieve DX Source and metadata options are only available from Command Palette (CMD+ SHIFT + P on MACOSX or CTRL + SHIFT + P on windows) 233 | 234 | 3. Previously the Save To Server tried running command on Non Salesforce files .This update fixes this and only saves if the working directory root has sfdx-project.json file. 235 | 236 | ### 0.1.8 237 | 238 | 1.Switch between authenticated orgs using new Switch Org Command .This opens up to switch and deploy the code between orgs using SFDX:Deploy To Org Command 239 | 240 | ![Navigations](./images/switchorg.png) 241 | 242 | 2.Fix AutoSave to now not run terminal command if file type is not supported 243 | 244 | 3.Better naming and Grouping .All Commands now CCDX as the prefix . 245 | 246 | 4.LWC(Lighnting Web Components) support improved 247 | 248 | 5.Introduces sfdx-core library in the build opening up lot more existing features to come in next release. 249 | 250 | ### 0.1.4 251 | 252 | 1.Auto Save enabled .You can disable using the autosave property 253 | 254 | ![Auto Save Feature](./images/autosavefeature.png) 255 | 256 | Use the settings (Select Code > Preferences > Settings) from the gear icon and modify the usersettings to disable the autosave feature as shown below by setting dx-code-companion.autosave.enabled as false . 257 | 258 | ![Auto Save Feature](./images/autosavedisable.png) 259 | 260 | 2.Save LWC Components(Under preview).Upgrade the mo-dx-plugin using sfdx:plugins:update mo-dx-plugin 261 | 262 | ### 0.1.3 263 | 264 | 1.Add support to retrieve metadata using package name in regular metadata format 265 | 266 | 2.Add some useful link in editor title for vf preview , app builder page ,metadata coverage report and component Library. 267 | 268 | ### 0.0.5 269 | 270 | 1. Fixes issues for keyboard shortcut 271 | 272 | ### 0.0.2 273 | 274 | 1. Provides quick save apex,vf,aura bundles to salesforce server 275 | 2. Retrieve Source from Salesforce using DX Source format. 276 | 3. 3X performant than salesforce deploy command for apex,aura and vf files. 277 | 278 | ----------------------------------------------------------------------------------------------------------- 279 | 280 | ### For more information and contribution to project visit the below repositories and use issues tab to log any feedback or issues . 281 | 282 | * [Mo DX Plugin Repository](https://github.com/msrivastav13/mo-dx-plugin) 283 | * [DX Code Companion](https://github.com/msrivastav13/DX-Code-Companion) 284 | 285 | **Enjoy!** 286 | -------------------------------------------------------------------------------- /images/addChangesets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/addChangesets.png -------------------------------------------------------------------------------- /images/apexsave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/apexsave.png -------------------------------------------------------------------------------- /images/aurasave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/aurasave.png -------------------------------------------------------------------------------- /images/autosavedisable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/autosavedisable.png -------------------------------------------------------------------------------- /images/autosavefeature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/autosavefeature.png -------------------------------------------------------------------------------- /images/changesetDeploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/changesetDeploy.png -------------------------------------------------------------------------------- /images/changesetdir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/changesetdir.png -------------------------------------------------------------------------------- /images/changesetname.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/changesetname.png -------------------------------------------------------------------------------- /images/deploySrc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/deploySrc.png -------------------------------------------------------------------------------- /images/deployorgselector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/deployorgselector.png -------------------------------------------------------------------------------- /images/error_log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/error_log.png -------------------------------------------------------------------------------- /images/install_plugins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/install_plugins.png -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/logo.png -------------------------------------------------------------------------------- /images/logo_revised.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/logo_revised.png -------------------------------------------------------------------------------- /images/lwcsave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/lwcsave.png -------------------------------------------------------------------------------- /images/manageConflictSettings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/manageConflictSettings.png -------------------------------------------------------------------------------- /images/manageConflicts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/manageConflicts.png -------------------------------------------------------------------------------- /images/navigation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/navigation.png -------------------------------------------------------------------------------- /images/retrieve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/retrieve.png -------------------------------------------------------------------------------- /images/retrievePkg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/retrievePkg.png -------------------------------------------------------------------------------- /images/retrieve_changeset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/retrieve_changeset.png -------------------------------------------------------------------------------- /images/switchorg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msrivastav13/DX-Code-Companion/f08e1f12fa079ef6864f13ede4c27887e24ab0ff/images/switchorg.png -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dx-code-companion", 3 | "version": "0.4.9", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.10.4", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", 10 | "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.10.4" 14 | } 15 | }, 16 | "@babel/helper-validator-identifier": { 17 | "version": "7.10.4", 18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", 19 | "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", 20 | "dev": true 21 | }, 22 | "@babel/highlight": { 23 | "version": "7.10.4", 24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", 25 | "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", 26 | "dev": true, 27 | "requires": { 28 | "@babel/helper-validator-identifier": "^7.10.4", 29 | "chalk": "^2.0.0", 30 | "js-tokens": "^4.0.0" 31 | } 32 | }, 33 | "@salesforce/bunyan": { 34 | "version": "2.0.0", 35 | "resolved": "https://registry.npmjs.org/@salesforce/bunyan/-/bunyan-2.0.0.tgz", 36 | "integrity": "sha512-5hq+HWQSeymuygl3i9ehlQo3XWrlBE+A+QzmpDaoK37op4u9M+SBUbXfOW0IABOQCg+JmfQPocSMV74hRoqU9w==", 37 | "requires": { 38 | "dayjs": "^1.8.16", 39 | "dayjs-plugin-utc": "^0.1.2", 40 | "dtrace-provider": "~0.6", 41 | "mv": "~2", 42 | "safe-json-stringify": "~1" 43 | } 44 | }, 45 | "@salesforce/core": { 46 | "version": "2.25.1", 47 | "resolved": "https://registry.npmjs.org/@salesforce/core/-/core-2.25.1.tgz", 48 | "integrity": "sha512-kRo1Uce8sFFXNBEu3odJ4zsFkvja+s/cmj7ICI6EvCsgwMHSLCw4P7zhqAsOJnBUim3M2qb4p0HpVtkQ4Cz3Kg==", 49 | "requires": { 50 | "@salesforce/bunyan": "^2.0.0", 51 | "@salesforce/kit": "^1.5.0", 52 | "@salesforce/schemas": "^1.0.1", 53 | "@salesforce/ts-types": "^1.5.13", 54 | "@types/graceful-fs": "^4.1.5", 55 | "@types/jsforce": "^1.9.29", 56 | "@types/mkdirp": "^1.0.1", 57 | "debug": "^3.1.0", 58 | "graceful-fs": "^4.2.4", 59 | "jsen": "0.6.6", 60 | "jsforce": "^1.10.1", 61 | "jsonwebtoken": "8.5.0", 62 | "mkdirp": "1.0.4", 63 | "sfdx-faye": "^1.0.9", 64 | "ts-retry-promise": "^0.6.0" 65 | } 66 | }, 67 | "@salesforce/kit": { 68 | "version": "1.5.14", 69 | "resolved": "https://registry.npmjs.org/@salesforce/kit/-/kit-1.5.14.tgz", 70 | "integrity": "sha512-vGzNltfWo7wtaDR0Drgf3nAMWsJ5ZheM4LODfFZeorsFk4Xj8J6hPJWuMcYUT07yCenECQalOjT0SU3p77QgYA==", 71 | "requires": { 72 | "@salesforce/ts-types": "^1.5.13", 73 | "tslib": "^2.2.0" 74 | }, 75 | "dependencies": { 76 | "tslib": { 77 | "version": "2.3.0", 78 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", 79 | "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" 80 | } 81 | } 82 | }, 83 | "@salesforce/schemas": { 84 | "version": "1.1.0", 85 | "resolved": "https://registry.npmjs.org/@salesforce/schemas/-/schemas-1.1.0.tgz", 86 | "integrity": "sha512-6D7DvE6nFxpLyyTnrOIbbAeCJw2r/EpinFAcMh6gU0gA/CGfSbwV/8uR3uHLYL2zCyCZLH8jJ4dZ3BzCMqc+Eg==" 87 | }, 88 | "@salesforce/ts-types": { 89 | "version": "1.5.17", 90 | "resolved": "https://registry.npmjs.org/@salesforce/ts-types/-/ts-types-1.5.17.tgz", 91 | "integrity": "sha512-zyF1+4EacGsIWtfntbq7PvxjB2XABz33RzKfOhot15JC4tFiQaSFPtNb8d6hj7BkQSjo2Zs3qEeLJwRFcpaEIQ==", 92 | "requires": { 93 | "tslib": "^2.2.0" 94 | }, 95 | "dependencies": { 96 | "tslib": { 97 | "version": "2.3.0", 98 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", 99 | "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" 100 | } 101 | } 102 | }, 103 | "@tootallnate/once": { 104 | "version": "1.1.2", 105 | "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", 106 | "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", 107 | "dev": true 108 | }, 109 | "@types/graceful-fs": { 110 | "version": "4.1.5", 111 | "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", 112 | "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", 113 | "requires": { 114 | "@types/node": "*" 115 | } 116 | }, 117 | "@types/jsforce": { 118 | "version": "1.9.30", 119 | "resolved": "https://registry.npmjs.org/@types/jsforce/-/jsforce-1.9.30.tgz", 120 | "integrity": "sha512-T0fgAfa99sx13gkClPkJsQRHzTcJ0Rgj7//6XEY9Qq6VRQH0U+cxlM1fqAsQ8rhAfAzyGhQk+j1nR1cWkp06NQ==", 121 | "requires": { 122 | "@types/node": "*" 123 | } 124 | }, 125 | "@types/mkdirp": { 126 | "version": "1.0.1", 127 | "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.1.tgz", 128 | "integrity": "sha512-HkGSK7CGAXncr8Qn/0VqNtExEE+PHMWb+qlR1faHMao7ng6P3tAaoWWBMdva0gL5h4zprjIO89GJOLXsMcDm1Q==", 129 | "requires": { 130 | "@types/node": "*" 131 | } 132 | }, 133 | "@types/mocha": { 134 | "version": "8.2.2", 135 | "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", 136 | "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", 137 | "dev": true 138 | }, 139 | "@types/node": { 140 | "version": "14.17.4", 141 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.4.tgz", 142 | "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==" 143 | }, 144 | "agent-base": { 145 | "version": "6.0.1", 146 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz", 147 | "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==", 148 | "dev": true, 149 | "requires": { 150 | "debug": "4" 151 | }, 152 | "dependencies": { 153 | "debug": { 154 | "version": "4.1.1", 155 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 156 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 157 | "dev": true, 158 | "requires": { 159 | "ms": "^2.1.1" 160 | } 161 | } 162 | } 163 | }, 164 | "ajv": { 165 | "version": "6.12.6", 166 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 167 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 168 | "requires": { 169 | "fast-deep-equal": "^3.1.1", 170 | "fast-json-stable-stringify": "^2.0.0", 171 | "json-schema-traverse": "^0.4.1", 172 | "uri-js": "^4.2.2" 173 | } 174 | }, 175 | "ansi-styles": { 176 | "version": "3.2.1", 177 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 178 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 179 | "dev": true, 180 | "requires": { 181 | "color-convert": "^1.9.0" 182 | } 183 | }, 184 | "argparse": { 185 | "version": "1.0.10", 186 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 187 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 188 | "dev": true, 189 | "requires": { 190 | "sprintf-js": "~1.0.2" 191 | } 192 | }, 193 | "asap": { 194 | "version": "2.0.6", 195 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", 196 | "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" 197 | }, 198 | "asn1": { 199 | "version": "0.2.4", 200 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 201 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 202 | "requires": { 203 | "safer-buffer": "~2.1.0" 204 | } 205 | }, 206 | "assert-plus": { 207 | "version": "1.0.0", 208 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 209 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 210 | }, 211 | "asynckit": { 212 | "version": "0.4.0", 213 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 214 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 215 | }, 216 | "aws-sign2": { 217 | "version": "0.7.0", 218 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 219 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 220 | }, 221 | "aws4": { 222 | "version": "1.11.0", 223 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", 224 | "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" 225 | }, 226 | "balanced-match": { 227 | "version": "1.0.0", 228 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 229 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 230 | }, 231 | "base64-url": { 232 | "version": "2.3.3", 233 | "resolved": "https://registry.npmjs.org/base64-url/-/base64-url-2.3.3.tgz", 234 | "integrity": "sha512-dLMhIsK7OplcDauDH/tZLvK7JmUZK3A7KiQpjNzsBrM6Etw7hzNI1tLEywqJk9NnwkgWuFKSlx/IUO7vF6Mo8Q==" 235 | }, 236 | "bcrypt-pbkdf": { 237 | "version": "1.0.2", 238 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 239 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 240 | "requires": { 241 | "tweetnacl": "^0.14.3" 242 | } 243 | }, 244 | "brace-expansion": { 245 | "version": "1.1.11", 246 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 247 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 248 | "requires": { 249 | "balanced-match": "^1.0.0", 250 | "concat-map": "0.0.1" 251 | } 252 | }, 253 | "browser-stdout": { 254 | "version": "1.3.1", 255 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 256 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 257 | "dev": true 258 | }, 259 | "buffer-equal-constant-time": { 260 | "version": "1.0.1", 261 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 262 | "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" 263 | }, 264 | "buffer-from": { 265 | "version": "1.1.1", 266 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 267 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 268 | "dev": true 269 | }, 270 | "builtin-modules": { 271 | "version": "1.1.1", 272 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 273 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", 274 | "dev": true 275 | }, 276 | "caseless": { 277 | "version": "0.12.0", 278 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 279 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 280 | }, 281 | "chalk": { 282 | "version": "2.4.2", 283 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 284 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 285 | "dev": true, 286 | "requires": { 287 | "ansi-styles": "^3.2.1", 288 | "escape-string-regexp": "^1.0.5", 289 | "supports-color": "^5.3.0" 290 | } 291 | }, 292 | "co-prompt": { 293 | "version": "1.0.0", 294 | "resolved": "https://registry.npmjs.org/co-prompt/-/co-prompt-1.0.0.tgz", 295 | "integrity": "sha1-+zcOntrEhXayenMv5dfyHZ/G5vY=", 296 | "requires": { 297 | "keypress": "~0.2.1" 298 | } 299 | }, 300 | "coffeescript": { 301 | "version": "1.12.7", 302 | "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.12.7.tgz", 303 | "integrity": "sha512-pLXHFxQMPklVoEekowk8b3erNynC+DVJzChxS/LCBBgR6/8AJkHivkm//zbowcfc7BTCAjryuhx6gPqPRfsFoA==" 304 | }, 305 | "color-convert": { 306 | "version": "1.9.3", 307 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 308 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 309 | "dev": true, 310 | "requires": { 311 | "color-name": "1.1.3" 312 | } 313 | }, 314 | "color-name": { 315 | "version": "1.1.3", 316 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 317 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 318 | "dev": true 319 | }, 320 | "combined-stream": { 321 | "version": "1.0.8", 322 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 323 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 324 | "requires": { 325 | "delayed-stream": "~1.0.0" 326 | } 327 | }, 328 | "commander": { 329 | "version": "2.20.3", 330 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 331 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" 332 | }, 333 | "concat-map": { 334 | "version": "0.0.1", 335 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 336 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 337 | }, 338 | "core-util-is": { 339 | "version": "1.0.2", 340 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 341 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 342 | }, 343 | "csprng": { 344 | "version": "0.1.2", 345 | "resolved": "https://registry.npmjs.org/csprng/-/csprng-0.1.2.tgz", 346 | "integrity": "sha1-S8aPEvo2jSUqWYQcusqXSxirReI=", 347 | "requires": { 348 | "sequin": "*" 349 | } 350 | }, 351 | "csv-parse": { 352 | "version": "4.16.0", 353 | "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.0.tgz", 354 | "integrity": "sha512-Zb4tGPANH4SW0LgC9+s9Mnequs9aqn7N3/pCqNbVjs2XhEF6yWNU2Vm4OGl1v2Go9nw8rXt87Cm2QN/o6Vpqgg==" 355 | }, 356 | "csv-stringify": { 357 | "version": "1.1.2", 358 | "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-1.1.2.tgz", 359 | "integrity": "sha1-d6QVJlgbzjOA8SsA18W7rHDIK1g=", 360 | "requires": { 361 | "lodash.get": "~4.4.2" 362 | } 363 | }, 364 | "dashdash": { 365 | "version": "1.14.1", 366 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 367 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 368 | "requires": { 369 | "assert-plus": "^1.0.0" 370 | } 371 | }, 372 | "dayjs": { 373 | "version": "1.10.5", 374 | "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.5.tgz", 375 | "integrity": "sha512-BUFis41ikLz+65iH6LHQCDm4YPMj5r1YFLdupPIyM4SGcXMmtiLQ7U37i+hGS8urIuqe7I/ou3IS1jVc4nbN4g==" 376 | }, 377 | "dayjs-plugin-utc": { 378 | "version": "0.1.2", 379 | "resolved": "https://registry.npmjs.org/dayjs-plugin-utc/-/dayjs-plugin-utc-0.1.2.tgz", 380 | "integrity": "sha512-ExERH5o3oo6jFOdkvMP3gytTCQ9Ksi5PtylclJWghr7k7m3o2U5QrwtdiJkOxLOH4ghr0EKhpqGefzGz1VvVJg==" 381 | }, 382 | "debug": { 383 | "version": "3.2.7", 384 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", 385 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", 386 | "requires": { 387 | "ms": "^2.1.1" 388 | } 389 | }, 390 | "delayed-stream": { 391 | "version": "1.0.0", 392 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 393 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 394 | }, 395 | "diff": { 396 | "version": "4.0.2", 397 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 398 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 399 | "dev": true 400 | }, 401 | "dtrace-provider": { 402 | "version": "0.6.0", 403 | "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", 404 | "integrity": "sha1-CweNVReTfYcxAUUtkUZzdVe3XlE=", 405 | "optional": true, 406 | "requires": { 407 | "nan": "^2.0.8" 408 | } 409 | }, 410 | "ecc-jsbn": { 411 | "version": "0.1.2", 412 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 413 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 414 | "requires": { 415 | "jsbn": "~0.1.0", 416 | "safer-buffer": "^2.1.0" 417 | } 418 | }, 419 | "ecdsa-sig-formatter": { 420 | "version": "1.0.11", 421 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 422 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 423 | "requires": { 424 | "safe-buffer": "^5.0.1" 425 | } 426 | }, 427 | "es6-promise": { 428 | "version": "4.2.8", 429 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", 430 | "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", 431 | "dev": true 432 | }, 433 | "es6-promisify": { 434 | "version": "5.0.0", 435 | "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", 436 | "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", 437 | "dev": true, 438 | "requires": { 439 | "es6-promise": "^4.0.3" 440 | } 441 | }, 442 | "escape-string-regexp": { 443 | "version": "1.0.5", 444 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 445 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 446 | "dev": true 447 | }, 448 | "esprima": { 449 | "version": "4.0.1", 450 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 451 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 452 | "dev": true 453 | }, 454 | "extend": { 455 | "version": "3.0.2", 456 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 457 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 458 | }, 459 | "extsprintf": { 460 | "version": "1.3.0", 461 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 462 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 463 | }, 464 | "fast-deep-equal": { 465 | "version": "3.1.3", 466 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 467 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" 468 | }, 469 | "fast-json-stable-stringify": { 470 | "version": "2.1.0", 471 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 472 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" 473 | }, 474 | "faye": { 475 | "version": "1.4.0", 476 | "resolved": "https://registry.npmjs.org/faye/-/faye-1.4.0.tgz", 477 | "integrity": "sha512-kRrIg4be8VNYhycS2PY//hpBJSzZPr/DBbcy9VWelhZMW3KhyLkQR0HL0k0MNpmVoNFF4EdfMFkNAWjTP65g6w==", 478 | "requires": { 479 | "asap": "*", 480 | "csprng": "*", 481 | "faye-websocket": ">=0.9.1", 482 | "safe-buffer": "*", 483 | "tough-cookie": "*", 484 | "tunnel-agent": "*" 485 | } 486 | }, 487 | "faye-websocket": { 488 | "version": "0.11.4", 489 | "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", 490 | "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", 491 | "requires": { 492 | "websocket-driver": ">=0.5.1" 493 | } 494 | }, 495 | "forever-agent": { 496 | "version": "0.6.1", 497 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 498 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 499 | }, 500 | "form-data": { 501 | "version": "2.3.3", 502 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 503 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 504 | "requires": { 505 | "asynckit": "^0.4.0", 506 | "combined-stream": "^1.0.6", 507 | "mime-types": "^2.1.12" 508 | } 509 | }, 510 | "fs.realpath": { 511 | "version": "1.0.0", 512 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 513 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 514 | "dev": true 515 | }, 516 | "getpass": { 517 | "version": "0.1.7", 518 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 519 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 520 | "requires": { 521 | "assert-plus": "^1.0.0" 522 | } 523 | }, 524 | "glob": { 525 | "version": "6.0.4", 526 | "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", 527 | "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", 528 | "optional": true, 529 | "requires": { 530 | "inflight": "^1.0.4", 531 | "inherits": "2", 532 | "minimatch": "2 || 3", 533 | "once": "^1.3.0", 534 | "path-is-absolute": "^1.0.0" 535 | } 536 | }, 537 | "graceful-fs": { 538 | "version": "4.2.6", 539 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", 540 | "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" 541 | }, 542 | "growl": { 543 | "version": "1.10.5", 544 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 545 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 546 | "dev": true 547 | }, 548 | "har-schema": { 549 | "version": "2.0.0", 550 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 551 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 552 | }, 553 | "har-validator": { 554 | "version": "5.1.5", 555 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", 556 | "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", 557 | "requires": { 558 | "ajv": "^6.12.3", 559 | "har-schema": "^2.0.0" 560 | } 561 | }, 562 | "has-flag": { 563 | "version": "3.0.0", 564 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 565 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 566 | "dev": true 567 | }, 568 | "he": { 569 | "version": "1.1.1", 570 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 571 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 572 | "dev": true 573 | }, 574 | "http-parser-js": { 575 | "version": "0.5.3", 576 | "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", 577 | "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==" 578 | }, 579 | "http-proxy-agent": { 580 | "version": "4.0.1", 581 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", 582 | "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", 583 | "dev": true, 584 | "requires": { 585 | "@tootallnate/once": "1", 586 | "agent-base": "6", 587 | "debug": "4" 588 | }, 589 | "dependencies": { 590 | "debug": { 591 | "version": "4.1.1", 592 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 593 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 594 | "dev": true, 595 | "requires": { 596 | "ms": "^2.1.1" 597 | } 598 | } 599 | } 600 | }, 601 | "http-signature": { 602 | "version": "1.2.0", 603 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 604 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 605 | "requires": { 606 | "assert-plus": "^1.0.0", 607 | "jsprim": "^1.2.2", 608 | "sshpk": "^1.7.0" 609 | } 610 | }, 611 | "https-proxy-agent": { 612 | "version": "5.0.0", 613 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", 614 | "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", 615 | "dev": true, 616 | "requires": { 617 | "agent-base": "6", 618 | "debug": "4" 619 | }, 620 | "dependencies": { 621 | "debug": { 622 | "version": "4.1.1", 623 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 624 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 625 | "dev": true, 626 | "requires": { 627 | "ms": "^2.1.1" 628 | } 629 | } 630 | } 631 | }, 632 | "inflight": { 633 | "version": "1.0.6", 634 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 635 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 636 | "requires": { 637 | "once": "^1.3.0", 638 | "wrappy": "1" 639 | } 640 | }, 641 | "inherits": { 642 | "version": "2.0.4", 643 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 644 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 645 | }, 646 | "is-typedarray": { 647 | "version": "1.0.0", 648 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 649 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 650 | }, 651 | "is-wsl": { 652 | "version": "1.1.0", 653 | "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", 654 | "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" 655 | }, 656 | "isarray": { 657 | "version": "1.0.0", 658 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 659 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 660 | }, 661 | "isstream": { 662 | "version": "0.1.2", 663 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 664 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 665 | }, 666 | "js-tokens": { 667 | "version": "4.0.0", 668 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 669 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 670 | "dev": true 671 | }, 672 | "js-yaml": { 673 | "version": "3.14.0", 674 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", 675 | "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", 676 | "dev": true, 677 | "requires": { 678 | "argparse": "^1.0.7", 679 | "esprima": "^4.0.0" 680 | } 681 | }, 682 | "jsbn": { 683 | "version": "0.1.1", 684 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 685 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 686 | }, 687 | "jsen": { 688 | "version": "0.6.6", 689 | "resolved": "https://registry.npmjs.org/jsen/-/jsen-0.6.6.tgz", 690 | "integrity": "sha1-AkDBjPETUKwCFFb0in6xO9Z+BCA=" 691 | }, 692 | "jsforce": { 693 | "version": "1.10.1", 694 | "resolved": "https://registry.npmjs.org/jsforce/-/jsforce-1.10.1.tgz", 695 | "integrity": "sha512-rv+UpBR9n/sWdgLhyPOJuKgT9ZKngypYf9XOHoXVRpSllvTFCjn+M3H81Nu1oYjPH9JKXVS8hL1dmmq8+kOAJg==", 696 | "requires": { 697 | "base64-url": "^2.2.0", 698 | "co-prompt": "^1.0.0", 699 | "coffeescript": "^1.10.0", 700 | "commander": "^2.9.0", 701 | "csv-parse": "^4.10.1", 702 | "csv-stringify": "^1.0.4", 703 | "faye": "^1.2.0", 704 | "inherits": "^2.0.1", 705 | "lodash": "^4.17.19", 706 | "multistream": "^2.0.5", 707 | "opn": "^5.3.0", 708 | "promise": "^7.1.1", 709 | "readable-stream": "^2.1.0", 710 | "request": "^2.72.0", 711 | "xml2js": "^0.4.16" 712 | } 713 | }, 714 | "json-schema": { 715 | "version": "0.2.3", 716 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 717 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 718 | }, 719 | "json-schema-traverse": { 720 | "version": "0.4.1", 721 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 722 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 723 | }, 724 | "json-stringify-safe": { 725 | "version": "5.0.1", 726 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 727 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 728 | }, 729 | "jsonwebtoken": { 730 | "version": "8.5.0", 731 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz", 732 | "integrity": "sha512-IqEycp0znWHNA11TpYi77bVgyBO/pGESDh7Ajhas+u0ttkGkKYIIAjniL4Bw5+oVejVF+SYkaI7XKfwCCyeTuA==", 733 | "requires": { 734 | "jws": "^3.2.1", 735 | "lodash.includes": "^4.3.0", 736 | "lodash.isboolean": "^3.0.3", 737 | "lodash.isinteger": "^4.0.4", 738 | "lodash.isnumber": "^3.0.3", 739 | "lodash.isplainobject": "^4.0.6", 740 | "lodash.isstring": "^4.0.1", 741 | "lodash.once": "^4.0.0", 742 | "ms": "^2.1.1", 743 | "semver": "^5.6.0" 744 | } 745 | }, 746 | "jsprim": { 747 | "version": "1.4.1", 748 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 749 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 750 | "requires": { 751 | "assert-plus": "1.0.0", 752 | "extsprintf": "1.3.0", 753 | "json-schema": "0.2.3", 754 | "verror": "1.10.0" 755 | } 756 | }, 757 | "jwa": { 758 | "version": "1.4.1", 759 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 760 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 761 | "requires": { 762 | "buffer-equal-constant-time": "1.0.1", 763 | "ecdsa-sig-formatter": "1.0.11", 764 | "safe-buffer": "^5.0.1" 765 | } 766 | }, 767 | "jws": { 768 | "version": "3.2.2", 769 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 770 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 771 | "requires": { 772 | "jwa": "^1.4.1", 773 | "safe-buffer": "^5.0.1" 774 | } 775 | }, 776 | "keypress": { 777 | "version": "0.2.1", 778 | "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz", 779 | "integrity": "sha1-HoBFQlABjbrUw/6USX1uZ7YmnHc=" 780 | }, 781 | "lodash": { 782 | "version": "4.17.21", 783 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 784 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 785 | }, 786 | "lodash.get": { 787 | "version": "4.4.2", 788 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 789 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" 790 | }, 791 | "lodash.includes": { 792 | "version": "4.3.0", 793 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 794 | "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" 795 | }, 796 | "lodash.isboolean": { 797 | "version": "3.0.3", 798 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 799 | "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" 800 | }, 801 | "lodash.isinteger": { 802 | "version": "4.0.4", 803 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 804 | "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" 805 | }, 806 | "lodash.isnumber": { 807 | "version": "3.0.3", 808 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 809 | "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" 810 | }, 811 | "lodash.isplainobject": { 812 | "version": "4.0.6", 813 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 814 | "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" 815 | }, 816 | "lodash.isstring": { 817 | "version": "4.0.1", 818 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 819 | "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" 820 | }, 821 | "lodash.once": { 822 | "version": "4.1.1", 823 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 824 | "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" 825 | }, 826 | "mime-db": { 827 | "version": "1.48.0", 828 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", 829 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" 830 | }, 831 | "mime-types": { 832 | "version": "2.1.31", 833 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", 834 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", 835 | "requires": { 836 | "mime-db": "1.48.0" 837 | } 838 | }, 839 | "minimatch": { 840 | "version": "3.0.4", 841 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 842 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 843 | "requires": { 844 | "brace-expansion": "^1.1.7" 845 | } 846 | }, 847 | "minimist": { 848 | "version": "1.2.5", 849 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 850 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" 851 | }, 852 | "mkdirp": { 853 | "version": "1.0.4", 854 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", 855 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" 856 | }, 857 | "mocha": { 858 | "version": "5.2.0", 859 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", 860 | "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", 861 | "dev": true, 862 | "requires": { 863 | "browser-stdout": "1.3.1", 864 | "commander": "2.15.1", 865 | "debug": "3.1.0", 866 | "diff": "3.5.0", 867 | "escape-string-regexp": "1.0.5", 868 | "glob": "7.1.2", 869 | "growl": "1.10.5", 870 | "he": "1.1.1", 871 | "minimatch": "3.0.4", 872 | "mkdirp": "0.5.1", 873 | "supports-color": "5.4.0" 874 | }, 875 | "dependencies": { 876 | "commander": { 877 | "version": "2.15.1", 878 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", 879 | "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", 880 | "dev": true 881 | }, 882 | "debug": { 883 | "version": "3.1.0", 884 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 885 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 886 | "dev": true, 887 | "requires": { 888 | "ms": "2.0.0" 889 | } 890 | }, 891 | "diff": { 892 | "version": "3.5.0", 893 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 894 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 895 | "dev": true 896 | }, 897 | "glob": { 898 | "version": "7.1.2", 899 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 900 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 901 | "dev": true, 902 | "requires": { 903 | "fs.realpath": "^1.0.0", 904 | "inflight": "^1.0.4", 905 | "inherits": "2", 906 | "minimatch": "^3.0.4", 907 | "once": "^1.3.0", 908 | "path-is-absolute": "^1.0.0" 909 | } 910 | }, 911 | "minimist": { 912 | "version": "0.0.8", 913 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 914 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 915 | "dev": true 916 | }, 917 | "mkdirp": { 918 | "version": "0.5.1", 919 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 920 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 921 | "dev": true, 922 | "requires": { 923 | "minimist": "0.0.8" 924 | } 925 | }, 926 | "ms": { 927 | "version": "2.0.0", 928 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 929 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 930 | "dev": true 931 | }, 932 | "supports-color": { 933 | "version": "5.4.0", 934 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", 935 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", 936 | "dev": true, 937 | "requires": { 938 | "has-flag": "^3.0.0" 939 | } 940 | } 941 | } 942 | }, 943 | "ms": { 944 | "version": "2.1.2", 945 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 946 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 947 | }, 948 | "multistream": { 949 | "version": "2.1.1", 950 | "resolved": "https://registry.npmjs.org/multistream/-/multistream-2.1.1.tgz", 951 | "integrity": "sha512-xasv76hl6nr1dEy3lPvy7Ej7K/Lx3O/FCvwge8PeVJpciPPoNCbaANcNiBug3IpdvTveZUcAV0DJzdnUDMesNQ==", 952 | "requires": { 953 | "inherits": "^2.0.1", 954 | "readable-stream": "^2.0.5" 955 | } 956 | }, 957 | "mv": { 958 | "version": "2.1.1", 959 | "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", 960 | "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", 961 | "optional": true, 962 | "requires": { 963 | "mkdirp": "~0.5.1", 964 | "ncp": "~2.0.0", 965 | "rimraf": "~2.4.0" 966 | }, 967 | "dependencies": { 968 | "mkdirp": { 969 | "version": "0.5.5", 970 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 971 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 972 | "optional": true, 973 | "requires": { 974 | "minimist": "^1.2.5" 975 | } 976 | } 977 | } 978 | }, 979 | "nan": { 980 | "version": "2.14.2", 981 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", 982 | "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", 983 | "optional": true 984 | }, 985 | "ncp": { 986 | "version": "2.0.0", 987 | "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", 988 | "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", 989 | "optional": true 990 | }, 991 | "oauth-sign": { 992 | "version": "0.9.0", 993 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 994 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 995 | }, 996 | "once": { 997 | "version": "1.4.0", 998 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 999 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1000 | "requires": { 1001 | "wrappy": "1" 1002 | } 1003 | }, 1004 | "opn": { 1005 | "version": "5.5.0", 1006 | "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", 1007 | "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", 1008 | "requires": { 1009 | "is-wsl": "^1.1.0" 1010 | } 1011 | }, 1012 | "path-is-absolute": { 1013 | "version": "1.0.1", 1014 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1015 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 1016 | }, 1017 | "path-parse": { 1018 | "version": "1.0.6", 1019 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 1020 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 1021 | "dev": true 1022 | }, 1023 | "performance-now": { 1024 | "version": "2.1.0", 1025 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 1026 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 1027 | }, 1028 | "process-nextick-args": { 1029 | "version": "2.0.1", 1030 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 1031 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 1032 | }, 1033 | "promise": { 1034 | "version": "7.3.1", 1035 | "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", 1036 | "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", 1037 | "requires": { 1038 | "asap": "~2.0.3" 1039 | } 1040 | }, 1041 | "psl": { 1042 | "version": "1.8.0", 1043 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 1044 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" 1045 | }, 1046 | "punycode": { 1047 | "version": "2.1.1", 1048 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1049 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 1050 | }, 1051 | "qs": { 1052 | "version": "6.5.2", 1053 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 1054 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 1055 | }, 1056 | "readable-stream": { 1057 | "version": "2.3.7", 1058 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 1059 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 1060 | "requires": { 1061 | "core-util-is": "~1.0.0", 1062 | "inherits": "~2.0.3", 1063 | "isarray": "~1.0.0", 1064 | "process-nextick-args": "~2.0.0", 1065 | "safe-buffer": "~5.1.1", 1066 | "string_decoder": "~1.1.1", 1067 | "util-deprecate": "~1.0.1" 1068 | }, 1069 | "dependencies": { 1070 | "safe-buffer": { 1071 | "version": "5.1.2", 1072 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1073 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1074 | } 1075 | } 1076 | }, 1077 | "request": { 1078 | "version": "2.88.2", 1079 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", 1080 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", 1081 | "requires": { 1082 | "aws-sign2": "~0.7.0", 1083 | "aws4": "^1.8.0", 1084 | "caseless": "~0.12.0", 1085 | "combined-stream": "~1.0.6", 1086 | "extend": "~3.0.2", 1087 | "forever-agent": "~0.6.1", 1088 | "form-data": "~2.3.2", 1089 | "har-validator": "~5.1.3", 1090 | "http-signature": "~1.2.0", 1091 | "is-typedarray": "~1.0.0", 1092 | "isstream": "~0.1.2", 1093 | "json-stringify-safe": "~5.0.1", 1094 | "mime-types": "~2.1.19", 1095 | "oauth-sign": "~0.9.0", 1096 | "performance-now": "^2.1.0", 1097 | "qs": "~6.5.2", 1098 | "safe-buffer": "^5.1.2", 1099 | "tough-cookie": "~2.5.0", 1100 | "tunnel-agent": "^0.6.0", 1101 | "uuid": "^3.3.2" 1102 | }, 1103 | "dependencies": { 1104 | "tough-cookie": { 1105 | "version": "2.5.0", 1106 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", 1107 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", 1108 | "requires": { 1109 | "psl": "^1.1.28", 1110 | "punycode": "^2.1.1" 1111 | } 1112 | } 1113 | } 1114 | }, 1115 | "resolve": { 1116 | "version": "1.17.0", 1117 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", 1118 | "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", 1119 | "dev": true, 1120 | "requires": { 1121 | "path-parse": "^1.0.6" 1122 | } 1123 | }, 1124 | "rimraf": { 1125 | "version": "2.4.5", 1126 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", 1127 | "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", 1128 | "optional": true, 1129 | "requires": { 1130 | "glob": "^6.0.1" 1131 | } 1132 | }, 1133 | "safe-buffer": { 1134 | "version": "5.2.1", 1135 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1136 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 1137 | }, 1138 | "safe-json-stringify": { 1139 | "version": "1.2.0", 1140 | "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", 1141 | "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", 1142 | "optional": true 1143 | }, 1144 | "safer-buffer": { 1145 | "version": "2.1.2", 1146 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1147 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1148 | }, 1149 | "sax": { 1150 | "version": "1.2.4", 1151 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 1152 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" 1153 | }, 1154 | "semver": { 1155 | "version": "5.7.1", 1156 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1157 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 1158 | }, 1159 | "sequin": { 1160 | "version": "0.1.1", 1161 | "resolved": "https://registry.npmjs.org/sequin/-/sequin-0.1.1.tgz", 1162 | "integrity": "sha1-XC04nWajg3NOqvvEXt6ywcsb5wE=" 1163 | }, 1164 | "sfdx-faye": { 1165 | "version": "1.0.9", 1166 | "resolved": "https://registry.npmjs.org/sfdx-faye/-/sfdx-faye-1.0.9.tgz", 1167 | "integrity": "sha512-/p0Ifvhh9rVYj6YmYOBU+psQsP+9RrNrUU4lr1p+HhZhTgnviMIabcgKZUN12S69zUpl0YagpFdMhmxKGkf+5g==", 1168 | "requires": { 1169 | "asap": "~2.0.6", 1170 | "csprng": "~0.1.2", 1171 | "faye-websocket": "~0.9.1", 1172 | "tough-cookie": "~2.4.3", 1173 | "tunnel-agent": "~0.6.0" 1174 | }, 1175 | "dependencies": { 1176 | "faye-websocket": { 1177 | "version": "0.9.4", 1178 | "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.9.4.tgz", 1179 | "integrity": "sha1-iFk0x57/sECVSeDAo4Ae0XpAza0=", 1180 | "requires": { 1181 | "websocket-driver": ">=0.5.1" 1182 | } 1183 | }, 1184 | "punycode": { 1185 | "version": "1.4.1", 1186 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 1187 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 1188 | }, 1189 | "tough-cookie": { 1190 | "version": "2.4.3", 1191 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 1192 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 1193 | "requires": { 1194 | "psl": "^1.1.24", 1195 | "punycode": "^1.4.1" 1196 | } 1197 | } 1198 | } 1199 | }, 1200 | "source-map": { 1201 | "version": "0.6.1", 1202 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1203 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1204 | "dev": true 1205 | }, 1206 | "source-map-support": { 1207 | "version": "0.5.19", 1208 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 1209 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 1210 | "dev": true, 1211 | "requires": { 1212 | "buffer-from": "^1.0.0", 1213 | "source-map": "^0.6.0" 1214 | } 1215 | }, 1216 | "sprintf-js": { 1217 | "version": "1.0.3", 1218 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1219 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 1220 | "dev": true 1221 | }, 1222 | "sshpk": { 1223 | "version": "1.16.1", 1224 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 1225 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 1226 | "requires": { 1227 | "asn1": "~0.2.3", 1228 | "assert-plus": "^1.0.0", 1229 | "bcrypt-pbkdf": "^1.0.0", 1230 | "dashdash": "^1.12.0", 1231 | "ecc-jsbn": "~0.1.1", 1232 | "getpass": "^0.1.1", 1233 | "jsbn": "~0.1.0", 1234 | "safer-buffer": "^2.0.2", 1235 | "tweetnacl": "~0.14.0" 1236 | } 1237 | }, 1238 | "string_decoder": { 1239 | "version": "1.1.1", 1240 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 1241 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1242 | "requires": { 1243 | "safe-buffer": "~5.1.0" 1244 | }, 1245 | "dependencies": { 1246 | "safe-buffer": { 1247 | "version": "5.1.2", 1248 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1249 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1250 | } 1251 | } 1252 | }, 1253 | "supports-color": { 1254 | "version": "5.5.0", 1255 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1256 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1257 | "dev": true, 1258 | "requires": { 1259 | "has-flag": "^3.0.0" 1260 | } 1261 | }, 1262 | "tough-cookie": { 1263 | "version": "4.0.0", 1264 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", 1265 | "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", 1266 | "requires": { 1267 | "psl": "^1.1.33", 1268 | "punycode": "^2.1.1", 1269 | "universalify": "^0.1.2" 1270 | } 1271 | }, 1272 | "ts-retry-promise": { 1273 | "version": "0.6.0", 1274 | "resolved": "https://registry.npmjs.org/ts-retry-promise/-/ts-retry-promise-0.6.0.tgz", 1275 | "integrity": "sha512-8DF80uA7JPu6m8ouHxGkyBpPTIGQnsgIUgLDqcRaD7EEhVowjG72KqCX334gsa1P+AmzeTVdd/xEzVFCAuPCtg==" 1276 | }, 1277 | "tslib": { 1278 | "version": "1.13.0", 1279 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", 1280 | "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", 1281 | "dev": true 1282 | }, 1283 | "tslint": { 1284 | "version": "6.1.3", 1285 | "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", 1286 | "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", 1287 | "dev": true, 1288 | "requires": { 1289 | "@babel/code-frame": "^7.0.0", 1290 | "builtin-modules": "^1.1.1", 1291 | "chalk": "^2.3.0", 1292 | "commander": "^2.12.1", 1293 | "diff": "^4.0.1", 1294 | "glob": "^7.1.1", 1295 | "js-yaml": "^3.13.1", 1296 | "minimatch": "^3.0.4", 1297 | "mkdirp": "^0.5.3", 1298 | "resolve": "^1.3.2", 1299 | "semver": "^5.3.0", 1300 | "tslib": "^1.13.0", 1301 | "tsutils": "^2.29.0" 1302 | }, 1303 | "dependencies": { 1304 | "glob": { 1305 | "version": "7.1.6", 1306 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 1307 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 1308 | "dev": true, 1309 | "requires": { 1310 | "fs.realpath": "^1.0.0", 1311 | "inflight": "^1.0.4", 1312 | "inherits": "2", 1313 | "minimatch": "^3.0.4", 1314 | "once": "^1.3.0", 1315 | "path-is-absolute": "^1.0.0" 1316 | } 1317 | }, 1318 | "mkdirp": { 1319 | "version": "0.5.5", 1320 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 1321 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 1322 | "dev": true, 1323 | "requires": { 1324 | "minimist": "^1.2.5" 1325 | } 1326 | } 1327 | } 1328 | }, 1329 | "tsutils": { 1330 | "version": "2.29.0", 1331 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", 1332 | "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", 1333 | "dev": true, 1334 | "requires": { 1335 | "tslib": "^1.8.1" 1336 | } 1337 | }, 1338 | "tunnel-agent": { 1339 | "version": "0.6.0", 1340 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 1341 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 1342 | "requires": { 1343 | "safe-buffer": "^5.0.1" 1344 | } 1345 | }, 1346 | "tweetnacl": { 1347 | "version": "0.14.5", 1348 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 1349 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 1350 | }, 1351 | "typescript": { 1352 | "version": "4.3.5", 1353 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", 1354 | "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", 1355 | "dev": true 1356 | }, 1357 | "universalify": { 1358 | "version": "0.1.2", 1359 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 1360 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 1361 | }, 1362 | "uri-js": { 1363 | "version": "4.4.1", 1364 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1365 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1366 | "requires": { 1367 | "punycode": "^2.1.0" 1368 | } 1369 | }, 1370 | "util-deprecate": { 1371 | "version": "1.0.2", 1372 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1373 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 1374 | }, 1375 | "uuid": { 1376 | "version": "3.4.0", 1377 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", 1378 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" 1379 | }, 1380 | "verror": { 1381 | "version": "1.10.0", 1382 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 1383 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 1384 | "requires": { 1385 | "assert-plus": "^1.0.0", 1386 | "core-util-is": "1.0.2", 1387 | "extsprintf": "^1.2.0" 1388 | } 1389 | }, 1390 | "vscode": { 1391 | "version": "1.1.37", 1392 | "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.37.tgz", 1393 | "integrity": "sha512-vJNj6IlN7IJPdMavlQa1KoFB3Ihn06q1AiN3ZFI/HfzPNzbKZWPPuiU+XkpNOfGU5k15m4r80nxNPlM7wcc0wg==", 1394 | "dev": true, 1395 | "requires": { 1396 | "glob": "^7.1.2", 1397 | "http-proxy-agent": "^4.0.1", 1398 | "https-proxy-agent": "^5.0.0", 1399 | "mocha": "^5.2.0", 1400 | "semver": "^5.4.1", 1401 | "source-map-support": "^0.5.0", 1402 | "vscode-test": "^0.4.1" 1403 | }, 1404 | "dependencies": { 1405 | "glob": { 1406 | "version": "7.1.6", 1407 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 1408 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 1409 | "dev": true, 1410 | "requires": { 1411 | "fs.realpath": "^1.0.0", 1412 | "inflight": "^1.0.4", 1413 | "inherits": "2", 1414 | "minimatch": "^3.0.4", 1415 | "once": "^1.3.0", 1416 | "path-is-absolute": "^1.0.0" 1417 | } 1418 | } 1419 | } 1420 | }, 1421 | "vscode-test": { 1422 | "version": "0.4.3", 1423 | "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.4.3.tgz", 1424 | "integrity": "sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w==", 1425 | "dev": true, 1426 | "requires": { 1427 | "http-proxy-agent": "^2.1.0", 1428 | "https-proxy-agent": "^2.2.1" 1429 | }, 1430 | "dependencies": { 1431 | "agent-base": { 1432 | "version": "4.3.0", 1433 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", 1434 | "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", 1435 | "dev": true, 1436 | "requires": { 1437 | "es6-promisify": "^5.0.0" 1438 | } 1439 | }, 1440 | "debug": { 1441 | "version": "3.1.0", 1442 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1443 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1444 | "dev": true, 1445 | "requires": { 1446 | "ms": "2.0.0" 1447 | } 1448 | }, 1449 | "http-proxy-agent": { 1450 | "version": "2.1.0", 1451 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", 1452 | "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", 1453 | "dev": true, 1454 | "requires": { 1455 | "agent-base": "4", 1456 | "debug": "3.1.0" 1457 | } 1458 | }, 1459 | "https-proxy-agent": { 1460 | "version": "2.2.4", 1461 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", 1462 | "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", 1463 | "dev": true, 1464 | "requires": { 1465 | "agent-base": "^4.3.0", 1466 | "debug": "^3.1.0" 1467 | } 1468 | }, 1469 | "ms": { 1470 | "version": "2.0.0", 1471 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1472 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 1473 | "dev": true 1474 | } 1475 | } 1476 | }, 1477 | "websocket-driver": { 1478 | "version": "0.7.4", 1479 | "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", 1480 | "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", 1481 | "requires": { 1482 | "http-parser-js": ">=0.5.1", 1483 | "safe-buffer": ">=5.1.0", 1484 | "websocket-extensions": ">=0.1.1" 1485 | } 1486 | }, 1487 | "websocket-extensions": { 1488 | "version": "0.1.4", 1489 | "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", 1490 | "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" 1491 | }, 1492 | "wrappy": { 1493 | "version": "1.0.2", 1494 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1495 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1496 | }, 1497 | "xml2js": { 1498 | "version": "0.4.23", 1499 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", 1500 | "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", 1501 | "requires": { 1502 | "sax": ">=0.6.0", 1503 | "xmlbuilder": "~11.0.0" 1504 | } 1505 | }, 1506 | "xmlbuilder": { 1507 | "version": "11.0.1", 1508 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 1509 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" 1510 | } 1511 | } 1512 | } 1513 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dx-code-companion", 3 | "displayName": "SalesforceDX Code Companion", 4 | "description": "An extension that works alongside the Salesforce Extensions for Vscode with faster apex,vf and aura components save performance", 5 | "version": "0.4.9", 6 | "publisher": "MohithShrivastava", 7 | "engines": { 8 | "vscode": "^1.30.0" 9 | }, 10 | "icon": "images/logo.png", 11 | "keywords": [ 12 | "sfdx", 13 | "salesforcedx", 14 | "salesforce", 15 | "Salesforce", 16 | "ligtning web components", 17 | "Apex", 18 | "Visualforce", 19 | "Aura Components" 20 | ], 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/msrivastav13/DX-Code-Companion.git" 24 | }, 25 | "categories": [ 26 | "Other" 27 | ], 28 | "activationEvents": [ 29 | "workspaceContains:sfdx-project.json" 30 | ], 31 | "main": "./out/extension", 32 | "contributes": { 33 | "commands": [ 34 | { 35 | "command": "retrieve.dxSource", 36 | "title": "CCDX: Retrieve DX Source From Package" 37 | }, 38 | { 39 | "command": "refresh.source", 40 | "title": "CCDX: Refresh From Server" 41 | }, 42 | { 43 | "command": "retrieve.pkgSource", 44 | "title": "CCDX: Retrieve Source From Package" 45 | }, 46 | { 47 | "command": "deploy.source", 48 | "title": "CCDX: Save To Salesforce" 49 | }, 50 | { 51 | "command": "compare.source", 52 | "title": "CCDX: Compare With Server" 53 | }, 54 | { 55 | "command": "open.lightningPage", 56 | "title": "CCDX: Open Lightning Builder page" 57 | }, 58 | { 59 | "command": "open.metadataCoverageReport", 60 | "title": "CCDX: Open MetadataCoverage Report" 61 | }, 62 | { 63 | "command": "open.componentLibrary", 64 | "title": "CCDX: Open Component Library" 65 | }, 66 | { 67 | "command": "open.vf", 68 | "title": "CCDX: Open Visualforce Page" 69 | }, 70 | { 71 | "command": "open.slds", 72 | "title": "CCDX: Open SLDS Website" 73 | }, 74 | { 75 | "command": "switch.org", 76 | "title": "CCDX: Switch Org" 77 | }, 78 | { 79 | "command": "open.org", 80 | "title": "CCDX: Open Default Org" 81 | }, 82 | { 83 | "command": "deploy.src", 84 | "title": "CCDX: Deploy Source To Salesforce" 85 | }, 86 | { 87 | "command": "changeset.retrieve", 88 | "title": "CCDX: Retrieve Source From Changeset" 89 | }, 90 | { 91 | "command": "changeset.addorgs", 92 | "title": "CCDX: Add Orgs For Changeset Deployment" 93 | }, 94 | { 95 | "command": "deploy.staticresource", 96 | "title": "CCDX: Deploy Static Resource" 97 | }, 98 | { 99 | "command": "extension.installplugin", 100 | "title": "Install Dependent Plugin" 101 | } 102 | ], 103 | "menus": { 104 | "editor/context": [ 105 | { 106 | "command": "deploy.source", 107 | "group": "DXCompanion", 108 | "when": "CCDXActive" 109 | }, 110 | { 111 | "command": "refresh.source", 112 | "group": "DXCompanion", 113 | "when": "CCDXActive" 114 | }, 115 | { 116 | "command": "compare.source", 117 | "group": "DXCompanion", 118 | "when": "CCDXActive" 119 | } 120 | ], 121 | "editor/title": [ 122 | { 123 | "command": "open.componentLibrary", 124 | "group": "OpenCmd", 125 | "when": "CCDXActive" 126 | }, 127 | { 128 | "command": "open.metadataCoverageReport", 129 | "group": "OpenCmd", 130 | "when": "CCDXActive" 131 | }, 132 | { 133 | "command": "open.slds", 134 | "group": "OpenCmd", 135 | "when": "CCDXActive" 136 | }, 137 | { 138 | "command": "open.lightningPage", 139 | "group": "OpenCmd", 140 | "when": "CCDXActive && resourceExtname =~ /(.flexipage|.xml)/" 141 | }, 142 | { 143 | "command": "open.vf", 144 | "group": "OpenCmd", 145 | "when": "CCDXActive && resourceExtname == .page" 146 | }, 147 | { 148 | "command": "open.org", 149 | "group": "OpenCmd", 150 | "when": "CCDXActive" 151 | } 152 | ], 153 | "explorer/context": [ 154 | { 155 | "command": "deploy.staticresource", 156 | "group": "DXCompanion", 157 | "when": "explorerResourceIsFolder && CCDXActive" 158 | }, 159 | { 160 | "command": "deploy.src", 161 | "group": "DXCompanion", 162 | "when": "explorerResourceIsFolder && resourceFilename == src && CCDXActive" 163 | }, 164 | { 165 | "command": "changeset.retrieve", 166 | "title": "CCDX: Retrieve Source From Changeset", 167 | "group": "DXCompanion", 168 | "when": "explorerResourceIsFolder && resourceFilename == changesets && CCDXActive" 169 | }, 170 | { 171 | "command": "changeset.addorgs", 172 | "title": "CCDX: Add Orgs For Changeset Deployment", 173 | "group": "DXCompanion", 174 | "when": "resourceFilename == orgs.json && CCDXActive" 175 | } 176 | ], 177 | "extension/context": [ 178 | { 179 | "command": "extension.installplugin", 180 | "group": "2_configure", 181 | "when": "extensionStatus==installed" 182 | } 183 | ] 184 | }, 185 | "keybindings": [ 186 | { 187 | "command": "deploy.source", 188 | "key": "cmd+shift+c", 189 | "win": "ctrl+shift+c", 190 | "linux": "ctrl+shift+c", 191 | "when": "editorFocus" 192 | } 193 | ], 194 | "configuration": { 195 | "type": "object", 196 | "title": "SalesforceDX Companion Features", 197 | "properties": { 198 | "dx-code-companion.autosave.enabled": { 199 | "type": "boolean", 200 | "default": true, 201 | "description": "Saves to salesforce automatically" 202 | }, 203 | "dx-code-companion.manageconflict.enabled": { 204 | "type": "boolean", 205 | "default": false, 206 | "description": "Compare code in local file with file in salesforce" 207 | }, 208 | "dx-code-companion.staticresourcefolder.resourceBundleFoldername": { 209 | "type": "string", 210 | "default": "staticresources", 211 | "description": "Folder name where you have your Single page application" 212 | } 213 | } 214 | } 215 | }, 216 | "scripts": { 217 | "vscode:prepublish": "npm run compile", 218 | "compile": "tsc -p ./", 219 | "watch": "tsc -watch -p ./", 220 | "postinstall": "node ./node_modules/vscode/bin/install", 221 | "test": "npm run compile && node ./node_modules/vscode/bin/test" 222 | }, 223 | "devDependencies": { 224 | "@types/mocha": "^8.2.2", 225 | "@types/node": "^14.17.4", 226 | "tslint": "^6.1.3", 227 | "typescript": "^4.3.5", 228 | "vscode": "^1.1.36" 229 | }, 230 | "dependencies": { 231 | "@salesforce/core": "^2.25.1" 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | // The module 'vscode' contains the VS Code extensibility API 3 | // Import the module and reference it with the alias vscode in your code below 4 | import * as vscode from 'vscode'; 5 | import {Config} from './services/config'; 6 | import CodeCompanionContentProvider from './providers/ccprovider' ; 7 | import {Changeset} from './services/changeset'; 8 | import {DeploySource} from './services/deploy'; 9 | import {NavigationService} from './services/navigation'; 10 | import {OSUtil} from './services/osUtils'; 11 | import {RetrieveSource} from './services/retrieve'; 12 | import {switchOrg} from './services/switchOrg'; 13 | import {VSCodeCore} from './services/vscodeCore'; 14 | // this method is called when your extension is activated 15 | // your extension is activated the very first time the command is executed 16 | export function activate(context: vscode.ExtensionContext) { 17 | 18 | // show activation message 19 | VSCodeCore.showActivationMessage(); 20 | 21 | const retrieveSource = vscode.commands.registerCommand('retrieve.dxSource', async () => { 22 | const connection = await Config.getConnection(); 23 | const retrievesrc = new RetrieveSource(connection); 24 | retrievesrc.retrieve('sfdx retrieve:dxsource -n '); 25 | }); 26 | 27 | const retrievepkgSource = vscode.commands.registerCommand('retrieve.pkgSource', async () => { 28 | const connection = await Config.getConnection(); 29 | const retrievesrc = new RetrieveSource(connection); 30 | retrievesrc.retrieve('sfdx retrieve:pkgsource -n '); 31 | }); 32 | 33 | const deploysrc = vscode.commands.registerCommand('deploy.src', async (fileUri: { path: string; }) => { 34 | await DeploySource.deploySrc(fileUri.path); 35 | }); 36 | 37 | const changesetRetrieve = vscode.commands.registerCommand('changeset.retrieve', async () => { 38 | let changeset = new Changeset(); 39 | await changeset.retrieve(); 40 | }); 41 | 42 | const changesetOrgAdd = vscode.commands.registerCommand('changeset.addorgs', async () => { 43 | let changeset = new Changeset(); 44 | await changeset.addOrgs(); 45 | }); 46 | 47 | const openSLDS = vscode.commands.registerCommand('open.slds', () => { 48 | NavigationService.openSLDSDocument(); 49 | }); 50 | 51 | const openMetadataCoverage = vscode.commands.registerCommand('open.metadataCoverageReport', () => { 52 | NavigationService.metadataCoverageReport(); 53 | }); 54 | 55 | const openComponentLibrary = vscode.commands.registerCommand('open.componentLibrary', () => { 56 | NavigationService.componentLibrary(); 57 | }); 58 | 59 | const openSalesforceOrg = vscode.commands.registerCommand('open.org', () => { 60 | let activeTerminal = VSCodeCore.setupTerminal(); 61 | if(activeTerminal){ 62 | let openCmd = 'sfdx force:org:open'; 63 | activeTerminal.sendText(openCmd); 64 | } 65 | }); 66 | 67 | const installPlugin = vscode.commands.registerCommand('extension.installplugin', () => { 68 | let activeTerminal = VSCodeCore.setupTerminal(); 69 | if(activeTerminal){ 70 | let openCmd = 'sfdx plugins:install mo-dx-plugin'; 71 | activeTerminal.sendText(openCmd); 72 | } 73 | }); 74 | 75 | const openVFPage = vscode.commands.registerCommand('open.vf', () => { 76 | let activeTerminal = VSCodeCore.setupTerminal(); 77 | if(activeTerminal){ 78 | let openCmd = 'sfdx force:org:open -p /apex/' + NavigationService.openVFPage(VSCodeCore.getFsPath()); 79 | activeTerminal.sendText(openCmd); 80 | } 81 | }); 82 | 83 | const openLightningAppPage = vscode.commands.registerCommand('open.lightningPage', () => { 84 | let activeTerminal = VSCodeCore.setupTerminal(); 85 | if(activeTerminal){ 86 | let openCmd = 'sfdx force:source:open -f ' + '"' + VSCodeCore.getFsPath() + '"'; 87 | activeTerminal.sendText(openCmd); 88 | } 89 | }); 90 | 91 | const switchorg = vscode.commands.registerCommand('switch.org', async () => { 92 | await switchOrg(); 93 | }); 94 | 95 | const deployStaticResource = vscode.commands.registerCommand('deploy.staticresource', (uri:vscode.Uri) => { 96 | const staticresourcefolder = vscode.workspace.getConfiguration("dx-code-companion").staticresourcefolder.resourceBundleFoldername; 97 | let activeTerminal = VSCodeCore.setupTerminal(); 98 | if(activeTerminal){ 99 | if(uri.fsPath.indexOf(staticresourcefolder) !== -1) { 100 | let openCmd = 'sfdx deploy:staticresource -p ' + '"' + OSUtil.toUnixStyle(uri.fsPath) + '"' + ' -r ' + staticresourcefolder; 101 | activeTerminal.sendText(openCmd); 102 | } 103 | } 104 | }); 105 | 106 | const deploySource = vscode.commands.registerCommand('deploy.source', () => { 107 | if(vscode.window.activeTextEditor){ 108 | DeploySource.deployToSFDC(vscode.window.activeTextEditor.document); 109 | } 110 | }); 111 | 112 | const refreshSource = vscode.commands.registerCommand('refresh.source', async () => { 113 | if(vscode.window.activeTextEditor){ 114 | DeploySource.refreshFromServer(vscode.window.activeTextEditor.document); 115 | } 116 | }); 117 | 118 | const compareSource = vscode.commands.registerCommand('compare.source', async () => { 119 | if(vscode.window.activeTextEditor){ 120 | DeploySource.compareWithServer(vscode.window.activeTextEditor.document); 121 | } 122 | }); 123 | 124 | // Provider for compare view when server files are modified 125 | context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider('codecompanion', CodeCompanionContentProvider.getInstance())); 126 | // Trigger Deploy on Save 127 | context.subscriptions.push(vscode.workspace.onDidSaveTextDocument((textDocument: vscode.TextDocument) => { 128 | if(vscode.window.activeTextEditor) { 129 | // Execute save only for the opened Editor file save event 130 | if(vscode.window.activeTextEditor.document.uri.fsPath === textDocument.uri.fsPath) { 131 | DeploySource.deploy(textDocument); 132 | } 133 | } 134 | })); 135 | 136 | context.subscriptions.push(deploySource); 137 | context.subscriptions.push(changesetRetrieve); 138 | context.subscriptions.push(compareSource); 139 | context.subscriptions.push(refreshSource); 140 | context.subscriptions.push(retrieveSource); 141 | context.subscriptions.push(retrievepkgSource); 142 | context.subscriptions.push(openLightningAppPage); 143 | context.subscriptions.push(openMetadataCoverage); 144 | context.subscriptions.push(openComponentLibrary); 145 | context.subscriptions.push(openVFPage); 146 | context.subscriptions.push(openSLDS); 147 | context.subscriptions.push(switchorg); 148 | context.subscriptions.push(openSalesforceOrg); 149 | context.subscriptions.push(deploysrc); 150 | context.subscriptions.push(changesetOrgAdd); 151 | context.subscriptions.push(deployStaticResource); 152 | context.subscriptions.push(installPlugin); 153 | } 154 | // this method is called when your extension is deactivated 155 | export function deactivate() { 156 | VSCodeCore.showActivationMessage().dispose(); 157 | } -------------------------------------------------------------------------------- /src/providers/ccprovider.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | 3 | export default class CodeCompanionContentProvider implements vscode.TextDocumentContentProvider { 4 | 5 | private static instance: CodeCompanionContentProvider; 6 | public static serverContent: string; 7 | 8 | public static getInstance() { 9 | if(!CodeCompanionContentProvider.instance) { 10 | this.instance = new CodeCompanionContentProvider(); 11 | } 12 | return this.instance; 13 | } 14 | 15 | provideTextDocumentContent(uri: vscode.Uri): Thenable { 16 | return new Promise( async (resolve, reject) => { 17 | if(CodeCompanionContentProvider.serverContent) { 18 | resolve(CodeCompanionContentProvider.serverContent); 19 | } 20 | }); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /src/services/changeset.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as fs from 'fs'; 4 | import * as vscode from 'vscode'; 5 | import {Config} from './config'; 6 | import { VSCodeCore } from './vscodeCore'; 7 | import {VSCodeUI} from './vscodeUI'; 8 | 9 | export class Changeset { 10 | 11 | public async retrieve(): Promise { 12 | 13 | const name: string = await VSCodeUI.showInputBox('Enter changeset name'); 14 | if(vscode.workspace.workspaceFolders){ 15 | const changesetDir = vscode.workspace.workspaceFolders[0].uri.fsPath + '/changesets' ; 16 | const subDirectory = changesetDir + '/' + name.trim().toLowerCase().replace(/\s/g,''); 17 | const orgsJson = vscode.workspace.workspaceFolders[0].uri.fsPath + '/changesets/orgs.json'; 18 | 19 | if(!fs.existsSync(changesetDir)) { 20 | //create changesets directory 21 | fs.mkdirSync(changesetDir); 22 | const defaultorg = await Config.getDefaultUsername(); 23 | const orgArray: Array = [defaultorg]; 24 | await fs.writeFile(orgsJson,JSON.stringify(orgArray), 'UTF-8', (err) => { 25 | if (err) { 26 | throw err; 27 | } 28 | }); 29 | } 30 | if(!fs.existsSync(subDirectory)) { 31 | fs.mkdirSync(subDirectory); 32 | } 33 | let activeTerminal = VSCodeCore.setupTerminal(); 34 | if(activeTerminal){ 35 | //let retrievecommand = 'sfdx force:mdapi:retrieve -s -p ' + '"' + name + '"' + ' -r ' + subDirectory + ' -w 30 --json'; 36 | let retrievecommand = 'sfdx retrieve:pkgsource -n ' + '"' + name + '"' + ' -r ' + 'changesets/' + name.trim().toLowerCase().replace(/\s/g,'') + '/src'; 37 | activeTerminal.sendText(retrievecommand); 38 | } 39 | } 40 | } 41 | 42 | public async addOrgs() : Promise { 43 | if(vscode.workspace.workspaceFolders){ 44 | const orgsJson = vscode.workspace.workspaceFolders[0].uri.fsPath + '/changesets/orgs.json'; 45 | await fs.readFile(orgsJson, async (err, currentorgs) => { 46 | if (err) { 47 | throw err; 48 | } 49 | if(currentorgs) { 50 | const currentOrgsArray : string[] = JSON.parse(currentorgs.toString()); 51 | let allOrgsListArray = await Config.getAllOrgs(); 52 | allOrgsListArray = allOrgsListArray.filter((el) => !currentOrgsArray.includes(el)); 53 | const selectedOrgs = await VSCodeUI.showQuickPickMultiple(allOrgsListArray); 54 | if(selectedOrgs) { 55 | currentOrgsArray.push.apply(currentOrgsArray, selectedOrgs); 56 | await fs.writeFile(orgsJson,JSON.stringify(currentOrgsArray), 'UTF-8', (err) => { 57 | if (err) { 58 | throw err; 59 | } 60 | }); 61 | } 62 | } 63 | }); 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /src/services/commandBuilder.ts: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | import * as path from "path"; 4 | import { Metadata } from "../services/findMetadataType"; 5 | import { workspace } from "vscode"; 6 | 7 | export class CommandService { 8 | protected filepath: string; 9 | protected directory: string; 10 | public metadataDef: Metadata; 11 | 12 | constructor(filepath: string) { 13 | this.filepath = filepath; 14 | this.directory = path.basename(path.dirname(path.dirname(this.filepath))); 15 | this.metadataDef = new Metadata(this.filepath); 16 | } 17 | 18 | public generateCommand() { 19 | let command = "sfdx deploy:"; 20 | const metadata = this.metadataDef; 21 | // const auraFiles = ['.cmp','.app','.evt','.css','.js','design','svg','tokens','intf','auradoc']; 22 | command = command + metadata.getMetadataType().CommandName + " "; 23 | command = command + "-p " + '"' + this.filepath + '"'; 24 | if (this.metadataDef.getMetadataType().CommandName === "staticresource") { 25 | command = 26 | command + 27 | " -r " + 28 | workspace.getConfiguration("dx-code-companion").staticresourcefolder 29 | .resourceBundleFoldername; 30 | } 31 | return command; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/services/config.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as sfcore from '@salesforce/core'; 4 | import * as vscode from 'vscode'; 5 | import * as path from 'path'; 6 | 7 | export class Config { 8 | 9 | public static async getAllOrgs(): Promise { 10 | const authFiles = await sfcore.AuthInfo.listAllAuthFiles(); 11 | const orgs = authFiles.map(authfile => authfile.replace('.json', '')); 12 | return orgs; 13 | } 14 | 15 | private static async getAllAliases(): Promise { 16 | const aliases = await sfcore.Aliases.create(sfcore.Aliases.getDefaultOptions()); 17 | return aliases; 18 | } 19 | 20 | public static async getAllOrgAliases(): Promise { 21 | const orgAlias = []; 22 | const orgs = await this.getAllOrgs(); 23 | const aliases = await this.getAllAliases(); 24 | // Map the aliases onto the orgs 25 | for (const org of orgs) { 26 | if(aliases.getKeysByValue(org)) { 27 | orgAlias.push( aliases.getKeysByValue(org) + ':' + org ); 28 | } 29 | } 30 | return orgAlias; 31 | } 32 | 33 | public static async getConnection(): Promise { 34 | let defaultusername = await Config.getDefaultUsername(); 35 | const connection = await sfcore.Connection.create({ 36 | authInfo: await sfcore.AuthInfo.create({ username: defaultusername}) 37 | }); 38 | return connection; 39 | } 40 | 41 | public static async getDefaultUsername() { 42 | if(vscode.workspace && vscode.workspace.workspaceFolders) { 43 | const rootPath = vscode.workspace.workspaceFolders[0].uri.fsPath; 44 | const myLocalConfig = await sfcore.ConfigFile.create({ 45 | isGlobal: false, 46 | rootFolder: path.join(rootPath, '.sfdx'), 47 | filename: 'sfdx-config.json' 48 | }); 49 | const localValue = myLocalConfig.get('defaultusername'); 50 | let defaultusername = await sfcore.Aliases.fetch(JSON.stringify(localValue).replace(/\"/g, '')); 51 | return defaultusername; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/services/deploy.ts: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | import * as fs from "fs"; 4 | import * as path from "path"; 5 | import * as vscode from "vscode"; 6 | import CodeCompanionContentProvider from "../providers/ccprovider"; 7 | import { ServerResult } from "../typings/ccdxTypings"; 8 | import { CommandService } from "./commandBuilder"; 9 | import { Config } from "./config"; 10 | import { SalesforceUtil } from "./sfdcUtils"; 11 | import { VSCodeCore } from "./vscodeCore"; 12 | import { OSUtil } from "./osUtils"; 13 | import { VSCodeUI } from "./vscodeUI"; 14 | 15 | export class DeploySource { 16 | private static lastSavedToServer: string; 17 | 18 | public static async compareWithServer(textDocument: vscode.TextDocument) { 19 | if (this.supportedFileForDeploy()) { 20 | // The authorization creates sfdx-project.json files and this extension supports only auth done using sfdx cli 21 | if (this.isProjectAuthroizedToSFDC()) { 22 | if (vscode.window.activeTextEditor) { 23 | const { 24 | commandToExecute, 25 | filename, 26 | fileextension 27 | } = DeploySource.extractInfo(textDocument); 28 | const metadataType = commandToExecute.metadataDef.getMetadataType() 29 | .MetadataName; 30 | const serverResponse = await this.getServerCopy( 31 | metadataType, 32 | filename, 33 | fileextension 34 | ); 35 | if (serverResponse.exist) { 36 | // Set content provider content 37 | CodeCompanionContentProvider.serverContent = serverResponse.Body; 38 | var sfuri: vscode.Uri = vscode.Uri.parse( 39 | `codecompanion://salesforce.com/${metadataType}/${filename}.${fileextension}?${Date.now()}` 40 | ); 41 | vscode.commands.executeCommand( 42 | "vscode.diff", 43 | sfuri, 44 | textDocument.uri, 45 | `${filename}.${fileextension}(SERVER) <~> ${filename}.${fileextension} (LOCAL)`, 46 | { preview: false } 47 | ); 48 | } 49 | } 50 | } 51 | } 52 | } 53 | 54 | public static deployToSFDC(textDocument: vscode.TextDocument) { 55 | if (this.supportedFileForDeploy()) { 56 | // The authorization creates sfdx-project.json files and this extension supports only auth done using sfdx cli 57 | if (this.isProjectAuthroizedToSFDC()) { 58 | if (vscode.window.activeTextEditor) { 59 | const { 60 | commandToExecute, 61 | filename, 62 | fileextension 63 | } = DeploySource.extractInfo(textDocument); 64 | if ( 65 | vscode.workspace.getConfiguration("dx-code-companion") 66 | .manageconflict.enabled 67 | ) { 68 | const metadataType = commandToExecute.metadataDef.getMetadataType() 69 | .MetadataName; 70 | this.save( 71 | metadataType, 72 | filename, 73 | textDocument, 74 | commandToExecute, 75 | fileextension 76 | ); 77 | } else { 78 | this.executeDeployCommand(commandToExecute); 79 | } 80 | } 81 | } else { 82 | vscode.window.showErrorMessage("Authorize a salesforce org"); 83 | } 84 | } 85 | } 86 | 87 | private static extractInfo(textDocument: vscode.TextDocument) { 88 | const filepath = VSCodeCore.getFsPath(); 89 | const filepathArray = path.basename(textDocument.fileName).split("."); 90 | const filename = filepathArray[0]; 91 | let fileextension = filepathArray[1]; 92 | if (filepathArray.length > 2) { 93 | fileextension = fileextension + "." + filepathArray[2]; 94 | } 95 | const commandToExecute = new CommandService(filepath); 96 | return { commandToExecute, filename, fileextension }; 97 | } 98 | 99 | private static save( 100 | metadataType: string, 101 | filename: string, 102 | textDocument: vscode.TextDocument, 103 | commandToExecute: CommandService, 104 | fileextension: string 105 | ) { 106 | vscode.window.withProgress( 107 | { 108 | location: vscode.ProgressLocation.Notification, 109 | title: "Comparing with server copy" 110 | }, 111 | () => { 112 | var p = new Promise(async resolve => { 113 | const serverResponse = await this.getServerCopy( 114 | metadataType, 115 | filename, 116 | fileextension 117 | ); 118 | if (serverResponse.exist) { 119 | // Set content provider content 120 | CodeCompanionContentProvider.serverContent = serverResponse.Body; 121 | if ( 122 | !this.compare(textDocument.getText(), serverResponse.Body) && 123 | !this.compare(serverResponse.Body, this.lastSavedToServer) 124 | ) { 125 | var sfuri: vscode.Uri = vscode.Uri.parse( 126 | `codecompanion://salesforce.com/${metadataType}/${filename}?${Date.now()}` 127 | ); 128 | vscode.commands.executeCommand( 129 | "vscode.diff", 130 | sfuri, 131 | textDocument.uri, 132 | `${filename}.${fileextension}(SERVER) <~> ${filename}.${fileextension} (LOCAL)`, 133 | { preview: true } 134 | ); 135 | vscode.window 136 | .showWarningMessage( 137 | "File has been modified in salesforce", 138 | "Refresh From Server", 139 | "Overwrite Server Copy" 140 | ) 141 | .then(s => { 142 | if (s === "Overwrite Server Copy") { 143 | this.run(commandToExecute, textDocument); 144 | } else if (s === "Refresh From Server") { 145 | this.refresh(serverResponse.Body); 146 | } 147 | }); 148 | } else { 149 | this.run(commandToExecute, textDocument); 150 | } 151 | } else { 152 | this.run(commandToExecute, textDocument); 153 | } 154 | resolve(); 155 | }); 156 | return p; 157 | } 158 | ); 159 | } 160 | 161 | public static async refreshFromServer(textDocument: vscode.TextDocument) { 162 | if (this.supportedFileForDeploy()) { 163 | // The authorization creates sfdx-project.json files and this extension supports only auth done using sfdx cli 164 | if (this.isProjectAuthroizedToSFDC()) { 165 | if (vscode.window.activeTextEditor) { 166 | const { 167 | commandToExecute, 168 | filename, 169 | fileextension 170 | } = DeploySource.extractInfo(textDocument); 171 | const metadataType = commandToExecute.metadataDef.getMetadataType() 172 | .MetadataName; 173 | vscode.window.withProgress( 174 | { 175 | location: vscode.ProgressLocation.Notification, 176 | title: "Refreshing.." 177 | }, 178 | () => { 179 | var p = new Promise(async resolve => { 180 | const serverResponse = await this.getServerCopy( 181 | metadataType, 182 | filename, 183 | fileextension 184 | ); 185 | this.refresh(serverResponse.Body); 186 | resolve(); 187 | }); 188 | return p; 189 | } 190 | ); 191 | } 192 | } 193 | } 194 | } 195 | 196 | private static run( 197 | commandToExecute: CommandService, 198 | textDocument: vscode.TextDocument 199 | ) { 200 | this.lastSavedToServer = textDocument.getText(); 201 | this.executeDeployCommand(commandToExecute); 202 | } 203 | 204 | private static refresh(filecontent: string) { 205 | this.lastSavedToServer = filecontent; 206 | fs.writeFileSync(VSCodeCore.getFsPath(), filecontent); 207 | } 208 | 209 | public static deploy(textDocument: vscode.TextDocument) { 210 | if ( 211 | vscode.workspace.getConfiguration("dx-code-companion").autosave.enabled 212 | ) { 213 | DeploySource.deployToSFDC(textDocument); 214 | } 215 | } 216 | 217 | private static async getServerCopy( 218 | metadataName: string, 219 | fileName: string, 220 | fileextension: string 221 | ): Promise { 222 | const connection = await Config.getConnection(); 223 | const util = new SalesforceUtil(connection); 224 | return util.getFileContentFromServer(metadataName, fileName, fileextension); 225 | } 226 | 227 | private static compare(localfile: string, serverfile: string): boolean { 228 | if (localfile === serverfile) { 229 | return true; 230 | } else { 231 | return false; 232 | } 233 | } 234 | 235 | private static executeDeployCommand(cmd: CommandService): void { 236 | let activeTerminal = VSCodeCore.setupTerminal(); 237 | if (activeTerminal) { 238 | activeTerminal.sendText(cmd.generateCommand()); 239 | } 240 | } 241 | 242 | private static isProjectAuthroizedToSFDC(): boolean { 243 | let isProjectAuthorized: boolean = false; 244 | if (vscode.workspace.workspaceFolders) { 245 | // The authorization creates sfdx-project.json files and this extension supports only auth done using sfdx cli 246 | if ( 247 | fs.existsSync( 248 | vscode.workspace.workspaceFolders[0].uri.fsPath + "/sfdx-project.json" 249 | ) 250 | ) { 251 | isProjectAuthorized = true; 252 | } 253 | } 254 | return isProjectAuthorized; 255 | } 256 | 257 | private static supportedFileForDeploy(): boolean { 258 | let fileSupported = false; 259 | if (vscode.window.activeTextEditor) { 260 | const filePath = vscode.window.activeTextEditor.document.uri.fsPath; 261 | const resourcefoldername = vscode.workspace.getConfiguration( 262 | "dx-code-companion" 263 | ).staticresourcefolder.resourceBundleFoldername; 264 | // Check if this is a static resource 265 | if ( 266 | filePath.indexOf("/" + resourcefoldername + "/") !== -1 || 267 | filePath.indexOf("\\" + resourcefoldername + "\\") !== -1 268 | ) { 269 | fileSupported = true; 270 | } else { 271 | //At this point only few file types are supported for auto save 272 | const supportedFileTypes = [ 273 | "trigger", 274 | "cls", 275 | "cmp", 276 | "evt", 277 | "design", 278 | "tokens", 279 | "page", 280 | "svg", 281 | "auradoc", 282 | "component", 283 | "intf", 284 | "app" 285 | ]; 286 | const pathAsArray = filePath.split("/"); 287 | const lastparam = pathAsArray[pathAsArray.length - 1]; 288 | const fileExtension = lastparam.substring( 289 | lastparam.lastIndexOf(".") + 1 290 | ); 291 | const directory = path.basename(path.dirname(path.dirname(filePath))); 292 | if ( 293 | fileExtension === "js" || 294 | fileExtension === "css" || 295 | fileExtension === "html" 296 | ) { 297 | // check for immediate directory 298 | if (directory === "lwc" || directory === "aura") { 299 | fileSupported = true; 300 | } 301 | } 302 | if (supportedFileTypes.indexOf(fileExtension) !== -1) { 303 | fileSupported = true; 304 | } 305 | } 306 | } 307 | return fileSupported; 308 | } 309 | 310 | public static async deploySrc(uripath: string): Promise { 311 | if (vscode.workspace.workspaceFolders) { 312 | let activeTerminal = VSCodeCore.setupTerminal(); 313 | let deployCommand = 314 | "sfdx force:mdapi:deploy -d " + OSUtil.toUnixStyle(uripath) + " -w -1"; 315 | let runCommand = true; 316 | if (uripath.indexOf("changesets") > -1) { 317 | //changesets folder so ask for relevant org 318 | try { 319 | const orgs = fs.readFileSync( 320 | vscode.workspace.workspaceFolders[0].uri.fsPath + 321 | "/changesets/orgs.json" 322 | ); 323 | const username = await VSCodeUI.showQuickPick( 324 | JSON.parse(orgs.toString()), 325 | "Select Org for deployment(To display more orgs add usernames in orgs.json)" 326 | ); 327 | deployCommand = deployCommand + " -u " + username; 328 | if (!username) { 329 | runCommand = false; 330 | } 331 | } catch (error) { 332 | throw error; 333 | } 334 | } 335 | if (activeTerminal && runCommand) { 336 | activeTerminal.sendText(deployCommand); 337 | } 338 | } 339 | } 340 | } 341 | -------------------------------------------------------------------------------- /src/services/findMetadataType.ts: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | import * as path from "path"; 4 | import { MetadataType } from "../typings/ccdxTypings"; 5 | import * as vscode from "vscode"; 6 | export class Metadata { 7 | protected filepath: string; 8 | protected directory: string; 9 | protected isstaticresource: boolean; 10 | 11 | private resourcefoldername = vscode.workspace.getConfiguration( 12 | "dx-code-companion" 13 | ).staticresourcefolder.resourceBundleFoldername; 14 | 15 | constructor(filepath: string) { 16 | this.filepath = filepath; 17 | this.directory = path.basename(path.dirname(path.dirname(this.filepath))); 18 | this.isstaticresource = 19 | filepath.indexOf("\\" + this.resourcefoldername + "\\") === -1 && 20 | filepath.indexOf("/" + this.resourcefoldername + "/") === -1 21 | ? false 22 | : true; 23 | } 24 | 25 | public getMetadataType(): MetadataType { 26 | const metadataType = {} as MetadataType; 27 | // check for static Resource 28 | if (this.isstaticresource) { 29 | metadataType.MetadataName = "StaticResource"; 30 | metadataType.CommandName = "staticresource"; 31 | } else { 32 | // const auraFiles = ['.cmp','.app','.evt','.css','.js','design','svg','tokens','intf','auradoc']; 33 | if (this.filepath.includes(".cls")) { 34 | metadataType.MetadataName = "ApexClass"; 35 | metadataType.CommandName = "apex"; 36 | } else if (this.filepath.includes(".trigger")) { 37 | metadataType.MetadataName = "ApexTrigger"; 38 | metadataType.CommandName = "trigger"; 39 | } else if (this.filepath.includes(".page")) { 40 | metadataType.MetadataName = "ApexPage"; 41 | metadataType.CommandName = "vf"; 42 | } else if (this.filepath.includes(".component")) { 43 | metadataType.MetadataName = "ApexComponent"; 44 | metadataType.CommandName = "vfcomponent"; 45 | } else if (this.directory === "aura") { 46 | metadataType.MetadataName = "AuraDefinition"; 47 | metadataType.CommandName = "aura"; 48 | } else if (this.directory === "lwc") { 49 | metadataType.MetadataName = "LightningComponent"; 50 | metadataType.CommandName = "lwc"; 51 | } else { 52 | // Modify this to add support for other Metadata Types 53 | metadataType.MetadataName = "unknown"; 54 | metadataType.CommandName = "unknown"; 55 | } 56 | } 57 | return metadataType; 58 | } 59 | 60 | // function to get file extension 61 | public static getDefType( 62 | extension: string, 63 | filename: string | null 64 | ): string | undefined { 65 | let auratype; 66 | switch (extension) { 67 | case "app": { 68 | // APPLICATION — Lightning Components app 69 | auratype = "APPLICATION"; 70 | break; 71 | } 72 | case "cmp": { 73 | // COMPONENT — component markup 74 | auratype = "COMPONENT"; 75 | break; 76 | } 77 | case "auradoc": { 78 | // DOCUMENTATION — documentation markup 79 | auratype = "DOCUMENTATION"; 80 | break; 81 | } 82 | case "css": { 83 | // STYLE — style (CSS) resource 84 | auratype = "STYLE"; 85 | break; 86 | } 87 | case "evt": { 88 | // EVENT — event definition 89 | auratype = "EVENT"; 90 | break; 91 | } 92 | case "design": { 93 | // DESIGN — design definition 94 | auratype = "DESIGN"; 95 | break; 96 | } 97 | case "svg": { 98 | // SVG — SVG graphic resource 99 | auratype = "SVG"; 100 | break; 101 | } 102 | case "js": { 103 | if (filename !== null) { 104 | const fname = filename.toLowerCase(); 105 | if (fname.endsWith("controller")) { 106 | auratype = "CONTROLLER"; 107 | } else if (fname.endsWith("helper")) { 108 | auratype = "HELPER"; 109 | } else if (fname.endsWith("renderer")) { 110 | // RENDERER — client-side renderer 111 | auratype = "RENDERER"; 112 | } 113 | } 114 | break; 115 | } 116 | case "tokens": { 117 | auratype = "TOKENS"; 118 | break; 119 | } 120 | case "intf": { 121 | auratype = "INTERFACE"; 122 | break; 123 | } 124 | default: { 125 | auratype = ""; 126 | } 127 | } 128 | return auratype; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/services/navigation.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as path from 'path'; 4 | import * as vscode from 'vscode'; 5 | 6 | 7 | export class NavigationService { 8 | 9 | public static metadataCoverageReport() { 10 | NavigationService.vscodeOpenurl('https://developer.salesforce.com/docs/metadata-coverage'); 11 | } 12 | 13 | public static componentLibrary() { 14 | NavigationService.vscodeOpenurl('https://developer.salesforce.com/docs/component-library'); 15 | } 16 | 17 | public static openSLDSDocument() { 18 | NavigationService.vscodeOpenurl('https://www.lightningdesignsystem.com/'); 19 | } 20 | 21 | public static vscodeOpenurl(url: string) { 22 | vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(url)); 23 | } 24 | 25 | public static openVFPage(filePath: string) { 26 | let fileName = path.basename(filePath); 27 | fileName = fileName.replace('.page',''); 28 | return fileName; 29 | } 30 | } -------------------------------------------------------------------------------- /src/services/osUtils.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export class OSUtil { 4 | 5 | public static toUnixStyle(path: string): string { 6 | return path.replace(/\\/g, "/"); 7 | } 8 | 9 | public static isWindowsOs(): boolean { 10 | const operatingsystem : string = process.platform; 11 | if(operatingsystem.includes('win')) { 12 | return true; 13 | } else { 14 | return false; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/services/retrieve.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Connection } from '@salesforce/core'; 4 | import { QueryResult } from '../typings/ccdxTypings'; 5 | import { SalesforceUtil } from './sfdcUtils'; 6 | import { VSCodeCore } from './vscodeCore'; 7 | import { VSCodeUI } from './vscodeUI'; 8 | 9 | export class RetrieveSource { 10 | 11 | private connection: Connection; 12 | 13 | constructor (conn: Connection) { 14 | this.connection = conn; 15 | } 16 | 17 | public async retrieve(cmd: string): Promise { 18 | const sfdcUtil = new SalesforceUtil(this.connection); 19 | const packages = await sfdcUtil.getPackages() as QueryResult; 20 | const pkgs = packages.records.map( pkg => pkg.Name); 21 | const unmanagedpkg = await VSCodeUI.showQuickPick(pkgs); 22 | if(unmanagedpkg) { 23 | let activeTerminal = VSCodeCore.setupTerminal(); 24 | if(activeTerminal){ 25 | let retrievecommand = cmd + '"' + unmanagedpkg + '"' ; 26 | activeTerminal.sendText(retrievecommand); 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/services/sfdcUtils.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Connection } from '@salesforce/core'; 4 | import { Metadata } from '../services/findMetadataType'; 5 | import { Query, ServerResult } from '../typings/ccdxTypings'; 6 | 7 | 8 | export class SalesforceUtil { 9 | 10 | private connection: Connection; 11 | 12 | constructor (conn: Connection) { 13 | this.connection = conn; 14 | } 15 | 16 | public async getPackages() : Promise { 17 | const connection = await this.connection; 18 | return await connection.tooling.query('SELECT Name, NamespacePrefix FROM MetadataPackage'); 19 | } 20 | 21 | public async getNamespace(): Promise { 22 | let namespacePrefix = ''; 23 | const connection = await this.connection; 24 | const Organization = await connection.query('Select NamespacePrefix from Organization'); 25 | if(Organization.totalSize > 0){ 26 | const organizationRec = Organization.records[0]; 27 | namespacePrefix = organizationRec['NamespacePrefix']; 28 | } 29 | return namespacePrefix; 30 | } 31 | 32 | public async getFileContentFromServer(metadataType: string, filename: string,fileextension: string): Promise { 33 | const namespacePrefix = await this.getNamespace(); 34 | const connection = await this.connection; 35 | const query = await this.getToolingQuery(metadataType,filename,fileextension,namespacePrefix); 36 | let serverResponse = {} as ServerResult; 37 | serverResponse.exist = false; 38 | const result = await connection.tooling.query(query.queryString); 39 | if(result.records.length > 0) { 40 | const response = result.records[0]; 41 | serverResponse.Body = response[query.bodyfield]; 42 | serverResponse.exist = true; 43 | } 44 | 45 | return serverResponse; 46 | } 47 | 48 | private async getToolingQuery (metadataType: string, filename: string | null, fileextension: string, namespacePrefix: string): Promise { 49 | let bodyfield: string; 50 | let wherefield: string; 51 | let lwcpath: string = ''; 52 | let auraDefId: string | null = ''; 53 | let lwcDefId: string | null = ''; 54 | let componentName: string | null = ''; 55 | const query = {} as Query; 56 | switch(metadataType) { 57 | case "ApexClass": { 58 | bodyfield = 'Body'; 59 | wherefield = 'Name'; 60 | break; 61 | } 62 | case "ApexTrigger": { 63 | bodyfield = 'Body'; 64 | wherefield = 'Name'; 65 | break; 66 | } 67 | case "ApexComponent": { 68 | bodyfield = 'Markup'; 69 | wherefield = 'Name'; 70 | break; 71 | } 72 | case "ApexPage": { 73 | bodyfield = 'Markup'; 74 | wherefield = 'Name'; 75 | break; 76 | } 77 | case "AuraDefinition": { 78 | if( filename !== null && (filename.endsWith('Helper') || filename.endsWith('Controller'))) { 79 | componentName = filename.replace('Helper' ,''); 80 | componentName = componentName.replace('Controller' ,''); 81 | } else { 82 | componentName = filename; 83 | } 84 | const auraDefinition = await this.getDefinition(componentName, namespacePrefix, 'AuraDefinitionBundle'); 85 | bodyfield = 'Source'; 86 | wherefield = 'AuraDefinitionBundleId'; 87 | metadataType = 'AuraDefinition'; 88 | auraDefId = this.getDefId(auraDefinition, auraDefId); 89 | break; 90 | } 91 | case "LightningComponent": { 92 | lwcpath = this.getlwcPath(filename, fileextension); 93 | const lwcDefinition = await this.getDefinition(filename, namespacePrefix, 'LightningComponentBundle'); 94 | bodyfield = 'Source'; 95 | wherefield = 'LightningComponentBundleId'; 96 | metadataType = 'LightningComponentResource'; 97 | lwcDefId = this.getDefId(lwcDefinition, lwcDefId); 98 | break; 99 | } 100 | default: { 101 | bodyfield = 'Body'; 102 | wherefield = 'Name'; 103 | } 104 | } 105 | query.queryString = `Select ${bodyfield} from ${metadataType}`; 106 | if(metadataType === 'AuraDefinition') { 107 | const deftype = Metadata.getDefType(fileextension,filename); 108 | query.queryString += ` where DefType='${deftype}'`; 109 | if(filename !== null){ 110 | query.queryString += ` and ${wherefield}='${auraDefId}'`; 111 | } 112 | } else if(metadataType === 'LightningComponentResource') { 113 | query.queryString += ` where FilePath='${lwcpath}'`; 114 | if(filename !== null){ 115 | query.queryString += ` and ${wherefield}='${lwcDefId}'`; 116 | } 117 | } else { 118 | query.queryString += ` where ${wherefield}='${filename}'`; 119 | // Add Namespace Prefix 120 | if(namespacePrefix !== null) { 121 | query.queryString += ` and NamespacePrefix=${namespacePrefix}`; 122 | } else { 123 | query.queryString += ` and NamespacePrefix=null`; 124 | } 125 | } 126 | query.bodyfield = bodyfield; 127 | return query; 128 | } 129 | 130 | 131 | private getlwcPath(filename: string | null, fileextension: string): string { 132 | let lwcpath: string; 133 | lwcpath = 'lwc/' + filename + '/' + filename + '.' + fileextension; 134 | return lwcpath; 135 | } 136 | 137 | private getDefId(definition: any, filename: string | null) { 138 | if (definition.length > 0) { 139 | filename = definition[0].Id; 140 | } 141 | else { 142 | filename = null; 143 | } 144 | return filename; 145 | } 146 | 147 | private async getDefinition(filename: string | null, namespacePrefix: string, typename: string) { 148 | const connection = this.connection; 149 | const definition = await connection.tooling.sobject(typename).find({ 150 | DeveloperName: filename, 151 | NamespacePrefix: namespacePrefix 152 | }); 153 | return definition; 154 | } 155 | } -------------------------------------------------------------------------------- /src/services/switchOrg.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Config } from './config'; 4 | import { VSCodeCore } from './vscodeCore'; 5 | import { VSCodeUI } from './vscodeUI'; 6 | 7 | export async function switchOrg(): Promise { 8 | const orgs = await Config.getAllOrgAliases(); 9 | const result = await VSCodeUI.showQuickPick(orgs); 10 | let cmd = 'sfdx force:config:set defaultusername='; 11 | if(result){ 12 | cmd = cmd + result.split(':')[0]; 13 | let activeTerminal = VSCodeCore.setupTerminal(); 14 | if(activeTerminal){ 15 | activeTerminal.sendText(cmd); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/services/vscodeCore.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as vscode from 'vscode'; 4 | import { OSUtil } from './osUtils'; 5 | 6 | export class VSCodeCore { 7 | 8 | private static terminalName: string = 'DX Companion'; 9 | 10 | private static ensureTerminalExists(): boolean { 11 | if ((vscode.window).terminals.length === 0) { 12 | return false; 13 | } 14 | return true; 15 | } 16 | 17 | public static setupTerminal(): vscode.Terminal { 18 | let activeTerminal; 19 | if(this.ensureTerminalExists()){ 20 | activeTerminal = vscode.window.terminals[0]; 21 | if(activeTerminal){ 22 | activeTerminal.show(true); 23 | } 24 | } else { 25 | // Create Terminal via VScode API 26 | const terminalName = this.terminalName; 27 | activeTerminal = vscode.window.createTerminal(terminalName); 28 | activeTerminal.show(true); 29 | } 30 | return activeTerminal; 31 | } 32 | 33 | public static getFsPath(): string { 34 | let path = ''; 35 | if(vscode.window.activeTextEditor) { 36 | path = vscode.window.activeTextEditor.document.uri.fsPath; 37 | if(OSUtil.isWindowsOs()) { 38 | path = OSUtil.toUnixStyle(path); //change to unix style for windows 39 | } 40 | } 41 | return path; 42 | } 43 | 44 | public static showActivationMessage(): vscode.StatusBarItem { 45 | vscode.commands.executeCommand('setContext', 'CCDXActive', true); 46 | const ccdx = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 90); 47 | ccdx.text = `DX Code Companion $(rocket)`; 48 | ccdx.tooltip = 'SalesforceDX Code Companion is Active ! Enjoy!!!!'; 49 | ccdx.command = 'open.org'; 50 | ccdx.show(); 51 | return ccdx; 52 | } 53 | } -------------------------------------------------------------------------------- /src/services/vscodeUI.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | export class VSCodeUI { 6 | 7 | public static async showInputBox(placeholder: string): Promise { 8 | const result = await vscode.window.showInputBox({ 9 | ignoreFocusOut : true, 10 | value: undefined, 11 | valueSelection: [2, 4], 12 | placeHolder: placeholder, 13 | prompt: placeholder 14 | }); 15 | return result; 16 | } 17 | 18 | public static async showQuickPick(options: string[], placeholder?:string, canPickMany?:true ) { 19 | const result = await vscode.window.showQuickPick(options, { 20 | placeHolder: placeholder, 21 | ignoreFocusOut : true, 22 | canPickMany : canPickMany 23 | }); 24 | return result; 25 | } 26 | 27 | public static async showQuickPickMultiple(options: string[] ) { 28 | const result = await vscode.window.showQuickPick(options, { 29 | canPickMany : true 30 | }); 31 | return result; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /src/test/extension.test.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Note: This example test is leveraging the Mocha test framework. 3 | // Please refer to their documentation on https://mochajs.org/ for help. 4 | // 5 | 6 | // The module 'assert' provides assertion methods from node 7 | import * as assert from 'assert'; 8 | 9 | // You can import and use all API from the 'vscode' module 10 | // as well as import your extension to test it 11 | // import * as vscode from 'vscode'; 12 | // import * as myExtension from '../extension'; 13 | 14 | // Defines a Mocha test suite to group tests of similar kind together 15 | suite("Extension Tests", function () { 16 | 17 | // Defines a Mocha unit test 18 | test("Something 1", function() { 19 | assert.equal(-1, [1, 2, 3].indexOf(5)); 20 | assert.equal(-1, [1, 2, 3].indexOf(0)); 21 | }); 22 | }); -------------------------------------------------------------------------------- /src/test/index.ts: -------------------------------------------------------------------------------- 1 | // 2 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 3 | // 4 | // This file is providing the test runner to use when running extension tests. 5 | // By default the test runner in use is Mocha based. 6 | // 7 | // You can provide your own test runner if you want to override it by exporting 8 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 9 | // host can call to run the tests. The test runner is expected to use console.log 10 | // to report the results back to the caller. When the tests are finished, return 11 | // a possible error to the callback or null if none. 12 | 13 | import * as testRunner from 'vscode/lib/testrunner'; 14 | 15 | // You can directly control Mocha options by uncommenting the following lines 16 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info 17 | testRunner.configure({ 18 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 19 | useColors: true // colored output from test results 20 | }); 21 | 22 | module.exports = testRunner; -------------------------------------------------------------------------------- /src/typings/ccdxTypings.ts: -------------------------------------------------------------------------------- 1 | export interface QueryResult { 2 | totalSize: number; 3 | done: boolean; 4 | records: Record[]; 5 | } 6 | 7 | export interface Record { 8 | Name : string; 9 | NamespacePrefix : string; 10 | } 11 | 12 | export interface MetadataType { 13 | MetadataName : string; 14 | CommandName : string; 15 | } 16 | 17 | export interface Query { 18 | queryString : string; 19 | bodyfield : string; 20 | } 21 | 22 | export interface ServerResult { 23 | Body : string; 24 | exist: boolean; 25 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src", 11 | /* Strict Type-Checking Option */ 12 | "strict": true, /* enable all strict type-checking options */ 13 | /* Additional Checks */ 14 | "noUnusedLocals": true /* Report errors on unused locals. */ 15 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 16 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 17 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 18 | }, 19 | "exclude": [ 20 | "node_modules", 21 | ".vscode-test" 22 | ] 23 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-string-throw": true, 4 | "no-unused-expression": true, 5 | "no-duplicate-variable": true, 6 | "curly": true, 7 | "class-name": true, 8 | "semicolon": [ 9 | true, 10 | "always" 11 | ], 12 | "triple-equals": true 13 | }, 14 | "defaultSeverity": "warning" 15 | } -------------------------------------------------------------------------------- /vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your VS Code Extension 2 | 3 | ## What's in the folder 4 | * This folder contains all of the files necessary for your extension. 5 | * `package.json` - this is the manifest file in which you declare your extension and command. 6 | The sample plugin registers a command and defines its title and command name. With this information 7 | VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command. 9 | The file exports one function, `activate`, which is called the very first time your extension is 10 | activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 11 | We pass the function containing the implementation of the command as the second parameter to 12 | `registerCommand`. 13 | 14 | ## Get up and running straight away 15 | * Press `F5` to open a new window with your extension loaded. 16 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. 17 | * Set breakpoints in your code inside `src/extension.ts` to debug your extension. 18 | * Find output from your extension in the debug console. 19 | 20 | ## Make changes 21 | * You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. 22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. 23 | 24 | ## Explore the API 25 | * You can open the full set of our API when you open the file `node_modules/vscode/vscode.d.ts`. 26 | 27 | ## Run tests 28 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. 29 | * Press `F5` to run the tests in a new window with your extension loaded. 30 | * See the output of the test result in the debug console. 31 | * Make changes to `test/extension.test.ts` or create new test files inside the `test` folder. 32 | * By convention, the test runner will only consider files matching the name pattern `**.test.ts`. 33 | * You can create folders inside the `test` folder to structure your tests any way you want. 34 | --------------------------------------------------------------------------------