diff --git a/.gitignore b/.gitignore index c99c7b65..e1183eeb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ package-lock.json *.vsix *.lock *.log +.history diff --git a/CHANGELOG.md b/CHANGELOG.md index e84f5d03..24233c89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,143 +1,143 @@ -# ChangeLog : Settings Sync [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Synchronize%20your%20%40VisualStudio%20%40code%20Settings%20Across%20Multiple%20Machines%20using%20%40github%20GIST%20by%20%40itsShanKhan&url=https://github.com/shanalikhan/code-settings-sync&via=code&hashtags=code,vscode,SettingsSync,developers) [![Follow](https://img.shields.io/twitter/follow/itsShanKhan.svg?style=social&label=Follow)](https://twitter.com/intent/follow?screen_name=itsShanKhan) - -[![Version](https://vsmarketplacebadge.apphb.com/version/Shan.code-settings-sync.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) [![Travis](https://img.shields.io/travis/rust-lang/rust.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) [![Master course](https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20Course%20%E2%86%92-gray.svg?colorA=444444&colorB=4F44D6)](https://t.co/8BEMyhpKU5?amp=1) - -#### v3.4.3 - September 23,2019 - -* Share GitHub Gist ID message Fixed [#1033](https://github.com/shanalikhan/code-settings-sync/issues/1033) -* Consistency between GitHub Gist and Description across extension readme [#1023](https://github.com/shanalikhan/code-settings-sync/issues/1023) -* Snippets Sync. Fixed [#993](https://github.com/shanalikhan/code-settings-sync/issues/993) -* GitHub Api connection improved [#1027](https://github.com/shanalikhan/code-settings-sync/issues/1027) -* Extension always asks to enable Force Upload [#1016](https://github.com/shanalikhan/code-settings-sync/issues/1016) - Thanks for PR [#1026](https://github.com/shanalikhan/code-settings-sync/pull/1026) by [@karl-lunarg](https://github.com/karl-lunarg) -* UX Improved for the Force Upload [#1035](https://github.com/shanalikhan/code-settings-sync/issues/1035) - Thanks for PR [#1042](https://github.com/shanalikhan/code-settings-sync/pull/1042) by [@karl-lunarg](https://github.com/karl-lunarg) -* Webview does not set a content security policy [#1010](https://github.com/shanalikhan/code-settings-sync/issues/1010) - Thanks for PR [#1020](https://github.com/shanalikhan/code-settings-sync/pull/1020) by [@ParkourKarthik](https://github.com/ParkourKarthik) -* Icon Improved - Thanks for PR [#1022](https://github.com/shanalikhan/code-settings-sync/pull/1022) by [@Pustur](https://github.com/Pustur) -* Improved German Languauge Support - Thanks for PR [#1040](https://github.com/shanalikhan/code-settings-sync/pull/1040) by [@jan-di](https://github.com/jan-di) -* Improved Chinese Language Support - Thanks for PR [#1028](https://github.com/shanalikhan/code-settings-sync/pull/1028) by [@YunChaoTsai](https://github.com/YunChaoTsai) -* Readme Improved - Thanks for PR [#1031](https://github.com/shanalikhan/code-settings-sync/pull/1031) by [@faliure](https://github.com/faliure) -* Slack Link Updated -* Node Modules Updated - -#### v3.4.2 - August 21, 2019 - -* Multiple Lanugages Support Improved [#1009](https://github.com/shanalikhan/code-settings-sync/pull/1009) by [@ XanatosX](https://github.com/XanatosX ) , [#999](https://github.com/shanalikhan/code-settings-sync/pull/999) by [@o3LL](https://github.com/o3LL) , [#994](https://github.com/shanalikhan/code-settings-sync/pull/994) by [@mijien0179](https://github.com/mijien0179) , [#981](https://github.com/shanalikhan/code-settings-sync/pull/981) by [@ryul1206](https://github.com/ryul1206) -* Hide GitHub Token on Summary [#974](https://github.com/shanalikhan/code-settings-sync/issues/974) -* Only Show "Share Gist" Dialog when Public Gist is created [#977](https://github.com/shanalikhan/code-settings-sync/issues/977) -* Sync Pragma Improved [#1003](https://github.com/shanalikhan/code-settings-sync/issues/1003) - Thanks for PR [#1012](https://github.com/shanalikhan/code-settings-sync/pull/1012) by [@protium-dev](https://github.com/protium-dev) -* UI Bug Fix where users were unable to select GIST [#983](https://github.com/shanalikhan/code-settings-sync/issues/983) - -#### v3.4.1 - July 22, 2019 - -* Turn off notifications on code startup [#959](https://github.com/shanalikhan/code-settings-sync/issues/959) - Thanks for PR [#960](https://github.com/shanalikhan/code-settings-sync/pull/960) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) -* Chinese Translation Improved - Thanks for PR [#966](https://github.com/shanalikhan/code-settings-sync/pull/966) by [@linsui](https://github.com/linsui) and [#961](https://github.com/shanalikhan/code-settings-sync/pull/961) by [@ziofat](https://github.com/ziofat) -* Russian Translation Improved - Thanks for PR [#957](https://github.com/shanalikhan/code-settings-sync/pull/957) by [@AndreyWV](https://github.com/AndreyWV) - -#### v3.4.0 - July 15, 2019 - -* Settings Sync now use Webviews to allow you to configure settings [#506](https://github.com/shanalikhan/code-settings-sync/issues/506) - Thanks for PR [#876](https://github.com/shanalikhan/code-settings-sync/pull/876) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) -* code snippets not being synced after update to 3.3.0 [#927](https://github.com/shanalikhan/code-settings-sync/issues/927) - Thanks for PR [#928](https://github.com/shanalikhan/code-settings-sync/pull/928) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) -* Implement upload delay setting [#390](https://github.com/shanalikhan/code-settings-sync/issues/390) - Thanks for PR [#925](https://github.com/shanalikhan/code-settings-sync/pull/925) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) -* Dont Upload If GIST and settings content are the same. [#316](https://github.com/shanalikhan/code-settings-sync/issues/316) - Thanks for PR [#923](https://github.com/shanalikhan/code-settings-sync/pull/923) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) -* Prevent accidental upload [#350](https://github.com/shanalikhan/code-settings-sync/issues/350) - Thanks for PR [#923](https://github.com/shanalikhan/code-settings-sync/pull/923) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) - -#### v3.3.1 - June 25,2019 -* Small Improvements - -#### v3.3.0 - June 25,2019 - -* Code OSS Version Support Added [#668](https://github.com/shanalikhan/code-settings-sync/issues/668) - Thanks for PR [#859](https://github.com/shanalikhan/code-settings-sync/pull/859) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) -* Remote Development Support Added [#870](https://github.com/shanalikhan/code-settings-sync/issues/870) - Thanks for PR [#871](https://github.com/shanalikhan/code-settings-sync/pull/871) by [@mjbvz](https://github.com/mjbvz) -* Pragma Util Support for `keybindings.json` Added [#800](https://github.com/shanalikhan/code-settings-sync/issues/800) - Thanks for PR [#854](https://github.com/shanalikhan/code-settings-sync/pull/854) by [@njkevlani](https://github.com/njkevlani) -* Support OS specific `keybindings.json` in single file [#515](https://github.com/shanalikhan/code-settings-sync/issues/515) - Thanks for PR [#854](https://github.com/shanalikhan/code-settings-sync/pull/854) by [@njkevlani](https://github.com/njkevlani) -* Improved Auto Upload Process [#839](https://github.com/shanalikhan/code-settings-sync/issues/839) - Thanks for PR [#909](https://github.com/shanalikhan/code-settings-sync/pull/909) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) -* Improved Pragma Util to ignore some values[#865](https://github.com/shanalikhan/code-settings-sync/issues/865) - Thanks for PR [#872](https://github.com/shanalikhan/code-settings-sync/pull/872) by [@ioprotium](https://github.com/ioprotium) -* Ignore auto-upload process for some settings [#754](https://github.com/shanalikhan/code-settings-sync/issues/754) - Thanks for PR [#872](https://github.com/shanalikhan/code-settings-sync/pull/872) by [@ioprotium](https://github.com/ioprotium) -* Language localization improved and more languages added. [#886](https://github.com/shanalikhan/code-settings-sync/issues/886) - Thanks for PR [#915](https://github.com/shanalikhan/code-settings-sync/pull/915) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) -* Improved Command line text [#891](https://github.com/shanalikhan/code-settings-sync/issues/891 ) - by [@nawordar](https://github.com/nawordar) -* Support For Azure Data Studio -* Node Modules Updated and code refactoring. - -#### v3.2.9 - April 18,2019 - -* Bug : Fixed Code that kills Extension Host for MacOS [#827](https://github.com/shanalikhan/code-settings-sync/issues/827) - Thanks for PR [#834](https://github.com/shanalikhan/code-settings-sync/pull/834) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) -* Bug : Download From Public Gist not working [#816](https://github.com/shanalikhan/code-settings-sync/issues/816) -* Bug : Auto Upload Fix [#832](https://github.com/shanalikhan/code-settings-sync/issues/832) - Thanks for PR [#835](https://github.com/shanalikhan/code-settings-sync/pull/835) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) -* Improvement - Inserts some empty lines in the beginning of `settings.json` [#819](https://github.com/shanalikhan/code-settings-sync/issues/819) - Thanks for PR [#828](https://github.com/shanalikhan/code-settings-sync/pull/828) by [@knyhle](https://github.com/knyhle) -* Wiki : Update Documentation - Thanks for PR [#828](https://github.com/shanalikhan/code-settings-sync/pull/845) by [@colinaaa](https://github.com/colinaaa) - -#### v3.2.8 - April 04,2019 - -* Bug : auto upload doesn't work when make change on settings [#801](https://github.com/shanalikhan/code-settings-sync/issues/801) - Thanks for PR [#807](https://github.com/shanalikhan/code-settings-sync/pull/807) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) -* Bug : Auto Upload / Download : Disable change detection for workspace storage folder [#708](https://github.com/shanalikhan/code-settings-sync/issues/708) - Thanks for PR [#811](https://github.com/shanalikhan/code-settings-sync/pull/811) by [@knyhle](https://github.com/knyhle) -* Pretiffy Custom Settings JSON - Thanks for PR [#812](https://github.com/shanalikhan/code-settings-sync/pull/812) by [@knyhle](https://github.com/knyhle) -* Improvement - Remove manual visx package installation in favour of extension download by CLI [#820](https://github.com/shanalikhan/code-settings-sync/issues/820) -* Improvement - Remove replaceCodeSettings from Settings Sync configurations [#805](https://github.com/shanalikhan/code-settings-sync/issues/805) - -#### v3.2.7 - March 06,2019 - -* Bug : Fixing Extensions Sync on Windows [#789](https://github.com/shanalikhan/code-settings-sync/issues/789) - Thanks for PR [#791](https://github.com/shanalikhan/code-settings-sync/pull/791) by [@LuisUrrutia](https://github.com/LuisUrrutia) - -#### v3.2.6 - March 05,2019 - -* Bug : Syncing of extensions not working in portable mode [#756](https://github.com/shanalikhan/code-settings-sync/issues/756) - Thanks for PR [#782](https://github.com/shanalikhan/code-settings-sync/pull/782) by [@LuisUrrutia](https://github.com/LuisUrrutia) -* Bug : Fixing NODE_TLS_REJECT_UNAUTHORIZED [#776](https://github.com/shanalikhan/code-settings-sync/issues/776) - Thanks for PR [#779](https://github.com/shanalikhan/code-settings-sync/pull/779) by [@MattMorgis](https://github.com/MattMorgis) -* Documentation Updated -* Packages Updated - -#### v3.2.5 - Feb 15,2019 - -* Bug : Not working with VSCode 1.31 [#762](https://github.com/shanalikhan/code-settings-sync/issues/762) - Thanks for PR [#763](https://github.com/shanalikhan/code-settings-sync/pull/763) by [@nekonenene](https://github.com/nekonenene) -* Bug : Multi-line settings aren't ignored properly using sync pragma [#701](https://github.com/shanalikhan/code-settings-sync/issues/701) - Thanks for PR [#750](https://github.com/shanalikhan/code-settings-sync/pull/750) by [@ioprotium](https://github.com/ioprotium) -* Packages updated, small improvements - -#### v3.2.3 - 11 Dec, 2018 - -* Startup : Long startup activation time on the first start [#656](https://github.com/shanalikhan/code-settings-sync/issues/656) - Thanks for PR [#717](https://github.com/shanalikhan/code-settings-sync/pull/717) by [@thejewdude](https://github.com/thejewdude) -* Feature : Adding coder.com support [#714](https://github.com/shanalikhan/code-settings-sync/issues/714) - Thanks for PR [#720](https://github.com/shanalikhan/code-settings-sync/pull/720) by [@deansheather](https://github.com/deansheather) - -#### v3.2.2 - 26 Nov, 2018 - -* Sync Advance Setting Menu doesnt open when JSON not Valid [#683](https://github.com/shanalikhan/code-settings-sync/issues/683) - -#### v3.2.1 - 23 Nov, 2018 - -* Bug : Only install missing extensions in Portable Vs Code [#687](https://github.com/shanalikhan/code-settings-sync/issues/687) -* Bug : Error: Cannot read property 'token' of undefined [#685](https://github.com/shanalikhan/code-settings-sync/issues/685) -* Bug : sync-ignore isn't ignoring my local value, it deletes it [#686](https://github.com/shanalikhan/code-settings-sync/issues/686) -* Bug : Download of extension packages failed [#642](https://github.com/shanalikhan/code-settings-sync/issues/642) - Thanks for PR [#705](https://github.com/shanalikhan/code-settings-sync/pull/705) by [@emptyother](https://github.com/emptyother) - - -#### v3.2.0 - 17 Oct, 2018 - -* Prompt to reload VSCode after installing extensions [#629](https://github.com/shanalikhan/code-settings-sync/issues/629) -* Keep output of CLI installation command [#628](https://github.com/shanalikhan/code-settings-sync/issues/628) -* Dont write default settings sync config to code settings.json [#513](https://github.com/shanalikhan/code-settings-sync/issues/513) -* vscodium download settings fails [#650](https://github.com/shanalikhan/code-settings-sync/issues/650) - Thanks for PR [#651](https://github.com/shanalikhan/code-settings-sync/pull/651) by [@stripedpajamas](https://github.com/stripedpajamas) -* Does not work with Portable Visual Studio Code [#331](https://github.com/shanalikhan/code-settings-sync/issues/331) -* Flatpak Support for Settings Sync [#621](https://github.com/shanalikhan/code-settings-sync/issues/621) - Thanks for PR [#657](https://github.com/shanalikhan/code-settings-sync/pull/657) by [@laloch](https://github.com/laloch) -* Per-platform / per-hostname inline settings [#640](https://github.com/shanalikhan/code-settings-sync/issues/640) - Thanks for PR [#667](https://github.com/shanalikhan/code-settings-sync/pull/667) by [@ioprotium](https://github.com/ioprotium) -* Idea/Suggestion: Adds support to sync custom files [#258](https://github.com/shanalikhan/code-settings-sync/issues/258) - Thanks for PR [#258](https://github.com/shanalikhan/code-settings-sync/pull/258) by [@tkrtmy](https://github.com/tkrtmy) - - -For Previous releases change log view the [post](http://shanalikhan.github.io/2016/05/14/Visual-studio-code-sync-settings-release-notes.html) - - -## [Contributions](https://github.com/shanalikhan/code-settings-sync/blob/master/CONTRIBUTING.md) - -### Financial - -[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=4W3EWHHBSYMM8&lc=IE&item_name=Code%20Settings%20Sync&item_number=visual%20studio%20code%20settings%20sync¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted) - -I also welcome financial contributions in case of special feature requests on my [open collective](https://opencollective.com/code-settings-sync). - -### Community - -You may join slack community and disscus the ideas over there. - - -Drawing - - -I'm looking for contributors to work with me so we can make the extension smoother and more feature rich. -Let me know if anyone is willing to [contribute](https://github.com/shanalikhan/code-settings-sync/blob/master/CONTRIBUTING.md). - +# ChangeLog : Settings Sync [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Synchronize%20your%20%40VisualStudio%20%40code%20Settings%20Across%20Multiple%20Machines%20using%20%40github%20GIST%20by%20%40itsShanKhan&url=https://github.com/shanalikhan/code-settings-sync&via=code&hashtags=code,vscode,SettingsSync,developers) [![Follow](https://img.shields.io/twitter/follow/itsShanKhan.svg?style=social&label=Follow)](https://twitter.com/intent/follow?screen_name=itsShanKhan) + +[![Version](https://vsmarketplacebadge.apphb.com/version/Shan.code-settings-sync.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) [![Travis](https://img.shields.io/travis/rust-lang/rust.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) [![Master course](https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20Course%20%E2%86%92-gray.svg?colorA=444444&colorB=4F44D6)](https://t.co/8BEMyhpKU5?amp=1) + +#### v3.4.3 - September 23,2019 + +* Share GitHub Gist ID message Fixed [#1033](https://github.com/shanalikhan/code-settings-sync/issues/1033) +* Consistency between GitHub Gist and Description across extension readme [#1023](https://github.com/shanalikhan/code-settings-sync/issues/1023) +* Snippets Sync. Fixed [#993](https://github.com/shanalikhan/code-settings-sync/issues/993) +* GitHub Api connection improved [#1027](https://github.com/shanalikhan/code-settings-sync/issues/1027) +* Extension always asks to enable Force Upload [#1016](https://github.com/shanalikhan/code-settings-sync/issues/1016) - Thanks for PR [#1026](https://github.com/shanalikhan/code-settings-sync/pull/1026) by [@karl-lunarg](https://github.com/karl-lunarg) +* UX Improved for the Force Upload [#1035](https://github.com/shanalikhan/code-settings-sync/issues/1035) - Thanks for PR [#1042](https://github.com/shanalikhan/code-settings-sync/pull/1042) by [@karl-lunarg](https://github.com/karl-lunarg) +* Webview does not set a content security policy [#1010](https://github.com/shanalikhan/code-settings-sync/issues/1010) - Thanks for PR [#1020](https://github.com/shanalikhan/code-settings-sync/pull/1020) by [@ParkourKarthik](https://github.com/ParkourKarthik) +* Icon Improved - Thanks for PR [#1022](https://github.com/shanalikhan/code-settings-sync/pull/1022) by [@Pustur](https://github.com/Pustur) +* Improved German Languauge Support - Thanks for PR [#1040](https://github.com/shanalikhan/code-settings-sync/pull/1040) by [@jan-di](https://github.com/jan-di) +* Improved Chinese Language Support - Thanks for PR [#1028](https://github.com/shanalikhan/code-settings-sync/pull/1028) by [@YunChaoTsai](https://github.com/YunChaoTsai) +* Readme Improved - Thanks for PR [#1031](https://github.com/shanalikhan/code-settings-sync/pull/1031) by [@faliure](https://github.com/faliure) +* Slack Link Updated +* Node Modules Updated + +#### v3.4.2 - August 21, 2019 + +* Multiple Lanugages Support Improved [#1009](https://github.com/shanalikhan/code-settings-sync/pull/1009) by [@ XanatosX](https://github.com/XanatosX ) , [#999](https://github.com/shanalikhan/code-settings-sync/pull/999) by [@o3LL](https://github.com/o3LL) , [#994](https://github.com/shanalikhan/code-settings-sync/pull/994) by [@mijien0179](https://github.com/mijien0179) , [#981](https://github.com/shanalikhan/code-settings-sync/pull/981) by [@ryul1206](https://github.com/ryul1206) +* Hide GitHub Token on Summary [#974](https://github.com/shanalikhan/code-settings-sync/issues/974) +* Only Show "Share Gist" Dialog when Public Gist is created [#977](https://github.com/shanalikhan/code-settings-sync/issues/977) +* Sync Pragma Improved [#1003](https://github.com/shanalikhan/code-settings-sync/issues/1003) - Thanks for PR [#1012](https://github.com/shanalikhan/code-settings-sync/pull/1012) by [@protium-dev](https://github.com/protium-dev) +* UI Bug Fix where users were unable to select GIST [#983](https://github.com/shanalikhan/code-settings-sync/issues/983) + +#### v3.4.1 - July 22, 2019 + +* Turn off notifications on code startup [#959](https://github.com/shanalikhan/code-settings-sync/issues/959) - Thanks for PR [#960](https://github.com/shanalikhan/code-settings-sync/pull/960) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) +* Chinese Translation Improved - Thanks for PR [#966](https://github.com/shanalikhan/code-settings-sync/pull/966) by [@linsui](https://github.com/linsui) and [#961](https://github.com/shanalikhan/code-settings-sync/pull/961) by [@ziofat](https://github.com/ziofat) +* Russian Translation Improved - Thanks for PR [#957](https://github.com/shanalikhan/code-settings-sync/pull/957) by [@AndreyWV](https://github.com/AndreyWV) + +#### v3.4.0 - July 15, 2019 + +* Settings Sync now use Webviews to allow you to configure settings [#506](https://github.com/shanalikhan/code-settings-sync/issues/506) - Thanks for PR [#876](https://github.com/shanalikhan/code-settings-sync/pull/876) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) +* code snippets not being synced after update to 3.3.0 [#927](https://github.com/shanalikhan/code-settings-sync/issues/927) - Thanks for PR [#928](https://github.com/shanalikhan/code-settings-sync/pull/928) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) +* Implement upload delay setting [#390](https://github.com/shanalikhan/code-settings-sync/issues/390) - Thanks for PR [#925](https://github.com/shanalikhan/code-settings-sync/pull/925) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) +* Dont Upload If GIST and settings content are the same. [#316](https://github.com/shanalikhan/code-settings-sync/issues/316) - Thanks for PR [#923](https://github.com/shanalikhan/code-settings-sync/pull/923) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) +* Prevent accidental upload [#350](https://github.com/shanalikhan/code-settings-sync/issues/350) - Thanks for PR [#923](https://github.com/shanalikhan/code-settings-sync/pull/923) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) + +#### v3.3.1 - June 25,2019 +* Small Improvements + +#### v3.3.0 - June 25,2019 + +* Code OSS Version Support Added [#668](https://github.com/shanalikhan/code-settings-sync/issues/668) - Thanks for PR [#859](https://github.com/shanalikhan/code-settings-sync/pull/859) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) +* Remote Development Support Added [#870](https://github.com/shanalikhan/code-settings-sync/issues/870) - Thanks for PR [#871](https://github.com/shanalikhan/code-settings-sync/pull/871) by [@mjbvz](https://github.com/mjbvz) +* Pragma Util Support for `keybindings.json` Added [#800](https://github.com/shanalikhan/code-settings-sync/issues/800) - Thanks for PR [#854](https://github.com/shanalikhan/code-settings-sync/pull/854) by [@njkevlani](https://github.com/njkevlani) +* Support OS specific `keybindings.json` in single file [#515](https://github.com/shanalikhan/code-settings-sync/issues/515) - Thanks for PR [#854](https://github.com/shanalikhan/code-settings-sync/pull/854) by [@njkevlani](https://github.com/njkevlani) +* Improved Auto Upload Process [#839](https://github.com/shanalikhan/code-settings-sync/issues/839) - Thanks for PR [#909](https://github.com/shanalikhan/code-settings-sync/pull/909) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) +* Improved Pragma Util to ignore some values[#865](https://github.com/shanalikhan/code-settings-sync/issues/865) - Thanks for PR [#872](https://github.com/shanalikhan/code-settings-sync/pull/872) by [@ioprotium](https://github.com/ioprotium) +* Ignore auto-upload process for some settings [#754](https://github.com/shanalikhan/code-settings-sync/issues/754) - Thanks for PR [#872](https://github.com/shanalikhan/code-settings-sync/pull/872) by [@ioprotium](https://github.com/ioprotium) +* Language localization improved and more languages added. [#886](https://github.com/shanalikhan/code-settings-sync/issues/886) - Thanks for PR [#915](https://github.com/shanalikhan/code-settings-sync/pull/915) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) +* Improved Command line text [#891](https://github.com/shanalikhan/code-settings-sync/issues/891 ) - by [@nawordar](https://github.com/nawordar) +* Support For Azure Data Studio +* Node Modules Updated and code refactoring. + +#### v3.2.9 - April 18,2019 + +* Bug : Fixed Code that kills Extension Host for MacOS [#827](https://github.com/shanalikhan/code-settings-sync/issues/827) - Thanks for PR [#834](https://github.com/shanalikhan/code-settings-sync/pull/834) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) +* Bug : Download From Public Gist not working [#816](https://github.com/shanalikhan/code-settings-sync/issues/816) +* Bug : Auto Upload Fix [#832](https://github.com/shanalikhan/code-settings-sync/issues/832) - Thanks for PR [#835](https://github.com/shanalikhan/code-settings-sync/pull/835) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) +* Improvement - Inserts some empty lines in the beginning of `settings.json` [#819](https://github.com/shanalikhan/code-settings-sync/issues/819) - Thanks for PR [#828](https://github.com/shanalikhan/code-settings-sync/pull/828) by [@knyhle](https://github.com/knyhle) +* Wiki : Update Documentation - Thanks for PR [#828](https://github.com/shanalikhan/code-settings-sync/pull/845) by [@colinaaa](https://github.com/colinaaa) + +#### v3.2.8 - April 04,2019 + +* Bug : auto upload doesn't work when make change on settings [#801](https://github.com/shanalikhan/code-settings-sync/issues/801) - Thanks for PR [#807](https://github.com/shanalikhan/code-settings-sync/pull/807) by [@arnohovhannisyan](https://github.com/arnohovhannisyan) +* Bug : Auto Upload / Download : Disable change detection for workspace storage folder [#708](https://github.com/shanalikhan/code-settings-sync/issues/708) - Thanks for PR [#811](https://github.com/shanalikhan/code-settings-sync/pull/811) by [@knyhle](https://github.com/knyhle) +* Pretiffy Custom Settings JSON - Thanks for PR [#812](https://github.com/shanalikhan/code-settings-sync/pull/812) by [@knyhle](https://github.com/knyhle) +* Improvement - Remove manual visx package installation in favour of extension download by CLI [#820](https://github.com/shanalikhan/code-settings-sync/issues/820) +* Improvement - Remove replaceCodeSettings from Settings Sync configurations [#805](https://github.com/shanalikhan/code-settings-sync/issues/805) + +#### v3.2.7 - March 06,2019 + +* Bug : Fixing Extensions Sync on Windows [#789](https://github.com/shanalikhan/code-settings-sync/issues/789) - Thanks for PR [#791](https://github.com/shanalikhan/code-settings-sync/pull/791) by [@LuisUrrutia](https://github.com/LuisUrrutia) + +#### v3.2.6 - March 05,2019 + +* Bug : Syncing of extensions not working in portable mode [#756](https://github.com/shanalikhan/code-settings-sync/issues/756) - Thanks for PR [#782](https://github.com/shanalikhan/code-settings-sync/pull/782) by [@LuisUrrutia](https://github.com/LuisUrrutia) +* Bug : Fixing NODE_TLS_REJECT_UNAUTHORIZED [#776](https://github.com/shanalikhan/code-settings-sync/issues/776) - Thanks for PR [#779](https://github.com/shanalikhan/code-settings-sync/pull/779) by [@MattMorgis](https://github.com/MattMorgis) +* Documentation Updated +* Packages Updated + +#### v3.2.5 - Feb 15,2019 + +* Bug : Not working with VSCode 1.31 [#762](https://github.com/shanalikhan/code-settings-sync/issues/762) - Thanks for PR [#763](https://github.com/shanalikhan/code-settings-sync/pull/763) by [@nekonenene](https://github.com/nekonenene) +* Bug : Multi-line settings aren't ignored properly using sync pragma [#701](https://github.com/shanalikhan/code-settings-sync/issues/701) - Thanks for PR [#750](https://github.com/shanalikhan/code-settings-sync/pull/750) by [@ioprotium](https://github.com/ioprotium) +* Packages updated, small improvements + +#### v3.2.3 - 11 Dec, 2018 + +* Startup : Long startup activation time on the first start [#656](https://github.com/shanalikhan/code-settings-sync/issues/656) - Thanks for PR [#717](https://github.com/shanalikhan/code-settings-sync/pull/717) by [@thejewdude](https://github.com/thejewdude) +* Feature : Adding coder.com support [#714](https://github.com/shanalikhan/code-settings-sync/issues/714) - Thanks for PR [#720](https://github.com/shanalikhan/code-settings-sync/pull/720) by [@deansheather](https://github.com/deansheather) + +#### v3.2.2 - 26 Nov, 2018 + +* Sync Advance Setting Menu doesnt open when JSON not Valid [#683](https://github.com/shanalikhan/code-settings-sync/issues/683) + +#### v3.2.1 - 23 Nov, 2018 + +* Bug : Only install missing extensions in Portable Vs Code [#687](https://github.com/shanalikhan/code-settings-sync/issues/687) +* Bug : Error: Cannot read property 'token' of undefined [#685](https://github.com/shanalikhan/code-settings-sync/issues/685) +* Bug : sync-ignore isn't ignoring my local value, it deletes it [#686](https://github.com/shanalikhan/code-settings-sync/issues/686) +* Bug : Download of extension packages failed [#642](https://github.com/shanalikhan/code-settings-sync/issues/642) - Thanks for PR [#705](https://github.com/shanalikhan/code-settings-sync/pull/705) by [@emptyother](https://github.com/emptyother) + + +#### v3.2.0 - 17 Oct, 2018 + +* Prompt to reload VSCode after installing extensions [#629](https://github.com/shanalikhan/code-settings-sync/issues/629) +* Keep output of CLI installation command [#628](https://github.com/shanalikhan/code-settings-sync/issues/628) +* Dont write default settings sync config to code settings.json [#513](https://github.com/shanalikhan/code-settings-sync/issues/513) +* vscodium download settings fails [#650](https://github.com/shanalikhan/code-settings-sync/issues/650) - Thanks for PR [#651](https://github.com/shanalikhan/code-settings-sync/pull/651) by [@stripedpajamas](https://github.com/stripedpajamas) +* Does not work with Portable Visual Studio Code [#331](https://github.com/shanalikhan/code-settings-sync/issues/331) +* Flatpak Support for Settings Sync [#621](https://github.com/shanalikhan/code-settings-sync/issues/621) - Thanks for PR [#657](https://github.com/shanalikhan/code-settings-sync/pull/657) by [@laloch](https://github.com/laloch) +* Per-platform / per-hostname inline settings [#640](https://github.com/shanalikhan/code-settings-sync/issues/640) - Thanks for PR [#667](https://github.com/shanalikhan/code-settings-sync/pull/667) by [@ioprotium](https://github.com/ioprotium) +* Idea/Suggestion: Adds support to sync custom files [#258](https://github.com/shanalikhan/code-settings-sync/issues/258) - Thanks for PR [#258](https://github.com/shanalikhan/code-settings-sync/pull/258) by [@tkrtmy](https://github.com/tkrtmy) + + +For Previous releases change log view the [post](http://shanalikhan.github.io/2016/05/14/Visual-studio-code-sync-settings-release-notes.html) + + +## [Contributions](https://github.com/shanalikhan/code-settings-sync/blob/master/CONTRIBUTING.md) + +### Financial + +[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=4W3EWHHBSYMM8&lc=IE&item_name=Code%20Settings%20Sync&item_number=visual%20studio%20code%20settings%20sync¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted) + +I also welcome financial contributions in case of special feature requests on my [open collective](https://opencollective.com/code-settings-sync). + +### Community + +You may join slack community and disscus the ideas over there. + + +Drawing + + +I'm looking for contributors to work with me so we can make the extension smoother and more feature rich. +Let me know if anyone is willing to [contribute](https://github.com/shanalikhan/code-settings-sync/blob/master/CONTRIBUTING.md). + diff --git a/README.md b/README.md index 91387a1d..e7b6f28d 100644 --- a/README.md +++ b/README.md @@ -1,316 +1,316 @@ -# Settings Sync [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Synchronize%20your%20%40VisualStudio%20%40code%20Settings%20Across%20Multiple%20Machines%20using%20%40github%20GIST%20by%20%40itsShanKhan&url=https://github.com/shanalikhan/code-settings-sync&via=code&hashtags=code,vscode,SettingsSync,developers) [![Follow](https://img.shields.io/twitter/follow/itsShanKhan.svg?style=social&label=Follow)](https://twitter.com/intent/follow?screen_name=itsShanKhan) - -**Previously known as Visual Studio Code Settings Sync** - -[![Version](https://vsmarketplacebadge.apphb.com/version/Shan.code-settings-sync.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) [![Travis](https://img.shields.io/travis/rust-lang/rust.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) -[![Greenkeeper badge](https://badges.greenkeeper.io/shanalikhan/code-settings-sync.svg)](https://greenkeeper.io/) -[![Master course](https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20Course%20%E2%86%92-gray.svg?colorA=444444&colorB=4F44D6)](https://t.co/8BEMyhpKU5?amp=1) - -## Support - -While being free and open source, if you find it useful, please consider supporting it by donating via PayPal or Open Collective. If you are using it in office as a team, please ask your company to support us via Open Collective from just 2\$ per month! - - - - - - -
- - - -
-
- - - -
- *2$ Per Month -
-
- -Drawing - -
-
- -**Type Sync in command Palette in order to view all commands.** - -## Key Features - -``` -1. Use your GitHub account token and Gist. -2. Easy to Upload and Download on one click. -3. Show a summary page at the end with details about config and extensions effected. -4. Auto download Latest Settings on Startup. -5. Auto upload Settings on file change. -6. Share the Gist with other users and let them download your settings. -7. Supports GitHub Enterprise -8. Support pragmas with @sync keywords: host, os and env are supported. -9. GUI for changing settings / logging in -10. Allows you to Sync any file across your machines. -``` - -## It Syncs - -``` -All extensions and complete User Folder that Contains -1. Settings File -2. Keybinding File -3. Launch File -4. Snippets Folder -5. VSCode Extensions & Extensions Configurations -6. Workspaces Folder -``` - -## Shortcuts - -``` -1. Upload Key : Shift + Alt + U -2. Download Key : Shift + Alt + D - -(on macOS: Shift + Option + U / Shift + Option + D) -``` - -## Configure Settings Sync - - -Settings Sync Configuration page will be opened automatically on code start and requires two things to setup: - -1. GitHub Token -2. GitHub Gist Id - -GitHub Token needs to be retrived by your GitHub account while Settings Sync creates GIST if you are first time user. - -Following are the steps you need to perform to configure. - -- Click on `Login with GitHub` . -- Login GitHub on Browser and close the browser tab once you get Success message. -- If you are using Settings Sync first time GIST will be created automatically when you upload your settings. -- If you already have GitHub Gist, new window will be opened to allow you to select the GitHub Gist or `Skip` to create new Gist. - - - -![Login with GitHub](https://shanalikhan.github.io/img/login-with-github.png) - - -![Existing Gist](https://shanalikhan.github.io/img/existing-gist.png) - - -You can always **verify created gist** by going to `https://gist.github.com` and checking for a gist named `cloudSettings` - - -## Upload Your Settings - -**Press Shift + Alt + U** (macOS: Shift + Option + U) - -> Type ">Sync" In Command Palette into order download / upload - -When downloading or uploading for the first time, the welcome page will automatically open, where you can configure the Settings Sync. - -Once you select upload, after uploading the settings. You will see the Summary details with the list of each files and extensions uploaded. - -## Download your Settings - -**Press Shift + Alt + D** (macOS: Shift + Option + D) - -> Type ">Sync" In Command Palette into order download / upload - -When downloading or uploading for the first time, the welcome page will automatically open, where you can configure the Settings Sync. - -Once you select download, after downloading. Settings Sync will display you Summary containing the list of each files and extension being downloaded. - -New popup will be opened to allow you to restart the code to apply the settings. - -## Reset Extension Settings - -> Select **"> Sync : Reset Extension Settings"** in the Command Palette to reset your settings - - -## Settings - -Settings can be changed through the settings page, which can be accessed through **"> Sync : Advanced Options > Open Settings Page"** - -There are two types of settings in Settings Sync. -I will recommend you to read the configurations details [here](https://dev.to/shanalikhan/visual-studio-code-settings-sync-configurations-mn0). - - -### Gist Settings - -Gist Settings are stored in `settings.json` file of Code. -You can customize the settings in gist settings like: - -``` -1. Configure Gist Id (Environment) -2. Configure auto upload / download for GitHub Gist -3. Configure extension sync behaviour -4. Configure force download -4. Configure force upload -6. Configure quiet sync -``` - -```json - "sync.gist": "0c929b1a6c51015cdc9e0fe2e369ea4c", - "sync.autoDownload": false, - "sync.autoUpload": false, - "sync.forceDownload": false, - "sync.forceUpload": false, - "sync.quietSync": false, - "sync.removeExtensions": true, - "sync.syncExtensions": true -``` - -### Global Settings - -Global settings are present in `syncLocalSettings.json` inside `User` folder. These settings will be shared across multiple Gist Environments. - - -You can customize the sync: - -``` -1. Options by which files / folders and settings to exclude from upload. -2. Configure default Gist Environment name. -3. Replace the code settings after downloading. -4. Change the Gist description while creating new one in github. -5. Configure GitHub Enterprise Url -``` - -```json -{ - "ignoreUploadFiles": [ - "state.*", - "syncLocalSettings.json", - ".DS_Store", - "sync.lock", - "projects.json", - "projects_cache_vscode.json", - "projects_cache_git.json", - "projects_cache_svn.json", - "gpm_projects.json", - "gpm-recentItems.json" - ], - "ignoreUploadFolders": [ - "workspaceStorage" - ], - "ignoreExtensions": [], - "gistDescription": "Visual Studio Code Settings Sync Gist", - "version": 340, - "token": "YOUR_GITHUB_TOKEN", - "downloadPublicGist": false, - "supportedFileExtensions": [ "json", "code-snippets" ], - "openTokenLink": true, - "disableUpdateMessage": false, - "lastUpload": null, - "lastDownload": null, - "githubEnterpriseUrl": null, - "askGistDescription": false, - "customFiles": {}, - "hostName": null, - "universalKeybindings": false, - "autoUploadDelay": 20 -} -``` - -I will recommend you to read the configurations details [here](https://dev.to/shanalikhan/visual-studio-code-settings-sync-configurations-mn0). - - -## Features - -### Toggle Auto-Upload on change - -Auto-upload is **disabled by default**. When the settings are changed and saved this feature will automatically start the upload process and save the settings online. - -Please make sure you have valid github Token and Gist available to make it work properly. - -Select Command **"Sync : Advanced Options > Toggle Auto-Upload on Settings Change"** command to Turn ON / OFF the auto-upload. - -### Toggle Auto Download - -Auto Download is **disabled by default**. It will sync all the setting by default when the editor starts. -Please make sure you have valid github Token and Gist available to make it work properly. - -Select Command **"Sync : Advanced Options > Toggle Auto-Download On Startup"** command to Turn ON / OFF the auto download. - -### Toggle Force Download - -Force Download is **disabled by default**. By default, extension won't download the latest settings if you already have the latest downloaded version, but sometimes when you delete some extension locally and don't upload the settings it will still show that you have latest versions by date or time checks, by turning this ON it will always download the cloud settings on startup. - -Please make sure you have valid github Token and Gist available to make it work properly. - -Select Command **"Sync : Advanced Options > Toggle Force Download"** command to Turn ON / OFF the force download. - -### Toggle Force Upload - -Force Upload is **disabled by default**. By default, extension won't upload the settings if the gist has newer or identical content. By turning this ON it will always upload without checking for newer settings in the gist. - -Please make sure you have valid github Token and Gist available to make it work properly. - -Select Command **"Sync : Advanced Options > Toggle Force Upload"** command to Turn ON / OFF the force upload. - -### Toggle Summary - -Summary is **enabled by default** which shows all files and extensions that are added or deleted on a single page. -You may turn it off in order to make a upload and download process clean and quiet. - -Select Command **"Sync : Advanced Options > Show Summary Page On Upload / Download"** command to Turn ON / OFF the auto download. - - -### Custom Sync - -Settings Sync allows you to sync the files other from `User` folder. For example, your workspace settings and much more. Its upon you to utilize the full potential of Settings Sync across your machines or your teams machines. Read about custom sync [here](https://github.com/shanalikhan/code-settings-sync/wiki/Custom-Sync). - -### Sync Pragmas - -You can even manage which settings you want to ignore from being upload or download. Settings Sync even allows you to manage your `home` and `office` computer specific settings even OS related settings in single GitHub Gist. Read details about [Sync Pragmas here](https://github.com/shanalikhan/code-settings-sync/wiki/Sync-Pragmas). - -### Share Settings Across Teams & Users - -If you are looking to share your settings. Read the details [here](https://dev.to/shanalikhan/how-to-share-your-visual-studio-code-settings-and-extensions-39k). Settings Sync needs to create new Public GitHub Gist to share your settings with other users. - -### Troubleshooting - -If you ever get into problem while setting up the Settings Sync. You can check our troubleshooting guide that cover those scenarios [here](https://github.com/shanalikhan/code-settings-sync/wiki/Troubleshooting), you can also add your solution there if its not available there to help other users. - -## How To Contribute - -You can contribute in different ways. Read the details [here](https://github.com/shanalikhan/code-settings-sync/blob/master/CONTRIBUTING.md) - -**Fix and Earn** - You can also earn money by fixing the issues - Check the issues under bounty program [here](https://github.com/shanalikhan/code-settings-sync/labels/bounty). - -## Credits - -### Contributors - -Thank you to all the people who have already contributed to Settings Sync! - - -### Backers - -Thank you to all our backers! [[Become a backer](https://opencollective.com/code-settings-sync#backer)] - - -[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=4W3EWHHBSYMM8&lc=IE&item_name=Code%20Settings%20Sync&item_number=visual%20studio%20code%20settings%20sync¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted) - -### Sponsors - -Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/code-settings-sync)) - -## [Contributors](https://github.com/shanalikhan/code-settings-sync/graphs/contributors) - -# [Release Notes](https://shanalikhan.github.io/2016/05/14/Visual-studio-code-sync-settings-release-notes.html) - -# License - -[![Version](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/shanalikhan/code-settings-sync/blob/master/LICENSE) - -[![Version](https://vsmarketplacebadge.apphb.com/version/Shan.code-settings-sync.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) - -[![Installs](https://vsmarketplacebadge.apphb.com/installs/Shan.code-settings-sync.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) - -[![Ratings](https://vsmarketplacebadge.apphb.com/rating/Shan.code-settings-sync.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) - -[![Master course](https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20Course%20%E2%86%92-gray.svg?colorA=444444&colorB=4F44D6)](https://t.co/8BEMyhpKU5?amp=1) - - -Drawing - +# Settings Sync [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Synchronize%20your%20%40VisualStudio%20%40code%20Settings%20Across%20Multiple%20Machines%20using%20%40github%20GIST%20by%20%40itsShanKhan&url=https://github.com/shanalikhan/code-settings-sync&via=code&hashtags=code,vscode,SettingsSync,developers) [![Follow](https://img.shields.io/twitter/follow/itsShanKhan.svg?style=social&label=Follow)](https://twitter.com/intent/follow?screen_name=itsShanKhan) + +**Previously known as Visual Studio Code Settings Sync** + +[![Version](https://vsmarketplacebadge.apphb.com/version/Shan.code-settings-sync.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) [![Travis](https://img.shields.io/travis/rust-lang/rust.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) +[![Greenkeeper badge](https://badges.greenkeeper.io/shanalikhan/code-settings-sync.svg)](https://greenkeeper.io/) +[![Master course](https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20Course%20%E2%86%92-gray.svg?colorA=444444&colorB=4F44D6)](https://t.co/8BEMyhpKU5?amp=1) + +## Support + +While being free and open source, if you find it useful, please consider supporting it by donating via PayPal or Open Collective. If you are using it in office as a team, please ask your company to support us via Open Collective from just 2\$ per month! + + + + + + +
+ + + +
+
+ + + +
+ *2$ Per Month +
+
+ +Drawing + +
+
+ +**Type Sync in command Palette in order to view all commands.** + +## Key Features + +``` +1. Use your GitHub account token and Gist. +2. Easy to Upload and Download on one click. +3. Show a summary page at the end with details about config and extensions effected. +4. Auto download Latest Settings on Startup. +5. Auto upload Settings on file change. +6. Share the Gist with other users and let them download your settings. +7. Supports GitHub Enterprise +8. Support pragmas with @sync keywords: host, os and env are supported. +9. GUI for changing settings / logging in +10. Allows you to Sync any file across your machines. +``` + +## It Syncs + +``` +All extensions and complete User Folder that Contains +1. Settings File +2. Keybinding File +3. Launch File +4. Snippets Folder +5. VSCode Extensions & Extensions Configurations +6. Workspaces Folder +``` + +## Shortcuts + +``` +1. Upload Key : Shift + Alt + U +2. Download Key : Shift + Alt + D + +(on macOS: Shift + Option + U / Shift + Option + D) +``` + +## Configure Settings Sync + + +Settings Sync Configuration page will be opened automatically on code start and requires two things to setup: + +1. GitHub Token +2. GitHub Gist Id + +GitHub Token needs to be retrived by your GitHub account while Settings Sync creates GIST if you are first time user. + +Following are the steps you need to perform to configure. + +- Click on `Login with GitHub` . +- Login GitHub on Browser and close the browser tab once you get Success message. +- If you are using Settings Sync first time GIST will be created automatically when you upload your settings. +- If you already have GitHub Gist, new window will be opened to allow you to select the GitHub Gist or `Skip` to create new Gist. + + + +![Login with GitHub](https://shanalikhan.github.io/img/login-with-github.png) + + +![Existing Gist](https://shanalikhan.github.io/img/existing-gist.png) + + +You can always **verify created gist** by going to `https://gist.github.com` and checking for a gist named `cloudSettings` + + +## Upload Your Settings + +**Press Shift + Alt + U** (macOS: Shift + Option + U) + +> Type ">Sync" In Command Palette into order download / upload + +When downloading or uploading for the first time, the welcome page will automatically open, where you can configure the Settings Sync. + +Once you select upload, after uploading the settings. You will see the Summary details with the list of each files and extensions uploaded. + +## Download your Settings + +**Press Shift + Alt + D** (macOS: Shift + Option + D) + +> Type ">Sync" In Command Palette into order download / upload + +When downloading or uploading for the first time, the welcome page will automatically open, where you can configure the Settings Sync. + +Once you select download, after downloading. Settings Sync will display you Summary containing the list of each files and extension being downloaded. + +New popup will be opened to allow you to restart the code to apply the settings. + +## Reset Extension Settings + +> Select **"> Sync : Reset Extension Settings"** in the Command Palette to reset your settings + + +## Settings + +Settings can be changed through the settings page, which can be accessed through **"> Sync : Advanced Options > Open Settings Page"** + +There are two types of settings in Settings Sync. +I will recommend you to read the configurations details [here](https://dev.to/shanalikhan/visual-studio-code-settings-sync-configurations-mn0). + + +### Gist Settings + +Gist Settings are stored in `settings.json` file of Code. +You can customize the settings in gist settings like: + +``` +1. Configure Gist Id (Environment) +2. Configure auto upload / download for GitHub Gist +3. Configure extension sync behaviour +4. Configure force download +4. Configure force upload +6. Configure quiet sync +``` + +```json + "sync.gist": "0c929b1a6c51015cdc9e0fe2e369ea4c", + "sync.autoDownload": false, + "sync.autoUpload": false, + "sync.forceDownload": false, + "sync.forceUpload": false, + "sync.quietSync": false, + "sync.removeExtensions": true, + "sync.syncExtensions": true +``` + +### Global Settings + +Global settings are present in `syncLocalSettings.json` inside `User` folder. These settings will be shared across multiple Gist Environments. + + +You can customize the sync: + +``` +1. Options by which files / folders and settings to exclude from upload. +2. Configure default Gist Environment name. +3. Replace the code settings after downloading. +4. Change the Gist description while creating new one in github. +5. Configure GitHub Enterprise Url +``` + +```json +{ + "ignoreUploadFiles": [ + "state.*", + "syncLocalSettings.json", + ".DS_Store", + "sync.lock", + "projects.json", + "projects_cache_vscode.json", + "projects_cache_git.json", + "projects_cache_svn.json", + "gpm_projects.json", + "gpm-recentItems.json" + ], + "ignoreUploadFolders": [ + "workspaceStorage" + ], + "ignoreExtensions": [], + "gistDescription": "Visual Studio Code Settings Sync Gist", + "version": 340, + "token": "YOUR_GITHUB_TOKEN", + "downloadPublicGist": false, + "supportedFileExtensions": [ "json", "code-snippets" ], + "openTokenLink": true, + "disableUpdateMessage": false, + "lastUpload": null, + "lastDownload": null, + "githubEnterpriseUrl": null, + "askGistDescription": false, + "customFiles": {}, + "hostName": null, + "universalKeybindings": false, + "autoUploadDelay": 20 +} +``` + +I will recommend you to read the configurations details [here](https://dev.to/shanalikhan/visual-studio-code-settings-sync-configurations-mn0). + + +## Features + +### Toggle Auto-Upload on change + +Auto-upload is **disabled by default**. When the settings are changed and saved this feature will automatically start the upload process and save the settings online. + +Please make sure you have valid github Token and Gist available to make it work properly. + +Select Command **"Sync : Advanced Options > Toggle Auto-Upload on Settings Change"** command to Turn ON / OFF the auto-upload. + +### Toggle Auto Download + +Auto Download is **disabled by default**. It will sync all the setting by default when the editor starts. +Please make sure you have valid github Token and Gist available to make it work properly. + +Select Command **"Sync : Advanced Options > Toggle Auto-Download On Startup"** command to Turn ON / OFF the auto download. + +### Toggle Force Download + +Force Download is **disabled by default**. By default, extension won't download the latest settings if you already have the latest downloaded version, but sometimes when you delete some extension locally and don't upload the settings it will still show that you have latest versions by date or time checks, by turning this ON it will always download the cloud settings on startup. + +Please make sure you have valid github Token and Gist available to make it work properly. + +Select Command **"Sync : Advanced Options > Toggle Force Download"** command to Turn ON / OFF the force download. + +### Toggle Force Upload + +Force Upload is **disabled by default**. By default, extension won't upload the settings if the gist has newer or identical content. By turning this ON it will always upload without checking for newer settings in the gist. + +Please make sure you have valid github Token and Gist available to make it work properly. + +Select Command **"Sync : Advanced Options > Toggle Force Upload"** command to Turn ON / OFF the force upload. + +### Toggle Summary + +Summary is **enabled by default** which shows all files and extensions that are added or deleted on a single page. +You may turn it off in order to make a upload and download process clean and quiet. + +Select Command **"Sync : Advanced Options > Show Summary Page On Upload / Download"** command to Turn ON / OFF the auto download. + + +### Custom Sync + +Settings Sync allows you to sync the files other from `User` folder. For example, your workspace settings and much more. Its upon you to utilize the full potential of Settings Sync across your machines or your teams machines. Read about custom sync [here](https://github.com/shanalikhan/code-settings-sync/wiki/Custom-Sync). + +### Sync Pragmas + +You can even manage which settings you want to ignore from being upload or download. Settings Sync even allows you to manage your `home` and `office` computer specific settings even OS related settings in single GitHub Gist. Read details about [Sync Pragmas here](https://github.com/shanalikhan/code-settings-sync/wiki/Sync-Pragmas). + +### Share Settings Across Teams & Users + +If you are looking to share your settings. Read the details [here](https://dev.to/shanalikhan/how-to-share-your-visual-studio-code-settings-and-extensions-39k). Settings Sync needs to create new Public GitHub Gist to share your settings with other users. + +### Troubleshooting + +If you ever get into problem while setting up the Settings Sync. You can check our troubleshooting guide that cover those scenarios [here](https://github.com/shanalikhan/code-settings-sync/wiki/Troubleshooting), you can also add your solution there if its not available there to help other users. + +## How To Contribute + +You can contribute in different ways. Read the details [here](https://github.com/shanalikhan/code-settings-sync/blob/master/CONTRIBUTING.md) + +**Fix and Earn** - You can also earn money by fixing the issues - Check the issues under bounty program [here](https://github.com/shanalikhan/code-settings-sync/labels/bounty). + +## Credits + +### Contributors + +Thank you to all the people who have already contributed to Settings Sync! + + +### Backers + +Thank you to all our backers! [[Become a backer](https://opencollective.com/code-settings-sync#backer)] + + +[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=4W3EWHHBSYMM8&lc=IE&item_name=Code%20Settings%20Sync&item_number=visual%20studio%20code%20settings%20sync¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted) + +### Sponsors + +Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/code-settings-sync)) + +## [Contributors](https://github.com/shanalikhan/code-settings-sync/graphs/contributors) + +# [Release Notes](https://shanalikhan.github.io/2016/05/14/Visual-studio-code-sync-settings-release-notes.html) + +# License + +[![Version](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/shanalikhan/code-settings-sync/blob/master/LICENSE) + +[![Version](https://vsmarketplacebadge.apphb.com/version/Shan.code-settings-sync.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) + +[![Installs](https://vsmarketplacebadge.apphb.com/installs/Shan.code-settings-sync.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) + +[![Ratings](https://vsmarketplacebadge.apphb.com/rating/Shan.code-settings-sync.svg)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) + +[![Master course](https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20Course%20%E2%86%92-gray.svg?colorA=444444&colorB=4F44D6)](https://t.co/8BEMyhpKU5?amp=1) + + +Drawing + diff --git a/code-settings-sync.code-workspace b/code-settings-sync.code-workspace new file mode 100644 index 00000000..876a1499 --- /dev/null +++ b/code-settings-sync.code-workspace @@ -0,0 +1,8 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": {} +} \ No newline at end of file diff --git a/configs/webpack.development.config.js b/configs/webpack.development.config.js index 5b97ec30..9397bffd 100644 --- a/configs/webpack.development.config.js +++ b/configs/webpack.development.config.js @@ -1,9 +1,9 @@ "use strict"; -const merge = require('webpack-merge'); -const common = require('./webpack.config.js'); +const { merge } = require("webpack-merge"); +const common = require("./webpack.config.js"); module.exports = merge(common, { - mode: 'development', - devtool: 'source-map' -}); \ No newline at end of file + mode: "development", + devtool: "source-map", +}); diff --git a/debug.log b/debug.log deleted file mode 100644 index e3552b9b..00000000 --- a/debug.log +++ /dev/null @@ -1 +0,0 @@ -[1214/215632:ERROR:stream_listen_socket.cc(143)] send failed: WSAGetLastError()==0 diff --git a/package.json b/package.json index 6c870bc5..10a0f996 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "theme": "dark" }, "engines": { - "vscode": "^1.35.1" + "vscode": "^1.95.0" }, "badges": [ { @@ -153,37 +153,38 @@ "test": "npm run tslint-check && tsc -p ./ && mocha --recursive \"./out/test/**/*.js\"" }, "devDependencies": { - "@types/chai": "4.2.1", - "@types/express": "^4.16.1", + "@types/chai": "^5.0.1", + "@types/express": "^5.0.0", + "@types/fs-extra": "^11.0.4", "@types/lodash": "^4.14.123", - "@types/node-fetch": "^2.3.3", - "@types/fs-extra": "^8.0.0", - "@types/mocha": "^5.2.6", - "@types/node": "^12.0.9", - "@types/recursive-readdir": "^2.2.0", - "chai": "^4.2.0", - "clean-webpack-plugin": "^3.0.0", - "mocha": "^6.0.2", - "prettier": "^1.16.4", - "ts-loader": "^5.3.3", - "tslint": "^5.15.0", - "tslint-plugin-prettier": "^2.0.1", - "typescript": "^3.4.1", - "vscode": "^1.1.33", - "webpack": "^4.29.6", - "webpack-cli": "^3.3.0", - "webpack-merge": "^4.2.1" + "@types/mocha": "^10.0.10", + "@types/node": "^20.10.0", + "@types/node-fetch": "^2.6.12", + "@types/recursive-readdir": "^2.2.4", + "@types/vscode": "^1.95.0", + "@typescript-eslint/eslint-plugin": "^8.10.0", + "@typescript-eslint/parser": "^8.7.0", + "chai": "^5.1.2", + "clean-webpack-plugin": "^4.0.0", + "eslint": "^9.13.0", + "mocha": "^11.0.1", + "prettier": "^3.4.2", + "ts-loader": "^9.5.1", + "typescript": "^5.7.2", + "webpack": "^5.97.1", + "webpack-cli": "^5.1.4", + "webpack-merge": "^6.0.1" }, "dependencies": { - "@octokit/rest": "^16.23.2", - "adm-zip": "^0.4.13", + "@octokit/rest": "^21.0.2", + "adm-zip": "^0.5.16", "const": "^1.0.0", - "express": "^4.16.4", - "fs-extra": "^8.0.1", - "https-proxy-agent": "^2.2.1", + "express": "^4.21.2", + "fs-extra": "^11.2.0", + "https-proxy-agent": "^7.0.5", "lockfile": "^1.0.4", "lodash": "^4.17.15", - "node-fetch": "^2.5.0", + "node-fetch": "^3.3.2", "recursive-readdir": "^2.2.2", "temp": "^0.9.0", "vscode-chokidar": "^2.1.6" diff --git a/release-notes.json b/release-notes.json index 1c3b7536..2cff592d 100644 --- a/release-notes.json +++ b/release-notes.json @@ -1,52 +1,52 @@ -{ - "changes": [ - { - "details": "Add content security policy for webviews", - "type": "NEW", - "color": "success", - "author": "ParkourKarthik", - "pullRequest": "1020" - }, - { - "details": "Improve UX for the Force Upload", - "type": "NEW", - "color": "success", - "author": "karl-lunarg", - "pullRequest": "1042" - }, - { - "details": "Extension always asks to enable Force Upload", - "type": "FIX", - "color": "danger", - "author": "karl-lunarg", - "pullRequest": "1026" - }, - { - "details": "Languages, Icon and Wiki Improved", - "type": "NEW", - "color": "success" - }, - { - "details": "Github Gist Name Consistency across extension", - "type": "FIX", - "color": "danger" - }, - { - "details": "Snippets Sync. Fixed", - "type": "FIX", - "color": "danger" - }, - { - "details": "Share Settings Dialog Fixed", - "type": "FIX", - "color": "danger" - }, - { - "details": "Github Sync Improved", - "type": "FIX", - "color": "danger" - } - - ], - "currentVersion": "v3.4.3" -} +{ + "changes": [ + { + "details": "Add content security policy for webviews", + "type": "NEW", + "color": "success", + "author": "ParkourKarthik", + "pullRequest": "1020" + }, + { + "details": "Improve UX for the Force Upload", + "type": "NEW", + "color": "success", + "author": "karl-lunarg", + "pullRequest": "1042" + }, + { + "details": "Extension always asks to enable Force Upload", + "type": "FIX", + "color": "danger", + "author": "karl-lunarg", + "pullRequest": "1026" + }, + { + "details": "Languages, Icon and Wiki Improved", + "type": "NEW", + "color": "success" + }, + { + "details": "Github Gist Name Consistency across extension", + "type": "FIX", + "color": "danger" + }, + { + "details": "Snippets Sync. Fixed", + "type": "FIX", + "color": "danger" + }, + { + "details": "Share Settings Dialog Fixed", + "type": "FIX", + "color": "danger" + }, + { + "details": "Github Sync Improved", + "type": "FIX", + "color": "danger" + } + + ], + "currentVersion": "v3.4.3" +} diff --git a/src/commons.ts b/src/commons.ts index 7f5ab4ce..2252546a 100644 --- a/src/commons.ts +++ b/src/commons.ts @@ -1,531 +1,531 @@ -"use strict"; -import * as vscode from "vscode"; -import { Environment } from "./environmentPath"; -import localize from "./localize"; -import { CustomConfig } from "./models/customConfig.model"; -import { ExtensionConfig } from "./models/extensionConfig.model"; -import { LocalConfig } from "./models/localConfig.model"; -import { AutoUploadService } from "./service/autoUpload.service"; -import { File, FileService } from "./service/file.service"; -import { ExtensionInformation } from "./service/plugin.service"; -import { WebviewService } from "./service/webview.service"; -import { state } from "./state"; - -export default class Commons { - public static outputChannel: vscode.OutputChannel = null; - public static LogException( - error: any, - message: string, - msgBox: boolean, - callback?: () => void - ): void { - if (error) { - console.error(error); - if (error.status === 500) { - message = localize("common.error.connection"); - msgBox = false; - } else if (error.status === 401) { - msgBox = true; - message = localize("common.error.invalidToken"); - } else if (error.status === 4) { - message = localize("common.error.canNotSave"); - } else if (error.message) { - try { - message = JSON.parse(error.message).message; - if (message.toLowerCase() === "not found") { - msgBox = true; - message = localize("common.error.invalidGistId"); - } - } catch (error) { - // message = error.message; - } - } - } - - if (msgBox === true) { - vscode.window.showErrorMessage(message); - vscode.window.setStatusBarMessage("").dispose(); - } else { - vscode.window.setStatusBarMessage(message, 5000); - } - - if (callback) { - callback.apply(this); - } - } - - public static GetInputBox(token: boolean) { - if (token) { - const options: vscode.InputBoxOptions = { - placeHolder: localize("common.placeholder.enterGithubAccessToken"), - password: false, - prompt: localize("common.prompt.enterGithubAccessToken"), - ignoreFocusOut: true - }; - return options; - } else { - const options: vscode.InputBoxOptions = { - placeHolder: localize("common.placeholder.enterGistId"), - password: false, - prompt: localize("common.prompt.enterGistId"), - ignoreFocusOut: true - }; - return options; - } - } - - public autoUploadService: AutoUploadService; - public webviewService = new WebviewService(); - - public ERROR_MESSAGE: string = localize("common.error.message"); - - constructor() { - this.InitializeAutoUpload(); - } - - public async InitializeAutoUpload() { - const ignored = AutoUploadService.GetIgnoredItems( - await this.GetCustomSettings() - ); - this.autoUploadService = new AutoUploadService(ignored); - } - - public async HandleStartWatching() { - if (this.autoUploadService) { - this.autoUploadService.StartWatching(); - } else { - await this.InitializeAutoUpload(); - this.HandleStartWatching(); - } - } - - public async HandleStopWatching() { - if (this.autoUploadService) { - this.autoUploadService.StopWatching(); - } else { - await this.InitializeAutoUpload(); - this.HandleStopWatching(); - } - } - - public async InitalizeSettings(): Promise { - const settings = new LocalConfig(); - const extSettings = this.GetSettings(); - const cusSettings = await this.GetCustomSettings(); - - settings.customConfig = cusSettings; - settings.extConfig = extSettings; - return settings; - } - - public async GetCustomSettings(): Promise { - let customSettings = new CustomConfig(); - try { - const customExist: boolean = await FileService.FileExists( - state.environment.FILE_CUSTOMIZEDSETTINGS - ); - if (customExist) { - const customSettingStr: string = await FileService.ReadFile( - state.environment.FILE_CUSTOMIZEDSETTINGS - ); - const tempObj = JSON.parse(customSettingStr); - - Object.assign(customSettings, tempObj); - customSettings.token = customSettings.token.trim(); - } - } catch (e) { - customSettings = null; - Commons.LogException( - e, - "Sync : Unable to read " + - state.environment.FILE_CUSTOMIZEDSETTINGS_NAME + - ". Make sure its Valid JSON.", - true - ); - vscode.commands.executeCommand( - "vscode.open", - vscode.Uri.parse( - "http://shanalikhan.github.io/2017/02/19/Option-to-ignore-settings-folders-code-settings-sync.html" - ) - ); - } - return customSettings; - } - - public async SetCustomSettings(setting: CustomConfig): Promise { - try { - await FileService.WriteFile( - state.environment.FILE_CUSTOMIZEDSETTINGS, - JSON.stringify(setting, null, 4) - ); - return true; - } catch (e) { - Commons.LogException( - e, - "Sync : Unable to write " + - state.environment.FILE_CUSTOMIZEDSETTINGS_NAME, - true - ); - return false; - } - } - - public async StartMigrationProcess(): Promise { - const fileExist: boolean = await FileService.FileExists( - state.environment.FILE_CUSTOMIZEDSETTINGS - ); - let customSettings: CustomConfig = null; - const firstTime: boolean = !fileExist; - let fileChanged: boolean = firstTime; - - if (fileExist) { - customSettings = await this.GetCustomSettings(); - } else { - customSettings = new CustomConfig(); - } - // vscode.workspace.getConfiguration().update("sync.version", undefined, true); - - if (firstTime) { - const openExtensionPage = localize("common.action.openExtPage"); - vscode.window.showInformationMessage(localize("common.info.installed")); - vscode.window - .showInformationMessage( - localize("common.info.needHelp"), - openExtensionPage - ) - .then((val: string) => { - if (val === openExtensionPage) { - vscode.commands.executeCommand( - "vscode.open", - vscode.Uri.parse( - "https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync" - ) - ); - } - }); - } else if (customSettings.version < Environment.CURRENT_VERSION) { - fileChanged = true; - // #TODO : Remove this in new update - const newIgnoredList = new CustomConfig().ignoreUploadFiles; - newIgnoredList.forEach(m => { - if (customSettings.ignoreUploadFiles.indexOf(m) === -1) { - customSettings.ignoreUploadFiles.push(m); - } - }); - - if (state.context.globalState.get("synctoken")) { - const token = state.context.globalState.get("synctoken"); - if (token !== "") { - customSettings.token = String(token); - state.context.globalState.update("synctoken", ""); - vscode.window.showInformationMessage( - localize("common.info.setToken") - ); - } - } - - const releaseNotes = localize("common.action.releaseNotes"); - const writeReview = localize("common.action.writeReview"); - const support = localize("common.action.support"); - const joinCommunity = localize("common.action.joinCommunity"); - if (!customSettings.disableUpdateMessage) { - vscode.window - .showInformationMessage( - localize("common.info.updateTo", Environment.getVersion()), - releaseNotes, - writeReview, - support, - joinCommunity - ) - .then((val: string) => { - if (val === releaseNotes) { - vscode.commands.executeCommand( - "vscode.open", - vscode.Uri.parse( - "http://shanalikhan.github.io/2016/05/14/Visual-studio-code-sync-settings-release-notes.html" - ) - ); - } - if (val === writeReview) { - vscode.commands.executeCommand( - "vscode.open", - vscode.Uri.parse( - "https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync#review-details" - ) - ); - } - if (val === support) { - vscode.commands.executeCommand( - "vscode.open", - vscode.Uri.parse( - "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=4W3EWHHBSYMM8&lc=IE&item_name=Code%20Settings%20Sync&item_number=visual%20studio%20code%20settings%20sync¤cy_code=USD&bn=PP-DonationsBF:btn_donate_SM.gif:NonHosted" - ) - ); - } - if (val === joinCommunity) { - vscode.commands.executeCommand( - "vscode.open", - vscode.Uri.parse( - "https://join.slack.com/t/codesettingssync/shared_invite/enQtNzQyODMzMzI5MDQ3LWNmZjVkZjE2YTg0MzY1Y2EyYzVmYThmNzg2YjZkNjhhZWY3ZTEzN2I3ZTAxMjkwNWU0ZjMyZGFhMjdiZDI3ODU" - ) - ); - } - }); - } - } - - if (fileChanged) { - customSettings.version = Environment.CURRENT_VERSION; - await this.SetCustomSettings(customSettings); - } - return true; - } - - public async SaveSettings(setting: ExtensionConfig): Promise { - const config = vscode.workspace.getConfiguration("sync"); - const allKeysUpdated = new Array>(); - - const keys = Object.keys(setting); - keys.forEach(async keyName => { - if (setting[keyName] == null) { - setting[keyName] = ""; - } - if (keyName.toLowerCase() !== "token") { - if (config.get(keyName) !== setting[keyName]) { - allKeysUpdated.push(config.update(keyName, setting[keyName], true)); - } - } - }); - - try { - await Promise.all(allKeysUpdated); - if (state.context.globalState.get("syncCounter")) { - const counter = state.context.globalState.get("syncCounter"); - let count: number = parseInt(counter + "", 10); - if (count % 450 === 0) { - this.DonateMessage(); - } - count = count + 1; - state.context.globalState.update("syncCounter", count); - } else { - state.context.globalState.update("syncCounter", 1); - } - return true; - } catch (err) { - Commons.LogException(err, this.ERROR_MESSAGE, true); - return false; - } - } - - public async DonateMessage(): Promise { - const donateNow = localize("common.action.donate"); - const writeReview = localize("common.action.writeReview"); - const res = await vscode.window.showInformationMessage( - localize("common.info.donate"), - donateNow, - writeReview - ); - - if (res === donateNow) { - vscode.commands.executeCommand( - "vscode.open", - vscode.Uri.parse( - "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=4W3EWHHBSYMM8&lc=IE&item_name=Code%20Settings%20Sync&item_number=visual%20studio%20code%20settings%20sync¤cy_code=USD&bn=PP-DonationsBF:btn_donate_SM.gif:NonHosted" - ) - ); - } else if (res === writeReview) { - vscode.commands.executeCommand( - "vscode.open", - vscode.Uri.parse( - "https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync#review-details" - ) - ); - } - } - - public GetSettings(): ExtensionConfig { - const settings = new ExtensionConfig(); - - for (const key of Object.keys(settings)) { - if (key !== "token") { - settings[key] = vscode.workspace.getConfiguration("sync").get(key); - } - } - - settings.gist = settings.gist.trim(); - return settings; - } - - public async GetTokenAndSave(sett: CustomConfig): Promise { - const opt = Commons.GetInputBox(true); - - const token = ((await vscode.window.showInputBox(opt)) || "").trim(); - - if (token && token !== "esc") { - sett.token = token; - const saved = await this.SetCustomSettings(sett); - if (saved) { - vscode.window.setStatusBarMessage( - localize("common.info.tokenSaved"), - 1000 - ); - } - } - - return token; - } - public async GetGistAndSave(sett: ExtensionConfig): Promise { - const opt = Commons.GetInputBox(false); - - const gist = ((await vscode.window.showInputBox(opt)) || "").trim(); - - if (gist && gist !== "esc") { - sett.gist = gist; - const saved = await this.SaveSettings(sett); - if (saved) { - vscode.window.setStatusBarMessage( - localize("common.info.gistSaved"), - 1000 - ); - } - return gist; - } - } - - /** - * IgnoreSettings - */ - public async GetIgnoredSettings(settings: string[]): Promise { - const ignoreSettings: object = {}; - const config = vscode.workspace.getConfiguration(); - const keysUpdated: Array> = []; - - for (const key of settings) { - let keyValue: object = null; - keyValue = config.get(key, null); - if (keyValue !== null) { - ignoreSettings[key] = keyValue; - keysUpdated.push(config.update(key, undefined, true)); - } - } - - await Promise.all(keysUpdated); - - return ignoreSettings; - } - - /** - * RestoreIgnoredSettings - */ - public SetIgnoredSettings(ignoredSettings: object): void { - const config = vscode.workspace.getConfiguration(); - const keysUpdated: Array> = []; - for (const key of Object.keys(ignoredSettings)) { - keysUpdated.push(config.update(key, ignoredSettings[key], true)); - } - } - - /** - * AskGistDescription - */ - public async AskGistDescription(): Promise { - return vscode.window.showInputBox({ - prompt: localize("common.prompt.multipleGist"), - ignoreFocusOut: true, - placeHolder: localize("common.placeholder.multipleGist") - }); - } - - public ShowSummaryOutput( - upload: boolean, - files: File[], - removedExtensions: ExtensionInformation[], - addedExtensions: ExtensionInformation[], - ignoredExtensions: ExtensionInformation[], - syncSettings: LocalConfig - ) { - if (Commons.outputChannel === null) { - Commons.outputChannel = vscode.window.createOutputChannel( - "Code Settings Sync" - ); - } - - const outputChannel = Commons.outputChannel; - outputChannel.appendLine( - `CODE SETTINGS SYNC ${upload ? "UPLOAD" : "DOWNLOAD"} SUMMARY` - ); - outputChannel.appendLine(`Version: ${Environment.getVersion()}`); - outputChannel.appendLine(`--------------------`); - outputChannel.appendLine( - `GitHub Token: ${ - syncSettings.customConfig.token - ? syncSettings.customConfig.token.slice(0, 4) + "**********" - : "Anonymous" - }` - ); - outputChannel.appendLine(`GitHub Gist: ${syncSettings.extConfig.gist}`); - outputChannel.appendLine( - `GitHub Gist Type: ${syncSettings.publicGist ? "Public" : "Secret"}` - ); - outputChannel.appendLine(``); - if (!syncSettings.customConfig.token) { - outputChannel.appendLine( - `Anonymous Gist cannot be edited, the extension will always create a new one during upload.` - ); - } - outputChannel.appendLine( - `Restarting Visual Studio Code may be required to apply color and file icon theme.` - ); - outputChannel.appendLine(`--------------------`); - - outputChannel.appendLine(`Files ${upload ? "Upload" : "Download"}ed:`); - files - .filter(item => item.fileName.indexOf(".") > 0) - .forEach(item => { - outputChannel.appendLine(` ${item.fileName} > ${item.gistName}`); - }); - - outputChannel.appendLine(``); - outputChannel.appendLine(`Extensions Ignored:`); - - if (!ignoredExtensions || ignoredExtensions.length === 0) { - outputChannel.appendLine(` No extensions ignored.`); - } else { - ignoredExtensions.forEach(extn => { - outputChannel.appendLine(` ${extn.name} v${extn.version}`); - }); - } - - outputChannel.appendLine(``); - outputChannel.appendLine(`Extensions Removed:`); - - if (!syncSettings.extConfig.removeExtensions) { - outputChannel.appendLine(` Feature Disabled.`); - } else { - if (!removedExtensions || removedExtensions.length === 0) { - outputChannel.appendLine(` No extensions removed.`); - } else { - removedExtensions.forEach(extn => { - outputChannel.appendLine(` ${extn.name} v${extn.version}`); - }); - } - } - - if (addedExtensions) { - outputChannel.appendLine(``); - outputChannel.appendLine(`Extensions Added:`); - - if (addedExtensions.length === 0) { - outputChannel.appendLine(` No extensions installed.`); - } - - addedExtensions.forEach(extn => { - outputChannel.appendLine(` ${extn.name} v${extn.version}`); - }); - } - - outputChannel.appendLine(`--------------------`); - outputChannel.append(`Done.`); - outputChannel.show(true); - } -} +"use strict"; +import * as vscode from "vscode"; +import { Environment } from "./environmentPath"; +import localize from "./localize"; +import { CustomConfig } from "./models/customConfig.model"; +import { ExtensionConfig } from "./models/extensionConfig.model"; +import { LocalConfig } from "./models/localConfig.model"; +import { AutoUploadService } from "./service/autoUpload.service"; +import { File, FileService } from "./service/file.service"; +import { ExtensionInformation } from "./service/plugin.service"; +import { WebviewService } from "./service/webview.service"; +import { state } from "./state"; + +export default class Commons { + public static outputChannel: vscode.OutputChannel = null; + public static LogException( + error: any, + message: string, + msgBox: boolean, + callback?: () => void + ): void { + if (error) { + console.error(error); + if (error.status === 500) { + message = localize("common.error.connection"); + msgBox = false; + } else if (error.status === 401) { + msgBox = true; + message = localize("common.error.invalidToken"); + } else if (error.status === 4) { + message = localize("common.error.canNotSave"); + } else if (error.message) { + try { + message = JSON.parse(error.message).message; + if (message.toLowerCase() === "not found") { + msgBox = true; + message = localize("common.error.invalidGistId"); + } + } catch (error) { + // message = error.message; + } + } + } + + if (msgBox === true) { + vscode.window.showErrorMessage(message); + vscode.window.setStatusBarMessage("").dispose(); + } else { + vscode.window.setStatusBarMessage(message, 5000); + } + + if (callback) { + callback.apply(this); + } + } + + public static GetInputBox(token: boolean) { + if (token) { + const options: vscode.InputBoxOptions = { + placeHolder: localize("common.placeholder.enterGithubAccessToken"), + password: false, + prompt: localize("common.prompt.enterGithubAccessToken"), + ignoreFocusOut: true + }; + return options; + } else { + const options: vscode.InputBoxOptions = { + placeHolder: localize("common.placeholder.enterGistId"), + password: false, + prompt: localize("common.prompt.enterGistId"), + ignoreFocusOut: true + }; + return options; + } + } + + public autoUploadService: AutoUploadService; + public webviewService = new WebviewService(); + + public ERROR_MESSAGE: string = localize("common.error.message"); + + constructor() { + this.InitializeAutoUpload(); + } + + public async InitializeAutoUpload() { + const ignored = AutoUploadService.GetIgnoredItems( + await this.GetCustomSettings() + ); + this.autoUploadService = new AutoUploadService(ignored); + } + + public async HandleStartWatching() { + if (this.autoUploadService) { + this.autoUploadService.StartWatching(); + } else { + await this.InitializeAutoUpload(); + this.HandleStartWatching(); + } + } + + public async HandleStopWatching() { + if (this.autoUploadService) { + this.autoUploadService.StopWatching(); + } else { + await this.InitializeAutoUpload(); + this.HandleStopWatching(); + } + } + + public async InitalizeSettings(): Promise { + const settings = new LocalConfig(); + const extSettings = this.GetSettings(); + const cusSettings = await this.GetCustomSettings(); + + settings.customConfig = cusSettings; + settings.extConfig = extSettings; + return settings; + } + + public async GetCustomSettings(): Promise { + let customSettings = new CustomConfig(); + try { + const customExist: boolean = await FileService.FileExists( + state.environment.FILE_CUSTOMIZEDSETTINGS + ); + if (customExist) { + const customSettingStr: string = await FileService.ReadFile( + state.environment.FILE_CUSTOMIZEDSETTINGS + ); + const tempObj = JSON.parse(customSettingStr); + + Object.assign(customSettings, tempObj); + customSettings.token = customSettings.token.trim(); + } + } catch (e) { + customSettings = null; + Commons.LogException( + e, + "Sync : Unable to read " + + state.environment.FILE_CUSTOMIZEDSETTINGS_NAME + + ". Make sure its Valid JSON.", + true + ); + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse( + "http://shanalikhan.github.io/2017/02/19/Option-to-ignore-settings-folders-code-settings-sync.html" + ) + ); + } + return customSettings; + } + + public async SetCustomSettings(setting: CustomConfig): Promise { + try { + await FileService.WriteFile( + state.environment.FILE_CUSTOMIZEDSETTINGS, + JSON.stringify(setting, null, 4) + ); + return true; + } catch (e) { + Commons.LogException( + e, + "Sync : Unable to write " + + state.environment.FILE_CUSTOMIZEDSETTINGS_NAME, + true + ); + return false; + } + } + + public async StartMigrationProcess(): Promise { + const fileExist: boolean = await FileService.FileExists( + state.environment.FILE_CUSTOMIZEDSETTINGS + ); + let customSettings: CustomConfig = null; + const firstTime: boolean = !fileExist; + let fileChanged: boolean = firstTime; + + if (fileExist) { + customSettings = await this.GetCustomSettings(); + } else { + customSettings = new CustomConfig(); + } + // vscode.workspace.getConfiguration().update("sync.version", undefined, true); + + if (firstTime) { + const openExtensionPage = localize("common.action.openExtPage"); + vscode.window.showInformationMessage(localize("common.info.installed")); + vscode.window + .showInformationMessage( + localize("common.info.needHelp"), + openExtensionPage + ) + .then((val: string) => { + if (val === openExtensionPage) { + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse( + "https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync" + ) + ); + } + }); + } else if (customSettings.version < Environment.CURRENT_VERSION) { + fileChanged = true; + // #TODO : Remove this in new update + const newIgnoredList = new CustomConfig().ignoreUploadFiles; + newIgnoredList.forEach(m => { + if (customSettings.ignoreUploadFiles.indexOf(m) === -1) { + customSettings.ignoreUploadFiles.push(m); + } + }); + + if (state.context.globalState.get("synctoken")) { + const token = state.context.globalState.get("synctoken"); + if (token !== "") { + customSettings.token = String(token); + state.context.globalState.update("synctoken", ""); + vscode.window.showInformationMessage( + localize("common.info.setToken") + ); + } + } + + const releaseNotes = localize("common.action.releaseNotes"); + const writeReview = localize("common.action.writeReview"); + const support = localize("common.action.support"); + const joinCommunity = localize("common.action.joinCommunity"); + if (!customSettings.disableUpdateMessage) { + vscode.window + .showInformationMessage( + localize("common.info.updateTo", Environment.getVersion()), + releaseNotes, + writeReview, + support, + joinCommunity + ) + .then((val: string) => { + if (val === releaseNotes) { + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse( + "http://shanalikhan.github.io/2016/05/14/Visual-studio-code-sync-settings-release-notes.html" + ) + ); + } + if (val === writeReview) { + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse( + "https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync#review-details" + ) + ); + } + if (val === support) { + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse( + "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=4W3EWHHBSYMM8&lc=IE&item_name=Code%20Settings%20Sync&item_number=visual%20studio%20code%20settings%20sync¤cy_code=USD&bn=PP-DonationsBF:btn_donate_SM.gif:NonHosted" + ) + ); + } + if (val === joinCommunity) { + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse( + "https://join.slack.com/t/codesettingssync/shared_invite/enQtNzQyODMzMzI5MDQ3LWNmZjVkZjE2YTg0MzY1Y2EyYzVmYThmNzg2YjZkNjhhZWY3ZTEzN2I3ZTAxMjkwNWU0ZjMyZGFhMjdiZDI3ODU" + ) + ); + } + }); + } + } + + if (fileChanged) { + customSettings.version = Environment.CURRENT_VERSION; + await this.SetCustomSettings(customSettings); + } + return true; + } + + public async SaveSettings(setting: ExtensionConfig): Promise { + const config = vscode.workspace.getConfiguration("sync"); + const allKeysUpdated = new Array>(); + + const keys = Object.keys(setting); + keys.forEach(async keyName => { + if (setting[keyName] == null) { + setting[keyName] = ""; + } + if (keyName.toLowerCase() !== "token") { + if (config.get(keyName) !== setting[keyName]) { + allKeysUpdated.push(config.update(keyName, setting[keyName], true)); + } + } + }); + + try { + await Promise.all(allKeysUpdated); + if (state.context.globalState.get("syncCounter")) { + const counter = state.context.globalState.get("syncCounter"); + let count: number = parseInt(counter + "", 10); + if (count % 450 === 0) { + this.DonateMessage(); + } + count = count + 1; + state.context.globalState.update("syncCounter", count); + } else { + state.context.globalState.update("syncCounter", 1); + } + return true; + } catch (err) { + Commons.LogException(err, this.ERROR_MESSAGE, true); + return false; + } + } + + public async DonateMessage(): Promise { + const donateNow = localize("common.action.donate"); + const writeReview = localize("common.action.writeReview"); + const res = await vscode.window.showInformationMessage( + localize("common.info.donate"), + donateNow, + writeReview + ); + + if (res === donateNow) { + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse( + "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=4W3EWHHBSYMM8&lc=IE&item_name=Code%20Settings%20Sync&item_number=visual%20studio%20code%20settings%20sync¤cy_code=USD&bn=PP-DonationsBF:btn_donate_SM.gif:NonHosted" + ) + ); + } else if (res === writeReview) { + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse( + "https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync#review-details" + ) + ); + } + } + + public GetSettings(): ExtensionConfig { + const settings = new ExtensionConfig(); + + for (const key of Object.keys(settings)) { + if (key !== "token") { + settings[key] = vscode.workspace.getConfiguration("sync").get(key); + } + } + + settings.gist = settings.gist.trim(); + return settings; + } + + public async GetTokenAndSave(sett: CustomConfig): Promise { + const opt = Commons.GetInputBox(true); + + const token = ((await vscode.window.showInputBox(opt)) || "").trim(); + + if (token && token !== "esc") { + sett.token = token; + const saved = await this.SetCustomSettings(sett); + if (saved) { + vscode.window.setStatusBarMessage( + localize("common.info.tokenSaved"), + 1000 + ); + } + } + + return token; + } + public async GetGistAndSave(sett: ExtensionConfig): Promise { + const opt = Commons.GetInputBox(false); + + const gist = ((await vscode.window.showInputBox(opt)) || "").trim(); + + if (gist && gist !== "esc") { + sett.gist = gist; + const saved = await this.SaveSettings(sett); + if (saved) { + vscode.window.setStatusBarMessage( + localize("common.info.gistSaved"), + 1000 + ); + } + return gist; + } + } + + /** + * IgnoreSettings + */ + public async GetIgnoredSettings(settings: string[]): Promise { + const ignoreSettings: object = {}; + const config = vscode.workspace.getConfiguration(); + const keysUpdated: Array> = []; + + for (const key of settings) { + let keyValue: object = null; + keyValue = config.get(key, null); + if (keyValue !== null) { + ignoreSettings[key] = keyValue; + keysUpdated.push(config.update(key, undefined, true)); + } + } + + await Promise.all(keysUpdated); + + return ignoreSettings; + } + + /** + * RestoreIgnoredSettings + */ + public SetIgnoredSettings(ignoredSettings: object): void { + const config = vscode.workspace.getConfiguration(); + const keysUpdated: Array> = []; + for (const key of Object.keys(ignoredSettings)) { + keysUpdated.push(config.update(key, ignoredSettings[key], true)); + } + } + + /** + * AskGistDescription + */ + public async AskGistDescription(): Promise { + return vscode.window.showInputBox({ + prompt: localize("common.prompt.multipleGist"), + ignoreFocusOut: true, + placeHolder: localize("common.placeholder.multipleGist") + }); + } + + public ShowSummaryOutput( + upload: boolean, + files: File[], + removedExtensions: ExtensionInformation[], + addedExtensions: ExtensionInformation[], + ignoredExtensions: ExtensionInformation[], + syncSettings: LocalConfig + ) { + if (Commons.outputChannel === null) { + Commons.outputChannel = vscode.window.createOutputChannel( + "Code Settings Sync" + ); + } + + const outputChannel = Commons.outputChannel; + outputChannel.appendLine( + `CODE SETTINGS SYNC ${upload ? "UPLOAD" : "DOWNLOAD"} SUMMARY` + ); + outputChannel.appendLine(`Version: ${Environment.getVersion()}`); + outputChannel.appendLine(`--------------------`); + outputChannel.appendLine( + `GitHub Token: ${ + syncSettings.customConfig.token + ? syncSettings.customConfig.token.slice(0, 4) + "**********" + : "Anonymous" + }` + ); + outputChannel.appendLine(`GitHub Gist: ${syncSettings.extConfig.gist}`); + outputChannel.appendLine( + `GitHub Gist Type: ${syncSettings.publicGist ? "Public" : "Secret"}` + ); + outputChannel.appendLine(``); + if (!syncSettings.customConfig.token) { + outputChannel.appendLine( + `Anonymous Gist cannot be edited, the extension will always create a new one during upload.` + ); + } + outputChannel.appendLine( + `Restarting Visual Studio Code may be required to apply color and file icon theme.` + ); + outputChannel.appendLine(`--------------------`); + + outputChannel.appendLine(`Files ${upload ? "Upload" : "Download"}ed:`); + files + .filter(item => item.fileName.indexOf(".") > 0) + .forEach(item => { + outputChannel.appendLine(` ${item.fileName} > ${item.gistName}`); + }); + + outputChannel.appendLine(``); + outputChannel.appendLine(`Extensions Ignored:`); + + if (!ignoredExtensions || ignoredExtensions.length === 0) { + outputChannel.appendLine(` No extensions ignored.`); + } else { + ignoredExtensions.forEach(extn => { + outputChannel.appendLine(` ${extn.name} v${extn.version}`); + }); + } + + outputChannel.appendLine(``); + outputChannel.appendLine(`Extensions Removed:`); + + if (!syncSettings.extConfig.removeExtensions) { + outputChannel.appendLine(` Feature Disabled.`); + } else { + if (!removedExtensions || removedExtensions.length === 0) { + outputChannel.appendLine(` No extensions removed.`); + } else { + removedExtensions.forEach(extn => { + outputChannel.appendLine(` ${extn.name} v${extn.version}`); + }); + } + } + + if (addedExtensions) { + outputChannel.appendLine(``); + outputChannel.appendLine(`Extensions Added:`); + + if (addedExtensions.length === 0) { + outputChannel.appendLine(` No extensions installed.`); + } + + addedExtensions.forEach(extn => { + outputChannel.appendLine(` ${extn.name} v${extn.version}`); + }); + } + + outputChannel.appendLine(`--------------------`); + outputChannel.append(`Done.`); + outputChannel.show(true); + } +} diff --git a/src/enums.ts b/src/enums.ts index c283304e..69ebef8f 100644 --- a/src/enums.ts +++ b/src/enums.ts @@ -1,13 +1,13 @@ -export enum OsType { - Windows = "win32", - Linux = "linux", - Mac = "darwin" -} - -export enum SettingType { - Settings = 1, - Launch, - KeyBindings, - Locale, - Extensions -} +export enum OsType { + Windows = "win32", + Linux = "linux", + Mac = "darwin" +} + +export enum SettingType { + Settings = 1, + Launch, + KeyBindings, + Locale, + Extensions +} diff --git a/src/environmentPath.ts b/src/environmentPath.ts index 3f677141..611fa20d 100644 --- a/src/environmentPath.ts +++ b/src/environmentPath.ts @@ -1,196 +1,196 @@ -"use strict"; - -import { normalize, resolve } from "path"; -import * as vscode from "vscode"; -import { OsType } from "./enums"; -import { state } from "./state"; - -export const SUPPORTED_OS: string[] = Object.keys(OsType) - .filter(k => !/\d/.test(k)) - .map(k => k.toLowerCase()); // . ["windows", "linux", "mac"]; - -export function osTypeFromString(osName: string): OsType { - const capitalized: string = - osName[0].toUpperCase() + osName.substr(1).toLowerCase(); - return OsType[capitalized]; -} - -export class Environment { - public static CURRENT_VERSION: number = 343; - public static getVersion(): string { - return ( - Environment.CURRENT_VERSION.toString().slice(0, 1) + - "." + - Environment.CURRENT_VERSION.toString().slice(1, 2) + - "." + - Environment.CURRENT_VERSION.toString().slice(2, 3) - ); - } - - // public isInsiders: boolean = false; - // public isOss: boolean = false; - // public isCoderCom: boolean = false; - // public homeDir: string | null = null; - - public isPortable: boolean = false; - public USER_FOLDER: string = null; - - public CODE_BIN: string; - - public EXTENSION_FOLDER: string = null; - public PATH: string = null; - public OsType: OsType = null; - - public FILE_SETTING: string = null; - public FILE_LAUNCH: string = null; - public FILE_KEYBINDING: string = null; - public FILE_LOCALE: string = null; - public FILE_EXTENSION: string = null; - public FILE_CLOUDSETTINGS: string = null; - public FILE_SYNC_LOCK: string = null; - - public FILE_CUSTOMIZEDSETTINGS_NAME: string = "syncLocalSettings.json"; - public FILE_CUSTOMIZEDSETTINGS: string = null; - - public FILE_SETTING_NAME: string = "settings.json"; - public FILE_LAUNCH_NAME: string = "launch.json"; - public FILE_KEYBINDING_NAME: string = "keybindings.json"; - public FILE_KEYBINDING_MAC: string = "keybindingsMac.json"; - public FILE_KEYBINDING_DEFAULT: string = "keybindings.json"; - public FILE_EXTENSION_NAME: string = "extensions.json"; - public FILE_LOCALE_NAME: string = "locale.json"; - public FILE_SYNC_LOCK_NAME: string = "sync.lock"; - - public FILE_CLOUDSETTINGS_NAME: string = "cloudSettings"; - - public FOLDER_SNIPPETS: string = null; - - constructor() { - state.context.globalState.update("_", undefined); // Make sure the global state folder exists. This is needed for using this.context.globalStoragePath to access user folder - - this.isPortable = !!process.env.VSCODE_PORTABLE; - - this.OsType = process.platform as OsType; - if (!this.isPortable) { - this.PATH = resolve(state.context.globalStoragePath, "../../..").concat( - normalize("/") - ); - this.USER_FOLDER = resolve(this.PATH, "User").concat(normalize("/")); - this.EXTENSION_FOLDER = resolve( - vscode.extensions.all.filter( - extension => !extension.packageJSON.isBuiltin - )[0].extensionPath, - ".." - ).concat(normalize("/")); // Gets first non-builtin extension's path - } else { - this.PATH = process.env.VSCODE_PORTABLE; - this.USER_FOLDER = resolve(this.PATH, "user-data/User").concat( - normalize("/") - ); - this.EXTENSION_FOLDER = resolve(this.PATH, "extensions").concat( - normalize("/") - ); - } - - /* Start Legacy Code - - this.isInsiders = /insiders/.test(this.context.asAbsolutePath("")); - this.isOss = /\boss\b/.test(this.context.asAbsolutePath("")); - this.isCoderCom = - vscode.extensions.getExtension("coder.coder") !== undefined; - const isXdg = - !this.isInsiders && - !this.isCoderCom && - process.platform === "linux" && - !!process.env.XDG_DATA_HOME; - this.homeDir = isXdg - ? process.env.XDG_DATA_HOME - : process.env[process.platform === "win32" ? "USERPROFILE" : "HOME"]; - const configSuffix = `; $; {isXdg || this.isCoderCom ? "" : "."; }vscode$; { - this.isInsiders ? "-insiders" : this.isOss ? "-oss" : ""; - }`; - - if (!this.isPortable) { - if (process.platform === "darwin") { - this.PATH = process.env.HOME + "/Library/Application Support"; - this.OsType = OsType.Mac; - } else if (process.platform === "linux") { - if (!this.isCoderCom) { - this.PATH = - isXdg && !!process.env.XDG_CONFIG_HOME - ? process.env.XDG_CONFIG_HOME - : os.homedir() + "/.config"; - } else { - this.PATH = "/tmp"; - } - this.OsType = OsType.Linux; - } else if (process.platform === "win32") { - this.PATH = process.env.APPDATA; - this.OsType = OsType.Windows; - } else { - this.PATH = "/var/local"; - this.OsType = OsType.Linux; - } - } - - if (this.isPortable) { - this.PATH = process.env.VSCODE_PORTABLE; - if (process.platform === "darwin") { - this.OsType = OsType.Mac; - } else if (process.platform === "linux") { - this.OsType = OsType.Linux; - } else if (process.platform === "win32") { - this.OsType = OsType.Windows; - } else { - this.OsType = OsType.Linux; - } - } - - if (!this.isPortable) { - const possibleCodePaths = []; - if (this.isInsiders) { - possibleCodePaths.push("/Code - Insiders"); - } else if (this.isOss) { - possibleCodePaths.push("/Code - OSS"); - possibleCodePaths.push("/VSCodium"); - } else { - possibleCodePaths.push("/Code"); - } - for (const possibleCodePath of possibleCodePaths) { - try { - fs.statSync(this.PATH + possibleCodePath); - this.PATH = this.PATH + possibleCodePath; - break; - } catch (e) { - console.error("Error :" + possibleCodePath); - console.error(e); - } - } - this.ExtensionFolder = path.join( - this.homeDir, - configSuffix, - "extensions" - ); - this.USER_FOLDER = this.PATH.concat("/User/"); - } else { - this.USER_FOLDER = this.PATH.concat("/user-data/User/"); - this.ExtensionFolder = this.PATH.concat("/extensions/"); - } - - End Legacy Code */ - - this.FILE_EXTENSION = this.USER_FOLDER.concat(this.FILE_EXTENSION_NAME); - this.FILE_SETTING = this.USER_FOLDER.concat(this.FILE_SETTING_NAME); - this.FILE_LAUNCH = this.USER_FOLDER.concat(this.FILE_LAUNCH_NAME); - this.FILE_KEYBINDING = this.USER_FOLDER.concat(this.FILE_KEYBINDING_NAME); - this.FILE_LOCALE = this.USER_FOLDER.concat(this.FILE_LOCALE_NAME); - this.FOLDER_SNIPPETS = this.USER_FOLDER.concat("/snippets/"); - this.FILE_CLOUDSETTINGS = this.USER_FOLDER.concat( - this.FILE_CLOUDSETTINGS_NAME - ); - this.FILE_CUSTOMIZEDSETTINGS = this.USER_FOLDER.concat( - this.FILE_CUSTOMIZEDSETTINGS_NAME - ); - this.FILE_SYNC_LOCK = this.USER_FOLDER.concat(this.FILE_SYNC_LOCK_NAME); - } -} +"use strict"; + +import { normalize, resolve } from "path"; +import * as vscode from "vscode"; +import { OsType } from "./enums"; +import { state } from "./state"; + +export const SUPPORTED_OS: string[] = Object.keys(OsType) + .filter(k => !/\d/.test(k)) + .map(k => k.toLowerCase()); // . ["windows", "linux", "mac"]; + +export function osTypeFromString(osName: string): OsType { + const capitalized: string = + osName[0].toUpperCase() + osName.substr(1).toLowerCase(); + return OsType[capitalized]; +} + +export class Environment { + public static CURRENT_VERSION: number = 343; + public static getVersion(): string { + return ( + Environment.CURRENT_VERSION.toString().slice(0, 1) + + "." + + Environment.CURRENT_VERSION.toString().slice(1, 2) + + "." + + Environment.CURRENT_VERSION.toString().slice(2, 3) + ); + } + + // public isInsiders: boolean = false; + // public isOss: boolean = false; + // public isCoderCom: boolean = false; + // public homeDir: string | null = null; + + public isPortable: boolean = false; + public USER_FOLDER: string = null; + + public CODE_BIN: string; + + public EXTENSION_FOLDER: string = null; + public PATH: string = null; + public OsType: OsType = null; + + public FILE_SETTING: string = null; + public FILE_LAUNCH: string = null; + public FILE_KEYBINDING: string = null; + public FILE_LOCALE: string = null; + public FILE_EXTENSION: string = null; + public FILE_CLOUDSETTINGS: string = null; + public FILE_SYNC_LOCK: string = null; + + public FILE_CUSTOMIZEDSETTINGS_NAME: string = "syncLocalSettings.json"; + public FILE_CUSTOMIZEDSETTINGS: string = null; + + public FILE_SETTING_NAME: string = "settings.json"; + public FILE_LAUNCH_NAME: string = "launch.json"; + public FILE_KEYBINDING_NAME: string = "keybindings.json"; + public FILE_KEYBINDING_MAC: string = "keybindingsMac.json"; + public FILE_KEYBINDING_DEFAULT: string = "keybindings.json"; + public FILE_EXTENSION_NAME: string = "extensions.json"; + public FILE_LOCALE_NAME: string = "locale.json"; + public FILE_SYNC_LOCK_NAME: string = "sync.lock"; + + public FILE_CLOUDSETTINGS_NAME: string = "cloudSettings"; + + public FOLDER_SNIPPETS: string = null; + + constructor() { + state.context.globalState.update("_", undefined); // Make sure the global state folder exists. This is needed for using this.context.globalStoragePath to access user folder + + this.isPortable = !!process.env.VSCODE_PORTABLE; + + this.OsType = process.platform as OsType; + if (!this.isPortable) { + this.PATH = resolve(state.context.globalStoragePath, "../../..").concat( + normalize("/") + ); + this.USER_FOLDER = resolve(this.PATH, "User").concat(normalize("/")); + this.EXTENSION_FOLDER = resolve( + vscode.extensions.all.filter( + extension => !extension.packageJSON.isBuiltin + )[0].extensionPath, + ".." + ).concat(normalize("/")); // Gets first non-builtin extension's path + } else { + this.PATH = process.env.VSCODE_PORTABLE; + this.USER_FOLDER = resolve(this.PATH, "user-data/User").concat( + normalize("/") + ); + this.EXTENSION_FOLDER = resolve(this.PATH, "extensions").concat( + normalize("/") + ); + } + + /* Start Legacy Code + + this.isInsiders = /insiders/.test(this.context.asAbsolutePath("")); + this.isOss = /\boss\b/.test(this.context.asAbsolutePath("")); + this.isCoderCom = + vscode.extensions.getExtension("coder.coder") !== undefined; + const isXdg = + !this.isInsiders && + !this.isCoderCom && + process.platform === "linux" && + !!process.env.XDG_DATA_HOME; + this.homeDir = isXdg + ? process.env.XDG_DATA_HOME + : process.env[process.platform === "win32" ? "USERPROFILE" : "HOME"]; + const configSuffix = `; $; {isXdg || this.isCoderCom ? "" : "."; }vscode$; { + this.isInsiders ? "-insiders" : this.isOss ? "-oss" : ""; + }`; + + if (!this.isPortable) { + if (process.platform === "darwin") { + this.PATH = process.env.HOME + "/Library/Application Support"; + this.OsType = OsType.Mac; + } else if (process.platform === "linux") { + if (!this.isCoderCom) { + this.PATH = + isXdg && !!process.env.XDG_CONFIG_HOME + ? process.env.XDG_CONFIG_HOME + : os.homedir() + "/.config"; + } else { + this.PATH = "/tmp"; + } + this.OsType = OsType.Linux; + } else if (process.platform === "win32") { + this.PATH = process.env.APPDATA; + this.OsType = OsType.Windows; + } else { + this.PATH = "/var/local"; + this.OsType = OsType.Linux; + } + } + + if (this.isPortable) { + this.PATH = process.env.VSCODE_PORTABLE; + if (process.platform === "darwin") { + this.OsType = OsType.Mac; + } else if (process.platform === "linux") { + this.OsType = OsType.Linux; + } else if (process.platform === "win32") { + this.OsType = OsType.Windows; + } else { + this.OsType = OsType.Linux; + } + } + + if (!this.isPortable) { + const possibleCodePaths = []; + if (this.isInsiders) { + possibleCodePaths.push("/Code - Insiders"); + } else if (this.isOss) { + possibleCodePaths.push("/Code - OSS"); + possibleCodePaths.push("/VSCodium"); + } else { + possibleCodePaths.push("/Code"); + } + for (const possibleCodePath of possibleCodePaths) { + try { + fs.statSync(this.PATH + possibleCodePath); + this.PATH = this.PATH + possibleCodePath; + break; + } catch (e) { + console.error("Error :" + possibleCodePath); + console.error(e); + } + } + this.ExtensionFolder = path.join( + this.homeDir, + configSuffix, + "extensions" + ); + this.USER_FOLDER = this.PATH.concat("/User/"); + } else { + this.USER_FOLDER = this.PATH.concat("/user-data/User/"); + this.ExtensionFolder = this.PATH.concat("/extensions/"); + } + + End Legacy Code */ + + this.FILE_EXTENSION = this.USER_FOLDER.concat(this.FILE_EXTENSION_NAME); + this.FILE_SETTING = this.USER_FOLDER.concat(this.FILE_SETTING_NAME); + this.FILE_LAUNCH = this.USER_FOLDER.concat(this.FILE_LAUNCH_NAME); + this.FILE_KEYBINDING = this.USER_FOLDER.concat(this.FILE_KEYBINDING_NAME); + this.FILE_LOCALE = this.USER_FOLDER.concat(this.FILE_LOCALE_NAME); + this.FOLDER_SNIPPETS = this.USER_FOLDER.concat("/snippets/"); + this.FILE_CLOUDSETTINGS = this.USER_FOLDER.concat( + this.FILE_CLOUDSETTINGS_NAME + ); + this.FILE_CUSTOMIZEDSETTINGS = this.USER_FOLDER.concat( + this.FILE_CUSTOMIZEDSETTINGS_NAME + ); + this.FILE_SYNC_LOCK = this.USER_FOLDER.concat(this.FILE_SYNC_LOCK_NAME); + } +} diff --git a/src/extension.ts b/src/extension.ts index 4b3f8e36..7ebc3934 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,48 +1,48 @@ -"use strict"; - -import * as vscode from "vscode"; -import { Environment } from "./environmentPath"; -import { state } from "./state"; -import { Sync } from "./sync"; - -export async function activate(context: vscode.ExtensionContext) { - state.context = context; - state.environment = new Environment(); - - const sync = new Sync(); - - sync.bootstrap(); - - context.subscriptions.push( - vscode.commands.registerCommand( - "extension.updateSettings", - (optArgument?: string) => { - sync.upload.bind(sync, optArgument)(); - } - ) - ); - context.subscriptions.push( - vscode.commands.registerCommand( - "extension.downloadSettings", - sync.download.bind(sync) - ) - ); - context.subscriptions.push( - vscode.commands.registerCommand( - "extension.resetSettings", - sync.reset.bind(sync) - ) - ); - context.subscriptions.push( - vscode.commands.registerCommand( - "extension.HowSettings", - sync.how.bind(sync) - ) - ); - context.subscriptions.push( - vscode.commands.registerCommand( - "extension.otherOptions", - sync.advance.bind(sync) - ) - ); -} +"use strict"; + +import * as vscode from "vscode"; +import { Environment } from "./environmentPath"; +import { state } from "./state"; +import { Sync } from "./sync"; + +export async function activate(context: vscode.ExtensionContext) { + state.context = context; + state.environment = new Environment(); + + const sync = new Sync(); + + sync.bootstrap(); + + context.subscriptions.push( + vscode.commands.registerCommand( + "extension.updateSettings", + (optArgument?: string) => { + sync.upload.bind(sync, optArgument)(); + } + ) + ); + context.subscriptions.push( + vscode.commands.registerCommand( + "extension.downloadSettings", + sync.download.bind(sync) + ) + ); + context.subscriptions.push( + vscode.commands.registerCommand( + "extension.resetSettings", + sync.reset.bind(sync) + ) + ); + context.subscriptions.push( + vscode.commands.registerCommand( + "extension.HowSettings", + sync.how.bind(sync) + ) + ); + context.subscriptions.push( + vscode.commands.registerCommand( + "extension.otherOptions", + sync.advance.bind(sync) + ) + ); +} diff --git a/src/service/file.service.ts b/src/service/file.service.ts index 288064da..81bbe9a4 100644 --- a/src/service/file.service.ts +++ b/src/service/file.service.ts @@ -1,240 +1,240 @@ -"use strict"; - -import * as fs from "fs-extra"; -import * as path from "path"; -import * as recursiveRead from "recursive-readdir"; -import { CustomConfig } from "../models/customConfig.model"; - -export class File { - constructor( - public fileName: string, - public content: string, - public filePath: string, - public gistName: string - ) {} -} -export class FileService { - public static CUSTOMIZED_SYNC_PREFIX = "|customized_sync|"; - - public static async ReadFile(filePath: string): Promise { - try { - const data = await fs.readFile(filePath, { encoding: "utf8" }); - return data; - } catch (err) { - console.error(err); - throw err; - } - } - - public static async IsDirectory(filepath: string): Promise { - try { - const stat = await fs.lstat(filepath); - return stat.isDirectory(); - } catch (err) { - return false; - } - } - - public static async GetFile( - filePath: string, - fileName: string - ): Promise { - const fileExists: boolean = await FileService.FileExists(filePath); - - if (!fileExists) { - return null; - } - - const content = await FileService.ReadFile(filePath); - - if (content === null) { - return null; - } - - const pathFromUser: string = filePath.substring( - filePath.lastIndexOf("User") + 5, - filePath.length - ); - - const arr: string[] = pathFromUser.indexOf("/") - ? pathFromUser.split("/") - : pathFromUser.split(path.sep); - - let gistName: string = ""; - - arr.forEach((element, index) => { - if (index < arr.length - 1) { - gistName += element + "|"; - } else { - gistName += element; - } - }); - - const file: File = new File(fileName, content, filePath, gistName); - return file; - } - - public static async WriteFile( - filePath: string, - data: string - ): Promise { - if (!data) { - console.error( - new Error( - "Unable to write file. FilePath :" + filePath + " Data :" + data - ) - ); - return false; - } - try { - await fs.writeFile(filePath, data); - return true; - } catch (err) { - console.error(err); - return false; - } - } - - public static async ListFiles( - directory: string, - customSettings: CustomConfig - ): Promise { - function folderMatcher(file: string, stats: fs.Stats) { - if (stats.isDirectory()) { - return customSettings.ignoreUploadFolders.some(fold => { - return file.split(path.sep).includes(fold); - }); - } - return false; - } - function fileExtensionMatcher(file: string, stats: fs.Stats) { - if (stats.isDirectory()) { - return false; - } - const ext = path.extname(file).slice(1); - if (!customSettings.supportedFileExtensions.includes(ext)) { - return true; - } - return false; - } - const files = await recursiveRead(directory, [ - ...customSettings.ignoreUploadFiles, - folderMatcher, - fileExtensionMatcher - ]); - return Promise.all( - files.map(file => { - return FileService.GetFile(file, path.basename(file)); - }) - ); - } - - public static async CreateDirTree( - userFolder: string, - fileName: string - ): Promise { - let fullPath: string = userFolder; - let result: string; - - let paths: string[] = null; - if (fileName.indexOf("|") > -1) { - paths = fileName.split("|"); - } else if (fileName.indexOf("//") > -1) { - paths = fileName.split("//"); - } else if (fileName.indexOf("\\") > -1) { - paths = fileName.split("\\"); - } - - if (paths != null) { - for (let i = 0; i < paths.length - 1; i++) { - const element = paths[i]; - fullPath += element + path.sep; - await FileService.CreateDirectory(fullPath); - } - - result = fullPath + paths[paths.length - 1]; - return result; - } else { - result = fullPath + fileName; - - return result; - } - } - - public static async DeleteFile(filePath: string): Promise { - try { - const stat: boolean = await FileService.FileExists(filePath); - if (stat) { - await fs.unlink(filePath); - } - return true; - } catch (err) { - console.error("Unable to delete file. File Path is :" + filePath); - return false; - } - } - - public static async FileExists(filePath: string): Promise { - try { - await fs.access(filePath, fs.constants.F_OK); - return true; - } catch (err) { - return false; - } - } - - public static async CreateDirectory(name: string): Promise { - try { - await fs.mkdir(name); - return true; - } catch (err) { - if (err.code === "EEXIST") { - return false; - } - throw err; - } - } - - public static async GetCustomFile( - filePath: string, - fileName: string - ): Promise { - const fileExists: boolean = await FileService.FileExists(filePath); - - if (!fileExists) { - return null; - } - - const content = await FileService.ReadFile(filePath); - - if (content === null) { - return null; - } - - // for identifing Customized Sync file - const gistName: string = FileService.CUSTOMIZED_SYNC_PREFIX + fileName; - - const file: File = new File(fileName, content, filePath, gistName); - return file; - } - - public static async CreateCustomDirTree(filePath: string): Promise { - const dir = path.dirname(filePath); - const fileExists = await FileService.FileExists(dir); - - if (!fileExists) { - // mkdir recursively - await fs.mkdirs(dir); - } - - return filePath; - } - - public static ExtractFileName(fullPath: string): string { - return path.basename(fullPath); - } - - public static ConcatPath(...filePaths: string[]): string { - return filePaths.join(path.sep); - } -} +"use strict"; + +import * as fs from "fs-extra"; +import * as path from "path"; +import * as recursiveRead from "recursive-readdir"; +import { CustomConfig } from "../models/customConfig.model"; + +export class File { + constructor( + public fileName: string, + public content: string, + public filePath: string, + public gistName: string + ) {} +} +export class FileService { + public static CUSTOMIZED_SYNC_PREFIX = "|customized_sync|"; + + public static async ReadFile(filePath: string): Promise { + try { + const data = await fs.readFile(filePath, { encoding: "utf8" }); + return data; + } catch (err) { + console.error(err); + throw err; + } + } + + public static async IsDirectory(filepath: string): Promise { + try { + const stat = await fs.lstat(filepath); + return stat.isDirectory(); + } catch (err) { + return false; + } + } + + public static async GetFile( + filePath: string, + fileName: string + ): Promise { + const fileExists: boolean = await FileService.FileExists(filePath); + + if (!fileExists) { + return null; + } + + const content = await FileService.ReadFile(filePath); + + if (content === null) { + return null; + } + + const pathFromUser: string = filePath.substring( + filePath.lastIndexOf("User") + 5, + filePath.length + ); + + const arr: string[] = pathFromUser.indexOf("/") + ? pathFromUser.split("/") + : pathFromUser.split(path.sep); + + let gistName: string = ""; + + arr.forEach((element, index) => { + if (index < arr.length - 1) { + gistName += element + "|"; + } else { + gistName += element; + } + }); + + const file: File = new File(fileName, content, filePath, gistName); + return file; + } + + public static async WriteFile( + filePath: string, + data: string + ): Promise { + if (!data) { + console.error( + new Error( + "Unable to write file. FilePath :" + filePath + " Data :" + data + ) + ); + return false; + } + try { + await fs.writeFile(filePath, data); + return true; + } catch (err) { + console.error(err); + return false; + } + } + + public static async ListFiles( + directory: string, + customSettings: CustomConfig + ): Promise { + function folderMatcher(file: string, stats: fs.Stats) { + if (stats.isDirectory()) { + return customSettings.ignoreUploadFolders.some(fold => { + return file.split(path.sep).includes(fold); + }); + } + return false; + } + function fileExtensionMatcher(file: string, stats: fs.Stats) { + if (stats.isDirectory()) { + return false; + } + const ext = path.extname(file).slice(1); + if (!customSettings.supportedFileExtensions.includes(ext)) { + return true; + } + return false; + } + const files = await recursiveRead(directory, [ + ...customSettings.ignoreUploadFiles, + folderMatcher, + fileExtensionMatcher + ]); + return Promise.all( + files.map(file => { + return FileService.GetFile(file, path.basename(file)); + }) + ); + } + + public static async CreateDirTree( + userFolder: string, + fileName: string + ): Promise { + let fullPath: string = userFolder; + let result: string; + + let paths: string[] = null; + if (fileName.indexOf("|") > -1) { + paths = fileName.split("|"); + } else if (fileName.indexOf("//") > -1) { + paths = fileName.split("//"); + } else if (fileName.indexOf("\\") > -1) { + paths = fileName.split("\\"); + } + + if (paths != null) { + for (let i = 0; i < paths.length - 1; i++) { + const element = paths[i]; + fullPath += element + path.sep; + await FileService.CreateDirectory(fullPath); + } + + result = fullPath + paths[paths.length - 1]; + return result; + } else { + result = fullPath + fileName; + + return result; + } + } + + public static async DeleteFile(filePath: string): Promise { + try { + const stat: boolean = await FileService.FileExists(filePath); + if (stat) { + await fs.unlink(filePath); + } + return true; + } catch (err) { + console.error("Unable to delete file. File Path is :" + filePath); + return false; + } + } + + public static async FileExists(filePath: string): Promise { + try { + await fs.access(filePath, fs.constants.F_OK); + return true; + } catch (err) { + return false; + } + } + + public static async CreateDirectory(name: string): Promise { + try { + await fs.mkdir(name); + return true; + } catch (err) { + if (err.code === "EEXIST") { + return false; + } + throw err; + } + } + + public static async GetCustomFile( + filePath: string, + fileName: string + ): Promise { + const fileExists: boolean = await FileService.FileExists(filePath); + + if (!fileExists) { + return null; + } + + const content = await FileService.ReadFile(filePath); + + if (content === null) { + return null; + } + + // for identifing Customized Sync file + const gistName: string = FileService.CUSTOMIZED_SYNC_PREFIX + fileName; + + const file: File = new File(fileName, content, filePath, gistName); + return file; + } + + public static async CreateCustomDirTree(filePath: string): Promise { + const dir = path.dirname(filePath); + const fileExists = await FileService.FileExists(dir); + + if (!fileExists) { + // mkdir recursively + await fs.mkdirs(dir); + } + + return filePath; + } + + public static ExtractFileName(fullPath: string): string { + return path.basename(fullPath); + } + + public static ConcatPath(...filePaths: string[]): string { + return filePaths.join(path.sep); + } +} diff --git a/src/service/github.oauth.service.ts b/src/service/github.oauth.service.ts index ca2256ff..0c85e90e 100644 --- a/src/service/github.oauth.service.ts +++ b/src/service/github.oauth.service.ts @@ -21,10 +21,10 @@ export class GitHubOAuthService { : new URL("https://github.com"); this.server = this.app.listen(this.port); - this.app.get("/callback", async (req, res) => { + this.app.get("/callback", async (req: any, res: any) => { try { const params = new URLSearchParams( - await (await this.getToken(req.param("code"), host)).text() + await (await this.getToken(req.params("code"), host)).text() ); res.send(` @@ -62,13 +62,13 @@ export class GitHubOAuthService { const user = await this.getUser(token, host); - const gists: any[] = await this.getGists(token, user, host); + const gists: any = await this.getGists(token, user, host); - const gistViewList: any[] = gists.map(m => { + const gistViewList: any[] = gists.map((m) => { return { id: m.id, description: m.description, - updated_at: m.updated_at + updated_at: m.updated_at, }; }); @@ -88,10 +88,10 @@ export class GitHubOAuthService { const promise = fetch(`https://${host.hostname}/login/oauth/access_token`, { method: "POST", - body: params + body: params, }); - promise.catch(err => { + promise.catch((err) => { Commons.LogException(err, "Sync: Invalid GitHub Enterprise URL.", true); }); @@ -101,10 +101,10 @@ export class GitHubOAuthService { public async getGists(token: string, user: string, host: URL) { const promise = fetch(`https://api.${host.hostname}/users/${user}/gists`, { method: "GET", - headers: { Authorization: `token ${token}` } + headers: { Authorization: `token ${token}` }, }); - promise.catch(err => { + promise.catch((err) => { Commons.LogException(err, "Sync: Invalid GitHub Enterprise URL.", true); }); @@ -122,15 +122,15 @@ export class GitHubOAuthService { public async getUser(token: string, host: URL) { const promise = fetch(`https://api.${host.hostname}/user`, { method: "GET", - headers: { Authorization: `token ${token}` } + headers: { Authorization: `token ${token}` }, }); - promise.catch(err => { + promise.catch((err) => { Commons.LogException(err, "Sync: Invalid GitHub Enterprise URL.", true); }); const res = await promise; - const json = await res.json(); - return json.login; + const json: any = await res.json(); + return json?.login; } } diff --git a/src/service/github.service.ts b/src/service/github.service.ts index c9c2221d..aef71c12 100644 --- a/src/service/github.service.ts +++ b/src/service/github.service.ts @@ -1,203 +1,203 @@ -"use strict"; - -import * as GitHubApi from "@octokit/rest"; -import * as HttpsProxyAgent from "https-proxy-agent"; -import * as vscode from "vscode"; -import Commons from "../commons"; -import { CloudSettings } from "../models/cloudSettings.model"; -import { state } from "../state"; -import { File } from "./file.service"; - -interface IEnv { - [key: string]: string | undefined; - http_proxy: string; - HTTP_PROXY: string; -} - -interface IFixGistResponse extends Omit { - files: any | GitHubApi.GistsGetResponseFiles; -} - -export class GitHubService { - public userName: string = null; - public name: string = null; - private github: GitHubApi = null; - private GIST_JSON_EMPTY: any = { - description: "Visual Studio Code Sync Settings Gist", - public: false, - files: { - "settings.json": { - content: "// Empty" - }, - "launch.json": { - content: "// Empty" - }, - "keybindings.json": { - content: "// Empty" - }, - "extensions.json": { - content: "// Empty" - }, - "locale.json": { - content: "// Empty" - }, - "keybindingsMac.json": { - content: "// Empty" - }, - cloudSettings: { - content: "// Empty" - } - } - }; - - constructor(userToken: string, basePath: string) { - const githubApiConfig: GitHubApi.Options = {}; - - const proxyURL: string = - vscode.workspace.getConfiguration("http").get("proxy") || - (process.env as IEnv).http_proxy || - (process.env as IEnv).HTTP_PROXY; - if (basePath) { - githubApiConfig.baseUrl = basePath; - } - - if (proxyURL) { - githubApiConfig.agent = new HttpsProxyAgent(proxyURL); - } - - if (userToken !== null && userToken !== "") { - githubApiConfig.auth = `token ${userToken}`; - } - try { - this.github = new GitHubApi(githubApiConfig); - } catch (err) { - console.error(err); - } - if (userToken !== null && userToken !== "") { - this.github.users - .getAuthenticated({}) - .then(res => { - this.userName = res.data.login; - this.name = res.data.name; - console.log( - "Sync : Connected with user : " + "'" + this.userName + "'" - ); - }) - .catch(err => { - console.error(err); - }); - } - } - - public AddFile(list: File[], GIST_JSON_B: any) { - for (const file of list) { - if (file.content !== "") { - GIST_JSON_B.files[file.gistName] = {}; - GIST_JSON_B.files[file.gistName].content = file.content; - } - } - return GIST_JSON_B; - } - - public async CreateEmptyGIST( - publicGist: boolean, - gistDescription: string - ): Promise { - if (publicGist) { - this.GIST_JSON_EMPTY.public = true; - } else { - this.GIST_JSON_EMPTY.public = false; - } - if (gistDescription !== null && gistDescription !== "") { - this.GIST_JSON_EMPTY.description = gistDescription; - } - - try { - const res = await this.github.gists.create(this.GIST_JSON_EMPTY); - if (res.data && res.data.id) { - return res.data.id.toString(); - } else { - console.error("ID is null"); - console.log("Sync : " + "Response from GitHub is: "); - console.log(res); - } - } catch (err) { - console.error(err); - throw err; - } - } - - // This should return GitHubApi.Response but Types are wrong - public async ReadGist( - GIST: string - ): Promise> { - const promise = this.github.gists.get({ gist_id: GIST }); - const res = await promise.catch(err => { - if (String(err).includes("HttpError: Not Found")) { - return Commons.LogException(err, "Sync: Invalid Gist ID", true); - } - Commons.LogException(err, state.commons.ERROR_MESSAGE, true); - }); - if (res) { - return res; - } - } - - public async IsGistNewer( - GIST: string, - localLastDownload: Date - ): Promise { - const gist = await this.ReadGist(GIST); - if (!gist) { - return; - } - let gistCloudSetting: CloudSettings = null; - try { - gistCloudSetting = JSON.parse(gist.data.files.cloudSettings.content); - const gistLastUpload = new Date(gistCloudSetting.lastUpload); - if (!localLastDownload) { - return false; - } - return gistLastUpload > new Date(localLastDownload); - } catch (err) { - return false; - } - } - - public UpdateGIST(gistObject: any, files: File[]): any { - const allFiles: string[] = Object.keys(gistObject.data.files); - for (const fileName of allFiles) { - let exists = false; - - for (const settingFile of files) { - if (settingFile.gistName === fileName) { - exists = true; - } - } - - if (!exists && !fileName.startsWith("keybindings")) { - gistObject.data.files[fileName] = null; - } - } - - gistObject.data = this.AddFile(files, gistObject.data); - return gistObject; - } - - public async SaveGIST(gistObject: any): Promise { - gistObject.gist_id = gistObject.id; - // tslint:disable-next-line:comment-format - //TODO : use github.gists.update when issue is fixed. - const promise = this.github.request("PATCH /gists/:gist_id", gistObject); - const res = await promise.catch(err => { - if (String(err).includes("HttpError: Not Found")) { - return Commons.LogException(err, "Sync: Invalid Gist ID", true); - } - Commons.LogException(err, state.commons.ERROR_MESSAGE, true); - }); - - if (res) { - return true; - } - } -} +"use strict"; + +import * as GitHubApi from "@octokit/rest"; +import * as HttpsProxyAgent from "https-proxy-agent"; +import * as vscode from "vscode"; +import Commons from "../commons"; +import { CloudSettings } from "../models/cloudSettings.model"; +import { state } from "../state"; +import { File } from "./file.service"; + +interface IEnv { + [key: string]: string | undefined; + http_proxy: string; + HTTP_PROXY: string; +} + +interface IFixGistResponse extends Omit { + files: any | GitHubApi.GistsGetResponseFiles; +} + +export class GitHubService { + public userName: string = null; + public name: string = null; + private github: GitHubApi = null; + private GIST_JSON_EMPTY: any = { + description: "Visual Studio Code Sync Settings Gist", + public: false, + files: { + "settings.json": { + content: "// Empty" + }, + "launch.json": { + content: "// Empty" + }, + "keybindings.json": { + content: "// Empty" + }, + "extensions.json": { + content: "// Empty" + }, + "locale.json": { + content: "// Empty" + }, + "keybindingsMac.json": { + content: "// Empty" + }, + cloudSettings: { + content: "// Empty" + } + } + }; + + constructor(userToken: string, basePath: string) { + const githubApiConfig: GitHubApi.Options = {}; + + const proxyURL: string = + vscode.workspace.getConfiguration("http").get("proxy") || + (process.env as IEnv).http_proxy || + (process.env as IEnv).HTTP_PROXY; + if (basePath) { + githubApiConfig.baseUrl = basePath; + } + + if (proxyURL) { + githubApiConfig.agent = new HttpsProxyAgent(proxyURL); + } + + if (userToken !== null && userToken !== "") { + githubApiConfig.auth = `token ${userToken}`; + } + try { + this.github = new GitHubApi(githubApiConfig); + } catch (err) { + console.error(err); + } + if (userToken !== null && userToken !== "") { + this.github.users + .getAuthenticated({}) + .then(res => { + this.userName = res.data.login; + this.name = res.data.name; + console.log( + "Sync : Connected with user : " + "'" + this.userName + "'" + ); + }) + .catch(err => { + console.error(err); + }); + } + } + + public AddFile(list: File[], GIST_JSON_B: any) { + for (const file of list) { + if (file.content !== "") { + GIST_JSON_B.files[file.gistName] = {}; + GIST_JSON_B.files[file.gistName].content = file.content; + } + } + return GIST_JSON_B; + } + + public async CreateEmptyGIST( + publicGist: boolean, + gistDescription: string + ): Promise { + if (publicGist) { + this.GIST_JSON_EMPTY.public = true; + } else { + this.GIST_JSON_EMPTY.public = false; + } + if (gistDescription !== null && gistDescription !== "") { + this.GIST_JSON_EMPTY.description = gistDescription; + } + + try { + const res = await this.github.gists.create(this.GIST_JSON_EMPTY); + if (res.data && res.data.id) { + return res.data.id.toString(); + } else { + console.error("ID is null"); + console.log("Sync : " + "Response from GitHub is: "); + console.log(res); + } + } catch (err) { + console.error(err); + throw err; + } + } + + // This should return GitHubApi.Response but Types are wrong + public async ReadGist( + GIST: string + ): Promise> { + const promise = this.github.gists.get({ gist_id: GIST }); + const res = await promise.catch(err => { + if (String(err).includes("HttpError: Not Found")) { + return Commons.LogException(err, "Sync: Invalid Gist ID", true); + } + Commons.LogException(err, state.commons.ERROR_MESSAGE, true); + }); + if (res) { + return res; + } + } + + public async IsGistNewer( + GIST: string, + localLastDownload: Date + ): Promise { + const gist = await this.ReadGist(GIST); + if (!gist) { + return; + } + let gistCloudSetting: CloudSettings = null; + try { + gistCloudSetting = JSON.parse(gist.data.files.cloudSettings.content); + const gistLastUpload = new Date(gistCloudSetting.lastUpload); + if (!localLastDownload) { + return false; + } + return gistLastUpload > new Date(localLastDownload); + } catch (err) { + return false; + } + } + + public UpdateGIST(gistObject: any, files: File[]): any { + const allFiles: string[] = Object.keys(gistObject.data.files); + for (const fileName of allFiles) { + let exists = false; + + for (const settingFile of files) { + if (settingFile.gistName === fileName) { + exists = true; + } + } + + if (!exists && !fileName.startsWith("keybindings")) { + gistObject.data.files[fileName] = null; + } + } + + gistObject.data = this.AddFile(files, gistObject.data); + return gistObject; + } + + public async SaveGIST(gistObject: any): Promise { + gistObject.gist_id = gistObject.id; + // tslint:disable-next-line:comment-format + //TODO : use github.gists.update when issue is fixed. + const promise = this.github.request("PATCH /gists/:gist_id", gistObject); + const res = await promise.catch(err => { + if (String(err).includes("HttpError: Not Found")) { + return Commons.LogException(err, "Sync: Invalid Gist ID", true); + } + Commons.LogException(err, state.commons.ERROR_MESSAGE, true); + }); + + if (res) { + return true; + } + } +} diff --git a/src/service/plugin.service.ts b/src/service/plugin.service.ts index 12abe312..1b06c112 100644 --- a/src/service/plugin.service.ts +++ b/src/service/plugin.service.ts @@ -1,243 +1,243 @@ -"use strict"; -import * as vscode from "vscode"; - -export class ExtensionInformation { - public static fromJSON(text: string) { - try { - // TODO: JSON.parse may throw error - // Throw custom error should be more friendly - const obj = JSON.parse(text); - const meta = new ExtensionMetadata( - obj.meta.galleryApiUrl, - obj.meta.id, - obj.meta.downloadUrl, - obj.meta.publisherId, - obj.meta.publisherDisplayName, - obj.meta.date - ); - const item = new ExtensionInformation(); - item.metadata = meta; - item.name = obj.name; - item.publisher = obj.publisher; - item.version = obj.version; - return item; - } catch (err) { - throw new Error(err); - } - } - - public static fromJSONList(text: string) { - const extList: ExtensionInformation[] = []; - try { - // TODO: JSON.parse may throw error - // Throw custom error should be more friendly - const list = JSON.parse(text); - list.forEach(obj => { - const meta = new ExtensionMetadata( - obj.metadata.galleryApiUrl, - obj.metadata.id, - obj.metadata.downloadUrl, - obj.metadata.publisherId, - obj.metadata.publisherDisplayName, - obj.metadata.date - ); - const item = new ExtensionInformation(); - item.metadata = meta; - item.name = obj.name; - item.publisher = obj.publisher; - item.version = obj.version; - - if (item.name !== "code-settings-sync") { - extList.push(item); - } - }); - } catch (err) { - throw new Error(err); - } - - return extList; - } - - public metadata: ExtensionMetadata; - public name: string; - public version: string; - public publisher: string; -} - -export class ExtensionMetadata { - constructor( - public galleryApiUrl: string, - public id: string, - public downloadUrl: string, - public publisherId: string, - public publisherDisplayName: string, - public date: string - ) {} -} - -export class PluginService { - public static GetMissingExtensions( - remoteExt: string, - ignoredExtensions: string[] - ) { - const remoteList = ExtensionInformation.fromJSONList(remoteExt); - const localList = this.CreateExtensionList(); - - return remoteList.filter( - ext => - !ignoredExtensions.includes(ext.name) && - !localList.map(e => e.name).includes(ext.name) - ); - } - - public static GetDeletedExtensions( - remoteExtensions: ExtensionInformation[], - ignoredExtensions: string[] - ) { - const localExtensions = this.CreateExtensionList(); - - // for (var i = 0; i < remoteList.length; i++) { - - // var ext = remoteList[i]; - // var found: boolean = false; - - // for (var j = 0; j < localList.length; j++) { - // var localExt = localList[j]; - // if (ext.name == localExt.name) { - // found = true; - // break; - // } - // } - // if (!found) { - // deletedList.push(localExt); - // } - - // } - - return localExtensions.filter( - ext => - ext.name !== "code-settings-sync" && - !remoteExtensions.map(e => e.name).includes(ext.name) && - !ignoredExtensions.includes(ext.name) - ); - } - - public static CreateExtensionList() { - return vscode.extensions.all - .filter(ext => !ext.packageJSON.isBuiltin) - .map(ext => { - const meta = ext.packageJSON.__metadata || { - id: ext.packageJSON.uuid, - publisherId: ext.id, - publisherDisplayName: ext.packageJSON.publisher - }; - const data = new ExtensionMetadata( - meta.galleryApiUrl, - meta.id, - meta.downloadUrl, - meta.publisherId, - meta.publisherDisplayName, - meta.date - ); - const info = new ExtensionInformation(); - info.metadata = data; - info.name = ext.packageJSON.name; - info.publisher = ext.packageJSON.publisher; - info.version = ext.packageJSON.version; - return info; - }); - } - - public static async DeleteExtension( - extension: ExtensionInformation - ): Promise { - try { - await vscode.commands.executeCommand( - "workbench.extensions.uninstallExtension", - `${extension.publisher}.${extension.name}` - ); - return true; - } catch (err) { - throw new Error(err); - } - } - - public static async DeleteExtensions( - extensionsJson: string, - ignoredExtensions: string[] - ): Promise { - const remoteExtensions = ExtensionInformation.fromJSONList(extensionsJson); - const toDelete = PluginService.GetDeletedExtensions( - remoteExtensions, - ignoredExtensions - ); - - return Promise.all( - toDelete.map(async selectedExtension => { - try { - await PluginService.DeleteExtension(selectedExtension); - return selectedExtension; - } catch (err) { - throw new Error( - `Sync : Unable to delete extension ${selectedExtension.name} ${selectedExtension.version}: ${err}` - ); - } - }) - ); - } - - public static async InstallExtensions( - extensions: string, - ignoredExtensions: string[], - notificationCallBack: (...data: any[]) => void - ): Promise { - let addedExtensions: ExtensionInformation[] = []; - const missingExtensions = PluginService.GetMissingExtensions( - extensions, - ignoredExtensions - ); - if (missingExtensions.length === 0) { - notificationCallBack("Sync : No Extensions needs to be installed."); - return []; - } - addedExtensions = await PluginService.InstallWithAPI( - missingExtensions, - notificationCallBack - ); - return addedExtensions; - } - - public static async InstallWithAPI( - missingExtensions: ExtensionInformation[], - notificationCallBack: (...data: any[]) => void - ): Promise { - const addedExtensions: ExtensionInformation[] = []; - const missingExtensionsCount = missingExtensions.length; - notificationCallBack("TOTAL EXTENSIONS : " + missingExtensionsCount); - notificationCallBack(""); - notificationCallBack(""); - for (const ext of missingExtensions) { - const name = ext.publisher + "." + ext.name; - try { - notificationCallBack(""); - notificationCallBack(`[x] - EXTENSION: ${ext.name} - INSTALLING`); - await vscode.commands.executeCommand( - "workbench.extensions.installExtension", - name - ); - notificationCallBack(""); - notificationCallBack(`[x] - EXTENSION: ${ext.name} INSTALLED.`); - notificationCallBack( - ` ${missingExtensions.indexOf(ext) + - 1} OF ${missingExtensionsCount} INSTALLED`, - true - ); - notificationCallBack(""); - addedExtensions.push(ext); - } catch (err) { - throw new Error(err); - } - } - return addedExtensions; - } -} +"use strict"; +import * as vscode from "vscode"; + +export class ExtensionInformation { + public static fromJSON(text: string) { + try { + // TODO: JSON.parse may throw error + // Throw custom error should be more friendly + const obj = JSON.parse(text); + const meta = new ExtensionMetadata( + obj.meta.galleryApiUrl, + obj.meta.id, + obj.meta.downloadUrl, + obj.meta.publisherId, + obj.meta.publisherDisplayName, + obj.meta.date + ); + const item = new ExtensionInformation(); + item.metadata = meta; + item.name = obj.name; + item.publisher = obj.publisher; + item.version = obj.version; + return item; + } catch (err) { + throw new Error(err); + } + } + + public static fromJSONList(text: string) { + const extList: ExtensionInformation[] = []; + try { + // TODO: JSON.parse may throw error + // Throw custom error should be more friendly + const list = JSON.parse(text); + list.forEach(obj => { + const meta = new ExtensionMetadata( + obj.metadata.galleryApiUrl, + obj.metadata.id, + obj.metadata.downloadUrl, + obj.metadata.publisherId, + obj.metadata.publisherDisplayName, + obj.metadata.date + ); + const item = new ExtensionInformation(); + item.metadata = meta; + item.name = obj.name; + item.publisher = obj.publisher; + item.version = obj.version; + + if (item.name !== "code-settings-sync") { + extList.push(item); + } + }); + } catch (err) { + throw new Error(err); + } + + return extList; + } + + public metadata: ExtensionMetadata; + public name: string; + public version: string; + public publisher: string; +} + +export class ExtensionMetadata { + constructor( + public galleryApiUrl: string, + public id: string, + public downloadUrl: string, + public publisherId: string, + public publisherDisplayName: string, + public date: string + ) {} +} + +export class PluginService { + public static GetMissingExtensions( + remoteExt: string, + ignoredExtensions: string[] + ) { + const remoteList = ExtensionInformation.fromJSONList(remoteExt); + const localList = this.CreateExtensionList(); + + return remoteList.filter( + ext => + !ignoredExtensions.includes(ext.name) && + !localList.map(e => e.name).includes(ext.name) + ); + } + + public static GetDeletedExtensions( + remoteExtensions: ExtensionInformation[], + ignoredExtensions: string[] + ) { + const localExtensions = this.CreateExtensionList(); + + // for (var i = 0; i < remoteList.length; i++) { + + // var ext = remoteList[i]; + // var found: boolean = false; + + // for (var j = 0; j < localList.length; j++) { + // var localExt = localList[j]; + // if (ext.name == localExt.name) { + // found = true; + // break; + // } + // } + // if (!found) { + // deletedList.push(localExt); + // } + + // } + + return localExtensions.filter( + ext => + ext.name !== "code-settings-sync" && + !remoteExtensions.map(e => e.name).includes(ext.name) && + !ignoredExtensions.includes(ext.name) + ); + } + + public static CreateExtensionList() { + return vscode.extensions.all + .filter(ext => !ext.packageJSON.isBuiltin) + .map(ext => { + const meta = ext.packageJSON.__metadata || { + id: ext.packageJSON.uuid, + publisherId: ext.id, + publisherDisplayName: ext.packageJSON.publisher + }; + const data = new ExtensionMetadata( + meta.galleryApiUrl, + meta.id, + meta.downloadUrl, + meta.publisherId, + meta.publisherDisplayName, + meta.date + ); + const info = new ExtensionInformation(); + info.metadata = data; + info.name = ext.packageJSON.name; + info.publisher = ext.packageJSON.publisher; + info.version = ext.packageJSON.version; + return info; + }); + } + + public static async DeleteExtension( + extension: ExtensionInformation + ): Promise { + try { + await vscode.commands.executeCommand( + "workbench.extensions.uninstallExtension", + `${extension.publisher}.${extension.name}` + ); + return true; + } catch (err) { + throw new Error(err); + } + } + + public static async DeleteExtensions( + extensionsJson: string, + ignoredExtensions: string[] + ): Promise { + const remoteExtensions = ExtensionInformation.fromJSONList(extensionsJson); + const toDelete = PluginService.GetDeletedExtensions( + remoteExtensions, + ignoredExtensions + ); + + return Promise.all( + toDelete.map(async selectedExtension => { + try { + await PluginService.DeleteExtension(selectedExtension); + return selectedExtension; + } catch (err) { + throw new Error( + `Sync : Unable to delete extension ${selectedExtension.name} ${selectedExtension.version}: ${err}` + ); + } + }) + ); + } + + public static async InstallExtensions( + extensions: string, + ignoredExtensions: string[], + notificationCallBack: (...data: any[]) => void + ): Promise { + let addedExtensions: ExtensionInformation[] = []; + const missingExtensions = PluginService.GetMissingExtensions( + extensions, + ignoredExtensions + ); + if (missingExtensions.length === 0) { + notificationCallBack("Sync : No Extensions needs to be installed."); + return []; + } + addedExtensions = await PluginService.InstallWithAPI( + missingExtensions, + notificationCallBack + ); + return addedExtensions; + } + + public static async InstallWithAPI( + missingExtensions: ExtensionInformation[], + notificationCallBack: (...data: any[]) => void + ): Promise { + const addedExtensions: ExtensionInformation[] = []; + const missingExtensionsCount = missingExtensions.length; + notificationCallBack("TOTAL EXTENSIONS : " + missingExtensionsCount); + notificationCallBack(""); + notificationCallBack(""); + for (const ext of missingExtensions) { + const name = ext.publisher + "." + ext.name; + try { + notificationCallBack(""); + notificationCallBack(`[x] - EXTENSION: ${ext.name} - INSTALLING`); + await vscode.commands.executeCommand( + "workbench.extensions.installExtension", + name + ); + notificationCallBack(""); + notificationCallBack(`[x] - EXTENSION: ${ext.name} INSTALLED.`); + notificationCallBack( + ` ${missingExtensions.indexOf(ext) + + 1} OF ${missingExtensionsCount} INSTALLED`, + true + ); + notificationCallBack(""); + addedExtensions.push(ext); + } catch (err) { + throw new Error(err); + } + } + return addedExtensions; + } +} diff --git a/src/util.ts b/src/util.ts index d090b916..d353345a 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,31 +1,31 @@ -"use strict"; - -export class Util { - public static async Sleep(ms: number): Promise { - return new Promise(resolve => { - setTimeout(() => { - resolve(ms); - }, ms); - }); - } - /** - * promisify the function - * it will be remove when vscode use node@^8.0 - * @param fn - */ - public static promisify( - fn: (...args: any[]) => any - ): (...whatever: any[]) => Promise { - return function(...argv) { - return new Promise((resolve, reject) => { - fn.call(this, ...argv, (err, data) => { - if (err) { - reject(err); - } else { - resolve(data); - } - }); - }); - }; - } -} +"use strict"; + +export class Util { + public static async Sleep(ms: number): Promise { + return new Promise(resolve => { + setTimeout(() => { + resolve(ms); + }, ms); + }); + } + /** + * promisify the function + * it will be remove when vscode use node@^8.0 + * @param fn + */ + public static promisify( + fn: (...args: any[]) => any + ): (...whatever: any[]) => Promise { + return function(...argv) { + return new Promise((resolve, reject) => { + fn.call(this, ...argv, (err, data) => { + if (err) { + reject(err); + } else { + resolve(data); + } + }); + }); + }; + } +} diff --git a/ui/landing-page/landing-page.html b/ui/landing-page/landing-page.html index 0288c197..d7d5ec88 100644 --- a/ui/landing-page/landing-page.html +++ b/ui/landing-page/landing-page.html @@ -1,178 +1,178 @@ - - - - - - - - - - - - - - -
-
-

- What's New in - - vX.X.X - - -

-
-
-
-

- Configuration -

-

- Login via GitHub to setup Settings Sync, or configure the settings - manually. -

- - -
-
-

- Show Your Support -

-

- While being free and open source, if you find - Settings Sync - useful, please consider supporting it by donating via PayPal or Open - Collective. -

- - -
-
-
- -
-
- - -
-
- - - - - - - + + + + + + + + + + + + + + +
+
+

+ What's New in + + vX.X.X + + +

+
+
+
+

+ Configuration +

+

+ Login via GitHub to setup Settings Sync, or configure the settings + manually. +

+ + +
+
+

+ Show Your Support +

+

+ While being free and open source, if you find + Settings Sync + useful, please consider supporting it by donating via PayPal or Open + Collective. +

+ + +
+
+
+ +
+
+ + +
+
+ + + + + + + diff --git a/ui/landing-page/landing-page.js b/ui/landing-page/landing-page.js index b3556322..52c23d2d 100644 --- a/ui/landing-page/landing-page.js +++ b/ui/landing-page/landing-page.js @@ -1,40 +1,40 @@ -// @ts-nocheck -const vscode = acquireVsCodeApi(); - -function sendCommand(command, data) { - vscode.postMessage({ - command, - data - }); -} - -function appendHTML(parent, html) { - var div = document.createElement("div"); - div.innerHTML = html; - while (div.children.length > 0) { - parent.appendChild(div.children[0]); - } - div.remove(); -} - -const releaseNoteTemplate = `
@TYPE@NOTE @EXTRA
`; - -const notesElement = document.querySelector("#notes"); -releaseNotes.changes.forEach(change => { - const html = releaseNoteTemplate - .replace(new RegExp("@NOTE", "g"), change.details) - .replace(new RegExp("@TYPE", "g"), change.type) - .replace(new RegExp("@COLOR", "g"), change.color) - .replace( - new RegExp("@EXTRA", "g"), - change.author && change.pullRequest - ? `(Thanks to @${change.author} for PR #${change.pullRequest})` - : "" - ); - appendHTML(notesElement, html); -}); - -const currentVersionElement = document.querySelector("#current-version"); -currentVersionElement.innerHTML = releaseNotes.currentVersion; - -document.querySelector("#customCheck1").checked = checked === "true"; +// @ts-nocheck +const vscode = acquireVsCodeApi(); + +function sendCommand(command, data) { + vscode.postMessage({ + command, + data + }); +} + +function appendHTML(parent, html) { + var div = document.createElement("div"); + div.innerHTML = html; + while (div.children.length > 0) { + parent.appendChild(div.children[0]); + } + div.remove(); +} + +const releaseNoteTemplate = `
@TYPE@NOTE @EXTRA
`; + +const notesElement = document.querySelector("#notes"); +releaseNotes.changes.forEach(change => { + const html = releaseNoteTemplate + .replace(new RegExp("@NOTE", "g"), change.details) + .replace(new RegExp("@TYPE", "g"), change.type) + .replace(new RegExp("@COLOR", "g"), change.color) + .replace( + new RegExp("@EXTRA", "g"), + change.author && change.pullRequest + ? `(Thanks to @${change.author} for PR #${change.pullRequest})` + : "" + ); + appendHTML(notesElement, html); +}); + +const currentVersionElement = document.querySelector("#current-version"); +currentVersionElement.innerHTML = releaseNotes.currentVersion; + +document.querySelector("#customCheck1").checked = checked === "true";