Compare commits

...

224 Commits

Author SHA1 Message Date
Karl Burtram
83a4316cf8 Fix typo in vbump (#17937) (#17938) 2021-12-15 12:19:38 -08:00
Karl Burtram
b4c22c698d Bump STS to rollback data type changes (#17935) (#17936) 2021-12-15 12:11:59 -08:00
Alex Ma
b44891657c Bump to langpack versions (#17910) (#17911)
* Bump to langpack versions

* fixed newline
2021-12-14 11:07:25 -08:00
Alex Ma
f99b27807f Langpack port for December release (#17905)
* Update to langpack for December release  (#17904)

* update to xlfs

* update to langpack json files

* [Loc] fix for newlines at end of package.json (#17906)
2021-12-14 07:27:32 -08:00
Charles Gagnon
93ea635bac Use standard key events for Notebook keybindings (#17880) (#17882)
* Use standard key events for Notebook keybindings

* Add more
2021-12-09 13:14:52 -08:00
Barbara Valdez
651f6fdcfc Fix split cell undo (#17845) (#17873)
* fix split cell undo
2021-12-08 16:31:32 -08:00
Alan Ren
cfc8e41798 open database dashboard (#17871) (#17872) 2021-12-08 15:35:20 -08:00
Barbara Valdez
bcd2e7313a Add undo/redo to convert cells (#17835) (#17867)
* add undo/redo to convert cells
2021-12-08 14:52:57 -08:00
Alan Ren
61f094f797 vbump sts (#17865) (#17868) 2021-12-08 14:51:52 -08:00
Kim Santiago
d5a3370b65 fix load publish profile not working (#17851) (#17862) 2021-12-08 11:23:11 -08:00
Alan Ren
a2d5b2acd1 fix grid actionbar (#17837) (#17854) 2021-12-08 10:16:32 -08:00
goyal-anjali
80541ce6f0 Add telemetry to troubleshoot customer issues (#17748)
* Add telemetry to troubleshoot customer issues

* Updating logerror method calls with custom errors

* Add performance telemetry
2021-12-06 11:39:41 +05:30
Rachel Kim
8d8b3983a9 Support multiple database migrations using network share (#17796)
* update database backup model to take list of network shares

* remove refreshMigrationTiles after startMigration in statemachine; add null checks
2021-12-03 17:07:11 -08:00
Rachel Kim
6aab9d41a3 Add backups restored progress when migrating from Azure Blob Storage (#17795) 2021-12-03 17:06:37 -08:00
Lucy Zhang
969eb16df7 Wait for all notebook models to load before shutting down active sessions during python upgrade (#17766)
* handle undefined model

* wait for kernel to load before restart

* comment

* await editor model resolved

* remove cast
2021-12-03 16:39:07 -08:00
Barbara Valdez
8a205965d2 add telemetry to undo/redo at cell level (#17804)
* add telemetry to undo/redo at cell level

*add sendTelemetryActionEvent that sends telemetry from notebook model
2021-12-03 16:21:52 -08:00
Alan Ren
cde4e05320 bump sts version (#17809) 2021-12-03 13:33:53 -08:00
Barbara Valdez
bb83110606 bump sqlservernotebook version (#17770)
* bump sqlservernotebook version

* Update version to 0.5.0
2021-12-03 13:03:32 -08:00
brian-harris
f9e1f38393 set initial target db name (#17801) 2021-12-03 10:58:17 -08:00
Alex Ma
a3faff2738 [Loc] update to sql-database-projects and sql xlfs (#17810) 2021-12-03 10:52:18 -08:00
Barbara Valdez
f404edbb60 do not show Add Section from command palette (#17805) 2021-12-03 09:19:35 -08:00
brian-harris
36364e10c4 add migration state management improvement (#17799)
* add migration state management improvement

* remove extra lines
2021-12-02 15:40:58 -08:00
Kim Santiago
43d235ea42 update .net sdk location strings now that .net 6 is supported (#17757)
* update .net install strings now that .net 6 is supported

* copy old setting value to new setting

* update strings

* add link to issue
2021-12-02 15:32:07 -08:00
Barbara Valdez
8b09ba8844 Implement undo/redo at cell level (#17744)
Implemented undo and redo for adding, deleting and moving cells.
2021-12-02 13:41:42 -08:00
Lucy Zhang
9b87973205 Enable add sql binding quickpick (#17790)
* enable add sql binding command

* add preview to command

* use resourceScheme instead of resourceExtname

* bump version to 0.15.0

* revert version bump
2021-12-02 12:19:11 -08:00
Alex Ma
5ad91135dd [Loc] update to sql-database-projects and sql xlfs (#17797) 2021-12-02 11:27:53 -08:00
Alan Ren
ba3e6343e8 dot not crash query editor (#17787) 2021-12-02 09:38:08 -08:00
csigs
d02eddda29 LEGO: check in for main to temporary branch. (#17794) 2021-12-02 09:35:28 -08:00
csigs
8b0371e036 LEGO: check in for main to temporary branch. (#17791) 2021-12-02 09:35:00 -08:00
Alan Ren
09c2e73f14 update dashboard taskbar separator (#17779) 2021-12-01 13:08:00 -08:00
csigs
39f8181af4 LEGO: check in for main to temporary branch. (#17778)
Co-authored-by: Alex Ma <alma1@microsoft.com>
2021-12-01 10:01:40 -08:00
csigs
5f6b2bdbb8 LEGO: check in for main to temporary branch. (#17775) 2021-12-01 09:39:53 -08:00
Alex Ma
de93938ef4 Added fix for Publish Target Label Position (#17771)
* Added fix for Publish Target Label Position

* renamed checkbox
2021-12-01 09:39:36 -08:00
Benjin Dubishar
56d5061942 Set default radio button selection, evaluate default component popula… (#17764)
* Set default radio button selection, evaluate default component population off of selection instead of unprocessed input

* rename var

* if -> switches

* Remove project radio buttons because they require commands that aren't yet checked in (and fail as a result)
2021-12-01 02:31:10 -08:00
Alan Ren
1006652a31 fix sorting bug (#17769)
* fix sorting bug

* comments
2021-11-30 17:11:57 -08:00
Leila Lali
7e17bfb6ec Added UI for user to accept EULA when deploying sql proj to docker container (#17762) 2021-11-30 15:08:23 -08:00
Chris LaFreniere
ce7935e7d2 Notebooks: Add Tooltips for Link/Image Buttons on Markdown Toolbar (#17763)
* Add title for tooltips

* Tweak tooltips
2021-11-30 12:40:06 -08:00
Aasim Khan
1f9a6a611b Editing pipeline ACR service connection endpoint to the latest one created (#17767)
* using the new registry endpoint

* updating the service connection

* Changing the name of acr service endpoint to SqlToolsContainer

* Updating web build acr endpoint as well.
2021-11-30 12:34:06 -08:00
Lewis Sanchez
c073897056 Fixes ADS Web bug around copying user codes and opening a browser tab when adding an Azure Account. (#17760)
* Fixes bug around copying user codes and opening a browser tab.

* Code review changes

* Additional review changes.

* Unnecessary import removed
2021-11-30 10:37:56 -08:00
Alex Ma
917a30e66f [Loc] Fix for duplicate strings in LCL files (#17756)
* WIP spanish lcl duplicate removal

* Revert "WIP spanish lcl duplicate removal"

This reverts commit 5f943153ec8980849a045c8bf7256d852571a778.

* fix for duplicate strings

* removed spaces
2021-11-29 11:26:26 -08:00
Cory Rivera
0149d9f051 Add additional notebook tests for handling relative links. (#17739) 2021-11-29 10:09:25 -08:00
Alex Ma
0bac949d3b [Loc] update to sql-database-projects xlf (#17743) 2021-11-23 17:13:39 -08:00
Kim Santiago
0847f7cd38 Remove .net 6 version cutoff for building sql projects (#17736)
* remove .net 6 version cutoff for building sql projects

* Revert "Warning when .NET 6 SDK is detected (#17422)"

This reverts commit 2ed8aeb565.

* add back skipVersionSupportedCheck

* add back return false

* addressing comments
2021-11-23 14:32:05 -10:00
Charles Gagnon
5d2f17408e Bump to latest version of azdata (#17735) 2021-11-22 20:35:28 -08:00
Alex Ma
da56e59f6e [Loc] update to Arc XLF (#17737) 2021-11-22 16:47:37 -08:00
Kim Santiago
33f01054c0 Update remove file for sdk style sql projects (#17688)
* add support for removing file in new style project

* fix test

* only load files, not whole project when checking if a <Build Remove> needs to be added

* merge changes

* fixes after merge
2021-11-22 14:45:43 -10:00
Charles Gagnon
4c191d4acc Add resource deployment samples for (#17734) 2021-11-22 15:49:05 -08:00
Kim Santiago
a79c61ff4e Fix ordering of reading sqlproj Build Includes and Removes (#17712)
* evaluate includes and removes in order in sqlproj

* fix after merge

* fix comment

* update comment
2021-11-22 11:50:06 -10:00
Candice Ye
ef4dab072a Enabled deployment of Azure Arc data controllers in directly connected mode (#17707)
* Added fields for connectivity mode, custom loc, auto-metrics, auto-logs, and the dynamic enablement of such fields.

* Changed the description of the data controller details page.

* Change notebook params to work for direct mode

* Added login to dc deployment notebooks

* Fixed auto upload metrics and logs true/false, separated login into another cell.

* Removed localization of indirect and direct connectivity labels.
2021-11-22 13:28:51 -08:00
Alex Ma
80f3f4eb88 [Loc] Update to schema-compare XLF (#17733) 2021-11-22 11:52:58 -08:00
Benjin Dubishar
1f98f29eae Apply changes from remote database to sqlproj - schema-compare changes (#17679)
* update project from database

* update project from database

* Merge from main

* Removing dupe test stub

* PR feedback

* cleanup

* PR feedback

* Fixing tests, adding stubs to update sqlproj as schema compare target

* updating code comment

Co-authored-by: Noureldine Yehia <t-nyehia@microsoft.com>
2021-11-22 10:50:36 -08:00
Charles Gagnon
0caa6390b9 Fix "unsupported version" error when adding sql binding package (#17721) 2021-11-22 10:44:46 -08:00
csigs
172e349947 LEGO: check in for main to temporary branch. (#17730) 2021-11-22 10:36:31 -08:00
csigs
5f3453c929 LEGO: check in for main to temporary branch. (#17726)
Co-authored-by: Alex Ma <alma1@microsoft.com>
2021-11-22 10:36:14 -08:00
csigs
37e1da4ba2 LEGO: check in for main to temporary branch. (#17725)
Co-authored-by: Alex Ma <alma1@microsoft.com>
2021-11-22 10:32:03 -08:00
Kim Santiago
bb28646670 Update one more variable name for sdk style projects (#17710) 2021-11-22 08:13:36 -10:00
csigs
9dcdfaea7a LEGO: check in for main to temporary branch. (#17724)
Co-authored-by: Alex Ma <alma1@microsoft.com>
2021-11-22 10:10:47 -08:00
csigs
cc21588db8 LEGO: check in for main to temporary branch. (#17722) 2021-11-22 09:55:06 -08:00
Charles Gagnon
6ba7bad90c Fix language flavor change on connection when in sqlcmd mode (#17719)
* Fix language flavor change on connection when in sqlcmd mode

* comment + fix
2021-11-19 15:04:54 -08:00
Alan Ren
ae5026b432 allow build to continue when cache task fails (#17720)
* cache task should not fail the build

* update cachesalt
2021-11-19 15:02:58 -08:00
Alan Ren
24b22f63d7 save password checkbox fix (#17718)
* save password checkbox fix

* remove code to reset the checkbox value
2021-11-19 13:35:35 -08:00
Charles Gagnon
77e4fdd407 Fix open external not working (#17717) 2021-11-19 11:25:23 -08:00
Charles Gagnon
8a6ea2669b Add additional properties to wizard page navigation events (#17716) 2021-11-19 10:18:13 -08:00
Alan Ren
3136ce1b4d input width in designer (#17714) 2021-11-19 10:12:47 -08:00
Cory Rivera
8e04d3992a Register additional editor overrides when adding new notebook file types (#17708)
* Also standardized file extension contributions to always start with a period, and to always do lower case string comparisons for file extensions.
2021-11-19 09:14:41 -08:00
csigs
09666bc4e8 LEGO: check in for main to temporary branch. (#17715) 2021-11-19 08:47:28 -08:00
Alex Ma
377479617f [Loc] update to sql-database-projects (#17713) 2021-11-18 18:59:53 -08:00
csigs
7862515eb5 LEGO: check in for main to temporary branch. (#17702)
Co-authored-by: Alex Ma <alma1@microsoft.com>
2021-11-18 18:34:05 -08:00
csigs
112810dbfb LEGO: check in for main to temporary branch. (#17699) 2021-11-18 18:32:30 -08:00
Alan Ren
c74a89674a bump sts version to 159 (#17709) 2021-11-18 17:48:10 -08:00
Alexander Ivanov
a801388e1d Improve accessibility for wizard steps navigation (#17669)
Our extension is relying on the wizard dialog. During accessibility testing it was discovered that wizard step buttons are being reported as links by the screen reader (NVDA, JAWS). Claimed expected behavior by the tester is that they should be announced as buttons.

I discussed this issue with accessibility SMEs and they said it is perfectly fine to keep them as links. They did mention that they would probably design the UX differently from the start, but given that we already have it this way, links are fine. They did suggest to add few additional ARIA attributes to the link elements:

- `aria-current="step"` if the link is for the currently active step. This literally just announces "current step" at the end, when you focus on a link
- `aria-disabled="true"` makes it say "**unavailable**; link; *<step number>*" when in NVDA "browse" mode and move to the grayed-out link.

So this change implements the said improvements.
2021-11-18 15:34:52 -08:00
Alan Ren
7cb7157821 code refactoring (#17706) 2021-11-18 14:51:23 -08:00
Leila Lali
9bdd6aca42 Adding UI for deploying a db proj to docker (#17495) 2021-11-18 14:44:33 -08:00
Charles Gagnon
88b754b739 Add instructions for developing VS Code version of sql-database-projects (#17705) 2021-11-18 14:07:39 -08:00
Alex Ma
480bf56cef [Loc] update to tabledesignercomponentinput (#17704) 2021-11-18 11:54:24 -08:00
Alan Ren
a273c54ebb properties pane improvements (#17700) 2021-11-18 10:41:12 -08:00
Alan Ren
7c26e14605 add foreign keys and constraints (#17697)
* foreign keys and constraints

* refactoring

* fix issues
2021-11-17 19:15:24 -08:00
Kim Santiago
6f03cbac97 support building msbuild sdk style projects (#17675)
* support building msbuild sdk style projects

* fixes after merge
2021-11-17 07:59:43 -10:00
Alan Ren
9e5a012dcd update the vmImage for build jobs (#17689)
* update vmImage for windows build

* update tar command

* use specific macos version
2021-11-16 21:08:11 -08:00
Alex Ma
812ab1cc91 [Loc] Update to sql-database-projects and sql.xlf (#17687) 2021-11-16 16:23:06 -08:00
Lucy Zhang
3d9f54b0c0 Sql Binding: Add "Check out pane for more details" when nuget package download fails (#17680)
* check output for more details

* detail error

* wait for result from showerrormessage
2021-11-16 15:01:05 -08:00
Sai Avishkar Sreerama
3cbd2fe5df sts 156 vbump (#17683) 2021-11-16 16:51:38 -06:00
Aditya Bist
2a127beb28 Designer: property descriptions (#17668)
* format

* added strings

* format doc

* use codicon instead

* show descriptions in property pane only

* fix ssdt string bug

* fix overflow option

* review comments

* review comments

* changes
2021-11-16 14:50:05 -08:00
Kim Santiago
6725e07ece update names for msbuild sdk style projects (#17677)
* update names for msbuild sdk style projects

* remove msbuild from names

* update comments
2021-11-16 11:23:19 -10:00
Kim Santiago
24a6de404c undo adding space in net core sdk location setting (#17684) 2021-11-16 10:51:24 -10:00
Kim Santiago
66c438db4d Fix sql projects net6 warnings (#17673)
* fix .net 6 error showing on startup

* fix double warning

* addressing comments

* update key string
2021-11-16 10:02:15 -10:00
Alexander Ivanov
1b83c4623d Respect ARIA label specified int he tree component options. (#17674)
During accessibility testing it was discovered that tree view in our wizard reads "Tree Node tree view" instead of the proper label that is specified. It turned out to be the problem with the tree component, where `ariaLabel` was hardcoded to "Tree Node", instead of the one provided in the options.

This change addresses the problem by passing through `ariaLabel` from the options object to the underlying tree control. I also removed the default `Tree Node` hardcoded label, as it didn't make much sense. This does mean that all tree-views that do not explicitly specify their aria-label will now get an empty label. I think this is better than having unrelated, unlocalized `Tree Node`.

I'm also worried about changes to the `ariaLabel` property after the component was initialized. I updated the code to propagate the value to the underlying tree view in the `setProperties` override of the tree component and hope that it will take care of it.
2021-11-16 09:15:45 -08:00
Alexander Ivanov
42b9f3b552 Provide aria-labels for node checkboxes in the tree view. (#17676)
During accessibility testing, it was discovered that screen reader does not announce what checkboxes in the tree view represent. It was merely announcing "checkbox unchecked", so it was not clear without visuals which checkbox the focus is on.

This change sets an `aria-label` of the checkbox elements to match the label of the owning tree node. This way the announcement becomes "My Node; checkbox; unchecked". This is fine as a quick solution to the problem, but in the future we may want to consider adding additional checkbox label property to the nodes exposed by the tree provider, so that each checkbox can announce additional information, if needed.
2021-11-16 08:13:18 -08:00
Lucy Zhang
343e314103 SQL Binding: Give default connection setting name (#17659)
* show sqlconnectionstring in quickpick

* fix duplicate sqlconnectionstring setting

* add (new)

* add sqlconnectionstring as default setting name

* check if sqlconnectionstring already exists
2021-11-15 18:53:52 -08:00
Alan Ren
fc0d175f39 fix issue reported by component governance (#17678)
* update json-schema version

* remove unused packages

* update package.json
2021-11-15 17:45:21 -08:00
Kim Santiago
5fccd8ebcd update add file/folder for msbuild sdk style projects (#17660)
* update add file for msbuild sdk style projects

* also handle add folder

* fix comment
2021-11-15 15:00:50 -10:00
Benjin Dubishar
b5f8e81250 Apply changes from Remote Database to sqlproj - mssql changes (#17655)
* update project from database

* update project from database

* update project from database

* Re-adding schemaComparePublishChanges for temporary backcompat

* Adding comment for keeping enum values in sync

* Correcting enum value

Co-authored-by: Noureldine Yehia <t-nyehia@microsoft.com>
2021-11-15 15:42:56 -08:00
Benjin Dubishar
d6159a2370 Bump tools service (#17671) 2021-11-15 14:40:40 -08:00
Lewis Sanchez
77e9d1c3a0 Corrects Web Build Pipeline ENOENT Error (#17656)
* Checks for successful directory creation

* Revert "Checks for successful directory creation"

This reverts commit 372409ef323f0d82e11992bc7bc33d607a7d5581.

* Checks for the existence of the logs directory before accessing.

* Adds SQL carbon edit comment

* Removing call to copy from non-existing directory.

* Removes unneeded import

* Checks for file existence before copying.

* Provides explanation for modification

* Replaces file existence check with exception handling.
2021-11-15 10:03:42 -08:00
Kim Santiago
bf1cc057be Refactoring readProjFile() (#17637)
* move reading project parts to different helper functions

* cleanup

* remove comment

* addressing comments
2021-11-12 15:02:52 -08:00
Alan Ren
4538103e60 use latest STS (#17658) 2021-11-12 13:33:52 -08:00
Alan Ren
7a1c0a67b9 vbump STS (#17653) 2021-11-11 15:07:09 -08:00
Lewis Sanchez
56a697c887 Resolves same-origin-policy violation when ADS web is running in a container (#17555)
* Stops appending port to authority for web mode

* Clarifies comment

* Adds missing sql carbon edit tag
2021-11-11 11:04:00 -08:00
Lucy Zhang
ba92694fa3 Show connection string example for add sql binding quickpick (#17650)
* add connection string example

* reorder
2021-11-11 10:54:13 -08:00
Alan Ren
1a9f2a5903 multi-level table support (#17638)
* multi-level table support

* comments

* address comments

* add period to end of sentence.
2021-11-10 17:15:08 -08:00
Charles Gagnon
e0ad23a559 Remove galleries list action (#17648) 2021-11-10 15:03:45 -08:00
Charles Gagnon
0a60ed4c75 Fix extensionsGallery.json name (#17646) 2021-11-10 14:51:09 -08:00
Charles Gagnon
f96a82f700 Add extension gallery update reminder action (#17644) 2021-11-10 14:45:19 -08:00
Maddy
6b226de450 refactor deltaDecorations logic (#17630) 2021-11-10 13:38:30 -08:00
Charles Gagnon
615df975ec Fix query editors restoring as plain text (#17643) 2021-11-10 12:31:43 -08:00
csigs
bcc66218d1 LEGO: check in for main to temporary branch. (#17639) 2021-11-10 11:53:37 -08:00
Alan Ren
6fb6f51295 fix dirty state of table designer (#17640)
* dirty state

* update original value on save
2021-11-10 11:39:53 -08:00
Maddy
1d3debb897 Maddy/edit mode events cleanup (#17636)
* remove multiple events

* correct preview check

* add test
2021-11-10 10:59:29 -08:00
Kim Santiago
b6047ad87d Move project entry classes to separate file (#17629)
* moving ProjectEntry stuff to another file

* cleanup
2021-11-09 16:03:39 -08:00
Cory Rivera
329ea4103c Make various enhancements to Notebook Provider registration. (#17609)
* Use built-in SQL ExecuteProvider by default if no other provider exists.

* Gracefully handle case where standardKernels are not defined for a provider.

* Standardize on just using arrays for various provider registration details.
2021-11-09 16:00:34 -08:00
Kim Santiago
8057bf855b add support for Build Remove (#17610) 2021-11-09 10:45:56 -08:00
Alex Ma
209a93c578 [Loc] Added LEGO branch changes from #17625 (#17631) 2021-11-08 19:29:44 -08:00
Sai Avishkar Sreerama
8a6268cce8 STS VBump with v147 (#17627) 2021-11-08 15:06:35 -06:00
csigs
e9ce8d902a LEGO: check in for main to temporary branch. (#17621) 2021-11-08 11:22:10 -08:00
Alex Ma
4727333974 [Loc] change location of designer strings (#17628) 2021-11-08 11:21:55 -08:00
Alan Ren
c00c5e044b move the designer component to workbench layer (#17620) 2021-11-08 10:26:27 -08:00
Charles Gagnon
f91a228066 Update dotnet version used by codesign (#17616) 2021-11-06 13:33:07 -07:00
Kim Santiago
a31388f37a fix test-extension-unit.js on mac (#17612)
* fix test-extensions-unit.js not working on mac

* add comment
2021-11-05 17:22:38 -07:00
Benjin Dubishar
9b06f3551d Revert "Bump tools service (#17607)" (#17613)
This reverts commit b4d72af3d4.
2021-11-05 16:52:48 -07:00
Alex Ma
a0cce62926 [Loc] update to table designer XLF (#17614) 2021-11-05 16:50:36 -07:00
Alan Ren
5f8e1f384f table designer editor icon (#17608)
* icon for table designer

* use more specific name

* use sql defined schema
2021-11-05 16:26:17 -07:00
Benjin Dubishar
b4d72af3d4 Bump tools service (#17607) 2021-11-05 14:48:28 -07:00
Kim Santiago
b8ea493f8c Add support for showing files for glob style sql projects (#17518)
* use glob to get files for new style msbuild sdk sqlproj

* add tests

* cleanup

* fix test

* don't show bin and obj files and folders

* handle other glob patterns

* fix duplicate entries getting added for glob patterns in project's folder
2021-11-05 13:29:47 -07:00
Alan Ren
c9be45b9c7 feature flag for table designer (#17597) 2021-11-05 11:19:59 -07:00
Alan Ren
1fe3f38c14 separate title and name for table designer editor (#17600) 2021-11-05 11:09:17 -07:00
Alan Ren
f5b1e7feb8 a couple properties pane UI changes (#17601) 2021-11-05 11:08:43 -07:00
Alex Ma
dd0261ca05 Alex/fixforjapaneselocalization (#17604)
* [Loc] Fix for localization build not working

* [Loc] update to sql-database-projects
2021-11-05 10:32:46 -07:00
v-srinisa
b8629acc4b Update CHANGELOG.md (#17596) 2021-11-04 18:03:51 -07:00
Benjin Dubishar
5160814623 Dedupe shell command execution logic (#17516)
* Moved to shellExecutionHelper

* First crack

* fixed the deploy tests

* PR comments

* trigger GitHub actions

Co-authored-by: llali <llali@microsoft.com>
2021-11-04 17:16:58 -07:00
Alan Ren
f07427f2c1 add open table designer event telemetry (#17595)
* add open table designer telemetry event

* rename variables to reflect the text change

* format code
2021-11-04 17:00:32 -07:00
Kim Santiago
a34b5a0db7 show better error messages when parsing sqlproj (#17589)
* show better error messages when parsing sqlproj

* show error messages in console
2021-11-04 16:43:31 -07:00
Alex Ma
00ff7a0000 [Loc] added xlf strings for designer and tabledesigner (#17593) 2021-11-04 10:18:12 -07:00
Aditya Bist
99f5c406e3 Added editor to table designer (#17576)
* format doc

* correct class name

* set content

* remove mssql commands

* merge classes

* code refactoring and bug fixing

* remove unnecessary class

* handle promise

Co-authored-by: Alan Ren <alanren@microsoft.com>
2021-11-03 21:07:36 -07:00
Alan Ren
893563c9c3 rename 'Advanced' tab to General (#17591) 2021-11-03 21:06:29 -07:00
Charles Gagnon
84ae306d57 Fix not being able to type in code cell after switching from text (#17590)
* Fix not being able to type in code cell after switching from text

* comment
2021-11-03 19:48:04 -07:00
Alan Ren
f3e1c2cc8b a few table designer improvements (#17588) 2021-11-03 17:57:47 -07:00
Candice Ye
6ae8db35df Bumping version for arc and azcli extensions. (#17587)
Co-authored-by: Candice Ye <canye@microsoft.com>
2021-11-03 16:06:09 -07:00
Alex Ma
07b2b8128a [Loc] update to workspace trust xlf (#17584) 2021-11-03 11:55:26 -07:00
Charles Gagnon
43fe0ce482 VS Code -> ADS setting descriptions (#17563) 2021-11-03 10:05:56 -07:00
Alex Ma
c02c564a46 [Loc] Update to table designer (#17577) 2021-11-02 20:45:48 -07:00
Alan Ren
a3a91fbdfc add column properties (#17574) 2021-11-02 18:50:44 -07:00
Kim Santiago
312b410fff Add type for Document in sql database projects (#17539) 2021-11-02 13:17:18 -07:00
Lucy Zhang
8c3c18e8dc decrease length of installed packages table (#17556) 2021-11-02 12:04:39 -07:00
Kim Santiago
0d485ffe2b fix DefaultValue getting loaded for publish profiles (#17526)
* fix DefaultValue getting loaded for publish profiles

* add comment
2021-11-02 11:32:25 -07:00
Karl Burtram
d7b0b6c251 Add untrusted workspace supported flags (#17557) 2021-11-01 20:48:05 -07:00
Karl Burtram
2be1ec0656 Update reference to html-query-plan to use npm.js (#17558)
* Update reference to html-query-plan to use npm.js

* Change some references to html-query-plan package
2021-11-01 20:46:54 -07:00
Christopher Suh
66ebbc2181 Save & Close Fixes (#17469)
* wip

* fixed save & close summary page

* cleanup

* pr comments
2021-11-01 15:12:04 -07:00
Charles Gagnon
de3ae26873 Add launch target for sample-resource-deployment (#17553) 2021-11-01 15:05:32 -07:00
Charles Gagnon
25711acde0 Add a few missed instantiation service usages (#17554)
* Add a few missed instantiation service usages

* remove unused
2021-11-01 14:32:37 -07:00
Aditya Bist
6dda9392e0 respect include header option (#17134)
* respect include header option

* use correct option for copying

* check for setting when copying

* add dependency injection

* use instantiation service

Co-authored-by: chgagnon <chgagnon@microsoft.com>
2021-11-01 12:36:19 -07:00
Charles Gagnon
9bbe39e9e2 Add sample value provider (#17548) 2021-11-01 11:27:03 -07:00
Alex Ma
cfdc7005a2 [Loc] update to arc xlf (#17551) 2021-11-01 11:26:56 -07:00
Charles Gagnon
470f063124 Don't localize paths in sample resource deployment (#17544) 2021-11-01 10:14:12 -07:00
Charles Gagnon
a9d96e166a Delete azurecore value provider and simplify type (#17543) 2021-11-01 10:13:58 -07:00
Shagun Sharma Tamta
08d3803453 Link Database Earliest and Latest Point in time with DryRun (#17506) 2021-10-29 17:46:05 -07:00
Alan Ren
b48f392ab2 optional database name option (#17538)
* optional database name option

* object explorer connection title

* revert unexpected change

* bug fixes
2021-10-29 16:37:35 -07:00
csigs
ce8f1156b1 LEGO: check in for main to temporary branch. (#17537) 2021-10-29 14:42:31 -07:00
Charles Gagnon
82805638ad Add onClosed event to ModelView dialogs (#17531)
* Add onClosed event to ModelView dialogs

* Use defined type

* Fix compile

* fix tests

* fix tests2

* Remove unused
2021-10-28 20:53:20 -07:00
Alex Ma
62b6e781ce [Loc] update to data-workspace strings (#17533) 2021-10-28 16:11:38 -07:00
Charles Gagnon
00e5380331 sql-database-projects dialog completion cleanup (#17525) 2021-10-28 13:51:48 -07:00
Charles Gagnon
114a768634 String updates for Data Workspace & SQL Proj (#17504)
* Clean up extension descriptions

* More cleanup

* learning to spell

* Remove unused loc strings

* Add bundling information & rename view container

* Update data workspace readme
2021-10-28 13:33:19 -07:00
Alan Ren
12261aa7a2 text editor interface (#17527) 2021-10-28 13:23:33 -07:00
Aasim Khan
447b969b5c updating sts to get sql star expansion (#17528) 2021-10-28 13:17:39 -07:00
chayaverma7
8906d44f24 Update package.json (#17529)
Version bump ADS by updating the number in package.json
2021-10-29 01:32:34 +05:30
Alex Ma
5ab66056c8 [Loc] update to Data Workspace and Sql-database-projects (#17524) 2021-10-28 09:47:49 -07:00
Kim Santiago
e372fd9bdc Add project name to update project message (#17512)
* add project name to update SSDT project message

* add quotes
2021-10-27 15:13:30 -07:00
Charles Gagnon
d70ea2fbcb Fix localized titles in VS Code marketplace (#17514) 2021-10-27 13:51:58 -07:00
Kim Santiago
fee9c6e071 Don't show update project warning for new style sqlproj (#17490)
* don't show SSDT update warning for new style projects

* update strings

* add checks for the 2 other ways to specify msbuild sdk

* add link to docs on how to use project sdk

Co-authored-by: Kim Santiago <kisantia@Kims-MacBook-Pro.local>
2021-10-27 12:53:38 -07:00
Charles Gagnon
ab6b290b04 Fix update-typings pipeline (#17511) 2021-10-27 12:42:04 -07:00
Charles Gagnon
ca20ae4d64 Fix typings files (#17509) 2021-10-27 12:29:00 -07:00
brian-harris
7a5ad9f3aa bump version to 0.1.10 (#17510) 2021-10-27 12:13:58 -07:00
Charles Gagnon
d40d6fbe12 Fix publisher for VS Code extensions (#17505) 2021-10-27 10:17:29 -07:00
chayaverma7
ec8e607f74 Update CHANGELOG.md (#17499)
* Update CHANGELOG.md

ADS Oct 2021 Release

* Update CHANGELOG.md

Corrected the content for Oct Release

* Update CHANGELOG.md
2021-10-27 22:03:56 +05:30
chayaverma7
49473be3f7 Update README.md (#17498)
ADS Oct 2021 Release
2021-10-27 22:02:58 +05:30
Alex Ma
d41c6f4052 [loc] update for arc xlf (#17500) 2021-10-26 16:48:33 -07:00
Candice Ye
67a9f7a547 Added logic to make SQL MIAA script to notebook with user-inputted values, and minor text changes. (#17452)
* Changed the placement of the getValue comment in IValueProvider interface.

* Simplified some params values to feed into deployment notebook better. Added logic to add flags to the sql miaa create calls in notebook. Removed variablename from estimated cost.

* Changed High Availability to Replicas

Co-authored-by: Candice Ye <canye@microsoft.com>
2021-10-26 15:49:29 -07:00
Kim Santiago
9b45911141 vbump dacpac, schema compare, and sql database projects (#17492) 2021-10-26 10:49:44 -07:00
csigs
3ec148248f LEGO: check in for main to temporary branch. (#17493) 2021-10-25 23:15:10 -07:00
Alex Ma
cb6768463c [Loc] update to sql-migration and sql (#17488) 2021-10-25 13:20:12 -07:00
brian-harris
aa0e52c245 improve account and tenant selection error handling (#17476)
* improve account/tenant selection error handling

* remove extra space from user string
2021-10-25 12:26:38 -07:00
Alan Ren
8230d39120 add designer property grouping support (#17485)
* add properties grouping support

* revert unexpected changes

* use common color
2021-10-25 11:25:19 -07:00
Alan Ren
7b9caffcc2 vbump sqltools service (#17484) 2021-10-25 11:00:10 -07:00
Charles Gagnon
7049890f24 Don't log internal command executions from ext host (#17482) 2021-10-25 10:53:09 -07:00
Alex Ma
94cb358eae [Loc] update to SQL xlf (#17486) 2021-10-25 10:32:55 -07:00
csigs
313e436c95 LEGO: check in for main to temporary branch. (#17481)
Co-authored-by: Alex Ma <alma1@microsoft.com>
2021-10-25 10:12:48 -07:00
csigs
4268a8749b LEGO: check in for main to temporary branch. (#17478)
Co-authored-by: Alex Ma <alma1@microsoft.com>
2021-10-25 10:09:55 -07:00
Charles Gagnon
89c15c9496 Fix assessment results dialog telemetry (#17483) 2021-10-25 09:51:00 -07:00
csigs
7843993180 LEGO: check in for main to temporary branch. (#17477)
Co-authored-by: Alex Ma <alma1@microsoft.com>
2021-10-25 09:49:54 -07:00
csigs
b1bc6d911b LEGO: check in for main to temporary branch. (#17474) 2021-10-25 09:45:49 -07:00
Alan Ren
4ba192a5c3 make the designer event based (#17472)
* make the designer event based

* pr comments
2021-10-22 17:25:12 -07:00
brian-harris
70f6eebc5a apply unique filter to getLocations api's (#17454)
* apply unique filter to getLocations api's

* filter resource locations to distinct list

* simplify location filter
2021-10-22 16:00:07 -07:00
Daniel Grajeda
6200a61382 Notebook Views initialization fix (#17109)
Separate the Views load from the initialization. This way we can load previously created views, and only add the new views data to the document when needed. For now, this happens only when a view is created.
2021-10-22 14:50:21 -07:00
Karl Burtram
6e65063317 Remove duplicate Getting Started contributions (#17465) 2021-10-22 12:52:49 -07:00
Charles Gagnon
f57c41fead Fix backups not restoring in correct editor (#17466) 2021-10-22 12:15:30 -07:00
Alex Ma
7a62f44441 [Loc] updates to loc for arc and sql-database (#17467) 2021-10-22 11:30:13 -07:00
csigs
e1d34c24a4 LEGO: check in for main to temporary branch. (#17461)
Co-authored-by: Karl Burtram <karlb@microsoft.com>
2021-10-22 10:19:54 -07:00
csigs
65e67e9a37 LEGO: check in for main to temporary branch. (#17453) 2021-10-22 10:05:30 -07:00
Benjin Dubishar
86320155ed Correcting log messages during autorest execution selection (#17434)
* Correcting log messages during autorest execution choice

* Combining redundant strings

* Correcting icon + loc

* Fixing typo
2021-10-22 06:01:11 -07:00
Candice Ye
dc0651aef7 Added a dynamic Cost Summary section to SQL MIAA Deployment Wizard (#17420)
* Added valueprovider for pricing. Pushing this for troubleshooting help.

* Committing changes for troubleshooting help. Moved InputValueType to typings file.

* Add readonly inputs to list

* Fixed ordering of package.json merge items

* Estimated cost moved to input page, ValueProvider only takes in a triggerfields[] and not a single string, fixed pricing logic.

* Removed pricingModel.ts

* Reverted some comments and code changes that were used in debugging.

* Changed some values from localizedConstants to single-quote constants'

* Changed some values from localizedConstants to single-quote constants'

* Added copyright header to pricingUtils.ts

* Removed try catch in extension.ts valueproviders, made some values in PricingUtils.ts top-level instead of exporting.

* Minor changes, added some comments and localized USD.

* Changes pricingutils classes to be constants, and added disposable to Hookupvalueprovider

Co-authored-by: Candice Ye <canye@microsoft.com>
Co-authored-by: chgagnon <chgagnon@microsoft.com>
2021-10-21 16:51:31 -07:00
Alan Ren
5fe569e864 fix scrolling issue (#17443) 2021-10-21 15:51:46 -07:00
Charles Gagnon
57130f2f2b Fix URL protocol for non-insiders builds (#17442) 2021-10-21 15:42:27 -07:00
Alex Ma
0b994651d1 [Loc] Update to sql-database-projects and sql-migration xlfs (#17445) 2021-10-21 15:41:25 -07:00
Z Chen
2ed8aeb565 Warning when .NET 6 SDK is detected (#17422)
* Check for max supported version

* Separate dialog for downgrade warning

* Address PR comments

* Use markdown link

* Update warning message
2021-10-21 13:48:52 -07:00
Benjin Dubishar
6f65119166 Use correct string when checking "browse" option (#17432)
* Correct browse string match

* Deduping const
2021-10-21 13:24:35 -07:00
Maddy
a05be3912e add path.posix while reading relative paths (#17326)
* path.posix

* add test for nested folders scenario

* update message and remove the redundant check
2021-10-21 12:47:01 -07:00
rajeshka
914ac2b09d remove trailing line after the cursor (#17431)
* remove trailing line after the cursor

* Addressed PR
2021-10-21 11:04:31 -07:00
Rachel Kim
4b26be5742 Retry sql migration (#17376) 2021-10-21 10:06:10 -07:00
csigs
decad711c5 LEGO: check in for main to temporary branch. (#17435) 2021-10-21 09:09:13 -07:00
csigs
4715993726 LEGO: check in for main to temporary branch. (#17430) 2021-10-21 09:07:52 -07:00
rajeshka
d196588661 fixing the svg (#17427) 2021-10-20 19:11:13 -07:00
Cory Rivera
0bc8e54568 Fix quoted link failures by removing quotes from unescaped paths, rather than just the escaped paths. (#17419) 2021-10-20 18:12:39 -07:00
Alex Ma
6fb66e5de6 [Loc] added designer and spinner strings (#17424) 2021-10-20 15:38:29 -07:00
rajeshka
d251bbd1a1 Fix for Split Cell duplicates cell #17400 (#17417) 2021-10-20 14:47:58 -07:00
Lucy Zhang
8212eecec7 add listener for celltype change (#17414) 2021-10-20 13:51:27 -07:00
Alan Ren
c89aa26c0a loading indicator for table designer (#17407)
* loading indicator for table designer

* fix layering error

* bug fix
2021-10-20 12:54:23 -07:00
Alan Ren
328ed83cb9 add disposeTableDesigner (#17394) 2021-10-19 14:28:56 -07:00
Charles Gagnon
ec8292adb7 Add initial developer guide for resource deployment (#17395)
* Add initial developer guide for resource deployment

* PR comments
2021-10-19 13:47:36 -07:00
Alex Ma
5238244380 [Loc] Addition to sql-database-projects xlf (#17391) 2021-10-19 11:01:28 -07:00
Alan Ren
569d5cf694 rename dataModel to viewModel (#17387) 2021-10-19 09:52:03 -07:00
Lewis Sanchez
e1a8885e43 New commit hash to use for distro after merging PR (#17389) 2021-10-19 09:08:58 -07:00
Lewis Sanchez
1fabd233e9 Add logging to ADS Web smoke tests, and skip failing tests. (#17353)
* Adds loggings to ADS pipeline

* Skips notebook smoke tests for ADS web.

* Skips failing create book dialog tests in web build

* Ignores import tests ADS web

* Groups related tests together for ADS Web and non-web

* Updates distro commit hash
2021-10-18 19:46:45 -07:00
Lucy Zhang
9a05d81215 use setContent instead of addElement (#17386) 2021-10-18 18:32:05 -07:00
Vasu Bhog
a8ee26ed89 Move split cell icon (#17383)
* move split cell icon before delete icon
2021-10-18 16:43:25 -07:00
csigs
dacfddc523 LEGO: check in for main to temporary branch. (#17384) 2021-10-18 13:40:07 -07:00
542 changed files with 38218 additions and 7764 deletions

View File

@@ -751,7 +751,7 @@
"chart.js",
"plotly.js",
"angular2-grid",
"html-query-plan",
"kburtram-query-plan",
"html-to-image",
"turndown",
"gridstack",

25
.vscode/launch.json vendored
View File

@@ -269,6 +269,31 @@
"presentation": {
"group": "4_web"
}
},
{
"name": "Run Sample Resource Deployment Extension",
"type": "sqlopsExtensionHost",
"request": "launch",
"windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.bat"
},
"osx": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
},
"linux": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
},
"args": [
"--extensionDevelopmentPath=${workspaceRoot}/samples/sample-resource-deployment"
],
"outFiles": [
"${workspaceRoot}/samples/sample-resource-deployment/out/**/*.js"
],
"preLaunchTask": "Watch sample-resource-deployment",
"presentation": {
"group": "5_samples"
},
"timeout": 30000
}
],
"compounds": [

12
.vscode/tasks.json vendored
View File

@@ -231,6 +231,18 @@
"group": "build",
"label": "npm: tsec-compile-check",
"detail": "node_modules/tsec/bin/tsec -p src/tsconfig.json --noEmit"
},
{
"type": "npm",
"script": "watch",
"label": "Watch sample-resource-deployment",
"path": "./samples/sample-resource-deployment/package.json",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": "build"
}
]
}

View File

@@ -1,5 +1,61 @@
# Change Log
## Version 1.33.1
* Release date: Nov 4, 2021
* Release status: General Availability
## Hotfix release
- Fix for [#16535 Unable to See Saved Connections in Restricted Mode](https://github.com/microsoft/azuredatastudio/issues/17535)
- Fix for [#17579 Can't type in Notebook code cell after editing text cell](https://github.com/microsoft/azuredatastudio/issues/17579)
| Platform |
| --------------------------------------- |
| [Windows User Installer][win-user] |
| [Windows System Installer][win-system] |
| [Windows ZIP][win-zip] |
| [macOS ZIP][osx-zip] |
| [Linux TAR.GZ][linux-zip] |
| [Linux RPM][linux-rpm] |
| [Linux DEB][linux-deb] |
[win-user]: https://go.microsoft.com/fwlink/?linkid=2176805
[win-system]: https://go.microsoft.com/fwlink/?linkid=2175910
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2176806
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2176807
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2176505
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2176005
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2176006
## Version 1.33.0
* Release date: October 27, 2021
* Release status: General Availability
## What's new in this version
* New Notebook Features:
* Notebook Views
* Split cell support
* Keyboard shortcuts for Markdown Toolbar Cells
* Ctrl/Cmd + B = Bold Text
* Ctrl/Cmd + I = Italicize Text
* Ctrl/Cmd + U = Underline Text
* Ctrl/Cmd + Shift + K = Add Code Block
* Ctrl/Cmd + Shift + H = Highlight Text
* Book improvements
* Add a new section
* Drag and Drop
* Extension Updates:
* Import
* Langpacks
* Schema Compare
* Sql Database Projects
* Bug Fixes
* Notebook linking improvements
* Horizontal Scrollbar improvement (when word wrap is off in MD Splitview / MD mode) in Notebooks
* Vertical Scrollbar improvement for MD Splitview in Notebooks
## Version 1.32.0
* Release date: August 18, 2021
* Release status: General Availability

View File

@@ -131,10 +131,10 @@ Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the [Source EULA](LICENSE.txt).
[win-user]: https://go.microsoft.com/fwlink/?linkid=2170400
[win-system]: https://go.microsoft.com/fwlink/?linkid=2170401
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2170402
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2169955
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2170045
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2170403
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2169956
[win-user]: https://go.microsoft.com/fwlink/?linkid=2176805
[win-system]: https://go.microsoft.com/fwlink/?linkid=2175910
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2176806
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2176807
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2176505
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2176005
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2176006

View File

@@ -1 +1 @@
2021-08-23T03:52:18.011Z
2021-11-19T02:27:18.022Z

View File

@@ -61,6 +61,7 @@ steps:
key: 'nodeModules | $(Agent.OS) | .build/yarnlockhash'
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
continueOnError: true
- script: |
set -e

View File

@@ -57,6 +57,7 @@ steps:
key: 'nodeModules | $(Agent.OS) | .build/yarnlockhash'
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
continueOnError: true
- script: |
set -e
@@ -187,7 +188,7 @@ steps:
displayName: 'Install .NET Core sdk for signing'
inputs:
packageType: sdk
version: 2.1.x
version: 5.0.x
installationPath: $(Agent.ToolsDirectory)/dotnet
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1

View File

@@ -52,6 +52,7 @@ steps:
# Sync up to latest from the DT repo
git remote add upstream https://github.com/DefinitelyTyped/DefinitelyTyped.git
git fetch upstream
git merge upstream/master
git push origin

View File

@@ -2,7 +2,7 @@ resources:
containers:
- container: linux-x64
image: sqltoolscontainers.azurecr.io/linux-build-agent:3
endpoint: ContainerRegistry
endpoint: SqlToolsContainers
jobs:
- job: Compile
@@ -20,7 +20,7 @@ jobs:
- job: macOS
condition: and(succeeded(), eq(variables['VSCODE_BUILD_MACOS'], 'true'), ne(variables['VSCODE_QUALITY'], 'saw'))
pool:
vmImage: macOS-latest
vmImage: 'macOS-10.15'
dependsOn:
- Compile
steps:
@@ -30,7 +30,7 @@ jobs:
- job: macOS_Signing
condition: and(succeeded(), eq(variables['VSCODE_BUILD_MACOS'], 'true'), eq(variables['signed'], true), ne(variables['VSCODE_QUALITY'], 'saw'))
pool:
vmImage: macOS-latest
vmImage: 'macOS-10.15'
dependsOn:
- macOS
steps:
@@ -53,7 +53,7 @@ jobs:
- job: Windows
condition: and(succeeded(), eq(variables['VSCODE_BUILD_WIN32'], 'true'))
pool:
vmImage: VS2017-Win2016
vmImage: 'windows-2019'
dependsOn:
- Compile
steps:

View File

@@ -2,7 +2,7 @@ resources:
containers:
- container: linux-x64
image: sqltoolscontainers.azurecr.io/web-build-image:2
endpoint: ContainerRegistry
endpoint: SqlToolsContainers
jobs:
- job: LinuxWeb

View File

@@ -43,6 +43,7 @@ steps:
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore Cache - Node Modules
continueOnError: true
- script: |
set -e
@@ -108,7 +109,7 @@ steps:
set -e
node ./node_modules/playwright/install.js
APP_ROOT=$(Agent.BuildDirectory)/vscode-reh-web-linux-x64
xvfb-run yarn smoketest --build "$(Agent.BuildDirectory)/vscode-reh-web-linux-x64" --web --headless --screenshots "$(Build.ArtifactStagingDirectory)/smokeshots"
xvfb-run yarn smoketest --build "$(Agent.BuildDirectory)/vscode-reh-web-linux-x64" --web --headless --screenshots "$(Build.ArtifactStagingDirectory)/smokeshots" --log "$(Build.ArtifactStagingDirectory)/logs/web/smoke.log"
displayName: Run smoke tests (Browser)
continueOnError: true
condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true'))
@@ -170,7 +171,7 @@ steps:
displayName: 'Install .NET Core sdk for signing'
inputs:
packageType: sdk
version: 2.1.x
version: 5.0.x
installationPath: $(Agent.ToolsDirectory)/dotnet
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1

View File

@@ -27,7 +27,7 @@ steps:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { tar --force-local -xzf $(Pipeline.Workspace)/compilation.tar.gz }
exec { tar -xf $(Pipeline.Workspace)/compilation.tar.gz }
displayName: Extract compilation output
- powershell: |
@@ -57,6 +57,7 @@ steps:
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore Cache - Node Modules
continueOnError: true
- powershell: |
. build/azure-pipelines/win32/exec.ps1

View File

@@ -65,5 +65,8 @@
"watch": "tsc -p tsconfig.build.json --watch",
"npmCheckJs": "tsc --noEmit"
},
"dependencies": {}
"dependencies": {},
"resolutions": {
"json-schema": "0.4.0"
}
}

View File

@@ -1382,10 +1382,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-stringify-safe@~5.0.1:
version "5.0.1"

View File

@@ -9,6 +9,12 @@
"vscode": "*",
"azdata": "*"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionPack": [
"Microsoft.agent",
"Microsoft.profiler",

View File

@@ -15,6 +15,12 @@
"scripts": {
"postinstall": "node ./build/postinstall.js"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"activationEvents": [
"onCommand:adminToolExtWin.launchSsmsMinPropertiesDialog",
"onCommand:adminToolExtWin.launchSsmsMinGswDialog"

View File

@@ -19,6 +19,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"Microsoft.mssql"
],

View File

@@ -1,27 +1,10 @@
{
"metadata": {
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python",
"version": "3.6.6",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
}
},
"nbformat_minor": 2,
"nbformat": 4,
"cells": [
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "82e60c1a-7acf-47ee-877f-9e85e92e11da"
},
"source": [
"![Microsoft](https://raw.githubusercontent.com/microsoft/azuredatastudio/main/extensions/arc/images/microsoft-small-logo.png)\n",
" \n",
@@ -33,13 +16,13 @@
"* The **Required information** will check and prompt you for password if it is not set in the environment variable. The password can be used to access the data controller.\n",
"\n",
"<span style=\"color:red\"><font size=\"3\">Please press the \"Run All\" button to run the notebook</font></span>"
],
"metadata": {
"azdata_cell_guid": "82e60c1a-7acf-47ee-877f-9e85e92e11da"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "714582b9-10ee-409e-ab12-15a4825c9471"
},
"source": [
"### **Prerequisites** \n",
"Ensure the following tools are installed and added to PATH before proceeding.\n",
@@ -49,23 +32,25 @@
"|kubectl | Command-line tool for monitoring the underlying Kubernetes cluster | [Installation](https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-binary-using-native-package-management) |\n",
"|Azure CLI (az) | Command-line tool for installing and managing resources in an Azure Arc cluster |[Installation](https://docs.microsoft.com/cli/azure/install-azure-cli-windows?tabs=azure-cli) |\n",
"|Azure CLI arcdata extension | Commands for using Azure Arc for Azure data services. | [Installation](https://docs.microsoft.com/azure/azure-arc/data/install-arcdata-extension)"
],
"metadata": {
"azdata_cell_guid": "714582b9-10ee-409e-ab12-15a4825c9471"
}
]
},
{
"cell_type": "markdown",
"source": [
"### **Setup**"
],
"metadata": {
"azdata_cell_guid": "e3dd8e75-e15f-44b4-81fc-1f54d6f0b1e2"
}
},
"source": [
"### **Setup**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "d973d5b4-7f0a-4a9d-b204-a16480f3940d",
"tags": []
},
"outputs": [],
"source": [
"import sys,os,getpass\n",
"def run_command(command):\n",
@@ -74,56 +59,56 @@
" if _exit_code != 0:\n",
" sys.exit(f'Command execution failed with exit code: {str(_exit_code)}.\\n\\t{command}\\n')\n",
" print(f'Successfully executed: {command}')"
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "d973d5b4-7f0a-4a9d-b204-a16480f3940d",
"tags": []
}
]
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "4b266b2d-bd1b-4565-92c9-3fc146cdce6d"
},
"source": [
"### **Set variables**\n",
"Generated by Azure Data Studio using the values collected in the 'Create Azure Arc data controller' wizard."
],
"metadata": {
"azdata_cell_guid": "4b266b2d-bd1b-4565-92c9-3fc146cdce6d"
}
]
},
{
"cell_type": "markdown",
"source": [
"### **Check dependencies**"
],
"metadata": {
"azdata_cell_guid": "2544648b-59c9-4ce5-a3b6-87086e214d4c"
}
},
"source": [
"### **Check dependencies**"
]
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"run_command('az --version')"
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "691671d7-3f05-406c-a183-4cff7d17f83d",
"tags": []
}
},
"outputs": [],
"source": [
"run_command('az --version')"
]
},
{
"cell_type": "markdown",
"source": [
"### **Required information**"
],
"metadata": {
"azdata_cell_guid": "0bb02e76-fee8-4dbc-a75b-d5b9d1b187d0"
}
},
"source": [
"### **Required information**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "e7e10828-6cae-45af-8c2f-1484b6d4f9ac",
"tags": []
},
"outputs": [],
"source": [
"if \"AZDATA_NB_VAR_ARC_ADMIN_PASSWORD\" in os.environ:\n",
" arc_admin_password = os.environ[\"AZDATA_NB_VAR_ARC_ADMIN_PASSWORD\"]\n",
@@ -135,85 +120,130 @@
" confirm_password = getpass.getpass(prompt = 'Confirm password')\n",
" if arc_admin_password != confirm_password:\n",
" sys.exit(f'Passwords do not match.')"
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "e7e10828-6cae-45af-8c2f-1484b6d4f9ac",
"tags": []
}
]
},
{
"cell_type": "markdown",
"source": [
"### **Set and show current context**"
],
"metadata": {
"azdata_cell_guid": "127c8042-181f-4862-a390-96e59c181d09"
}
},
"source": [
"### **Set and show current context**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "7d1a03d4-1df8-48eb-bff0-0042603b95b1",
"tags": []
},
"outputs": [],
"source": [
"os.environ[\"KUBECONFIG\"] = arc_config_file\n",
"run_command(f'kubectl config use-context {arc_cluster_context}')\n",
"run_command('kubectl config current-context')"
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "7d1a03d4-1df8-48eb-bff0-0042603b95b1",
"tags": []
}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Create Azure Arc Data Controller**"
],
"metadata": {
"azdata_cell_guid": "efe78cd3-ed73-4c9b-b586-fdd6c07dd37f"
}
"### **Log in to Azure CLI**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"is_indirect = arc_data_controller_connectivity_mode == 'Indirect'\n",
"\n",
"if not is_indirect:\n",
"\trun_command('az login')"
]
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "efe78cd3-ed73-4c9b-b586-fdd6c07dd37f"
},
"source": [
"### **Create Azure Arc Data Controller**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "373947a1-90b9-49ee-86f4-17a4c7d4ca76",
"tags": []
},
"outputs": [],
"source": [
"print (f'Creating Azure Arc Data Controller: {arc_data_controller_name} using configuration {arc_cluster_context}')\n",
"os.environ[\"AZDATA_USERNAME\"] = arc_admin_username\n",
"os.environ[\"AZDATA_PASSWORD\"] = arc_admin_password\n",
"\n",
"namespace = f' --k8s-namespace {arc_data_controller_namespace}' if is_indirect else ''\n",
"use_k8s = ' --use-k8s' if is_indirect else ''\n",
"\n",
"custom_location = f' --custom-location {arc_data_controller_custom_location}' if not is_indirect else ''\n",
"\n",
"auto_upload_metrics_value = 'true' if arc_data_controller_auto_upload_metrics == 'true' else 'false'\n",
"auto_upload_logs_value = 'true' if arc_data_controller_auto_upload_logs == 'true' else 'false'\n",
"\n",
"auto_upload_metrics = f' --auto-upload-metrics {auto_upload_metrics_value}' if not is_indirect else ''\n",
"auto_upload_logs = f' --auto-upload-logs {auto_upload_logs_value}' if not is_indirect else ''\n",
"\n",
"if os.name == 'nt':\n",
" print(f'If you don\\'t see output produced by az, you can run the following command in a terminal window to check the deployment status:\\n\\t {os.environ[\"AZDATA_NB_VAR_KUBECTL\"]} get pods -n {arc_data_controller_namespace}')\n",
"run_command(f'az arcdata dc create --connectivity-mode indirect --name {arc_data_controller_name} --k8s-namespace {arc_data_controller_namespace} --subscription {arc_subscription} --resource-group {arc_resource_group} --location {arc_data_controller_location} --storage-class {arc_data_controller_storage_class} --profile-name {arc_profile} --infrastructure {arc_infrastructure} --use-k8s')\n",
"run_command(f'az arcdata dc create --connectivity-mode {arc_data_controller_connectivity_mode} --name {arc_data_controller_name}{namespace} --subscription {arc_subscription} --resource-group {arc_resource_group} --location {arc_data_controller_location} --storage-class {arc_data_controller_storage_class} --profile-name {arc_profile} --infrastructure {arc_infrastructure}{custom_location}{auto_upload_metrics}{auto_upload_logs}{use_k8s}')\n",
"print(f'Azure Arc Data Controller: {arc_data_controller_name} created.') "
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "373947a1-90b9-49ee-86f4-17a4c7d4ca76",
"tags": []
}
]
},
{
"cell_type": "markdown",
"source": [
"### **Setting context to created Azure Arc Data Controller**"
],
"metadata": {
"azdata_cell_guid": "a3ddc701-811d-4058-b3fb-b7295fcf50ae"
}
},
"source": [
"### **Setting context to created Azure Arc Data Controller**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "c974561f-13d0-4e7a-b74b-d781c2e06d68"
},
"outputs": [],
"source": [
"# Setting context to Data Controller.\n",
"#\n",
"run_command(f'kubectl config set-context --current --namespace {arc_data_controller_namespace}')"
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "c974561f-13d0-4e7a-b74b-d781c2e06d68"
}
]
}
]
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -1,28 +1,10 @@
{
"metadata": {
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"language_info": {
"name": "python",
"version": "3.6.6",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
}
},
"nbformat_minor": 2,
"nbformat": 4,
"cells": [
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "e4ed0892-7b5a-4d95-bd0d-a6c3eb0b2c99"
},
"source": [
"![Microsoft](https://raw.githubusercontent.com/microsoft/azuredatastudio/main/extensions/arc/images/microsoft-small-logo.png)\n",
" \n",
@@ -34,13 +16,13 @@
"* Make sure you have the target Azure Arc Data Controller already created.\n",
"\n",
"<span style=\"color:red\"><font size=\"3\">Please press the \"Run All\" button to run the notebook</font></span>"
],
"metadata": {
"azdata_cell_guid": "e4ed0892-7b5a-4d95-bd0d-a6c3eb0b2c99"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "d1c8258e-9efd-4380-a48c-cd675423ed2f"
},
"source": [
"### **Prerequisites** \n",
"Ensure the following tools are installed and added to PATH before proceeding.\n",
@@ -49,23 +31,25 @@
"|---|---|---|\n",
"|Azure CLI (az) | Command-line tool for installing and managing resources in an Azure Arc cluster |[Installation](https://docs.microsoft.com/cli/azure/install-azure-cli-windows?tabs=azure-cli) |\n",
"|Azure CLI arcdata extension | Commands for using Azure Arc for Azure data services. | [Installation](https://docs.microsoft.com/azure/azure-arc/data/install-arcdata-extension)"
],
"metadata": {
"azdata_cell_guid": "d1c8258e-9efd-4380-a48c-cd675423ed2f"
}
]
},
{
"cell_type": "markdown",
"source": [
"### **Setup and Check Prerequisites**"
],
"metadata": {
"azdata_cell_guid": "68531b91-ddce-47d7-a1d8-2ddc3d17f3e7"
}
},
"source": [
"### **Setup and Check Prerequisites**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "749d8dba-3da8-46e9-ae48-2b38056ab7a2",
"tags": []
},
"outputs": [],
"source": [
"import sys,os,json,subprocess\n",
"def run_command():\n",
@@ -80,38 +64,37 @@
" return output.stdout.decode(\"utf-8\")\n",
"cmd = 'az --version'\n",
"out = run_command()\n"
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "749d8dba-3da8-46e9-ae48-2b38056ab7a2",
"tags": []
}
]
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "68ec0760-27d1-4ded-9a9f-89077c40b8bb"
},
"source": [
"### **Set variables**\n",
"\n",
"#### \n",
"\n",
"Generated by Azure Data Studio using the values collected in the 'Deploy Azure SQL managed instance - Azure Arc' wizard"
],
"metadata": {
"azdata_cell_guid": "68ec0760-27d1-4ded-9a9f-89077c40b8bb"
}
]
},
{
"cell_type": "markdown",
"source": [
"### **Creating the SQL managed instance - Azure Arc instance**"
],
"metadata": {
"azdata_cell_guid": "90b0e162-2987-463f-9ce6-12dda1267189"
}
},
"source": [
"### **Creating the SQL managed instance - Azure Arc instance**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "4fbaf071-55a1-40bc-be7e-7b9b5547b886"
},
"outputs": [],
"source": [
"print (f'Creating the SQL managed instance - Azure Arc instance')\n",
"\n",
@@ -124,24 +107,44 @@
"storage_class_datalogs_option = f' --storage-class-datalogs \"{sql_storage_class_datalogs}\"'if sql_storage_class_datalogs else \"\"\n",
"storage_class_logs_option = f' --storage-class-logs \"{sql_storage_class_logs}\"'if sql_storage_class_logs else \"\"\n",
"storage_class_backup_option = f' --storage-class-backups \"{sql_storage_class_backups}\"'if sql_storage_class_backups else \"\"\n",
"retention_days = f' --retention-days \"{sql_retention_days}\"' if sql_retention_days else \"\"\n",
"retention_days = f' --retention-days \"{sql_retention_days}\"' if sql_retention_days else \"\"\n",
"\n",
"volume_size_data = f' --volume-size-data {sql_volume_size_data}Gi'\n",
"volume_size_datalogs = f' --volume-size-datalogs {sql_volume_size_datalogs}Gi'\n",
"volume_size_logs = f' --volume-size-logs {sql_volume_size_logs}Gi'\n",
"volume_size_backups = f' --volume-size-backups {sql_volume_size_backups}Gi'\n",
"\n",
"service_tier = f' --tier {sql_service_tier}'\n",
"cores_limit = f' --cores-limit {sql_cores_limit}'\n",
"dev_use = ' --dev' if sql_dev_use else ''\n",
"license_type = ' --license-type BasePrice' if sql_license_type else ' --license-type LicenseIncluded'\n",
"\n",
"os.environ[\"AZDATA_USERNAME\"] = sql_username\n",
"os.environ[\"AZDATA_PASSWORD\"] = os.environ[\"AZDATA_NB_VAR_SQL_PASSWORD\"]\n",
"cmd = f'az sql mi-arc create --name {sql_instance_name} --k8s-namespace {arc_data_controller_namespace} --replicas {sql_replicas}{cores_request_option}{cores_limit_option}{memory_request_option}{memory_limit_option}{storage_class_data_option}{storage_class_datalogs_option}{storage_class_logs_option}{storage_class_backup_option}{volume_size_data}{volume_size_datalogs}{volume_size_logs}{volume_size_backups}{retention_days} --use-k8s'\n",
"cmd = f'az sql mi-arc create --name {sql_instance_name} --k8s-namespace {arc_data_controller_namespace} --replicas {sql_replicas}{cores_request_option}{cores_limit_option}{memory_request_option}{memory_limit_option}{storage_class_data_option}{storage_class_datalogs_option}{storage_class_logs_option}{storage_class_backup_option}{volume_size_data}{volume_size_datalogs}{volume_size_logs}{volume_size_backups}{retention_days}{service_tier}{dev_use}{license_type}{cores_limit} --use-k8s'\n",
"out=run_command()"
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "4fbaf071-55a1-40bc-be7e-7b9b5547b886"
}
]
}
]
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -2,7 +2,7 @@
"name": "arc",
"displayName": "%arc.displayName%",
"description": "%arc.description%",
"version": "0.9.6",
"version": "0.9.7",
"publisher": "Microsoft",
"preview": true,
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
@@ -21,6 +21,12 @@
"Microsoft.azcli",
"Microsoft.resource-deployment"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
@@ -255,6 +261,20 @@
"label": "%arc.data.controller.details.description%",
"labelWidth": "600px"
},
{
"type": "options",
"label": "%arc.data.controller.connectivity.mode%",
"required": true,
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
"options": {
"values": [
"Indirect",
"Direct"
],
"defaultValue": "Indirect",
"optionsType": "radio"
}
},
{
"type": "text",
"label": "%arc.data.controller.namespace%",
@@ -267,7 +287,11 @@
],
"defaultValue": "arc",
"required": true,
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_NAMESPACE"
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_NAMESPACE",
"enabled": {
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
"value": "Indirect"
}
},
{
"type": "text",
@@ -304,6 +328,39 @@
"onpremises",
"other"
]
},
{
"type": "text",
"label": "%arc.data.controller.custom.location%",
"description": "%arc.data.controller.custom.location.description%",
"required": true,
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CUSTOM_LOCATION",
"enabled": {
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
"value": "Direct"
}
},
{
"type": "checkbox",
"label": "%arc.data.controller.auto.upload.metrics%",
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_AUTO_UPLOAD_METRICS",
"description": "%arc.data.controller.auto.upload.metrics.description%",
"defaultValue": false,
"enabled": {
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
"value": "Direct"
}
},
{
"type": "checkbox",
"label": "%arc.data.controller.auto.upload.logs%",
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_AUTO_UPLOAD_LOGS",
"description": "%arc.data.controller.auto.upload.logs.description%",
"defaultValue": false,
"enabled": {
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
"value": "Direct"
}
}
]
},
@@ -983,7 +1040,7 @@
"fields": [
{
"type": "options",
"label": "%arc.sql.high.availability.label%",
"label": "%arc.sql.replicas%",
"description": "%arc.sql.high.availability.description%",
"required": true,
"variableName": "AZDATA_NB_VAR_SQL_REPLICAS",
@@ -1079,6 +1136,7 @@
"variableName": "AZDATA_NB_VAR_SQL_CORES_REQUEST",
"type": "number",
"min": 1,
"defaultValue": 2,
"required": false,
"validations": [
{
@@ -1095,6 +1153,7 @@
"type": "number",
"min": 1,
"required": false,
"defaultValue": 4,
"validations": [
{
"type": ">=",
@@ -1109,6 +1168,7 @@
"variableName": "AZDATA_NB_VAR_SQL_MEMORY_REQUEST",
"type": "number",
"min": 2,
"defaultValue": 4,
"required": false,
"validations": [
{
@@ -1124,6 +1184,7 @@
"variableName": "AZDATA_NB_VAR_SQL_MEMORY_LIMIT",
"type": "number",
"min": 2,
"defaultValue": 8,
"required": false,
"validations": [
{
@@ -1136,9 +1197,9 @@
{
"type": "options",
"label": "%arc.sql.service.tier.label%",
"variableName": "AZDATA_NB_VAR_SQL_SERVICE_TIER",
"description": "%arc.sql.service.tier.description%",
"required": true,
"variableName": "AZDATA_NB_VAR_SQL_SERVICE_TIER",
"options": {
"values": [
"%arc.sql.service.tier.business.critical%",
@@ -1151,10 +1212,16 @@
{
"type": "checkbox",
"label": "%arc.sql.dev.use.label%",
"description": "%arc.sql.dev.use.description%",
"defaultValue": "false",
"variableName": "AZDATA_NB_VAR_SQL_DEV_USE",
"required": true
"description": "%arc.sql.dev.use.description%",
"defaultValue": false
},
{
"type": "checkbox",
"label": "%arc.sql.license.type.label%",
"variableName": "AZDATA_NB_VAR_SQL_LICENSE_TYPE",
"description": "%arc.sql.license.type.description%",
"defaultValue": false
}
]
},
@@ -1179,13 +1246,85 @@
"description": "%arc.sql.retention.days.description%",
"variableName": "AZDATA_NB_VAR_SQL_RETENTION_DAYS",
"type": "number",
"min": 1,
"min": 0,
"max": 35,
"required": false
}
]
},
{
"title": "%arc.sql.cost.summary%",
"fields": [
{
"label": "%arc.sql.cost.summary.additional.charge%",
"type": "readonly_text",
"enabled": true,
"labelWidth": "750px",
"links": [
{
"text": "%arc.sql.cost.summary.pricing.details%",
"url": "https://aka.ms/ArcSQLBilling"
}
]
},
{
"label": "%arc.sql.cost.summary.cost.vcore%",
"type": "readonly_text",
"isEvaluated": true,
"defaultValue": "0.00 USD",
"valueProvider": {
"providerId": "params-to-cost-per-vcore",
"triggerFields": [
"AZDATA_NB_VAR_SQL_DEV_USE",
"AZDATA_NB_VAR_SQL_SERVICE_TIER"
]
}
},
{
"label": "%arc.sql.cost.summary.vcore.limit%",
"type": "readonly_text",
"isEvaluated": true,
"defaultValue": "x 4",
"valueProvider": {
"providerId": "params-to-vcore-limit",
"triggerFields": [
"AZDATA_NB_VAR_SQL_CORES_LIMIT"
]
}
},
{
"label": "%arc.sql.cost.summary.azure.hybrid.benefit.discount%",
"type": "readonly_text",
"isEvaluated": true,
"defaultValue": "- 0",
"valueProvider": {
"providerId": "params-to-hybrid-benefit-discount",
"triggerFields": [
"AZDATA_NB_VAR_SQL_CORES_LIMIT",
"AZDATA_NB_VAR_SQL_DEV_USE",
"AZDATA_NB_VAR_SQL_SERVICE_TIER",
"AZDATA_NB_VAR_SQL_LICENSE_TYPE"
]
}
},
{
"label": "%arc.sql.cost.summary.estimated.cost.per.month%",
"type": "readonly_text",
"defaultValue": "0.00 USD",
"valueProvider": {
"providerId": "params-to-estimated-cost",
"triggerFields": [
"AZDATA_NB_VAR_SQL_REPLICAS",
"AZDATA_NB_VAR_SQL_CORES_LIMIT",
"AZDATA_NB_VAR_SQL_DEV_USE",
"AZDATA_NB_VAR_SQL_SERVICE_TIER",
"AZDATA_NB_VAR_SQL_LICENSE_TYPE"
]
}
}
]
}
]
]
}
]
},
@@ -1235,7 +1374,6 @@
]
},
"dependencies": {
"request": "^2.88.0",
"uuid": "^8.3.0",
"vscode-nls": "^4.1.2",
"yamljs": "^0.3.0"
@@ -1243,7 +1381,6 @@
"devDependencies": {
"@types/mocha": "^5.2.5",
"@types/node": "^12.11.7",
"@types/request": "^2.48.3",
"@types/sinon": "^9.0.4",
"@types/uuid": "^8.3.0",
"@types/yamljs": "^0.2.31",

View File

@@ -10,6 +10,7 @@
"command.removeController.title": "Remove Controller",
"command.refresh.title": "Refresh",
"command.editConnection.title": "Edit Connection",
"command.estimateCostSqlMiaa.title": "Estimate Cost of SQL Managed Instance - Azure Arc",
"arc.openDashboard": "Manage",
"resource.type.azure.arc.display.name": "Azure Arc data controller (preview)",
@@ -27,13 +28,22 @@
"arc.data.controller.project.details.title": "Azure details",
"arc.data.controller.project.details.description": "Select the subscription to manage deployed resources and costs. Use resource groups like folders to organize and manage all your resources.",
"arc.data.controller.details.title": "Data controller details",
"arc.data.controller.details.description": "Provide a namespace, name and storage class for your Azure Arc data controller. This name will be used to identify your Arc instance for remote management and monitoring.",
"arc.data.controller.details.description": "For indirect mode, provide a namespace, name and storage class for your Azure Arc data controller. This name will be used to identify your Arc instance for remote management and monitoring. For direct mode you do not need to provide a namespace, but please provide the custom location name.",
"arc.data.controller.connectivity.mode": "Connectivity mode",
"arc.data.controller.namespace": "Data controller namespace",
"arc.data.controller.namespace.description": "Indirect mode only.",
"arc.data.controller.namespace.validation.description": "Namespace must consist of lower case alphanumeric characters or '-', start/end with an alphanumeric character, and be 63 characters or fewer in length.",
"arc.data.controller.name": "Data controller name",
"arc.data.controller.name.validation.description": "Name must consist of lower case alphanumeric characters, '-' or '.', start/end with an alphanumeric character and be 253 characters or less in length.",
"arc.data.controller.location": "Location",
"arc.data.controller.infrastructure": "Infrastructure",
"arc.data.controller.custom.location": "Custom Location",
"arc.data.controller.custom.location.description": "The name of the custom location. Direct mode only.",
"arc.data.controller.auto.upload.metrics": "Auto-upload Metrics",
"arc.data.controller.auto.upload.metrics.description": "Enable the automatic upload of metrics. Direct mode only.",
"arc.data.controller.auto.upload.logs": "Auto-upload Logs",
"arc.data.controller.auto.upload.logs.description": "Enable the automatic upload of logs. Direct mode only.",
"arc.data.controller.admin.account.title": "Administrator account",
"arc.data.controller.admin.account.name": "Data controller login",
"arc.data.controller.admin.account.password": "Password",
@@ -87,15 +97,39 @@
"arc.sql.invalid.instance.name": "Instance name must consist of lower case alphanumeric characters or '-', start with a letter, end with an alphanumeric character, and be 13 characters or fewer in length.",
"arc.storage-class.dc.label": "Storage Class",
"arc.sql.storage-class.dc.description": "The storage class to be used for all data and logs persistent volumes for all data controller pods that require them.",
"arc.sql.high.availability.label": "High Availability",
"arc.sql.high.availability.description": "Enable additional replicas for high availabilty. The compute and storage configuration selected below will be applied to all replicas.",
"arc.sql.service.tier.general.purpose": "General Purpose (Up to 24 vCores and 128 Gi of RAM, standard high availability)",
"arc.sql.service.tier.business.critical": "[PREVIEW] Business Critical (Unlimited vCores and RAM, advanced high availability)",
"arc.sql.one.replica": "1 replica",
"arc.sql.two.replicas": "2 replicas",
"arc.sql.three.replicas": "3 replicas",
"arc.sql.replicas": "Replicas",
"arc.sql.high.availability.description": "Enable additional replicas for high availabilty. The compute and storage configuration selected below will be applied to all replicas. Choose from: General Purpose (Up to 24 vCores and 128 Gi of RAM, standard high availability) or [PREVIEW] Business Critical (Unlimited vCores and RAM, advanced high availability).",
"arc.sql.service.tier.general.purpose": "GeneralPurpose",
"arc.sql.service.tier.business.critical": "BusinessCritical",
"arc.sql.one.replica": "1",
"arc.sql.two.replicas": "2",
"arc.sql.three.replicas": "3",
"arc.storage-class.data.label": "Storage Class (Data)",
"arc.sql.storage-class.data.description": "The storage class to be used for data (.mdf). If no value is specified, the default storage class will be used.",
"arc.sql.cost.summary.sql.miaa.cost.summary": "SQL Managed Instance - Azure Arc Cost Summary",
"arc.sql.cost.summary.sql.miaa": "SQL managed instance - Azure Arc",
"arc.sql.cost.summary.estimated.cost.per.month": "Estimated cost per month",
"arc.sql.summary.arc.by.microsoft" : "by Microsoft",
"arc.sql.cost.summary": "Cost Summary",
"arc.sql.cost.summary.service.tier": "Service Tier",
"arc.sql.cost.summary.general.purpose": "General Purpose",
"arc.sql.cost.summary.business.critical": "Business Critical",
"arc.sql.cost.summary.cost.vcore": "Cost per vCore (in USD)",
"arc.sql.cost.summary.vcore.limit": "CPU vCores Limit",
"arc.sql.cost.summary.azure.hybrid.benefit.discount": "Azure Hybrid Benefit discount (in USD)",
"arc.sql.cost.summary.sql.connection.info": "SQL Connection Information",
"arc.sql.cost.summary.sql.instance.settings": "SQL Instance Settings",
"arc.sql.cost.summary.service.tier.learn.more.description": "Select from the latest vCore service tiers available for SQL Managed Instance - Azure Arc including General Purpose and Business Critical. {0}",
"arc.sql.cost.summary.service.tier.learn.more.text": "Learn more",
"arc.sql.cost.summary.basics": "Basics",
"arc.sql.cost.summary.subscription": "Subscription",
"arc.sql.cost.summary.resource.group": "Resource group",
"arc.sql.cost.summary.instance.name": "Instance name",
"arc.sql.cost.summary.custom.location": "Custom location",
"arc.sql.cost.summary.admin.account": "Administrator account",
"arc.sql.cost.summary.managed.instance.admin.login": "Managed Instance admin login",
"arc.sql.cost.summary.additional.charge": "Additional charge per usage. See {0} for more detail.",
"arc.sql.cost.summary.pricing.details": "pricing details",
"arc.postgres.storage-class.data.description": "The storage class to be used for data persistent volumes",
"arc.storage-class.datalogs.label": "Storage Class (Database logs)",
"arc.sql.storage-class.datalogs.description": "The storage class to be used for database logs (.ldf). If no value is specified, the default storage class will be used.",
@@ -123,8 +157,10 @@
"arc.sql.service.tier.label": "Service Tier",
"arc.sql.service.tier.description": "Select from the latest vCore service tiers available for SQL Managed Instance - Azure Arc including General Purpose and Business Critical. {0}",
"arc.sql.dev.use.label": "For development use only",
"arc.sql.license.type.label": "I already have a SQL Server License",
"arc.sql.license.type.description": "Apply the Azure Hybrid Benefit if you already own a SQL Server License",
"arc.sql.pitr.description": "Point in time restore",
"arc.sql.retention.days.label": "PITR retention (days)",
"arc.sql.retention.days.label": "Point in time retention (days)",
"arc.sql.retention.days.description": "Specify how long you want to keep your point-in-time backups.",
"arc.sql.dev.use.description": "Check the box to indicate this instance will be used for development or testing purposes only. This instance will not be billed.",
"arc.postgres.storage-class.backups.description": "The storage class to be used for backup persistent volumes",

View File

@@ -0,0 +1,117 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { InputValueType } from 'resource-deployment';
import * as loc from '../localizedConstants';
export const SqlManagedInstanceGeneralPurpose = {
tierName: loc.generalPurposeLabel,
basePricePerCore: 80,
licenseIncludedPricePerCore: 153,
maxMemorySize: 128,
maxVCores: 24,
replicaOptions: [
{
text: loc.replicaOne,
value: 1,
}
],
defaultReplicaValue: 1
};
const SqlManagedInstanceBusinessCritical = {
tierName: loc.businessCriticalLabel,
// Set to real values when BC is ready
basePricePerCore: 0,
licenseIncludedPricePerCore: 0,
replicaOptions: [
{
text: loc.replicaTwo,
value: 2,
},
{
text: loc.replicaThree,
value: 3,
}
],
defaultReplicaValue: 3
};
export const SqlManagedInstancePricingLink: string = 'https://aka.ms/ArcSQLBilling';
export const serviceTierVarName = 'AZDATA_NB_VAR_SQL_SERVICE_TIER';
export const devUseVarName = 'AZDATA_NB_VAR_SQL_DEV_USE';
export const vcoresLimitVarName = 'AZDATA_NB_VAR_SQL_CORES_LIMIT';
export const licenseTypeVarName = 'AZDATA_NB_VAR_SQL_LICENSE_TYPE';
// Estimated base price for one vCore.
export function estimatedBasePriceForOneVCore(mapping: { [key: string]: InputValueType }): number {
let price = 0;
if (mapping[devUseVarName] === 'true') {
price = 0;
} else if (mapping[devUseVarName] === 'false') {
if (mapping[serviceTierVarName] === SqlManagedInstanceGeneralPurpose.tierName) {
price = SqlManagedInstanceGeneralPurpose.basePricePerCore;
} else if (mapping[serviceTierVarName] === SqlManagedInstanceBusinessCritical.tierName) {
price = SqlManagedInstanceBusinessCritical.basePricePerCore;
}
}
return price;
}
// Estimated SQL server license price for one vCore.
export function estimatedSqlServerLicensePriceForOneVCore(mapping: { [key: string]: InputValueType }): number {
let price = 0;
if (mapping[devUseVarName] === 'true') {
price = 0;
} else if (mapping[devUseVarName] === 'false') {
if (mapping[serviceTierVarName] === SqlManagedInstanceGeneralPurpose.tierName) {
price = SqlManagedInstanceGeneralPurpose.licenseIncludedPricePerCore - SqlManagedInstanceGeneralPurpose.basePricePerCore;
} else if (mapping[serviceTierVarName] === SqlManagedInstanceBusinessCritical.tierName) {
price = SqlManagedInstanceBusinessCritical.licenseIncludedPricePerCore - SqlManagedInstanceBusinessCritical.basePricePerCore;
}
}
return price;
}
// Full price for one vCore. This is shown on the cost summary card.
export function fullPriceForOneVCore(mapping: { [key: string]: InputValueType }): number {
return estimatedBasePriceForOneVCore(mapping) + estimatedSqlServerLicensePriceForOneVCore(mapping);
}
// Gets number of vCores limit specified
export function numCores(mapping: { [key: string]: InputValueType }): number {
return mapping[vcoresLimitVarName] ? <number>mapping[vcoresLimitVarName] : 0;
}
// Full price for all selected vCores.
export function vCoreFullPriceForAllCores(mapping: { [key: string]: InputValueType }): number {
return fullPriceForOneVCore(mapping) * numCores(mapping);
}
// SQL Server License price for all vCores. This is shown on the cost summary card if customer has SQL server license.
export function vCoreSqlServerLicensePriceForAllCores(mapping: { [key: string]: InputValueType }): number {
return estimatedSqlServerLicensePriceForOneVCore(mapping) * numCores(mapping);
}
// If the customer doesn't already have SQL Server License, AHB discount is set to zero because the price will be included
// in the total cost. If they already have it (they checked the box), then a discount will be applied.
export function azureHybridBenefitDiscount(mapping: { [key: string]: InputValueType }): number {
if (mapping[licenseTypeVarName] === 'true') {
return vCoreSqlServerLicensePriceForAllCores(mapping);
} else {
return 0;
}
}
// Total price that will be charged to a customer. Is shown on the cost summary card.
export function total(mapping: { [key: string]: InputValueType }): number {
return vCoreFullPriceForAllCores(mapping) - azureHybridBenefitDiscount(mapping);
}

View File

@@ -363,3 +363,11 @@ export function debounce(delay: number): Function {
};
});
}
export function getTimeStamp(dateTime: string | undefined): number {
return dateTime ? (new Date(dateTime)).getTime() : 0;
}
export function checkISOTimeString(dateTime: string): boolean {
return /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d.*Z/.test(dateTime);
}

View File

@@ -14,6 +14,7 @@ import { ConnectToControllerDialog } from './ui/dialogs/connectControllerDialog'
import { AzureArcTreeDataProvider } from './ui/tree/azureArcTreeDataProvider';
import { ControllerTreeNode } from './ui/tree/controllerTreeNode';
import { TreeNode } from './ui/tree/treeNode';
import * as pricing from './common/pricingUtils';
export async function activate(context: vscode.ExtensionContext): Promise<arc.IExtension> {
IconPathHelper.setExtensionContext(context);
@@ -61,6 +62,38 @@ export async function activate(context: vscode.ExtensionContext): Promise<arc.IE
const rdApi = <rd.IExtension>vscode.extensions.getExtension(rd.extension.name)?.exports;
context.subscriptions.push(rdApi.registerOptionsSourceProvider(new ArcControllersOptionsSourceProvider(treeDataProvider)));
// Register valueprovider for getting the calculated cost per VCore.
context.subscriptions.push(rdApi.registerValueProvider({
id: 'params-to-cost-per-vcore',
getValue: async (mapping: { [key: string]: rd.InputValueType }) => {
return pricing.fullPriceForOneVCore(mapping);
}
}));
// Register valueprovider for getting the number of CPU VCores Limit input by the user.
context.subscriptions.push(rdApi.registerValueProvider({
id: 'params-to-vcore-limit',
getValue: async (mapping: { [key: string]: rd.InputValueType }) => {
return 'x ' + pricing.numCores(mapping).toString();
}
}));
// Register valueprovider for getting the amount of hybrid benefit discount to be applied.
context.subscriptions.push(rdApi.registerValueProvider({
id: 'params-to-hybrid-benefit-discount',
getValue: async (mapping: { [key: string]: rd.InputValueType }) => {
return '- ' + pricing.azureHybridBenefitDiscount(mapping).toString();
}
}));
// Register valueprovider for getting the total estimated cost.
context.subscriptions.push(rdApi.registerValueProvider({
id: 'params-to-estimated-cost',
getValue: async (mapping: { [key: string]: rd.InputValueType }) => {
return pricing.total(mapping).toString() + ' ' + loc.USD;
}
}));
return arcApi(treeDataProvider);
}

View File

@@ -60,18 +60,19 @@ export const type = localize('arc.type', "Type");
export const status = localize('arc.status', "Status");
export const database = localize('arc.database', "Database");
export const sourceDatabase = localize('arc.sourceDatabase', "Source database");
export const earliestPitrRestorePoint = localize('arc.earliestPitrRestorePoint', "Earliest PITR restore point");
export const latestpitrRestorePoint = localize('arc.latestpitrRestorePoint', "Latest PITR restore point");
export const pitr = localize('arc.pitr', "Point-in-time restore (PITR)");
export const earliestPitrRestorePoint = localize('arc.earliestPitrRestorePoint', "Earliest point in time");
export const latestpitrRestorePoint = localize('arc.latestpitrRestorePoint', "Latest point in time");
export const pitr = localize('arc.pitr', "Point in time restore");
export const projectDetails = localize('arc.projectDetails', "Project Details");
export const projectDetailsText = localize('arc.projectDetailsText', "Select the subscription to manage deployed resources. Use resource groups like folders to organize and manage all your resources.");
export const sourceDetails = localize('arc.sourceDetails', "Source Details");
export const sourceDetailsText = localize('arc.sourceDetailsText', "Select a backup source and provide details. Additional settings will be defaulted where possible based on the selected backup.");
export const databaseDetails = localize('arc.databaseDetails', "Database Details");
export const databaseDetailsText = localize('arc.databaseDetailsText', "Enter the required settings for this database, including a name and a target managed instance. By default, the source instance is selected.");
export const sourceDetailsText = localize('arc.sourceDetailsText', "Select a backup source and provide details. Additional settings will be defaulted where possible based on the selected database.");
export const databaseDetails = localize('arc.databaseDetails', "Destination Details");
export const restorePointDetails = localize('arc.restorePointDetails', "Restore Point Details");
export const databaseDetailsText = localize('arc.databaseDetailsText', "Enter the required settings for target database name and SQL managed instance. By default, the source managed instance is selected.");
export const restore = localize('arc.restore', "Restore");
export const instance = localize('arc.instance', "Instance");
export const restorePoint = localize('arc.restorePoint', "Restore point (UTC)");
export const restorePoint = localize('arc.restorePoint', "Restore point (UTC), in a time format: 'YYYY-MM-DDTHH:MM:SSZ");
export const restoreDatabase = localize('arc.restoreDatabase', "Restore Database");
export const miaaAdmin = localize('arc.miaaAdmin', "Managed instance admin");
export const extensionName = localize('arc.extensionName', "Extension name");
@@ -79,6 +80,7 @@ export const extensionsDescription = localize('arc.extensionsDescription', "Post
export const extensionsFunction = localize('arc.extensionsFunction', "Some extensions must be loaded into PostgreSQL at startup time before they can be used. These preloaded extensions can be viewed and edited below.");
export function extensionsAddFunction(extensions: string): string { return localize('arc.extensionsAddFunction', "Some extensions must be loaded into PostgreSQL at startup time before they can be used. To edit, type in comma separated list of valid extensions: ({0}).", extensions); }
export function extensionsAddErrorrMessage(extensions: string): string { return localize('arc.extensionsAddErrorrMessage', "Value should be either of the following: ({0}).", extensions); }
export function restorePointErrorMessage(earliestPoint: string, latestPoint: string) { return localize('arc.restorePointErrorrMessage', "Provide time in correct format and within range: {0} to {1}", earliestPoint, latestPoint); }
export const extensionsLearnMore = localize('arc.extensionsLearnMore', "Learn more about PostgreSQL extensions.");
export const extensionsTableLoading = localize('arc.extensionsTableLoading', "Table of preloaded extensions are loading.");
export const extensionsTableLabel = localize('arc.extensionsTableLabel', "Table of preloaded extensions.");
@@ -192,7 +194,8 @@ export const postgresComputeAndStorageDescriptionPartOne = localize('arc.postgre
export const miaaComputeAndStorageDescriptionPartOne = localize('arc.miaaComputeAndStorageDescriptionPartOne', "You can scale your Azure SQL managed instance - Azure Arc by");
export const miaaBackupsDatabasesDescription = localize('arc.miaaBackupsDatabasesDescription', "Databases with available backups are displayed below. Restore databases to this instance or any other instance within the same custom location.");
export const pitrInfo = localize('arc.pitrInfo', "Specify how long you want to keep your point-in-time backups. Customize this for backup availability.");
export const restoreInfo = localize('arc.restoreInfo', "Restore a database to an Azure Arc enabled SQL Managed Instance of your choice.");
export const restoreInfo = localize('arc.restoreInfo', "Restore a database to an Azure Arc enabled SQL Managed Instance.");
export const restorePointText = localize('arc.restorePointText', "Enter a restore point in the specified time format within given range of earliest and latest restore time.");
export const postgresComputeAndStorageDescriptionPartTwo = localize('arc.postgres.computeAndStorageDescriptionPartTwo', "PostgreSQL Hyperscale server group by");
export const computeAndStorageDescriptionPartThree = localize('arc.computeAndStorageDescriptionPartThree', "without downtime and by");
export const computeAndStorageDescriptionPartFour = localize('arc.computeAndStorageDescriptionPartFour', "Before doing so, you need to ensure");
@@ -274,6 +277,14 @@ export function connectionString(type: string): string { return localize({ key:
export function copyConnectionStringToClipboard(type: string): string { return localize({ key: 'arc.copyConnectionStringToClipboard', comment: ['{0} is the name of the type of connection string (e.g. Java)'] }, "Copy {0} Connection String to clipboard", type); }
export function copyValueToClipboard(valueName: string): string { return localize({ key: 'arc.copyValueToClipboard', comment: ['{0} is the name of the type of value being copied (e.g. Coordinator endpoint)'] }, "Copy {0} to clipboard", valueName); }
// Pricing Constants
export const replicaOne = localize('arc.replicaOne', "1");
export const replicaTwo = localize('arc.replicaTwo', "2");
export const replicaThree = localize('arc.replicaThree', "3");
export const generalPurposeLabel = localize('arc.generalPurposeLabel', "GeneralPurpose");
export const businessCriticalLabel = localize('arc.businessCriticalLabel', "BusinessCritical");
export const USD = localize('arc.USD', "USD");
// Errors
export const pgConnectionRequired = localize('arc.pgConnectionRequired', "A connection is required to show and set database engine settings.");
export const miaaConnectionRequired = localize('arc.miaaConnectionRequired', "A connection is required to list the databases on this instance.");
@@ -281,6 +292,7 @@ export const couldNotFindControllerRegistration = localize('arc.couldNotFindCont
export const dropMultipleExtensions = localize('arc.dropMultipleExtensions', "Currently dropping another extension, try again once that is completed.");
export function updateExtensionsFailed(error: any): string { return localize('arc.updateExtensionsFailed', "Editing extensions failed. {0}", getErrorMessage(error)); }
export function refreshFailed(error: any): string { return localize('arc.refreshFailed', "Refresh failed. {0}", getErrorMessage(error)); }
export function restoreTimeWindowUpdateFailed(error: any): string { return localize('arc.restoreTimeWindowUpdateFailed', "Point in time restore time window update failed. {0}", getErrorMessage(error)); }
export function resetFailed(error: any): string { return localize('arc.resetFailed', "Reset failed. {0}", getErrorMessage(error)); }
export function openDashboardFailed(error: any): string { return localize('arc.openDashboardFailed', "Error opening dashboard. {0}", getErrorMessage(error)); }
export function instanceDeletionFailed(name: string, error: any): string { return localize('arc.instanceDeletionFailed', "Failed to delete instance {0}. {1}", name, getErrorMessage(error)); }

View File

@@ -9,14 +9,14 @@ import * as azExt from 'az-ext';
import * as vscode from 'vscode';
import { UserCancelledError } from '../common/api';
import { Deferred } from '../common/promise';
import { parseIpAndPort } from '../common/utils';
import { getTimeStamp, parseIpAndPort } from '../common/utils';
import * as loc from '../localizedConstants';
import { ConnectToMiaaSqlDialog } from '../ui/dialogs/connectMiaaDialog';
import { AzureArcTreeDataProvider } from '../ui/tree/azureArcTreeDataProvider';
import { ControllerModel, Registration } from './controllerModel';
import { ResourceModel } from './resourceModel';
export type DatabaseModel = { name: string, status: string, lastBackup: string };
export type DatabaseModel = { name: string, status: string, earliestBackup: string, lastBackup: string };
export type RPModel = { recoveryPointObjective: string, retentionDays: string };
export type PITRModel = {
instanceName: string,
@@ -27,7 +27,9 @@ export type PITRModel = {
restorePoint: string,
earliestPitr: string,
latestPitr: string,
destDbName: string
};
export const systemDbs = ['master', 'msdb', 'tempdb', 'model'];
export class MiaaModel extends ResourceModel {
@@ -44,12 +46,20 @@ export class MiaaModel extends ResourceModel {
recoveryPointObjective: '',
retentionDays: ''
};
private _databaseTimeWindow: Map<string, string[]>;
private _refreshPromise: Deferred<void> | undefined = undefined;
private _pitrArgs = {
destName: '',
managedInstance: '',
time: '',
noWait: true,
dryRun: false
};
constructor(_controllerModel: ControllerModel, private _miaaInfo: MiaaResourceInfo, registration: Registration, private _treeDataProvider: AzureArcTreeDataProvider) {
super(_controllerModel, _miaaInfo, registration);
this._azApi = <azExt.IExtension>vscode.extensions.getExtension(azExt.extension.name)?.exports;
this._databaseTimeWindow = new Map<string, string[]>();
}
/**
@@ -92,6 +102,7 @@ export class MiaaModel extends ResourceModel {
this.configLastUpdated = new Date();
this.rpSettings.retentionDays = this._config?.spec?.backup?.retentionPeriodInDays?.toString() ?? '';
this._onConfigUpdated.fire(this._config);
this._onDatabasesUpdated.fire(this._databases);
} catch (err) {
// If an error occurs show a message so the user knows something failed but still
// fire the event so callers can know to update (e.g. so dashboards don't show the
@@ -138,6 +149,12 @@ export class MiaaModel extends ResourceModel {
throw error;
}
}
/**
* Gets the list of databases and adds backup earliest and latest point in time
* information, this could be used as an upper and lower time limit for restoring
* backup.
*/
public async getDatabases(promptForConnection: boolean = true): Promise<void> {
if (!this._connectionProfile) {
await this.getConnectionProfile(promptForConnection);
@@ -158,10 +175,21 @@ export class MiaaModel extends ResourceModel {
if (!databases) {
throw new Error('Could not fetch databases');
}
if (databases.length > 0 && typeof (databases[0]) === 'object') {
this._databases = (<azdata.DatabaseInfo[]>databases).map(db => { return { name: db.options['name'], status: db.options['state'], lastBackup: db.options['lastBackup'] }; });
} else {
this._databases = (<string[]>databases).map(db => { return { name: db, status: '-', lastBackup: '' }; });
else {
if (databases.length > 0 && typeof (databases[0]) === 'object') {
for (let i in databases) {
const di: azdata.DatabaseInfo = <azdata.DatabaseInfo>databases[i];
const name = di.options['name'];
await this.executeDryRun(di.options['name']);
const dm: DatabaseModel = {
name: name, status: di.options['state'], earliestBackup: this._databaseTimeWindow.get(name)?.[0] ?? '',
lastBackup: this._databaseTimeWindow.get(name)?.[1] ?? ''
};
this._databases[i] = dm;
}
} else {
this._databases = (<string[]>databases).map(db => { return { name: db, status: '-', earliestBackup: '', lastBackup: '' }; });
}
}
this.databasesLastUpdated = new Date();
this._onDatabasesUpdated.fire(this._databases);
@@ -206,4 +234,33 @@ export class MiaaModel extends ResourceModel {
await this._treeDataProvider.saveControllers();
}
protected async executeDryRun(dbName: string): Promise<void> {
// Allow next dry Run to be executed only after 5(300000 ms ) minutes from current time as the log backups are
// generated only at 5 minutes interval
if ((systemDbs.indexOf(dbName) === -1) && (Date.now() - getTimeStamp(this._databaseTimeWindow.get(dbName)?.[1]) >= 300000)) {
try {
//Execute dryRun for earliestTime and save latest time as well so there is one call to az cli
this._pitrArgs.destName = dbName + '-' + Date.now().toString();
this._pitrArgs.managedInstance = this.info.name;
this._pitrArgs.time = new Date().toISOString();
this._pitrArgs.noWait = false;
this._pitrArgs.dryRun = true;
const result = await this._azApi.az.sql.midbarc.restore(
dbName, this._pitrArgs, this.controllerModel.info.namespace, this.controllerModel.azAdditionalEnvVars);
const restoreResult = result.stdout;
if (restoreResult) {
const earliestTime = restoreResult['earliestRestoreTime'];
const latestTime = restoreResult['latestRestoreTime'];
console.log(loc.earliestPitrRestorePoint + '-' + dbName + ':' + earliestTime);
console.log(loc.latestpitrRestorePoint + '-' + dbName + ':' + latestTime);
this._databaseTimeWindow.set(dbName, [earliestTime, latestTime]);
}
}
catch (err) {
console.log(loc.pitr + ' ' + loc.failed + ':' + err);
this._databaseTimeWindow.set(dbName, ['', '']);
}
}
}
}

View File

@@ -20,7 +20,6 @@ export class MiaaBackupsPage extends DashboardPage {
this._azApi = vscode.extensions.getExtension(azExt.extension.name)?.exports;
this.disposables.push(
this._miaaModel.onDatabasesUpdated(() => this.eventuallyRunOnInitialized(() => this.handleDatabasesUpdated())),
this._miaaModel.onConfigUpdated(() => this.eventuallyRunOnInitialized(() => this.handleDatabasesUpdated()))
);
}
private _databasesContainer!: azdata.DivContainer;
@@ -32,16 +31,17 @@ export class MiaaBackupsPage extends DashboardPage {
private _databasesMessage!: azdata.TextComponent;
private readonly _azApi: azExt.IExtension;
public saveArgs: RPModel = {
private _saveArgs: RPModel = {
recoveryPointObjective: '',
retentionDays: ''
};
public pitrArgs = {
private _pitrArgs = {
destName: '',
managedInstance: '',
time: '',
noWait: true
noWait: true,
dryRun: false
};
public get title(): string {
@@ -66,7 +66,7 @@ export class MiaaBackupsPage extends DashboardPage {
.component();
const content = this.modelView.modelBuilder.divContainer().component();
this._databasesContainer = this.modelView.modelBuilder.divContainer().component();
root.addItem(content, { CSSStyles: { 'margin': '20px' } });
root.addItem(content, { CSSStyles: { 'margin': '5px' } });
const databaseTitle = this.modelView.modelBuilder.text().withProps({
value: loc.databases,
CSSStyles: { ...cssStyles.title },
@@ -130,11 +130,19 @@ export class MiaaBackupsPage extends DashboardPage {
headerCssStyles: cssStyles.tableHeader,
rowCssStyles: cssStyles.tableRow
},
{
displayName: loc.earliestPitrRestorePoint,
valueType: azdata.DeclarativeDataType.string,
isReadOnly: true,
width: '30%',
headerCssStyles: cssStyles.tableHeader,
rowCssStyles: cssStyles.tableRow
},
{
displayName: loc.latestpitrRestorePoint,
valueType: azdata.DeclarativeDataType.string,
isReadOnly: true,
width: '50%',
width: '30%',
headerCssStyles: cssStyles.tableHeader,
rowCssStyles: cssStyles.tableRow
},
@@ -142,7 +150,7 @@ export class MiaaBackupsPage extends DashboardPage {
displayName: loc.restore,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: '20%',
width: '10%',
headerCssStyles: cssStyles.tableHeader,
rowCssStyles: cssStyles.tableRow,
}
@@ -198,13 +206,13 @@ export class MiaaBackupsPage extends DashboardPage {
this._configureRetentionPolicyButton.onDidClick(async () => {
const retentionPolicySqlDialog = new ConfigureRPOSqlDialog(this._miaaModel);
this.refreshRD();
retentionPolicySqlDialog.showDialog(loc.configureRP, this.saveArgs.retentionDays);
retentionPolicySqlDialog.showDialog(loc.configureRP, this._saveArgs.retentionDays);
let rpArg = await retentionPolicySqlDialog.waitForClose();
if (rpArg) {
try {
this._configureRetentionPolicyButton.enabled = false;
this.saveArgs.retentionDays = rpArg.retentionDays;
this._saveArgs.retentionDays = rpArg.retentionDays;
await vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
@@ -213,7 +221,7 @@ export class MiaaBackupsPage extends DashboardPage {
},
async (_progress, _token): Promise<void> => {
await this._azApi.az.sql.miarc.edit(
this._miaaModel.info.name, this.saveArgs, this._miaaModel.controllerModel.info.namespace, this._miaaModel.controllerModel.azAdditionalEnvVars);
this._miaaModel.info.name, this._saveArgs, this._miaaModel.controllerModel.info.namespace, this._miaaModel.controllerModel.azAdditionalEnvVars);
try {
await this._miaaModel.refresh();
@@ -244,13 +252,16 @@ export class MiaaBackupsPage extends DashboardPage {
// If we were able to get the databases it means we have a good connection so update the username too
let databaseDisplay = this._miaaModel.databases.map(d => [
d.name,
d.earliestBackup,
d.lastBackup,
this.createRestoreButton(d)]);
let databasesValues = databaseDisplay.map(d => {
return d.map((value): azdata.DeclarativeTableCellValue => {
return { value: value };
});
});
this._databasesTable.setDataValues(databasesValues);
this._databasesTableLoading.loading = false;
@@ -271,7 +282,7 @@ export class MiaaBackupsPage extends DashboardPage {
}
private refreshRD(): void {
this.saveArgs.retentionDays = this._miaaModel.config?.spec?.backup?.retentionPeriodInDays.toString() ?? '';
this._saveArgs.retentionDays = this._miaaModel.config?.spec?.backup?.retentionPeriodInDays.toString() ?? '';
}
// Create restore button for every database entry in the database table
@@ -292,9 +303,9 @@ export class MiaaBackupsPage extends DashboardPage {
if (args) {
try {
restoreButton.enabled = false;
this.pitrArgs.destName = args.dbName;
this.pitrArgs.managedInstance = args.instanceName;
this.pitrArgs.time = `"${args.restorePoint}"`;
this._pitrArgs.destName = args.destDbName;
this._pitrArgs.managedInstance = args.instanceName;
this._pitrArgs.time = `"${args.restorePoint}"`;
await vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
@@ -303,7 +314,7 @@ export class MiaaBackupsPage extends DashboardPage {
},
async (_progress, _token): Promise<void> => {
await this._azApi.az.sql.midbarc.restore(
db.name, this.pitrArgs, this._miaaModel.controllerModel.info.namespace, this._miaaModel.controllerModel.azAdditionalEnvVars);
db.name, this._pitrArgs, this._miaaModel.controllerModel.info.namespace, this._miaaModel.controllerModel.azAdditionalEnvVars);
try {
await this._miaaModel.refresh();
} catch (error) {
@@ -320,4 +331,6 @@ export class MiaaBackupsPage extends DashboardPage {
}));
return restoreButton;
}
}

View File

@@ -32,7 +32,7 @@ export class ConfigureRPOSqlDialog extends InitializingComponent {
this.retentionDaysInputBox = this.modelBuilder.inputBox()
.withProps({
readOnly: false,
min: 1,
min: 0,
max: 35,
inputType: 'number',
ariaLabel: loc.retentionDays,

View File

@@ -5,6 +5,7 @@
import * as azdata from 'azdata';
import { Deferred } from '../../common/promise';
import { getTimeStamp, checkISOTimeString } from '../../common/utils';
import * as loc from '../../localizedConstants';
import * as vscode from 'vscode';
import { cssStyles } from '../../constants';
@@ -24,6 +25,7 @@ export class RestoreSqlDialog extends InitializingComponent {
restorePoint: '-',
earliestPitr: '-',
latestPitr: '-',
destDbName: '-',
};
private earliestRestorePointInputBox!: azdata.InputBoxComponent;
@@ -36,10 +38,11 @@ export class RestoreSqlDialog extends InitializingComponent {
private instanceInputBox!: azdata.InputBoxComponent;
protected _completionPromise = new Deferred<PITRModel | undefined>();
private _azurecoreApi: azurecore.IExtension;
protected disposables: vscode.Disposable[] = [];
constructor(protected _miaaModel: MiaaModel, protected _controllerModel: ControllerModel, protected _database: DatabaseModel) {
super();
this._azurecoreApi = vscode.extensions.getExtension(azurecore.extension.name)?.exports;
this.refreshPitrSettings();
}
public showDialog(dialogTitle: string): azdata.window.Dialog {
@@ -50,14 +53,15 @@ export class RestoreSqlDialog extends InitializingComponent {
this.refreshPitrSettings();
const pitrTitle = this.modelBuilder.text().withProps({
value: loc.pitr,
CSSStyles: { ...cssStyles.title }
CSSStyles: { ...cssStyles.title, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' },
}).component();
const projectDetailsTitle = this.modelBuilder.text().withProps({
value: loc.projectDetails,
CSSStyles: { ...cssStyles.title }
CSSStyles: { ...cssStyles.title, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
const projectDetailsTextLabel = this.modelBuilder.text().withProps({
value: loc.projectDetailsText,
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
this.subscriptionInputBox = this.modelBuilder.inputBox()
.withProps({
@@ -74,10 +78,11 @@ export class RestoreSqlDialog extends InitializingComponent {
const sourceDetailsTitle = this.modelBuilder.text().withProps({
value: loc.sourceDetails,
CSSStyles: { ...cssStyles.title }
CSSStyles: { ...cssStyles.title, 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
const sourceDetailsTextLabel = this.modelBuilder.text().withProps({
value: loc.sourceDetailsText,
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
this.sourceDbInputBox = this.modelBuilder.inputBox()
.withProps({
@@ -85,12 +90,15 @@ export class RestoreSqlDialog extends InitializingComponent {
ariaLabel: loc.sourceDatabase,
value: this._database.name
}).component();
const restoreDetailsTextLabel = this.modelBuilder.text().withProps({
value: loc.restorePointText,
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
this.earliestRestorePointInputBox = this.modelBuilder.inputBox()
.withProps({
enabled: false,
ariaLabel: loc.earliestPitrRestorePoint,
value: ''
value: this._database.earliestBackup
}).component();
this.latestRestorePointInputBox = this.modelBuilder.inputBox()
@@ -104,14 +112,39 @@ export class RestoreSqlDialog extends InitializingComponent {
.withProps({
readOnly: false,
ariaLabel: loc.restorePoint,
value: ''
value: '',
validationErrorMessage: loc.restorePointErrorMessage(this.earliestRestorePointInputBox.value ?? loc.earliestPitrRestorePoint, this.latestRestorePointInputBox.value ?? loc.latestpitrRestorePoint),
}).withValidation(async () => {
try {
if (!checkISOTimeString(this.restorePointInputBox.value ?? '')) { return false; }
if (this.earliestRestorePointInputBox.value) {
if ((getTimeStamp(this.restorePointInputBox.value) >= getTimeStamp(this.earliestRestorePointInputBox.value)
&& getTimeStamp(this.restorePointInputBox.value) <= getTimeStamp(this.latestRestorePointInputBox.value))) {
this.pitrSettings.restorePoint = this.restorePointInputBox.value ?? '';
return true;
}
else {
return false;
}
}
}
catch (err) {
throw err;
return false;
}
return true;
}).component();
const databaseDetailsTitle = this.modelBuilder.text().withProps({
const pitrDetailsTitle = this.modelBuilder.text().withProps({
value: loc.restorePointDetails,
CSSStyles: { ...cssStyles.title, 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
const destinationDetailsTitle = this.modelBuilder.text().withProps({
value: loc.databaseDetails,
CSSStyles: { ...cssStyles.title }
CSSStyles: { ...cssStyles.title, 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
const databaseDetailsTextLabel = this.modelBuilder.text().withProps({
value: loc.databaseDetailsText,
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
this.databaseNameInputBox = this.modelBuilder.inputBox()
.withProps({
@@ -119,7 +152,10 @@ export class RestoreSqlDialog extends InitializingComponent {
ariaLabel: loc.databaseName,
value: ''
}).component();
this.disposables.push(
this.databaseNameInputBox.onTextChanged(() => {
this.pitrSettings.destDbName = this.databaseNameInputBox.value ?? '';
}));
this.instanceInputBox = this.modelBuilder.inputBox()
.withProps({
enabled: false,
@@ -128,7 +164,7 @@ export class RestoreSqlDialog extends InitializingComponent {
}).component();
const info = this.modelBuilder.text().withProps({
value: loc.restoreInfo,
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'max-width': 'auto' }
}).component();
const link = this.modelBuilder.hyperlink().withProps({
@@ -178,22 +214,7 @@ export class RestoreSqlDialog extends InitializingComponent {
},
{
component: this.earliestRestorePointInputBox,
title: loc.earliestPitrRestorePoint,
},
{
component: this.latestRestorePointInputBox,
title: loc.latestpitrRestorePoint,
},
{
component: this.restorePointInputBox,
title: loc.restorePoint,
required: true
},
{
component: databaseDetailsTitle,
component: destinationDetailsTitle,
},
{
component: databaseDetailsTextLabel,
@@ -208,6 +229,27 @@ export class RestoreSqlDialog extends InitializingComponent {
title: loc.instance,
},
{
component: pitrDetailsTitle
},
{
component: restoreDetailsTextLabel,
},
{
component: this.earliestRestorePointInputBox,
title: loc.earliestPitrRestorePoint,
},
{
component: this.latestRestorePointInputBox,
title: loc.latestpitrRestorePoint,
},
{
component: this.restorePointInputBox,
title: loc.restorePoint,
required: true
},
],
title: ''
}]).withLayout({ width: '100%' }).component();
@@ -269,4 +311,9 @@ export class RestoreSqlDialog extends InitializingComponent {
this.pitrSettings.restorePoint = this._database.lastBackup;
this.pitrSettings.earliestPitr = '';
}
public updatePitrTimeWindow(earliestPitr: string, latestPitr: string): void {
this.earliestRestorePointInputBox.value = earliestPitr;
this.latestRestorePointInputBox.value = latestPitr;
}
}

View File

@@ -228,36 +228,16 @@
resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5"
integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==
"@types/caseless@*":
version "0.12.2"
resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8"
integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==
"@types/mocha@^5.2.5":
version "5.2.7"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea"
integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==
"@types/node@*":
version "13.11.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7"
integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==
"@types/node@^12.11.7":
version "12.12.47"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.47.tgz#5007b8866a2f9150de82335ca7e24dd1d59bdfb5"
integrity sha512-yzBInQFhdY8kaZmqoL2+3U5dSTMrKaYcb561VU+lDzAYvqt+2lojvBEy+hmpSNuXnPTx7m9+04CzWYOUqWME2A==
"@types/request@^2.48.3":
version "2.48.4"
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.4.tgz#df3d43d7b9ed3550feaa1286c6eabf0738e6cf7e"
integrity sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw==
dependencies:
"@types/caseless" "*"
"@types/node" "*"
"@types/tough-cookie" "*"
form-data "^2.5.0"
"@types/sinon@^9.0.4":
version "9.0.4"
resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-9.0.4.tgz#e934f904606632287a6e7f7ab0ce3f08a0dad4b1"
@@ -270,11 +250,6 @@
resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz#681df970358c82836b42f989188d133e218c458e"
integrity sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA==
"@types/tough-cookie@*":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d"
integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==
"@types/uuid@^8.3.0":
version "8.3.0"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f"
@@ -292,16 +267,6 @@ agent-base@4, agent-base@^4.3.0:
dependencies:
es6-promisify "^5.0.0"
ajv@^6.5.5:
version "6.12.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7"
integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ansi-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
@@ -328,45 +293,11 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
dependencies:
safer-buffer "~2.1.0"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
aws4@^1.8.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
dependencies:
tweetnacl "^0.14.3"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -385,11 +316,6 @@ callsite@^1.0.0:
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
chalk@^2.0.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -421,13 +347,6 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
combined-stream@^1.0.6, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
commander@2.15.1:
version "2.15.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
@@ -445,23 +364,11 @@ convert-source-map@^1.7.0:
dependencies:
safe-buffer "~5.1.1"
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
dependencies:
assert-plus "^1.0.0"
debug@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
@@ -504,11 +411,6 @@ default-require-extensions@^3.0.0:
dependencies:
strip-bom "^4.0.0"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
diff@3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
@@ -519,14 +421,6 @@ diff@^4.0.2:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
dependencies:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
es6-promise@^4.0.3:
version "4.2.8"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
@@ -544,54 +438,6 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
extsprintf@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
fast-deep-equal@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
form-data@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.6"
mime-types "^2.1.12"
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.6"
mime-types "^2.1.12"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@@ -602,13 +448,6 @@ gensync@^1.0.0-beta.1:
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
dependencies:
assert-plus "^1.0.0"
glob@7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
@@ -643,19 +482,6 @@ growl@1.10.5:
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
har-validator@~5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
dependencies:
ajv "^6.5.5"
har-schema "^2.0.0"
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -684,15 +510,6 @@ http-proxy-agent@^2.1.0:
agent-base "4"
debug "3.1.0"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
https-proxy-agent@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
@@ -719,21 +536,11 @@ is-buffer@~1.1.1:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
istanbul-lib-coverage@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49"
@@ -794,31 +601,11 @@ js-tokens@^4.0.0:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
jsesc@^2.5.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
json5@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
@@ -826,16 +613,6 @@ json5@^2.1.2:
dependencies:
minimist "^1.2.5"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.2.3"
verror "1.10.0"
just-extend@^4.0.2:
version "4.1.0"
resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.0.tgz#7278a4027d889601640ee0ce0e5a00b992467da4"
@@ -875,18 +652,6 @@ md5@^2.1.0:
crypt "~0.0.1"
is-buffer "~1.1.1"
mime-db@1.43.0:
version "1.43.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58"
integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==
mime-types@^2.1.12, mime-types@~2.1.19:
version "2.1.26"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06"
integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==
dependencies:
mime-db "1.43.0"
minimatch@3.0.4, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
@@ -975,11 +740,6 @@ nise@^4.0.1:
just-extend "^4.0.2"
path-to-regexp "^1.7.0"
oauth-sign@~0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@@ -1004,11 +764,6 @@ path-to-regexp@^1.7.0:
dependencies:
isarray "0.0.1"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
pify@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
@@ -1019,47 +774,6 @@ postinstall-build@^5.0.1:
resolved "https://registry.yarnpkg.com/postinstall-build/-/postinstall-build-5.0.3.tgz#238692f712a481d8f5bc8960e94786036241efc7"
integrity sha512-vPvPe8TKgp4FLgY3+DfxCE5PIfoXBK2lyLfNCxsRbDsV6vS4oU5RG/IWxrblMn6heagbnMED3MemUQllQ2bQUg==
psl@^1.1.28:
version "1.8.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
qs@~6.5.2:
version "6.5.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
request@^2.88.0:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.8.0"
caseless "~0.12.0"
combined-stream "~1.0.6"
extend "~3.0.2"
forever-agent "~0.6.1"
form-data "~2.3.2"
har-validator "~5.1.3"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.19"
oauth-sign "~0.9.0"
performance-now "^2.1.0"
qs "~6.5.2"
safe-buffer "^5.1.2"
tough-cookie "~2.5.0"
tunnel-agent "^0.6.0"
uuid "^3.3.2"
resolve@^1.3.2:
version "1.17.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
@@ -1074,21 +788,11 @@ rimraf@^2.6.3:
dependencies:
glob "^7.1.3"
safe-buffer@^5.0.1, safe-buffer@^5.1.2:
version "5.2.0"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
semver@^5.4.1, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
@@ -1171,21 +875,6 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
sshpk@^1.7.0:
version "1.16.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
bcrypt-pbkdf "^1.0.0"
dashdash "^1.12.0"
ecc-jsbn "~0.1.1"
getpass "^0.1.1"
jsbn "~0.1.0"
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
strip-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
@@ -1224,26 +913,6 @@ to-fast-properties@^2.0.0:
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
dependencies:
psl "^1.1.28"
punycode "^2.1.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
type-detect@4.0.8, type-detect@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
@@ -1258,32 +927,11 @@ typemoq@2.1.0, typemoq@^2.1.0:
lodash "^4.17.4"
postinstall-build "^5.0.1"
uri-js@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
dependencies:
punycode "^2.1.0"
uuid@^3.3.2:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.0:
version "8.3.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea"
integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
vscode-nls@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.2.tgz#ca8bf8bb82a0987b32801f9fddfdd2fb9fd3c167"

View File

@@ -16,6 +16,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"forceReload": true,
"contributes": {
"resourceDeploymentTypes": [

View File

@@ -2,7 +2,7 @@
"name": "azcli",
"displayName": "%azcli.arc.displayName%",
"description": "%azcli.arc.description%",
"version": "0.1.0",
"version": "0.1.1",
"publisher": "Microsoft",
"preview": true,
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
@@ -18,6 +18,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"microsoft.resource-deployment"
],
@@ -105,6 +111,9 @@
"typemoq": "^2.1.0",
"vscodetestcover": "^1.1.0"
},
"resolutions": {
"json-schema": "0.4.0"
},
"__metadata": {
"id": "84",
"publisherDisplayName": "Microsoft",

View File

@@ -140,6 +140,7 @@ export function getAzApi(localAzDiscovered: Promise<IAzTool | undefined>, azTool
managedInstance?: string,
time?: string,
noWait?: boolean,
dryRun?: boolean
},
namespace: string, additionalEnvVars?: azExt.AdditionalEnvVars) => {
await localAzDiscovered;

View File

@@ -185,16 +185,18 @@ export class AzTool implements azExt.IAzApi {
managedInstance?: string,
time?: string,
noWait?: boolean,
dryRun?: boolean
},
namespace: string,
additionalEnvVars?: azExt.AdditionalEnvVars
): Promise<azExt.AzOutput<void>> => {
): Promise<azExt.AzOutput<azExt.SqlMiDbRestoreResult>> => {
const argsArray = ['sql', 'midb-arc', 'restore', '--name', name, '--k8s-namespace', namespace, '--use-k8s'];
if (args.destName) { argsArray.push('--dest-name', args.destName); }
if (args.managedInstance) { argsArray.push('--managed-instance', args.managedInstance); }
if (args.time) { argsArray.push('--time', args.time); }
if (args.noWait) { argsArray.push('--no-wait'); }
return this.executeCommand<void>(argsArray, additionalEnvVars);
if (args.dryRun) { argsArray.push('--dry-run'); }
return this.executeCommand<azExt.SqlMiDbRestoreResult>(argsArray, additionalEnvVars);
}
}
};

View File

@@ -173,6 +173,17 @@ declare module 'az-ext' {
}
}
export interface SqlMiDbRestoreResult {
destDatabase: string, //testDbToRestore
earliestRestoreTime: string, // "2020-08-19T20:25:11Z"
latestRestoreTime: string, //"2020-08-19T20:25:11Z"
message: string, //Dry run for restore operation succeeded.
observedGeneration: number, //1
restorePoint: string, // "2020-08-19T20:25:11Z"
sourceDatabase: string, //testDb
state: string //Completed
}
export interface PostgresServerShowResult {
apiVersion: string, // "arcdata.microsoft.com/v1alpha1"
kind: string, // "postgresql"
@@ -336,10 +347,11 @@ declare module 'az-ext' {
managedInstance?: string, //sqlmi1
time?: string, //2021-10-12T11:16:30.000Z
noWait?: boolean, //true
dryRun?: boolean, //true
},
namespace?: string,
additionalEnvVars?: AdditionalEnvVars
): Promise<AzOutput<void>>
): Promise<AzOutput<SqlMiDbRestoreResult>>
}
},
getPath(): Promise<string>,

View File

@@ -768,10 +768,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
version "5.0.1"

View File

@@ -18,6 +18,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"resourceViewResources": [
{
@@ -322,11 +328,6 @@
}
]
},
"resourceDeploymentValueProviders": [
{
"id": "subscription-id-to-tenant-id"
}
],
"hasAzureResourceProviders": true
},
"dependencies": {

View File

@@ -153,27 +153,27 @@ export async function getLocations(appContext: AppContext, account?: AzureAccoun
result.errors.push(error);
return result;
}
await Promise.all(account.properties.tenants.map(async (tenant: { id: string; }) => {
try {
const path = `/subscriptions/${subscription.id}/locations?api-version=2020-01-01`;
const response = await makeHttpRequest(account, subscription, path, HttpRequestMethod.GET, undefined, ignoreErrors);
result.locations.push(...response.response.data.value);
result.errors.push(...response.errors);
} catch (err) {
const error = new Error(localize('azure.accounts.getLocations.queryError', "Error fetching locations for account {0} ({1}) subscription {2} ({3}) tenant {4} : {5}",
account.displayInfo.displayName,
account.displayInfo.userId,
subscription.id,
subscription.name,
tenant.id,
err instanceof Error ? err.message : err));
console.warn(error);
if (!ignoreErrors) {
throw error;
}
result.errors.push(error);
try {
const path = `/subscriptions/${subscription.id}/locations?api-version=2020-01-01`;
const response = await makeHttpRequest(account, subscription, path, HttpRequestMethod.GET, undefined, ignoreErrors);
result.locations.push(...response.response.data.value);
result.errors.push(...response.errors);
} catch (err) {
const error = new Error(localize('azure.accounts.getLocations.queryError', "Error fetching locations for account {0} ({1}) subscription {2} ({3}) tenant {4} : {5}",
account.displayInfo.displayName,
account.displayInfo.userId,
subscription.id,
subscription.name,
account.properties.tenants[0].id,
err instanceof Error ? err.message : err));
console.warn(error);
if (!ignoreErrors) {
throw error;
}
}));
result.errors.push(error);
}
return result;
}

View File

@@ -8,7 +8,6 @@ import * as vscode from 'vscode';
import { promises as fs } from 'fs';
import * as path from 'path';
import * as os from 'os';
import * as resourceDeployment from 'resource-deployment';
import { AppContext } from './appContext';
import { AzureAccountProviderService } from './account-provider/azureAccountProviderService';
@@ -115,40 +114,6 @@ export async function activate(context: vscode.ExtensionContext): Promise<azurec
}
});
// Don't block on this since there's a bit of a circular dependency here with the extension activation since resource deployment
// depends on this extension too. It's fine to wait a bit for that to finish before registering the provider
vscode.extensions.getExtension(resourceDeployment.extension.name).activate().then((api: resourceDeployment.IExtension) => {
context.subscriptions.push(api.registerValueProvider({
id: 'subscription-id-to-tenant-id',
getValue: async (triggerValue: string) => {
if (triggerValue === '') {
return '';
}
let accounts: azurecore.AzureAccount[] = [];
try {
accounts = await azdata.accounts.getAllAccounts();
} catch (err) {
console.warn(`Error fetching accounts for subscription-id-to-tenant-id provider : ${err}`);
return '';
}
for (const account of accounts) {
// Ignore any errors - they'll be logged in the called function and we still want to look
// at any subscriptions that are returned - worst case we'll just return an empty string if we didn't
// find the matching subscription
const subs = await azureResourceUtils.getSubscriptions(appContext, account, true);
const sub = subs.subscriptions.find(sub => sub.id === triggerValue);
if (sub) {
return sub.tenant;
}
}
console.error(`Unable to find subscription with ID ${triggerValue} when mapping subscription ID to tenant ID`);
return '';
}
}));
}).then(undefined, err => console.error('Error registering Azure ResourceDeployment value provider ', err));
return {
getSubscriptions(account?: azurecore.AzureAccount, ignoreErrors?: boolean, selectedOnly: boolean = false): Promise<azurecore.GetSubscriptionsResult> {
return selectedOnly

View File

@@ -7,5 +7,4 @@
/// <reference path='../../../../src/vs/vscode.proposed.d.ts'/>
/// <reference path='../../../../src/sql/azdata.d.ts'/>
/// <reference path='../../../../src/sql/azdata.proposed.d.ts'/>
/// <reference path='../../../resource-deployment/src/typings/resource-deployment.d.ts'/>
/// <reference types='@types/node'/>

View File

@@ -15,6 +15,12 @@
"activationEvents": [
"*"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"

View File

@@ -16,6 +16,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"typings": "./src/azuremonitor",
"contributes": {
"connectionProvider": {
@@ -109,20 +115,6 @@
"categoryValues": null,
"isRequired": true,
"isArray": false
},
{
"specialValueType": "databaseName",
"isIdentity": true,
"name": "database",
"displayName": "%azuremonitor.connectionOptions.databaseName.displayName%",
"description": "%azuremonitor.connectionOptions.databaseName.description%",
"groupName": "%azuremonitor.connectionProperties.groupName.source%",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
}
]
},

View File

@@ -11,6 +11,12 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin mmims/language-batchfile grammars/batchfile.cson ./syntaxes/batchfile.tmLanguage.json"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"languages": [
{

View File

@@ -27,6 +27,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"main": "./out/extension",
"contributes": {
"dataExplorer": {
@@ -248,7 +254,7 @@
},
{
"name": "azdata",
"version": "20.3.4"
"version": "20.3.9"
}
],
"when": "target=new-aks&&version=bdc2019"
@@ -266,7 +272,7 @@
},
{
"name": "azdata",
"version": "20.3.4"
"version": "20.3.9"
}
],
"when": "target=existing-aks&&version=bdc2019"
@@ -284,7 +290,7 @@
},
{
"name": "azdata",
"version": "20.3.4"
"version": "20.3.9"
}
],
"when": "target=existing-kubeadm&&version=bdc2019"
@@ -302,7 +308,7 @@
},
{
"name": "azdata",
"version": "20.3.4"
"version": "20.3.9"
}
],
"when": "target=existing-aro&&version=bdc2019"
@@ -320,7 +326,7 @@
},
{
"name": "azdata",
"version": "20.3.4"
"version": "20.3.9"
}
],
"when": "target=existing-openshift&&version=bdc2019"
@@ -356,5 +362,8 @@
},
"devDependencies": {
"@types/request": "^2.48.3"
},
"resolutions": {
"json-schema": "0.4.0"
}
}

View File

@@ -212,10 +212,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-stringify-safe@~5.0.1:
version "5.0.1"

View File

@@ -22,6 +22,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"main": "./out/extension",
"contributes": {
"configuration": {
@@ -618,7 +624,8 @@
"when": "viewItem == cms.resource.itemType.databaseServerContainer",
"group": "navigation@10"
}
],"commandPalette": [
],
"commandPalette": [
{
"command": "cms.resource.addRegisteredServer",
"when": "false"
@@ -647,7 +654,6 @@
}
},
"dependencies": {
"request": "2.88.0",
"vscode-nls": "^4.0.0"
},
"devDependencies": {

View File

@@ -192,16 +192,6 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
ajv@^5.3.0:
version "5.5.2"
resolved "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
ansi-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
@@ -221,45 +211,11 @@ append-transform@^2.0.0:
dependencies:
default-require-extensions "^3.0.0"
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
dependencies:
safer-buffer "~2.1.0"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
aws4@^1.8.0:
version "1.8.0"
resolved "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
dependencies:
tweetnacl "^0.14.3"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -278,11 +234,6 @@ callsite@^1.0.0:
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
chalk@^2.0.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -302,11 +253,6 @@ circular-json@^0.3.1:
resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==
co@^4.6.0:
version "4.6.0"
resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@@ -319,20 +265,6 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
combined-stream@1.0.6:
version "1.0.6"
resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
integrity sha1-cj599ugBrFYTETp+RFqbactjKBg=
dependencies:
delayed-stream "~1.0.0"
combined-stream@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==
dependencies:
delayed-stream "~1.0.0"
commander@2.15.1:
version "2.15.1"
resolved "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
@@ -350,23 +282,11 @@ convert-source-map@^1.7.0:
dependencies:
safe-buffer "~5.1.1"
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
dependencies:
assert-plus "^1.0.0"
debug@3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
@@ -409,68 +329,16 @@ default-require-extensions@^3.0.0:
dependencies:
strip-bom "^4.0.0"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
diff@3.5.0:
version "3.5.0"
resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
dependencies:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
extsprintf@^1.2.0:
version "1.4.0"
resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
fast-deep-equal@^1.0.0:
version "1.1.0"
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
form-data@~2.3.2:
version "2.3.2"
resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099"
integrity sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=
dependencies:
asynckit "^0.4.0"
combined-stream "1.0.6"
mime-types "^2.1.12"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@@ -481,13 +349,6 @@ gensync@^1.0.0-beta.1:
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
dependencies:
assert-plus "^1.0.0"
glob@7.1.2:
version "7.1.2"
resolved "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
@@ -534,19 +395,6 @@ growl@1.10.5:
resolved "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
har-validator@~5.1.0:
version "5.1.0"
resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29"
integrity sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==
dependencies:
ajv "^5.3.0"
har-schema "^2.0.0"
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -567,15 +415,6 @@ html-escaper@^2.0.0:
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@@ -594,16 +433,6 @@ is-buffer@~1.1.1:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
istanbul-lib-coverage@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49"
@@ -667,31 +496,11 @@ js-tokens@^4.0.0:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
jsesc@^2.5.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
json-schema-traverse@^0.3.0:
version "0.3.1"
resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
json5@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
@@ -699,16 +508,6 @@ json5@^2.1.2:
dependencies:
minimist "^1.2.5"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.2.3"
verror "1.10.0"
lodash@^4.16.4, lodash@^4.17.13, lodash@^4.17.4:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
@@ -738,18 +537,6 @@ md5@^2.1.0:
crypt "~0.0.1"
is-buffer "~1.1.1"
mime-db@~1.36.0:
version "1.36.0"
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397"
integrity sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==
mime-types@^2.1.12, mime-types@~2.1.19:
version "2.1.20"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19"
integrity sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==
dependencies:
mime-db "~1.36.0"
minimatch@3.0.4, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
@@ -820,11 +607,6 @@ ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
oauth-sign@~0.9.0:
version "0.9.0"
resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
once@^1.3.0:
version "1.4.0"
resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@@ -842,11 +624,6 @@ path-parse@^1.0.6:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
pify@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
@@ -857,47 +634,6 @@ postinstall-build@^5.0.1:
resolved "https://registry.npmjs.org/postinstall-build/-/postinstall-build-5.0.3.tgz#238692f712a481d8f5bc8960e94786036241efc7"
integrity sha512-vPvPe8TKgp4FLgY3+DfxCE5PIfoXBK2lyLfNCxsRbDsV6vS4oU5RG/IWxrblMn6heagbnMED3MemUQllQ2bQUg==
psl@^1.1.24:
version "1.1.29"
resolved "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67"
integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
qs@~6.5.2:
version "6.5.2"
resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
request@2.88.0:
version "2.88.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.8.0"
caseless "~0.12.0"
combined-stream "~1.0.6"
extend "~3.0.2"
forever-agent "~0.6.1"
form-data "~2.3.2"
har-validator "~5.1.0"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.19"
oauth-sign "~0.9.0"
performance-now "^2.1.0"
qs "~6.5.2"
safe-buffer "^5.1.2"
tough-cookie "~2.4.3"
tunnel-agent "^0.6.0"
uuid "^3.3.2"
resolve@^1.3.2:
version "1.15.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
@@ -912,16 +648,11 @@ rimraf@^2.6.3:
dependencies:
glob "^7.1.3"
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.1:
safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
semver@^5.4.1, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
@@ -986,22 +717,6 @@ source-map@^0.6.1:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
sshpk@^1.7.0:
version "1.14.2"
resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98"
integrity sha1-xvxhZIo9nE52T9P8306hBeSSupg=
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
dashdash "^1.12.0"
getpass "^0.1.1"
safer-buffer "^2.0.2"
optionalDependencies:
bcrypt-pbkdf "^1.0.0"
ecc-jsbn "~0.1.1"
jsbn "~0.1.0"
tweetnacl "~0.14.0"
strip-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
@@ -1040,26 +755,6 @@ to-fast-properties@^2.0.0:
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
tough-cookie@~2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
dependencies:
psl "^1.1.24"
punycode "^1.4.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
typemoq@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/typemoq/-/typemoq-2.1.0.tgz#4452ce360d92cf2a1a180f0c29de2803f87af1e8"
@@ -1069,20 +764,6 @@ typemoq@^2.1.0:
lodash "^4.17.4"
postinstall-build "^5.0.1"
uuid@^3.3.2:
version "3.3.2"
resolved "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
verror@1.10.0:
version "1.10.0"
resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
vscode-nls@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002"

View File

@@ -2,7 +2,7 @@
"name": "dacpac",
"displayName": "SQL Server Dacpac",
"description": "SQL Server Dacpac for Azure Data Studio.",
"version": "1.9.1",
"version": "1.10.0",
"publisher": "Microsoft",
"preview": false,
"engines": {
@@ -20,6 +20,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"Microsoft.mssql"
],

View File

@@ -1,3 +1,17 @@
# Microsoft Data Workspace for Azure Data Studio and VS Code
## Overview
This extension provides additional common functionality for database projects in Azure Data Studio and VS Code. It requires other extensions to contribute support for specific project types.
### VS Code
This extension is bundled into the `SQL Server (MSSQL)` extension for VS Code and is required by the `SQL Database Projects` extension. It will be installed automatically when those extensions are updated or installed.
### Azure Data Studio
This extension is built into Azure Data Studio and will show up under the list of builtin extensions.
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

View File

@@ -1,7 +1,7 @@
{
"name": "data-workspace",
"displayName": "%extension-displayName%",
"description": "%extension-description%",
"displayName": "Data Workspace",
"description": "Additional common functionality for database projects",
"version": "0.1.0",
"publisher": "Microsoft",
"preview": true,
@@ -20,6 +20,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [],
"contributes": {
"configuration": [

View File

@@ -1,8 +1,6 @@
{
"extension-displayName": "Data workspace",
"extension-description": "Data workspace",
"data-workspace-view-container-name": "Projects",
"main-view-name": "Projects",
"data-workspace-view-container-name": "Database Projects",
"main-view-name": "Database Projects",
"new-command": "New",
"refresh-workspace-command": "Refresh",
"close-workspace-command": "Close Workspace",

View File

@@ -1,5 +1,6 @@
{
"name": "data-workspace-vscode",
"publisher": "ms-mssql",
"extensionDependencies": [
"ms-mssql.mssql"
]

View File

@@ -8,7 +8,7 @@ declare module 'dataworkspace' {
import * as vscode from 'vscode';
export const enum extension {
name = 'Microsoft.data-workspace',
vscodeName = 'Microsoft.data-workspace-vscode'
vscodeName = 'ms-mssql.data-workspace-vscode'
}
/**

View File

@@ -20,6 +20,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"Microsoft.mssql"
],

View File

@@ -9,7 +9,7 @@
"azdata": "*"
},
"activationEvents": [
"onFileSystem:memfs",
"onFileSystem:memfs",
"onDebug",
"onCommand:integration-tests.onboarding.showDevelopers"
],
@@ -26,7 +26,7 @@
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:vscode-colorize-tests ./tsconfig.json"
},
"contributes": {
"commands":[
"commands": [
{
"command": "integration-tests.onboarding.showDevelopers",
"title": "Show Developers"
@@ -44,5 +44,8 @@
"mocha-multi-reporters": "^1.1.7",
"ms-rest-azure": "^2.6.0",
"vscodetestcover": "^1.1.0"
},
"resolutions": {
"json-schema": "0.4.0"
}
}

View File

@@ -54,6 +54,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: '',
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
let target: mssql.SchemaCompareEndpointInfo = {
@@ -63,6 +67,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: '',
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -114,6 +122,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: sourceDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
let target: mssql.SchemaCompareEndpointInfo = {
@@ -123,6 +135,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: targetDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -179,6 +195,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
let target: mssql.SchemaCompareEndpointInfo = {
@@ -188,6 +208,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: targetDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -231,6 +255,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: '',
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
let target: mssql.SchemaCompareEndpointInfo = {
@@ -240,6 +268,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: '',
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -297,6 +329,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
const target: mssql.SchemaCompareEndpointInfo = {
@@ -306,6 +342,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: targetDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -323,7 +363,7 @@ suite('Schema compare integration test suite @DacFx@', () => {
assertIncludeExcludeResult(includeResult, true, 0, 0);
//publish the updated changes. Function1 should not be added to the target database
const publishChangesResult = await schemaCompareService.schemaComparePublishChanges(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.execute);
const publishChangesResult = await schemaCompareService.schemaComparePublishDatabaseChanges(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.execute);
assert(publishChangesResult.success === true, `Publish changes should complete successfully. But it failed with error : ${publishChangesResult.errorMessage}`);
//verify table Table3 is added
@@ -372,6 +412,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
const target: mssql.SchemaCompareEndpointInfo = {
@@ -381,6 +425,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: targetDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -390,7 +438,7 @@ suite('Schema compare integration test suite @DacFx@', () => {
assertSchemaCompareResult(schemaCompareResult, operationId, 4);
//publish all the changes
const publishChangesResult = await schemaCompareService.schemaComparePublishChanges(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.execute);
const publishChangesResult = await schemaCompareService.schemaComparePublishDatabaseChanges(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.execute);
assert(publishChangesResult.success === true, `Publish changes should complete successfully. But it failed with error : ${publishChangesResult.errorMessage}`);
//verify table Table3 is added
@@ -435,6 +483,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
const target: mssql.SchemaCompareEndpointInfo = {
@@ -444,6 +496,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: targetDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};

View File

@@ -202,6 +202,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.45.tgz#4c49ba34106bc7dced77ff6bae8eb6543cde8351"
integrity sha512-tGVTbA+i3qfXsLbq9rEq/hezaHY55QxQLeXQL2ejNgFAxxrgu8eMmYIOsRcl7hN1uTLVsKOOYacV/rcJM3sfgQ==
"@xmldom/xmldom@^0.7.0":
version "0.7.5"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.5.tgz#09fa51e356d07d0be200642b0e4f91d8e6dd408d"
integrity sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==
adal-node@^0.1.28:
version "0.1.28"
resolved "https://registry.yarnpkg.com/adal-node/-/adal-node-0.1.28.tgz#468c4bb3ebbd96b1270669f4b9cba4e0065ea485"
@@ -217,6 +222,20 @@ adal-node@^0.1.28:
xmldom ">= 0.1.x"
xpath.js "~1.1.0"
adal-node@^0.2.2:
version "0.2.3"
resolved "https://registry.yarnpkg.com/adal-node/-/adal-node-0.2.3.tgz#87ed3dbed344f6e114e36bf18fe1c4e7d3cc6069"
integrity sha512-gMKr8RuYEYvsj7jyfCv/4BfKToQThz20SP71N3AtFn3ia3yAR8Qt2T3aVQhuJzunWs2b38ZsQV0qsZPdwZr7VQ==
dependencies:
"@xmldom/xmldom" "^0.7.0"
async "^2.6.3"
axios "^0.21.1"
date-utils "*"
jws "3.x.x"
underscore ">= 1.3.1"
uuid "^3.1.0"
xpath.js "~1.1.0"
ajv@^6.5.5:
version "6.10.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1"
@@ -275,6 +294,13 @@ async@>=0.6.0:
dependencies:
lodash "^4.17.11"
async@^2.6.3:
version "2.6.3"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
dependencies:
lodash "^4.17.14"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -290,6 +316,13 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
axios@^0.21.1:
version "0.21.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
dependencies:
follow-redirects "^1.14.0"
azure-keyvault@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/azure-keyvault/-/azure-keyvault-3.0.4.tgz#b7733d8f58d99a66f9ae766451556eb3b058dae5"
@@ -515,6 +548,11 @@ fast-json-stable-stringify@^2.0.0:
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
follow-redirects@^1.14.0:
version "1.14.5"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381"
integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
@@ -742,10 +780,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-stringify-safe@~5.0.1:
version "5.0.1"
@@ -786,7 +824,7 @@ jws@3.x.x:
jwa "^1.4.1"
safe-buffer "^5.0.1"
lodash@^4.14.0, lodash@^4.16.4, lodash@^4.17.11, lodash@^4.17.13:
lodash@^4.14.0, lodash@^4.16.4, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -904,7 +942,7 @@ moment@^2.21.0, moment@^2.22.2:
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
ms-rest-azure@^2.5.5, ms-rest-azure@^2.6.0:
ms-rest-azure@^2.5.5:
version "2.6.0"
resolved "https://registry.yarnpkg.com/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz#2098efec529eecfa0c6e215b69143abcaba12140"
integrity sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==
@@ -916,6 +954,17 @@ ms-rest-azure@^2.5.5, ms-rest-azure@^2.6.0:
request "^2.88.0"
uuid "^3.2.1"
ms-rest-azure@^2.6.0:
version "2.6.1"
resolved "https://registry.yarnpkg.com/ms-rest-azure/-/ms-rest-azure-2.6.1.tgz#f59911da931902d0d22f3f44b2a76cc317d02038"
integrity sha512-LRpluf3wI/GQiuPe8PorhuwKt7YP2atG0wMOdyqSM2SQQH3+VMl9crjEBRe19CNa9zdoxOIPsAdyMwKtDs8Ung==
dependencies:
adal-node "^0.2.2"
async "2.6.0"
ms-rest "^2.3.2"
request "^2.88.0"
uuid "^3.2.1"
ms-rest@^2.3.2:
version "2.5.0"
resolved "https://registry.yarnpkg.com/ms-rest/-/ms-rest-2.5.0.tgz#d483c003f7de7703ade6bc19c3b4319affac2687"

View File

@@ -20,6 +20,12 @@
"compile": "gulp compile-extension:kusto-client",
"update-grammar": "node ../../build/npm/update-grammar.js Microsoft/vscode-kusto ./syntaxes/kusto.tmLanguage"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"commands": [
{

View File

@@ -23,6 +23,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"Microsoft.mssql",
"Microsoft.notebook"
@@ -150,6 +156,9 @@
"typemoq": "^2.1.0",
"vscodetestcover": "^1.1.0"
},
"resolutions": {
"json-schema": "0.4.0"
},
"__metadata": {
"id": "65",
"publisherDisplayName": "Microsoft",

View File

@@ -303,6 +303,7 @@ export function createViewContext(): ViewTestContext {
registerCloseValidator: () => { },
registerOperation: () => { },
onValidityChanged: new vscode.EventEmitter<boolean>().event,
onClosed: new vscode.EventEmitter<azdata.window.CloseReason>().event,
registerContent: () => { },
modelView: undefined!,
valid: true

View File

@@ -769,10 +769,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-stringify-safe@~5.0.1:
version "5.0.1"

View File

@@ -1,6 +1,6 @@
{
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
"version": "3.0.0-release.139",
"version": "3.0.0-release.174",
"downloadFileNames": {
"Windows_86": "win-x86-net5.0.zip",
"Windows_64": "win-x64-net5.0.zip",

View File

@@ -19,6 +19,12 @@
"update-grammar": "node ../../build/npm/update-grammar.js Microsoft/vscode-mssql syntaxes/SQL.plist ./syntaxes/sql.tmLanguage.json",
"postinstall": "node ./build/postinstall.js"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"problemMatchers": [
{
@@ -492,6 +498,11 @@
"command": "mssqlCluster.livy.cmd.submitFileToSparkJob",
"when": "nodeType == mssqlCluster:file && nodeSubType =~/:spark:/",
"group": "1mssqlCluster@6"
},
{
"command": "mssql.designTable",
"when": "connectionProvider == MSSQL && nodeType == Table && config.tableDesigner.enableFeature",
"group": "0_query@3"
}
],
"notebook/toolbar": [
@@ -1304,5 +1315,8 @@
"should": "^13.2.3",
"typemoq": "^2.1.0",
"vscodetestcover": "^1.1.0"
},
"resolutions": {
"json-schema": "0.4.0"
}
}

View File

@@ -628,13 +628,20 @@ export interface SchemaCompareGenerateScriptParams {
taskExecutionMode: TaskExecutionMode;
}
export interface SchemaComparePublishChangesParams {
export interface SchemaComparePublishDatabaseChangesParams {
operationId: string;
targetServerName: string;
targetDatabaseName: string;
taskExecutionMode: TaskExecutionMode;
}
export interface SchemaComparePublishProjectChangesParams {
operationId: string;
targetProjectPath: string;
targetFolderStructure: mssql.ExtractTarget;
taskExecutionMode: TaskExecutionMode;
}
export interface SchemaCompareGetOptionsParams {
}
@@ -673,7 +680,15 @@ export namespace SchemaCompareGenerateScriptRequest {
}
export namespace SchemaComparePublishChangesRequest {
export const type = new RequestType<SchemaComparePublishChangesParams, azdata.ResultStatus, void, void>('schemaCompare/publish');
export const type = new RequestType<SchemaComparePublishDatabaseChangesParams, azdata.ResultStatus, void, void>('schemaCompare/publish');
}
export namespace SchemaComparePublishDatabaseChangesRequest {
export const type = new RequestType<SchemaComparePublishDatabaseChangesParams, azdata.ResultStatus, void, void>('schemaCompare/publishDatabase');
}
export namespace SchemaComparePublishProjectChangesRequest {
export const type = new RequestType<SchemaComparePublishProjectChangesParams, mssql.SchemaComparePublishProjectResult, void, void>('schemaCompare/publishProject');
}
export namespace SchemaCompareGetDefaultOptionsRequest {
@@ -1030,12 +1045,12 @@ export namespace GetSqlMigrationAssessmentItemsRequest {
export interface TableDesignerEditRequestParams {
tableInfo: azdata.designers.TableInfo,
tableChangeInfo: azdata.designers.DesignerEdit,
data: azdata.designers.DesignerData
viewModel: azdata.designers.DesignerViewModel
}
export interface SaveTableDesignerChangesRequestParams {
tableInfo: azdata.designers.TableInfo,
data: azdata.designers.DesignerData
viewModel: azdata.designers.DesignerViewModel
}
export namespace GetTableDesignerInfoRequest {
@@ -1050,4 +1065,7 @@ export namespace SaveTableDesignerChangesRequest {
export const type = new RequestType<SaveTableDesignerChangesRequestParams, void, void, void>('tabledesigner/savechanges');
}
export namespace DisposeTableDesignerRequest {
export const type = new RequestType<azdata.designers.TableInfo, void, void, void>('tabledesigner/dispose');
}
// ------------------------------- < Table Designer > ------------------------------------

View File

@@ -1117,10 +1117,10 @@ export class TableDesignerFeature extends SqlOpsFeature<undefined> {
return Promise.reject(e);
}
};
const processTableEdit = (tableInfo: azdata.designers.TableInfo, data: azdata.designers.DesignerData, tableChangeInfo: azdata.designers.DesignerEdit): Thenable<azdata.designers.DesignerEditResult> => {
const processTableEdit = (tableInfo: azdata.designers.TableInfo, viewModel: azdata.designers.DesignerViewModel, tableChangeInfo: azdata.designers.DesignerEdit): Thenable<azdata.designers.DesignerEditResult> => {
let params: contracts.TableDesignerEditRequestParams = {
tableInfo: tableInfo,
data: data,
viewModel: viewModel,
tableChangeInfo: tableChangeInfo
};
try {
@@ -1132,10 +1132,10 @@ export class TableDesignerFeature extends SqlOpsFeature<undefined> {
}
};
const saveTable = (tableInfo: azdata.designers.TableInfo, data: azdata.designers.DesignerData): Thenable<void> => {
const saveTable = (tableInfo: azdata.designers.TableInfo, viewModel: azdata.designers.DesignerViewModel): Thenable<void> => {
let params: contracts.SaveTableDesignerChangesRequestParams = {
tableInfo: tableInfo,
data: data
viewModel: viewModel
};
try {
return client.sendRequest(contracts.SaveTableDesignerChangesRequest.type, params);
@@ -1146,11 +1146,22 @@ export class TableDesignerFeature extends SqlOpsFeature<undefined> {
}
};
const disposeTableDesigner = (tableInfo: azdata.designers.TableInfo): Thenable<void> => {
try {
return client.sendRequest(contracts.DisposeTableDesignerRequest.type, tableInfo);
}
catch (e) {
client.logFailedRequest(contracts.DisposeTableDesignerRequest.type, e);
return Promise.reject(e);
}
};
return azdata.dataprotocol.registerTableDesignerProvider({
providerId: client.providerId,
getTableDesignerInfo,
processTableEdit,
saveTable
saveTable,
disposeTableDesigner
});
}
}

View File

@@ -122,7 +122,10 @@ export const enum SchemaDifferenceType {
export const enum SchemaCompareEndpointType {
Database = 0,
Dacpac = 1
Dacpac = 1,
Project = 2,
// must be kept in-sync with SchemaCompareEndpointType in SQL Tools Service
// located at \src\Microsoft.SqlTools.ServiceLayer\SchemaCompare\Contracts\SchemaCompareRequest.cs
}
export interface SchemaCompareEndpointInfo {
@@ -134,6 +137,10 @@ export interface SchemaCompareEndpointInfo {
ownerUri: string;
connectionDetails: azdata.ConnectionInfo;
connectionName?: string;
projectFilePath: string;
targetScripts: string[];
folderStructure: string;
dataSchemaProvider: string;
}
export interface SchemaCompareObjectId {
@@ -307,10 +314,11 @@ export interface SchemaCompareObjectId {
}
export interface ISchemaCompareService {
schemaCompare(operationId: string, sourceEndpointInfo: SchemaCompareEndpointInfo, targetEndpointInfo: SchemaCompareEndpointInfo, taskExecutionMode: azdata.TaskExecutionMode, deploymentOptions: DeploymentOptions): Thenable<SchemaCompareResult>;
schemaCompareGenerateScript(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus>;
schemaComparePublishChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus>;
schemaComparePublishDatabaseChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus>;
schemaComparePublishProjectChanges(operationId: string, targetProjectPath: string, targetFolderStructure: ExtractTarget, taskExecutionMode: azdata.TaskExecutionMode): Thenable<SchemaComparePublishProjectResult>;
schemaCompareGetDefaultOptions(): Thenable<SchemaCompareOptionsResult>;
schemaCompareIncludeExcludeNode(operationId: string, diffEntry: DiffEntry, IncludeRequest: boolean, taskExecutionMode: azdata.TaskExecutionMode): Thenable<SchemaCompareIncludeExcludeResult>;
schemaCompareOpenScmp(filePath: string): Thenable<SchemaCompareOpenScmpResult>;
@@ -328,6 +336,12 @@ export interface SchemaCompareOpenScmpResult extends azdata.ResultStatus {
excludedTargetElements: SchemaCompareObjectId[];
}
export interface SchemaComparePublishProjectResult extends azdata.ResultStatus {
changedFiles: string[];
addedFiles: string[];
deletedFiles: string[];
}
//#endregion
//#region --- dacfx

View File

@@ -55,11 +55,31 @@ export class SchemaCompareService implements mssql.ISchemaCompareService {
}
public schemaComparePublishChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
const params: contracts.SchemaComparePublishChangesParams = { operationId: operationId, targetServerName: targetServerName, targetDatabaseName: targetDatabaseName, taskExecutionMode: taskExecutionMode };
return this.client.sendRequest(contracts.SchemaComparePublishChangesRequest.type, params).then(
const params: contracts.SchemaComparePublishDatabaseChangesParams = { operationId: operationId, targetServerName: targetServerName, targetDatabaseName: targetDatabaseName, taskExecutionMode: taskExecutionMode };
return this.client.sendRequest(contracts.SchemaComparePublishChangesRequest.type, params).then(undefined,
e => {
this.client.logFailedRequest(contracts.SchemaComparePublishChangesRequest.type, e); return Promise.resolve(undefined);
}
);
}
public schemaComparePublishDatabaseChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
const params: contracts.SchemaComparePublishDatabaseChangesParams = { operationId: operationId, targetServerName: targetServerName, targetDatabaseName: targetDatabaseName, taskExecutionMode: taskExecutionMode };
return this.client.sendRequest(contracts.SchemaComparePublishDatabaseChangesRequest.type, params).then(
undefined,
e => {
this.client.logFailedRequest(contracts.SchemaComparePublishChangesRequest.type, e);
this.client.logFailedRequest(contracts.SchemaComparePublishDatabaseChangesRequest.type, e);
return Promise.resolve(undefined);
}
);
}
public schemaComparePublishProjectChanges(operationId: string, targetProjectPath: string, targetFolderStructure: mssql.ExtractTarget, taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.SchemaComparePublishProjectResult> {
const params: contracts.SchemaComparePublishProjectChangesParams = { operationId: operationId, targetProjectPath: targetProjectPath, targetFolderStructure: targetFolderStructure, taskExecutionMode: taskExecutionMode };
return this.client.sendRequest(contracts.SchemaComparePublishProjectChangesRequest.type, params).then(
undefined,
(e: any) => {
this.client.logFailedRequest(contracts.SchemaComparePublishProjectChangesRequest.type, e);
return Promise.resolve(undefined);
}
);

View File

@@ -7,15 +7,17 @@ import { AppContext } from '../appContext';
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import { sqlProviderName } from '../constants';
import { generateUuid } from 'vscode-languageclient/lib/utils/uuid';
export function registerTableDesignerCommands(appContext: AppContext) {
appContext.extensionContext.subscriptions.push(vscode.commands.registerCommand('mssql.newTable', async (context: azdata.ObjectExplorerContext) => {
const connectionUri = await azdata.connection.getUriForConnection(context.connectionProfile.id);
const connectionString = await azdata.connection.getConnectionString(context.connectionProfile.id, true);
await azdata.designers.openTableDesigner(sqlProviderName, {
server: context.connectionProfile.serverName,
database: context.connectionProfile.databaseName,
isNewTable: true,
connectionUri: connectionUri
id: generateUuid(),
connectionString: connectionString
});
}));
@@ -24,6 +26,7 @@ export function registerTableDesignerCommands(appContext: AppContext) {
const database = context.connectionProfile.databaseName;
const schema = context.nodeInfo.metadata.schema;
const name = context.nodeInfo.metadata.name;
const connectionString = await azdata.connection.getConnectionString(context.connectionProfile.id, true);
const connectionUri = await azdata.connection.getUriForConnection(context.connectionProfile.id);
await azdata.designers.openTableDesigner(sqlProviderName, {
server: server,
@@ -31,9 +34,8 @@ export function registerTableDesignerCommands(appContext: AppContext) {
isNewTable: false,
name: name,
schema: schema,
id: `${server}|${database}|${schema}|${name}`,
connectionUri: connectionUri
id: `${connectionUri}|${database}|${schema}|${name}`,
connectionString: connectionString
});
}));
}

View File

@@ -1136,10 +1136,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-stringify-safe@~5.0.1:
version "5.0.1"

View File

@@ -13,6 +13,12 @@
"activationEvents": [
"*"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"configuration": {
"type": "object",
@@ -418,6 +424,10 @@
"command": "notebook.command.addNotebook",
"when": "false"
},
{
"command": "notebook.command.addSection",
"when": "false"
},
{
"command": "notebook.command.addMarkdown",
"when": "false"
@@ -680,48 +690,50 @@
]
}
],
"notebook.providers": {
"provider": "jupyter",
"fileExtensions": [
"IPYNB"
],
"standardKernels": [
{
"name": "pysparkkernel",
"displayName": "PySpark",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "sparkkernel",
"displayName": "Spark | Scala",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "sparkrkernel",
"displayName": "Spark | R",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "python3",
"displayName": "Python 3",
"connectionProviderIds": []
},
{
"name": "powershell",
"displayName": "PowerShell",
"connectionProviderIds": []
}
]
}
"notebook.providers": [
{
"provider": "jupyter",
"fileExtensions": [
".ipynb"
],
"standardKernels": [
{
"name": "pysparkkernel",
"displayName": "PySpark",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "sparkkernel",
"displayName": "Spark | Scala",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "sparkrkernel",
"displayName": "Spark | R",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "python3",
"displayName": "Python 3",
"connectionProviderIds": []
},
{
"name": "powershell",
"displayName": "PowerShell",
"connectionProviderIds": []
}
]
}
]
},
"dependencies": {
"@jupyterlab/services": "^3.2.1",
@@ -762,7 +774,8 @@
"vscodetestcover": "^1.1.0"
},
"resolutions": {
"url-parse": "^1.5.1"
"url-parse": "^1.5.1",
"json-schema": "0.4.0"
},
"enableProposedApi": true
}

View File

@@ -89,26 +89,26 @@ export class BookTocManager implements IBookTocManager {
let toc: JupyterBookSection[] = [];
for (const content of contents) {
try {
const contentStat = (await fs.promises.stat(path.join(directory, content)));
const contentStat = (await fs.promises.stat(path.posix.join(directory, content)));
const parsedFile = path.parse(content);
if (contentStat.isFile() && allowedFileExtensions.includes(parsedFile.ext)) {
let filePath = directory === rootDirectory ? path.posix.join(path.posix.sep, parsedFile.name) : path.posix.join(path.posix.sep, path.relative(rootDirectory, directory), parsedFile.name);
let filePath = directory === rootDirectory ? path.posix.join(path.posix.sep, parsedFile.name) : path.posix.join(path.posix.sep, path.posix.relative(rootDirectory, directory), parsedFile.name);
const section: JupyterBookSection = {
title: parsedFile.name,
file: filePath
};
toc.push(section);
} else if (contentStat.isDirectory()) {
let files = await fs.promises.readdir(path.join(directory, content));
let files = await fs.promises.readdir(path.posix.join(directory, content));
let initFile = this.getInitFile(files);
let filePath = directory === rootDirectory ? path.posix.join(path.posix.sep, parsedFile.name, initFile.name) : path.posix.join(path.posix.sep, path.relative(rootDirectory, directory), parsedFile.name, initFile.name);
let filePath = directory === rootDirectory ? path.posix.join(path.posix.sep, parsedFile.name, initFile.name) : path.posix.join(path.posix.sep, path.posix.relative(rootDirectory, directory), parsedFile.name, initFile.name);
let section: JupyterBookSection = {};
section = {
title: parsedFile.name,
file: filePath,
expand_sections: true,
numbered: false,
sections: await this.createTocFromDir(files, path.join(directory, content), rootDirectory)
sections: await this.createTocFromDir(files, path.posix.join(directory, content), rootDirectory)
};
toc.push(section);
}

View File

@@ -92,7 +92,7 @@ export class InstalledPackagesTab {
}
],
data: [[]],
height: '600px',
height: '500px',
width: '400px'
}).component();
this.disposables.push(this.installedPackagesTable.onCellAction(async (rowState) => {

View File

@@ -85,6 +85,7 @@ describe('BookTocManagerTests', function () {
let rootFolderPath: string;
let root2FolderPath: string;
const subfolder = 'Subfolder';
const subfolder2 = 'Subfolder2';
afterEach(function (): void {
sinon.restore();
@@ -94,7 +95,7 @@ describe('BookTocManagerTests', function () {
rootFolderPath = path.join(os.tmpdir(), `BookTestData_${uuid.v4()}`);
bookFolderPath = path.join(os.tmpdir(), `BookTestData_${uuid.v4()}`);
root2FolderPath = path.join(os.tmpdir(), `BookTestData_${uuid.v4()}`);
notebooks = ['notebook1.ipynb', 'notebook2.ipynb', 'notebook3.ipynb', 'index.md'];
notebooks = ['notebook1.ipynb', 'notebook2.ipynb', 'notebook3.ipynb', 'index.md', 'notebook4.ipynb', 'notebook5.ipynb'];
await fs.mkdir(rootFolderPath);
await fs.writeFile(path.join(rootFolderPath, notebooks[0]), '');
@@ -104,6 +105,8 @@ describe('BookTocManagerTests', function () {
await fs.mkdir(root2FolderPath);
await fs.mkdir(path.join(root2FolderPath, subfolder));
await fs.mkdir(path.join(root2FolderPath, subfolder, subfolder2));
await fs.writeFile(path.join(root2FolderPath, notebooks[0]), '');
await fs.writeFile(path.join(root2FolderPath, subfolder, notebooks[1]), '');
await fs.writeFile(path.join(root2FolderPath, subfolder, notebooks[2]), '');
@@ -145,6 +148,51 @@ describe('BookTocManagerTests', function () {
should(bookTocManager.tableofContents.length).be.equal(4);
should(listFiles.length).be.equal(7);
});
it ('should create a table of contents with sections if folder contains subfolders', async () => {
await fs.writeFile(path.join(root2FolderPath, subfolder, subfolder2, notebooks[4]), '');
await fs.writeFile(path.join(root2FolderPath, subfolder, subfolder2, notebooks[5]), '');
let bookTocManager: BookTocManager = new BookTocManager();
await bookTocManager.createBook(bookFolderPath, root2FolderPath);
let listFiles = await fs.promises.readdir(bookFolderPath);
should(bookTocManager.tableofContents.length).be.equal(3);
should(listFiles.length).be.equal(5);
let expectedSubSections: IJupyterBookSectionV2[] = [{
title: 'notebook4',
file: path.posix.join(path.posix.sep, subfolder, subfolder2, 'notebook4')
},
{
title: 'notebook5',
file: path.posix.join(path.posix.sep, subfolder, subfolder2, 'notebook5')
}];
let expectedSection: IJupyterBookSectionV2[] = [{
title: 'index',
file: path.posix.join(path.posix.sep, subfolder, 'index')
},
{
title: 'notebook2',
file: path.posix.join(path.posix.sep, subfolder, 'notebook2')
},
{
title: 'notebook3',
file: path.posix.join(path.posix.sep, subfolder, 'notebook3')
},
{
title: 'Subfolder2',
file: path.posix.join(path.posix.sep, subfolder, subfolder2, 'notebook4'),
sections : expectedSubSections
}];
const index = bookTocManager.tableofContents.findIndex(entry => entry.file === path.posix.join(path.posix.sep, subfolder, 'index'));
should(index).not.be.equal(-1, 'Should find a section with the Subfolder entry');
if (index !== -1) {
let subsection = bookTocManager.tableofContents[index].sections.find(entry => entry.file === path.posix.join(path.posix.sep, subfolder, subfolder2, 'notebook4'));
should(equalSections(subsection, expectedSection[3])).be.true('Should find a subsection with the subfolder2 inside the subfolder');
}
});
});
describe('EditingBooks', () => {

View File

@@ -1171,10 +1171,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-stable-stringify@^1.0.1:
version "1.0.1"

View File

@@ -25,6 +25,12 @@
"extensionDependencies": [
"Microsoft.mssql"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"commands": [
{

View File

@@ -20,6 +20,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [],
"contributes": {
"commands": [

View File

@@ -0,0 +1,236 @@
# Resource Deployment Extension Developer Guide
This guide is meant to provide details on what this extension does and how other extension authors are meant to use it. If there is any missing or incorrect information please submit an [issue](https://github.com/microsoft/azuredatastudio/issues).
## Overview
This extension provides a way for other extension authors to contribute types to the Resource Deployment Wizard which allows users to create and deploy resources such as servers.
This wizard is launched by either running the `Deployment: New Deployment...` command from the command palette or by clicking the `...` on the `Connections` pane and selecting `New Deployment...`
## How to Contribute a new Type
Resource Deployment types are contributed through the `package.json` of a loaded extension. This is done by adding an `resourceDeploymentTypes` property under the `contributes` section of your `package.json`.
``` json
... // Other sections in your package.json
"contributes": {
..., // Other contributions
"resourceDeploymentTypes": [
// provided types go here
]
}
```
The rest of this guide will detail the various options and configuration available to provided types - most contributions will only need a subset of the available features.
The [sample-resource-deployment](https://github.com/microsoft/azuredatastudio/tree/main/samples/sample-resource-deployment) extension provides working examples of contributed sample resource deployment types.
## resourceDeploymentTypes Schema
The contribution must adhere to a specific schema, if there is an error in your `package.json` such as an unexpected type then this may result in errors in both your extension and the feature as a whole.
**!! THIS IS A WORK IN PROGRESS, IF YOU NEED INFORMATION ON A SPECIFIC TOPIC PLEASE OPEN AN ISSUE!**
### resourceDeploymentTypes
This is the top contribution and must be an array of [ResourceType](#resourcetype) objects.
``` json
"resourceDeploymentTypes": [
{
... // Contributed type
},
{
... // Another contributed type
}
]
```
### ResourceType
The type is defined [here](https://github.com/microsoft/azuredatastudio/blob/main/extensions/resource-deployment/src/interfaces.ts#L13).
There are a number of properties on each `ResourceType`.
`name` - The name of the type, this is not displayed to the user so should be a non-localized value and typically `-` delimited (e.g. `my-resource-type`)
`displayName` - The name of the type displayed to the user, this should be a localized string
`description` - The description of the type displayed to the user
`platforms` - The OS platforms that the type supports running on, options are `linux` (Linux distros), `darwin` (MacOS), `win32` (Windows) or`*` for all.
`icon` - The icon to display for the type - supports either single icon or separate ones for light and dark mode. The icon should be in `svg` format.
`options` - An array of [ResourceTypeOption](#resourcetypeoption) objects, allowing users to provide different sub-options for a given resource type. (e.g. the specific version of SQL Server to deploy)
`providers` - An array of [DeploymentProvider](#deploymentprovider) objects which define the wizards, dialogs or other means for a user to deploy their resource.
`agreements` - **OPTIONAL** An array of [AgreementInfo](#agreementinfo) objects which define any agreements the user must accept before proceeding with the deployment.
`displayIndex` - **OPTIONAL** A number corresponding to where the type should be displayed relative to the other types. A lower number means it will show up earlier in the list. Any types which don't specify this value will be shown last.
`okButtonText` - **OPTIONAL** The text to use for the `OK` button at the bottom of the Type Picker dialog. Default is `Select`.
`helpTexts` - **OPTIONAL** An array of strings to display to the user providing more information for the resource type (such as links to docs)
`tags` - **OPTIONAL** An array of strings that are used to indicate the category that the resource type belongs to. The usable tags are defined [here](https://github.com/microsoft/azuredatastudio/blob/main/extensions/resource-deployment/src/constants.ts#L10).
### ResourceTypeOption
**TODO**
### DeploymentProvider
#### Provider Types
There are a number of different types of providers that can be used which affect what happens when the user selects that provider. These are indicated by what fields the provider contains - the provider is checked in order of top to bottom for each property and uses the first type that it finds in the properties for that provider.
`Notebook Wizard` - A wizard is opened that can be used to prompt the user for values and display information, and then at the very end will open the specified Notebook with those values injected in. Indicated by the presence of the `notebookWizard` property.
`Dialog` - A single page dialog is opened that can be used to prompt the user for values. Indicated by the presence of the `dialog` property.
`Notebook` - The specified Notebook is opened for the user to run. Indicated by the presence of the `notebook` property.
`Download` - An installer is downloaded and ran. Indicated by the presence of the `downloadUrl` property.
`Web Page` - The specified URL is opened in the default browser for the user. Indicated by the presence of the `webPageUrl` property.
`Command` - The specified command is executed. Indicated by the presence of the `command` property.
### AgreementInfo
**TODO**
### NotebookWizard (extends [WizardInfoBase](#wizardinfobase))
See [NotebookWizardInfo](https://github.com/microsoft/azuredatastudio/blob/main/extensions/resource-deployment/src/interfaces.ts#L170) for how it's defined in code.
`notebook` - The path to the Python-based Notebook that is used as a template for the wizard.
`pages` - An array of [NotebookWizardPageInfo](#notebookwizardpageinfo) containing information for each page in the Notebook Wizard.
`codeCellInsertionPosition` - **OPTIONAL** The index of the code cell to insert the injected parameters cell. Default is 0.
### WizardInfoBase
`type` - **OPTIONAL** This is an internal type only used for BDC deployment wizards. Any other deployment providers can leave it out.
`doneAction`
`scriptAction` - **OPTIONAL**
`title`
`name` - **OPTIONAL**
`pages` - An array of the pages for this wizard. Each wizard implementation will usually have its own page type that extends [PageInfoBase](#pageinfobase).
`isSummaryPageAutoGenerated` - **OPTIONAL**
### NotebookWizardPageInfo (extends [PageInfoBase](#pageinfobase))
`description` - **OPTIONAL** The page description to display at the top of the page.
### PageInfoBase
`title` - The title to display for the page
`isSummaryPage` - **OPTIONAL** Whether this page is set as a summary page that displays a summary of the Note
`sections` - An array of [SectionInfo] objects containing the details of each section to display on this page.
### SectionInfo (extends [FieldInfoBase](#fieldinfobase))
`title` - **OPTIONAL** The title to display at the top of the section
`fields` - **OPTIONAL** An array of [FieldInfo](#fieldinfo) objects containing details for each field in this section.
`rows` - **OPTIONAL** Used for wide dialogs or wizards, the label for each field will be placed to the left of the field component.
`collapsible` - **OPTIONAL** Whether the section is collapsible or not. Default is `true`.
`collapsed` - **OPTIONAL** Whether the section starts off collapsed. Default is `false`.
`spaceBetweenFields` - **OPTIONAL** A string defining how much space should be between each field. Default is `50px`.
### FieldInfo
`subFields`
`type`
`defaultValue`
`confirmationRequired`
`confirmationLabel`
`min`
`max`
`required`
`options` - **REQUIRED** if `type` is `options`. See [Options](#options) for more information.
`placeHolder`
`description`
`labelCSSStyles`
`fontWeight`
`editable`
`enabled`
`dynamicOptions`
`isEvaluated`
`validations`
`valueProvider` - **OPTIONAL** If defined then the value for this field is retrieved using the specified [Value Provider](#value-provider).
#### Options
This defines the set of options for this field to display. There are a number of different ways to configure the set of options :
* String array (`string[]`) - A static list of values that will be shown as a dropdown. Default value selected is defined as `FieldInfo.defaultValue`.
* CategoryValue array (`azdata.CategoryValue[]`) - A static list of CategoryValue objects that will be shown as a dropdown. Each value will define a display name separate from its value - use this for values you want to display differently to the user (such as names for an Azure region).
* [OptionsInfo](#optionsinfo) - An object allowing more control over the option values.
See [sample-options](https://github.com/microsoft/azuredatastudio/blob/main/samples/sample-resource-deployment/package.json) for example implementations.
##### OptionsInfo
This object defines a set of options for a field, similar to the arrays that can be used for the [options](#options) field but with greater control over of the options. Currently there are two reasons that you would use this object over the arrays - either you want to display the options as something other than a dropdown or you wish to use an [Options Source Provider](#options-source-provider) to populate the options dynamically.
`values` - An array of either `strings` or `azdata.CategoryValue` objects. See [options](#options) for more details on each of those.
`defaultValue` - The string value of the default option to have selected
`optionsType` - How to display the options, either `radio` or `dropdown`
`source` - OPTIONAL If set defines the [Options Source Provider](#options-source-provider) to use for populating the options dynamically.
### Options Source Provider
### Value Provider
When a field specifies a value provider then it is saying that the value for that field is dynamic and will be retrieved from a value provider that is registered by an extension separately. This can be used for more complex logic such as running calculations, reading files, making web requests, etc.
See [sample-value-provider](https://github.com/microsoft/azuredatastudio/blob/main/samples/sample-resource-deployment/package.json) for an example implementation.
**NOTE** There is currently some behavior that should be known before using this :
1. The value providers are hooked up after all the components are made, so order doesn't generally matter (you don't have to define the trigger fields before the target field) when the values are on the same page.
2. If the fields are on different pages then currently the hookup logic is non-deterministic and so you may end up with trigger components not existing yet if they are on a different page which hasn't completed its initialization. **So currently having a value provider that has trigger fields on another page is not something officially supported. Contact the dev team if you need this for your scenario**
`providerId` - The string ID of this provider, this must be registered by an extension using [registerValueProvider](https://github.com/microsoft/azuredatastudio/blob/main/extensions/resource-deployment/src/typings/resource-deployment.d.ts#L47).
`triggerFields` - The field IDs (`variableName` or `label`) of the fields that - when changed - will trigger `getValue` to be called and the result set as the value of the dependent field. **NOTE** While `variableName` OR `label` is supported it is generally strongly suggested to use a `variableName` (even if you don't need that variable in the final deployment target) due to potential localization mismatches that could happen between the localized strings in the package.json and the ones used by the `valueProvider`.

View File

@@ -21,6 +21,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"microsoft.mssql",
"microsoft.notebook"

View File

@@ -307,7 +307,7 @@ export interface DynamicOptionsAlternates {
export interface ValueProviderInfo {
providerId: string,
triggerField: string
triggerFields: string[]
}
export interface FieldInfoBase {

View File

@@ -5,10 +5,10 @@
import * as azdata from 'azdata';
import 'mocha';
import { InputValueType } from 'resource-deployment';
import * as should from 'should';
import * as sinon from 'sinon';
import * as vscode from 'vscode';
import { InputValueType } from '../../../ui/modelViewUtils';
import { createValidation, GreaterThanOrEqualsValidation, IntegerValidation, LessThanOrEqualsValidation, RegexValidation, validateInputBoxComponent, Validation, ValidationType } from '../../../ui/validation/validations';
const inputBox = <azdata.InputBoxComponent>{

View File

@@ -24,9 +24,19 @@ declare module 'resource-deployment' {
getIsPassword?: (variableName: string) => boolean | Promise<boolean>;
}
export type InputValueType = string | number | boolean | undefined;
export interface IValueProvider {
/**
* The ID associated with this value provider. Fields use this ID in the package.json to indicate which provider to use to get the value for that field.
* Each ID must be globally unique - an error will be thrown if the same ID is already registered.
*/
readonly id: string,
getValue(triggerValue: string): Promise<string>;
/**
* Gets a calculated value based on the given input values.
* @param triggerValues A map of the trigger field names and their current values specified in the valueProvider field info
*/
getValue(triggerValues: {[key: string]: InputValueType}): Promise<InputValueType>;
}
/**
@@ -38,6 +48,12 @@ declare module 'resource-deployment' {
export interface IExtension {
registerOptionsSourceProvider(provider: IOptionsSourceProvider): vscode.Disposable,
/**
* Registers a value provider that resource deployment definitions can use to dynamically fetch the value for specified fields.
* @param provider The provider to register
* @returns A disposable is returned that will unregister the provider when is disposed - this should be used to ensure
* that the provider is unregistered when the extension is uninstalled/deactivated.
*/
registerValueProvider(provider: IValueProvider): vscode.Disposable
}
}

View File

@@ -7,7 +7,7 @@ import { azureResource } from 'azureResource';
import * as fs from 'fs';
import { EOL } from 'os';
import * as path from 'path';
import { IOptionsSourceProvider } from 'resource-deployment';
import { InputValueType, IOptionsSourceProvider } from 'resource-deployment';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { getDateTimeString, getErrorMessage, isUserCancelledError, throwUnless } from '../common/utils';
@@ -33,7 +33,6 @@ const localize = nls.loadMessageBundle();
*/
export type Validator = () => { valid: boolean, message: string };
export type InputValueType = string | number | undefined;
export type InputComponent = azdata.TextComponent | azdata.InputBoxComponent | azdata.DropDownComponent | azdata.CheckBoxComponent | RadioGroupLoadingComponentBuilder;
export type InputComponentInfo<T extends InputComponent> = {
component: T;
@@ -471,20 +470,35 @@ async function hookUpValueProviders(context: WizardPageContext): Promise<void> {
if (field.valueProvider) {
const fieldKey = field.variableName || field.label;
const fieldComponent = context.inputComponents[fieldKey];
const targetComponent = context.inputComponents[field.valueProvider.triggerField];
if (!targetComponent) {
console.error(`Could not find target component ${field.valueProvider.triggerField} when hooking up value providers for ${field.label}`);
return;
}
const provider = await valueProviderService.getValueProvider(field.valueProvider.providerId);
let targetComponentLabelToComponent: { [label: string]: InputComponentInfo<InputComponent>; } = {};
field.valueProvider.triggerFields.forEach((triggerField) => {
const targetComponent = context.inputComponents[triggerField];
if (!targetComponent) {
console.error(`Could not find target component '${triggerField}' when hooking up value providers for '${field.label}'`);
return;
}
targetComponentLabelToComponent[triggerField] = targetComponent;
});
// If one triggerfield changes value, update the new field value.
const updateFields = async () => {
const targetComponentValue = await targetComponent.getValue();
const newFieldValue = await provider.getValue(targetComponentValue?.toString() ?? '');
let targetComponentLabelToValue: { [label: string]: InputValueType; } = {};
for (let label in targetComponentLabelToComponent) {
targetComponentLabelToValue[label] = await targetComponentLabelToComponent[label].getValue();
}
let newFieldValue = await provider.getValue(targetComponentLabelToValue);
fieldComponent.setValue(newFieldValue);
};
targetComponent.onValueChanged(() => {
updateFields();
});
// Set the onValueChanged behavior for each component
for (let label in targetComponentLabelToComponent) {
context.onNewDisposableCreated(targetComponentLabelToComponent[label].onValueChanged(() => {
updateFields();
}));
}
await updateFields();
}
}));
@@ -762,7 +776,10 @@ function processDropdownOptionsTypeField(context: FieldContext): azdata.DropDown
// Note we don't currently check that the value actually exists in the list - if it doesn't then it'll
// just default to the first one anyways
const initialValue = context.fieldInfo.variableName && context.initialVariableValues?.[context.fieldInfo.variableName]?.toString();
const defaultValue = initialValue || options.defaultValue;
const optionValues = options.values;
// If we have an array of CategoryValues then find the option that matches the defaultValue specified - otherwise just use the defaultValue provided
const defaultValueOption = (optionValues && optionValues.length > 0 && typeof optionValues[0] === 'object') ? (optionValues as azdata.CategoryValue[]).find(v => v.name === options.defaultValue) : options.defaultValue;
const defaultValue = initialValue || defaultValueOption;
const dropdown = createDropdownInputInfo(context.view, {
values: options.values,
defaultValue: defaultValue,
@@ -863,6 +880,18 @@ function processReadonlyTextField(context: FieldContext, allowEvaluation: boolea
const text = context.fieldInfo.defaultValue !== undefined
? createLabel(context.view, { text: context.fieldInfo.defaultValue, description: '', required: false, width: context.fieldInfo.inputWidth })
: undefined;
if (text) {
// If we created the text component then add it to our list of inputs so other fields can utilize it
const onChangedEmitter = new vscode.EventEmitter<void>(); // Stub event since we don't currently support updating this when the dependent fields change
context.onNewDisposableCreated(onChangedEmitter);
context.onNewInputComponentCreated(context.fieldInfo.variableName || context.fieldInfo.label, {
component: text,
getValue: async (): Promise<InputValueType> => typeof text.value === 'string' ? text.value : text.value?.join(EOL),
setValue: (value: InputValueType) => text.value = value?.toString(),
onValueChanged: onChangedEmitter.event,
});
}
addLabelInputPairToContainer(context.view, context.components, label, text, context.fieldInfo);
return { label: label, text: text };
}

View File

@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import { InputValueType } from 'resource-deployment';
import * as vscode from 'vscode';
import { isUndefinedOrEmpty, throwUnless } from '../../common/utils';
import { InputValueType } from '../modelViewUtils';
export interface ValidationResult {
valid: boolean;

View File

@@ -2,7 +2,7 @@
"name": "schema-compare",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.12.0",
"version": "1.13.0",
"publisher": "Microsoft",
"preview": false,
"engines": {
@@ -23,6 +23,12 @@
"extensionDependencies": [
"Microsoft.mssql"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"commands": [
{

View File

@@ -9,7 +9,7 @@ import * as loc from '../localizedConstants';
import * as path from 'path';
import { SchemaCompareMainWindow } from '../schemaCompareMainWindow';
import { TelemetryReporter, TelemetryViews } from '../telemetry';
import { getEndpointName, getRootPath, exists } from '../utils';
import { getEndpointName, getRootPath, exists, getAzdataApi, getSchemaCompareEndpointString } from '../utils';
import * as mssql from '../../../mssql';
const titleFontSize: number = 13;
@@ -18,13 +18,16 @@ interface Deferred<T> {
resolve: (result: T | Promise<T>) => void;
reject: (reason: any) => void;
}
export class SchemaCompareDialog {
public dialog: azdata.window.Dialog;
public dialogName: string;
private schemaCompareTab: azdata.window.DialogTab;
private sourceDacpacRadioButton: azdata.RadioButtonComponent;
private sourceDatabaseRadioButton: azdata.RadioButtonComponent;
private schemaCompareTab: azdata.window.DialogTab;
private sourceProjectRadioButton: azdata.RadioButtonComponent;
private sourceDacpacComponent: azdata.FormComponent;
private sourceProjectFilePathComponent: azdata.FormComponent;
private sourceTextBox: azdata.InputBoxComponent;
private sourceFileButton: azdata.ButtonComponent;
private sourceServerComponent: azdata.FormComponent;
@@ -32,22 +35,30 @@ export class SchemaCompareDialog {
private sourceConnectionButton: azdata.ButtonComponent;
private sourceDatabaseComponent: azdata.FormComponent;
private sourceDatabaseDropdown: azdata.DropDownComponent;
private sourceEndpointType: mssql.SchemaCompareEndpointType;
private sourceDbEditable: string;
private sourceDacpacPath: string;
private sourceProjectFilePath: string;
private targetDacpacComponent: azdata.FormComponent;
private targetProjectFilePathComponent: azdata.FormComponent;
private targetProjectStructureComponent: azdata.FormComponent;
private targetTextBox: azdata.InputBoxComponent;
private targetFileButton: azdata.ButtonComponent;
private targetStructureDropdown: azdata.DropDownComponent;
private targetServerComponent: azdata.FormComponent;
protected targetServerDropdown: azdata.DropDownComponent;
private targetConnectionButton: azdata.ButtonComponent;
private targetDatabaseComponent: azdata.FormComponent;
private targetDatabaseDropdown: azdata.DropDownComponent;
private formBuilder: azdata.FormBuilder;
private sourceIsDacpac: boolean;
private targetIsDacpac: boolean;
private connectionId: string;
private sourceDbEditable: string;
private targetDacpacPath: string;
private targetProjectFilePath: string;
private targetEndpointType: mssql.SchemaCompareEndpointType;
private targetDbEditable: string;
private previousSource: mssql.SchemaCompareEndpointInfo;
private previousTarget: mssql.SchemaCompareEndpointInfo;
private formBuilder: azdata.FormBuilder;
private connectionId: string;
private toDispose: vscode.Disposable[] = [];
private initDialogComplete: Deferred<void>;
private initDialogPromise: Promise<void> = new Promise<void>((resolve, reject) => this.initDialogComplete = { resolve, reject });
@@ -59,6 +70,11 @@ export class SchemaCompareDialog {
constructor(private schemaCompareMainWindow: SchemaCompareMainWindow, private view?: azdata.ModelView, private extensionContext?: vscode.ExtensionContext) {
this.previousSource = schemaCompareMainWindow.sourceEndpointInfo;
this.previousTarget = schemaCompareMainWindow.targetEndpointInfo;
this.dialog = azdata.window.createModelViewDialog(loc.SchemaCompareLabel);
this.dialog.registerCloseValidator(async () => {
return this.validate();
});
}
protected async initializeDialog(): Promise<void> {
@@ -79,27 +95,17 @@ export class SchemaCompareDialog {
this.dialog.okButton.label = loc.OkButtonText;
this.dialog.okButton.enabled = false;
this.dialog.okButton.onClick(async () => await this.execute());
this.toDispose.push(this.dialog.okButton.onClick(async () => await this.handleOkButtonClick()));
this.dialog.cancelButton.label = loc.CancelButtonText;
this.dialog.cancelButton.onClick(async () => await this.cancel());
this.toDispose.push(this.dialog.cancelButton.onClick(async () => await this.cancel()));
azdata.window.openDialog(this.dialog);
await this.initDialogPromise;
}
public async execute(): Promise<void> {
if (this.sourceIsDacpac) {
this.schemaCompareMainWindow.sourceEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Dacpac,
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
packageFilePath: this.sourceTextBox.value,
connectionDetails: undefined
};
} else {
if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Database) {
const sourceServerDropdownValue = this.sourceServerDropdown.value as ConnectionDropdownValue;
const ownerUri = await azdata.connection.getUriForConnection(sourceServerDropdownValue.connection.connectionId);
@@ -109,23 +115,45 @@ export class SchemaCompareDialog {
serverName: sourceServerDropdownValue.name,
databaseName: this.sourceDatabaseDropdown.value.toString(),
ownerUri: ownerUri,
projectFilePath: '',
targetScripts: [],
folderStructure: '',
packageFilePath: '',
dataSchemaProvider: '',
connectionDetails: undefined,
connectionName: sourceServerDropdownValue.connection.options.connectionName
};
}
if (this.targetIsDacpac) {
this.schemaCompareMainWindow.targetEndpointInfo = {
} else if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Dacpac) {
this.schemaCompareMainWindow.sourceEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Dacpac,
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
packageFilePath: this.targetTextBox.value,
projectFilePath: '',
targetScripts: [],
folderStructure: '',
dataSchemaProvider: '',
packageFilePath: this.sourceTextBox.value,
connectionDetails: undefined
};
} else {
this.schemaCompareMainWindow.sourceEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Project,
projectFilePath: this.sourceTextBox.value,
targetScripts: await this.getTargetScripts(true),
dataSchemaProvider: await this.getDsp(this.sourceTextBox.value),
folderStructure: '',
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
packageFilePath: '',
connectionDetails: undefined
};
}
if (this.targetEndpointType === mssql.SchemaCompareEndpointType.Database) {
const targetServerDropdownValue = this.targetServerDropdown.value as ConnectionDropdownValue;
const ownerUri = await azdata.connection.getUriForConnection(targetServerDropdownValue.connection.connectionId);
@@ -135,16 +163,48 @@ export class SchemaCompareDialog {
serverName: targetServerDropdownValue.name,
databaseName: this.targetDatabaseDropdown.value.toString(),
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
packageFilePath: '',
dataSchemaProvider: '',
connectionDetails: undefined,
connectionName: targetServerDropdownValue.connection.options.connectionName
};
} else if (this.targetEndpointType === mssql.SchemaCompareEndpointType.Dacpac) {
this.schemaCompareMainWindow.targetEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Dacpac,
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
packageFilePath: this.targetTextBox.value,
connectionDetails: undefined
};
} else {
this.schemaCompareMainWindow.targetEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Project,
projectFilePath: this.targetTextBox.value,
folderStructure: this.targetStructureDropdown!.value as string,
targetScripts: await this.getTargetScripts(false),
dataSchemaProvider: await this.getDsp(this.targetTextBox.value),
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
packageFilePath: '',
connectionDetails: undefined
};
}
TelemetryReporter.createActionEvent(TelemetryViews.SchemaCompareDialog, 'SchemaCompareStart')
.withAdditionalProperties({
sourceIsDacpac: this.sourceIsDacpac.toString(),
targetIsDacpac: this.targetIsDacpac.toString()
sourceEndpointType: getSchemaCompareEndpointString(this.sourceEndpointType),
targetEndpointType: getSchemaCompareEndpointString(this.targetEndpointType)
}).send();
// update source and target values that are displayed
@@ -182,6 +242,7 @@ export class SchemaCompareDialog {
}
protected async cancel(): Promise<void> {
this.dispose();
}
private async initializeSchemaCompareTab(): Promise<void> {
@@ -190,36 +251,67 @@ export class SchemaCompareDialog {
this.view = view;
}
let sourceValue = '';
if (this.schemaCompareMainWindow.sourceEndpointInfo && this.schemaCompareMainWindow.sourceEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Dacpac) {
sourceValue = this.schemaCompareMainWindow.sourceEndpointInfo.packageFilePath;
} else if (this.schemaCompareMainWindow.sourceEndpointInfo && this.schemaCompareMainWindow.sourceEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Project) {
sourceValue = this.schemaCompareMainWindow.sourceEndpointInfo.projectFilePath;
}
this.sourceTextBox = this.view.modelBuilder.inputBox().withProps({
value: this.schemaCompareMainWindow.sourceEndpointInfo ? this.schemaCompareMainWindow.sourceEndpointInfo.packageFilePath : '',
value: sourceValue,
width: this.textBoxWidth,
ariaLabel: loc.sourceFile
}).component();
this.sourceTextBox.onTextChanged(async (e) => {
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Dacpac) {
this.sourceDacpacPath = e;
} else if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Project) {
this.sourceProjectFilePath = e;
}
});
let targetValue = '';
if (this.schemaCompareMainWindow.targetEndpointInfo && this.schemaCompareMainWindow.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Dacpac) {
targetValue = this.schemaCompareMainWindow.targetEndpointInfo.packageFilePath;
} else if (this.schemaCompareMainWindow.targetEndpointInfo && this.schemaCompareMainWindow.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Project) {
targetValue = this.schemaCompareMainWindow.targetEndpointInfo.projectFilePath;
}
this.targetTextBox = this.view.modelBuilder.inputBox().withProps({
value: this.schemaCompareMainWindow.targetEndpointInfo ? this.schemaCompareMainWindow.targetEndpointInfo.packageFilePath : '',
value: targetValue,
width: this.textBoxWidth,
ariaLabel: loc.targetFile
}).component();
this.targetTextBox.onTextChanged(async () => {
this.targetTextBox.onTextChanged(async (e) => {
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
if (this.targetEndpointType === mssql.SchemaCompareEndpointType.Dacpac) {
this.targetDacpacPath = e;
} else if (this.targetEndpointType === mssql.SchemaCompareEndpointType.Project) {
this.targetProjectFilePath = e;
}
});
this.sourceServerComponent = this.createSourceServerDropdown();
this.sourceDatabaseComponent = this.createSourceDatabaseDropdown();
this.targetServerComponent = this.createTargetServerDropdown();
this.targetDatabaseComponent = this.createTargetDatabaseDropdown();
this.sourceDacpacComponent = this.createFileBrowser(false, this.schemaCompareMainWindow.sourceEndpointInfo);
this.targetDacpacComponent = this.createFileBrowser(true, this.schemaCompareMainWindow.targetEndpointInfo);
this.sourceDacpacComponent = this.createFileBrowser(false, true, this.schemaCompareMainWindow.sourceEndpointInfo);
this.targetDacpacComponent = this.createFileBrowser(true, true, this.schemaCompareMainWindow.targetEndpointInfo);
this.sourceProjectFilePathComponent = this.createFileBrowser(false, false, this.schemaCompareMainWindow.sourceEndpointInfo);
this.targetProjectFilePathComponent = this.createFileBrowser(true, false, this.schemaCompareMainWindow.targetEndpointInfo);
this.targetProjectStructureComponent = this.createStructureDropdown();
let sourceRadioButtons = this.createSourceRadioButtons();
let targetRadioButtons = this.createTargetRadioButtons();
@@ -227,31 +319,37 @@ export class SchemaCompareDialog {
let sourceComponents = [];
let targetComponents = [];
// start source and target with either dacpac or database selection based on what the previous value was
if (this.schemaCompareMainWindow.sourceEndpointInfo && this.schemaCompareMainWindow.sourceEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
sourceComponents = [
sourceRadioButtons,
this.sourceServerComponent,
this.sourceDatabaseComponent
];
} else {
sourceComponents = [
sourceRadioButtons,
this.sourceDacpacComponent,
];
// start source and target with either dacpac, database, or project selection based on what the previous value was
sourceComponents = [sourceRadioButtons];
switch (this.sourceEndpointType) {
case mssql.SchemaCompareEndpointType.Database:
sourceComponents.push(
this.sourceServerComponent,
this.sourceDatabaseComponent);
break;
case mssql.SchemaCompareEndpointType.Dacpac:
sourceComponents.push(this.sourceDacpacComponent);
break;
case mssql.SchemaCompareEndpointType.Project:
sourceComponents.push(this.sourceProjectFilePathComponent);
break;
}
if (this.schemaCompareMainWindow.targetEndpointInfo && this.schemaCompareMainWindow.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
targetComponents = [
targetRadioButtons,
this.targetServerComponent,
this.targetDatabaseComponent
];
} else {
targetComponents = [
targetRadioButtons,
this.targetDacpacComponent,
];
targetComponents = [targetRadioButtons];
switch (this.targetEndpointType) {
case mssql.SchemaCompareEndpointType.Database:
targetComponents.push(
this.targetServerComponent,
this.targetDatabaseComponent);
break;
case mssql.SchemaCompareEndpointType.Dacpac:
targetComponents.push(this.targetDacpacComponent);
break;
case mssql.SchemaCompareEndpointType.Project:
targetComponents.push(this.targetProjectFilePathComponent);
break;
}
this.formBuilder = <azdata.FormBuilder>this.view.modelBuilder.formContainer()
@@ -274,17 +372,26 @@ export class SchemaCompareDialog {
let formModel = this.formBuilder.component();
await this.view.initializeModel(formModel);
if (this.sourceIsDacpac) {
await this.sourceDacpacRadioButton.focus();
} else {
await this.sourceDatabaseRadioButton.focus();
switch (this.sourceEndpointType) {
case (mssql.SchemaCompareEndpointType.Database):
await this.sourceDatabaseRadioButton.focus();
break;
case (mssql.SchemaCompareEndpointType.Dacpac):
await this.sourceDacpacRadioButton.focus();
break;
case (mssql.SchemaCompareEndpointType.Project):
await this.sourceProjectRadioButton.focus();
break;
}
this.initDialogComplete.resolve();
});
}
private createFileBrowser(isTarget: boolean, endpoint: mssql.SchemaCompareEndpointInfo): azdata.FormComponent {
private createFileBrowser(isTarget: boolean, dacpac: boolean, endpoint: mssql.SchemaCompareEndpointInfo): azdata.FormComponent {
let currentTextbox = isTarget ? this.targetTextBox : this.sourceTextBox;
if (isTarget) {
this.targetFileButton = this.view.modelBuilder.button().withProps({
title: loc.selectTargetFile,
@@ -302,8 +409,9 @@ export class SchemaCompareDialog {
}
let currentButton = isTarget ? this.targetFileButton : this.sourceFileButton;
const filter = dacpac ? 'dacpac' : 'sqlproj';
currentButton.onDidClick(async (click) => {
currentButton.onDidClick(async () => {
// file browser should open where the current dacpac is or the appropriate default folder
let rootPath = getRootPath();
let defaultUri = endpoint && endpoint.packageFilePath && await exists(endpoint.packageFilePath) ? endpoint.packageFilePath : rootPath;
@@ -316,7 +424,7 @@ export class SchemaCompareDialog {
defaultUri: vscode.Uri.file(defaultUri),
openLabel: loc.open,
filters: {
'dacpac Files': ['dacpac'],
'Files': [filter],
}
}
);
@@ -336,6 +444,22 @@ export class SchemaCompareDialog {
};
}
private createStructureDropdown(): azdata.FormComponent {
this.targetStructureDropdown = this.view.modelBuilder.dropDown().withProps({
editable: true,
fireOnTextChange: true,
ariaLabel: loc.targetStructure,
width: this.textBoxWidth,
values: [loc.file, loc.flat, loc.objectType, loc.schema, loc.schemaObjectType],
value: loc.schemaObjectType,
}).component();
return {
component: this.targetStructureDropdown,
title: loc.StructureDropdownLabel,
};
}
private createSourceRadioButtons(): azdata.FormComponent {
this.sourceDacpacRadioButton = this.view.modelBuilder.radioButton()
.withProps({
@@ -349,36 +473,69 @@ export class SchemaCompareDialog {
label: loc.DatabaseRadioButtonLabel
}).component();
this.sourceProjectRadioButton = this.view.modelBuilder.radioButton()
.withProps({
name: 'source',
label: loc.ProjectRadioButtonLabel
}).component();
// show dacpac file browser
this.sourceDacpacRadioButton.onDidClick(async () => {
this.sourceIsDacpac = true;
this.sourceEndpointType = mssql.SchemaCompareEndpointType.Dacpac;
this.sourceTextBox.value = this.sourceDacpacPath;
this.formBuilder.removeFormItem(this.sourceServerComponent);
this.formBuilder.removeFormItem(this.sourceDatabaseComponent);
this.formBuilder.removeFormItem(this.sourceProjectFilePathComponent);
this.formBuilder.insertFormItem(this.sourceDacpacComponent, 2, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
// show server and db dropdowns
this.sourceDatabaseRadioButton.onDidClick(async () => {
this.sourceIsDacpac = false;
this.sourceEndpointType = mssql.SchemaCompareEndpointType.Database;
this.formBuilder.insertFormItem(this.sourceServerComponent, 2, { horizontal: true, titleFontSize: titleFontSize });
this.formBuilder.insertFormItem(this.sourceDatabaseComponent, 3, { horizontal: true, titleFontSize: titleFontSize });
this.formBuilder.removeFormItem(this.sourceDacpacComponent);
this.formBuilder.removeFormItem(this.sourceProjectFilePathComponent);
await this.populateServerDropdown(false);
});
// if source is currently a db, show it in the server and db dropdowns
if (this.schemaCompareMainWindow.sourceEndpointInfo && this.schemaCompareMainWindow.sourceEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
this.sourceDatabaseRadioButton.checked = true;
this.sourceIsDacpac = false;
} else {
this.sourceDacpacRadioButton.checked = true;
this.sourceIsDacpac = true;
// show project directory browser
this.sourceProjectRadioButton.onDidClick(async () => {
this.sourceEndpointType = mssql.SchemaCompareEndpointType.Project;
this.sourceTextBox.value = this.sourceProjectFilePath;
this.formBuilder.removeFormItem(this.sourceServerComponent);
this.formBuilder.removeFormItem(this.sourceDatabaseComponent);
this.formBuilder.removeFormItem(this.sourceDacpacComponent);
this.formBuilder.insertFormItem(this.sourceProjectFilePathComponent, 2, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
this.sourceEndpointType = this.schemaCompareMainWindow.sourceEndpointInfo?.endpointType ?? mssql.SchemaCompareEndpointType.Database; // default to database if no specific source is passed
switch (this.sourceEndpointType) {
case mssql.SchemaCompareEndpointType.Dacpac:
this.sourceDacpacRadioButton.checked = true;
break;
case mssql.SchemaCompareEndpointType.Project:
this.sourceProjectRadioButton.checked = true;
break;
case mssql.SchemaCompareEndpointType.Database:
this.sourceDatabaseRadioButton.checked = true;
break;
}
let radioButtons = [this.sourceDatabaseRadioButton, this.sourceDacpacRadioButton];
// TODO: re-add once database projects changes are checked in; chicken-and-egg problem (https://github.com/microsoft/azuredatastudio/pull/17738)
// if (vscode.extensions.getExtension(loc.sqlDatabaseProjectExtensionId)) {
// radioButtons.push(this.sourceProjectRadioButton);
// }
let flexRadioButtonsModel = this.view.modelBuilder.flexContainer()
.withLayout({ flexFlow: 'column' })
.withItems([this.sourceDacpacRadioButton, this.sourceDatabaseRadioButton])
.withItems(radioButtons)
.withProps({ ariaRole: 'radiogroup' })
.component();
@@ -389,50 +546,85 @@ export class SchemaCompareDialog {
}
private createTargetRadioButtons(): azdata.FormComponent {
let dacpacRadioButton = this.view.modelBuilder.radioButton()
let targetDacpacRadioButton = this.view.modelBuilder.radioButton()
.withProps({
name: 'target',
label: loc.DacpacRadioButtonLabel
}).component();
let databaseRadioButton = this.view.modelBuilder.radioButton()
let targetDatabaseRadioButton = this.view.modelBuilder.radioButton()
.withProps({
name: 'target',
label: loc.DatabaseRadioButtonLabel
}).component();
let targetProjectRadioButton = this.view.modelBuilder.radioButton()
.withProps({
name: 'target',
label: loc.ProjectRadioButtonLabel
}).component();
// show dacpac file browser
dacpacRadioButton.onDidClick(async () => {
this.targetIsDacpac = true;
targetDacpacRadioButton.onDidClick(async () => {
this.targetEndpointType = mssql.SchemaCompareEndpointType.Dacpac;
this.targetTextBox.value = this.targetDacpacPath;
this.formBuilder.removeFormItem(this.targetServerComponent);
this.formBuilder.removeFormItem(this.targetDatabaseComponent);
this.formBuilder.removeFormItem(this.targetProjectFilePathComponent);
this.formBuilder.removeFormItem(this.targetProjectStructureComponent);
this.formBuilder.addFormItem(this.targetDacpacComponent, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
// show server and db dropdowns
databaseRadioButton.onDidClick(async () => {
this.targetIsDacpac = false;
targetDatabaseRadioButton.onDidClick(async () => {
this.targetEndpointType = mssql.SchemaCompareEndpointType.Database;
this.formBuilder.removeFormItem(this.targetDacpacComponent);
this.formBuilder.removeFormItem(this.targetProjectFilePathComponent);
this.formBuilder.removeFormItem(this.targetProjectStructureComponent);
this.formBuilder.addFormItem(this.targetServerComponent, { horizontal: true, titleFontSize: titleFontSize });
this.formBuilder.addFormItem(this.targetDatabaseComponent, { horizontal: true, titleFontSize: titleFontSize });
await this.populateServerDropdown(true);
});
// if target is currently a db, show it in the server and db dropdowns
if (this.schemaCompareMainWindow.targetEndpointInfo && this.schemaCompareMainWindow.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
databaseRadioButton.checked = true;
this.targetIsDacpac = false;
} else {
dacpacRadioButton.checked = true;
this.targetIsDacpac = true;
// show project directory browser
targetProjectRadioButton.onDidClick(async () => {
this.targetEndpointType = mssql.SchemaCompareEndpointType.Project;
this.targetTextBox.value = this.targetProjectFilePath;
this.formBuilder.removeFormItem(this.targetServerComponent);
this.formBuilder.removeFormItem(this.targetDatabaseComponent);
this.formBuilder.removeFormItem(this.targetDacpacComponent);
this.formBuilder.addFormItem(this.targetProjectFilePathComponent, { horizontal: true, titleFontSize: titleFontSize });
this.formBuilder.addFormItem(this.targetProjectStructureComponent, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
this.targetEndpointType = this.schemaCompareMainWindow.targetEndpointInfo?.endpointType ?? mssql.SchemaCompareEndpointType.Database; // default to database if no specific target is passed
switch (this.targetEndpointType) {
case mssql.SchemaCompareEndpointType.Dacpac:
targetDacpacRadioButton.checked = true;
break;
case mssql.SchemaCompareEndpointType.Project:
targetProjectRadioButton.checked = true;
break;
case mssql.SchemaCompareEndpointType.Database:
targetDatabaseRadioButton.checked = true;
break;
}
let radioButtons = [targetDatabaseRadioButton, targetDacpacRadioButton];
// TODO: re-add once database projects changes are checked in; chicken-and-egg problem (https://github.com/microsoft/azuredatastudio/pull/17738)
// if (vscode.extensions.getExtension(loc.sqlDatabaseProjectExtensionId)) {
// radioButtons.push(targetProjectRadioButton);
// }
let flexRadioButtonsModel = this.view.modelBuilder.flexContainer()
.withLayout({ flexFlow: 'column' })
.withItems([dacpacRadioButton, databaseRadioButton]
)
.withItems(radioButtons)
.withProps({ ariaRole: 'radiogroup' })
.component();
@@ -443,18 +635,83 @@ export class SchemaCompareDialog {
}
private async shouldEnableOkayButton(): Promise<boolean> {
let sourcefilled = (this.sourceIsDacpac && await this.existsDacpac(this.sourceTextBox.value))
|| (!this.sourceIsDacpac && !isNullOrUndefined(this.sourceDatabaseDropdown.value) && this.sourceDatabaseDropdown.values.findIndex(x => this.matchesValue(x, this.sourceDbEditable)) !== -1);
let targetfilled = (this.targetIsDacpac && await this.existsDacpac(this.targetTextBox.value))
|| (!this.targetIsDacpac && !isNullOrUndefined(this.targetDatabaseDropdown.value) && this.targetDatabaseDropdown.values.findIndex(x => this.matchesValue(x, this.targetDbEditable)) !== -1);
let sourcefilled = (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Dacpac && await this.existsDacpac(this.sourceTextBox.value))
|| (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Project && this.existsProjectFile(this.sourceTextBox.value))
|| (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Database && !isNullOrUndefined(this.sourceDatabaseDropdown.value) && this.sourceDatabaseDropdown.values.findIndex(x => this.matchesValue(x, this.sourceDbEditable)) !== -1);
let targetfilled = (this.targetEndpointType === mssql.SchemaCompareEndpointType.Dacpac && await this.existsDacpac(this.targetTextBox.value))
|| (this.targetEndpointType === mssql.SchemaCompareEndpointType.Project && this.existsProjectFile(this.targetTextBox.value))
|| (this.targetEndpointType === mssql.SchemaCompareEndpointType.Database && !isNullOrUndefined(this.targetDatabaseDropdown.value) && this.targetDatabaseDropdown.values.findIndex(x => this.matchesValue(x, this.targetDbEditable)) !== -1);
return sourcefilled && targetfilled;
}
public async handleOkButtonClick(): Promise<void> {
await this.execute();
this.dispose();
}
protected showErrorMessage(message: string): void {
this.dialog.message = {
text: message,
level: getAzdataApi()!.window.MessageLevel.Error
};
}
async validate(): Promise<boolean> {
try {
// check project extension is installed
if (!vscode.extensions.getExtension(loc.sqlDatabaseProjectExtensionId) &&
(this.sourceEndpointType === mssql.SchemaCompareEndpointType.Project ||
this.targetEndpointType === mssql.SchemaCompareEndpointType.Project)) {
this.showErrorMessage(loc.noProjectExtension);
return false;
}
// check Database Schema Providers are set and valid
if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Project) {
try {
await this.getDsp(this.sourceTextBox.value);
} catch (err) {
this.showErrorMessage(loc.dspErrorSource);
}
}
if (this.targetEndpointType === mssql.SchemaCompareEndpointType.Project) {
try {
await this.getDsp(this.targetTextBox.value);
} catch (err) {
this.showErrorMessage(loc.dspErrorTarget);
}
}
return true;
} catch (e) {
this.showErrorMessage(e?.message ? e.message : e);
return false;
}
}
private dispose(): void {
this.toDispose.forEach(disposable => disposable.dispose());
}
private async existsDacpac(filename: string): Promise<boolean> {
return !isNullOrUndefined(filename) && await exists(filename) && (filename.toLocaleLowerCase().endsWith('.dacpac'));
}
private async existsProjectFile(filename: string): Promise<boolean> {
return !isNullOrUndefined(filename) && await exists(filename) && (filename.toLocaleLowerCase().endsWith('.sqlproj'));
}
private async getTargetScripts(source: boolean): Promise<string[]> {
const projectFilePath = source ? this.sourceTextBox.value : this.targetTextBox.value;
return await vscode.commands.executeCommand(loc.sqlDatabaseProjectsGetTargetScripts, projectFilePath);
}
private async getDsp(projectFilePath: string): Promise<string> {
return await vscode.commands.executeCommand(loc.sqlDatabaseProjectsGetDsp, projectFilePath);
}
protected createSourceServerDropdown(): azdata.FormComponent {
this.sourceServerDropdown = this.view.modelBuilder.dropDown().withProps(
{
@@ -524,9 +781,7 @@ export class SchemaCompareDialog {
width: this.textBoxWidth
}
).component();
this.targetConnectionButton = this.createConnectionButton(true);
this.targetServerDropdown.onValueChanged(async (value) => {
if (value.selected && this.targetServerDropdown.values.findIndex(x => this.matchesValue(x, value.selected)) === -1) {
await this.targetDatabaseDropdown.updateProperties({
@@ -539,10 +794,8 @@ export class SchemaCompareDialog {
await this.populateDatabaseDropdown((this.targetServerDropdown.value as ConnectionDropdownValue).connection, true);
}
});
// don't await so that dialog loading won't be blocked. Dropdown will show loading indicator until it is populated
this.populateServerDropdown(true);
return {
component: this.targetServerDropdown,
title: loc.ServerDropdownLabel,

View File

@@ -7,7 +7,7 @@ import * as vscode from 'vscode';
import { SchemaCompareMainWindow } from './schemaCompareMainWindow';
export async function activate(extensionContext: vscode.ExtensionContext): Promise<void> {
vscode.commands.registerCommand('schemaCompare.start', async (context: any) => { await new SchemaCompareMainWindow(undefined, extensionContext, undefined).start(context); });
vscode.commands.registerCommand('schemaCompare.start', async (sourceContext: any, targetContext: any = undefined, comparisonResult: any = undefined) => { await new SchemaCompareMainWindow(undefined, extensionContext, undefined).start(sourceContext, targetContext, comparisonResult); });
}
export function deactivate(): void {

View File

@@ -14,9 +14,11 @@ export const TargetTitle: string = localize('schemaCompareDialog.TargetTitle', "
export const FileTextBoxLabel: string = localize('schemaCompareDialog.fileTextBoxLabel', "File");
export const DacpacRadioButtonLabel: string = localize('schemaCompare.dacpacRadioButtonLabel', "Data-tier Application File (.dacpac)");
export const DatabaseRadioButtonLabel: string = localize('schemaCompare.databaseButtonLabel', "Database");
export const ProjectRadioButtonLabel: string = localize('schemaCompare.projectButtonLabel', "Database Project");
export const RadioButtonsLabel: string = localize('schemaCompare.radioButtonsLabel', "Type");
export const ServerDropdownLabel: string = localize('schemaCompareDialog.serverDropdownTitle', "Server");
export const DatabaseDropdownLabel: string = localize('schemaCompareDialog.databaseDropdownTitle', "Database");
export const StructureDropdownLabel: string = localize('schemaCompareDialog.structureDropdownLabel', "Folder Structure");
export const SchemaCompareLabel: string = localize('schemaCompare.dialogTitle', "Schema Compare");
export const differentSourceMessage: string = localize('schemaCompareDialog.differentSourceMessage', "A different source schema has been selected. Compare to see the comparison?");
export const differentTargetMessage: string = localize('schemaCompareDialog.differentTargetMessage', "A different target schema has been selected. Compare to see the comparison?");
@@ -31,6 +33,12 @@ export const sourceServer: string = localize('schemaCompareDialog.sourceServerDr
export const targetServer: string = localize('schemaCompareDialog.targetServerDropdown', "Target Server");
export const defaultText: string = localize('schemaCompareDialog.defaultUser', "default");
export const open: string = localize('schemaCompare.openFile', "Open");
export const targetStructure = localize('targetStructure', "Target Folder Structure");
export const file = localize('file', "File");
export const flat = localize('flat', "Flat");
export const objectType = localize('objectType', "Object Type");
export const schema = localize('schema', "Schema");
export const schemaObjectType = localize('schemaObjectType', "Schema/Object Type");
export const selectSourceFile: string = localize('schemaCompare.selectSourceFile', "Select source file");
export const selectTargetFile: string = localize('schemaCompare.selectTargetFile', "Select target file");
export const ResetButtonText: string = localize('SchemaCompareOptionsDialog.Reset', "Reset");
@@ -61,7 +69,7 @@ export const include: string = localize('schemaCompare.includeColumnName', "Incl
export const action: string = localize('schemaCompare.actionColumn', "Action");
export const targetName: string = localize('schemaCompare.targetNameColumn', "Target Name");
export const generateScriptDisabled: string = localize('schemaCompare.generateScriptButtonDisabledTitle', "Generate script is enabled when the target is a database");
export const applyDisabled: string = localize('schemaCompare.applyButtonDisabledTitle', "Apply is enabled when the target is a database");
export const applyDisabled: string = localize('schemaCompare.applyButtonDisabledTitle', "Apply is enabled when the target is a database or database project");
export function cannotExcludeMessageDependent(diffEntryName: string, firstDependentName: string): string { return localize('schemaCompare.cannotExcludeMessageWithDependent', "Cannot exclude {0}. Included dependents exist, such as {1}", diffEntryName, firstDependentName); }
export function cannotIncludeMessageDependent(diffEntryName: string, firstDependentName: string): string { return localize('schemaCompare.cannotIncludeMessageWithDependent', "Cannot include {0}. Excluded dependents exist, such as {1}", diffEntryName, firstDependentName); }
export function cannotExcludeMessage(diffEntryName: string): string { return localize('schemaCompare.cannotExcludeMessage', "Cannot exclude {0}. Included dependents exist", diffEntryName); }
@@ -318,3 +326,20 @@ export function cancelErrorMessage(errorMessage: string): string { return locali
export function generateScriptErrorMessage(errorMessage: string): string { return localize('schemaCompare.generateScriptErrorMessage', "Generate script failed: '{0}'", (errorMessage) ? errorMessage : 'Unknown'); }
export function applyErrorMessage(errorMessage: string): string { return localize('schemaCompare.updateErrorMessage', "Schema Compare Apply failed '{0}'", errorMessage ? errorMessage : 'Unknown'); }
export function openScmpErrorMessage(errorMessage: string): string { return localize('schemaCompare.openScmpErrorMessage', "Open scmp failed: '{0}'", (errorMessage) ? errorMessage : 'Unknown'); }
export const applyError: string = localize('schemaCompare.applyError', "There was an error updating the project");
export const dspErrorSource: string = localize('schemaCompareDialog.dspErrorSource', "The source .sqlproj file does not specify a database schema component");
export const dspErrorTarget: string = localize('schemaCompareDialog.dspErrorTarget', "The target .sqlproj file does not specify a database schema component");
export const noProjectExtension: string = localize('schemaCompareDialog.noProjectExtension', "The sql-database-projects extension is required to perform schema comparison with database projects");
export const noProjectExtensionApply: string = localize('schemaCompareDialog.noProjectExtensionApply', "The sql-database-projects extension is required to apply changes to a project");
// Information messages
export const applySuccess: string = localize('schemaCompare.applySuccess', "Project was successfully updated");
// Extensions
export const sqlDatabaseProjectExtensionId: string = 'microsoft.sql-database-projects';
// Commands
export const sqlDatabaseProjectsGetTargetScripts: string = 'sqlDatabaseProjects.schemaCompareGetTargetScripts';
export const sqlDatabaseProjectsGetDsp: string = 'sqlDatabaseProjects.schemaCompareGetDsp';
export const sqlDatabaseProjectsPublishChanges: string = 'sqlDatabaseProjects.schemaComparePublishProjectChanges';
export const sqlDatabaseProjectsShowProjectsView: string = 'sqlDatabaseProjects.schemaCompareShowProjectsView';

View File

@@ -11,7 +11,7 @@ import * as mssql from '../../mssql';
import * as loc from './localizedConstants';
import { SchemaCompareOptionsDialog } from './dialogs/schemaCompareOptionsDialog';
import { TelemetryReporter, TelemetryViews } from './telemetry';
import { getTelemetryErrorType, getEndpointName, verifyConnectionAndGetOwnerUri, getRootPath } from './utils';
import { getTelemetryErrorType, getEndpointName, verifyConnectionAndGetOwnerUri, getRootPath, getSchemaCompareEndpointString } from './utils';
import { SchemaCompareDialog } from './dialogs/schemaCompareDialog';
import { isNullOrUndefined } from 'util';
@@ -81,14 +81,33 @@ export class SchemaCompareMainWindow {
this.editor = azdata.workspace.createModelViewEditor(loc.SchemaCompareLabel, { retainContextWhenHidden: true, supportsSave: true, resourceName: schemaCompareResourceName }, 'SchemaCompareEditor');
}
// schema compare can get started with three contexts for the source:
// schema compare can get started with four contexts for the source:
// 1. undefined
// 2. connection profile
// 3. dacpac
public async start(context: any): Promise<void> {
// if schema compare was launched from a db, set that as the source
let profile = context ? <azdata.IConnectionProfile>context.connectionProfile : undefined;
let sourceDacpac = context as string;
// 4. project
public async start(sourceContext: any, targetContext: mssql.SchemaCompareEndpointInfo = undefined, comparisonResult: mssql.SchemaCompareResult = undefined): Promise<void> {
const targetIsSetAsProject: boolean = targetContext && targetContext.endpointType === mssql.SchemaCompareEndpointType.Project;
// if schema compare was launched from a db or a connection profile, set that as the source
let profile: azdata.IConnectionProfile;
if (targetIsSetAsProject) {
profile = sourceContext;
this.targetEndpointInfo = targetContext;
} else {
profile = sourceContext ? <azdata.IConnectionProfile>sourceContext.connectionProfile : undefined;
}
let sourceDacpac = undefined;
let sourceProject = undefined;
if (!profile && sourceContext as string && (sourceContext as string).endsWith('.dacpac')) {
sourceDacpac = sourceContext as string;
} else if (!profile) {
sourceProject = sourceContext as string;
}
if (profile) {
let ownerUri = await azdata.connection.getUriForConnection((profile.id));
let usr = profile.userName;
@@ -104,7 +123,11 @@ export class SchemaCompareMainWindow {
ownerUri: ownerUri,
packageFilePath: '',
connectionDetails: undefined,
connectionName: profile.connectionName
connectionName: profile.connectionName,
projectFilePath: '',
targetScripts: [],
dataSchemaProvider: '',
folderStructure: ''
};
} else if (sourceDacpac) {
this.sourceEndpointInfo = {
@@ -114,7 +137,25 @@ export class SchemaCompareMainWindow {
databaseName: '',
ownerUri: '',
packageFilePath: sourceDacpac,
connectionDetails: undefined
connectionDetails: undefined,
projectFilePath: '',
targetScripts: [],
dataSchemaProvider: '',
folderStructure: ''
};
} else if (sourceProject) {
this.sourceEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Project,
packageFilePath: '',
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
connectionDetails: undefined,
projectFilePath: sourceProject,
targetScripts: [],
dataSchemaProvider: undefined,
folderStructure: ''
};
}
@@ -123,6 +164,10 @@ export class SchemaCompareMainWindow {
this.registerContent(),
this.editor.openEditor()
]);
if (targetIsSetAsProject) {
await this.execute(comparisonResult);
}
}
private async registerContent(): Promise<void> {
@@ -162,7 +207,8 @@ export class SchemaCompareMainWindow {
this.createSourceAndTargetButtons();
this.sourceName = getEndpointName(this.sourceEndpointInfo);
this.targetName = ' ';
this.targetName = getEndpointName(this.targetEndpointInfo);
this.sourceNameComponent = this.view.modelBuilder.inputBox().withProps({
value: this.sourceName,
title: this.sourceName,
@@ -275,33 +321,43 @@ export class SchemaCompareMainWindow {
this.deploymentOptions = deploymentOptions;
}
public async execute() {
TelemetryReporter.sendActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonStarted');
public async execute(comparisonResult: mssql.SchemaCompareCompletionResult = undefined) {
const service = await this.getService();
if (!this.operationId) {
// create once per page
this.operationId = generateGuid();
}
if (comparisonResult) {
this.operationId = comparisonResult.operationId;
this.comparisonResult = comparisonResult;
this.flexModel.removeItem(this.startText);
} else {
TelemetryReporter.sendActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonStarted');
this.comparisonResult = await service.schemaCompare(this.operationId, this.sourceEndpointInfo, this.targetEndpointInfo, azdata.TaskExecutionMode.execute, this.deploymentOptions);
if (!this.comparisonResult || !this.comparisonResult.success) {
TelemetryReporter.createErrorEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonFailed', undefined, getTelemetryErrorType(this.comparisonResult?.errorMessage))
if (!this.operationId) {
// create once per page
this.operationId = generateGuid();
}
this.comparisonResult = await service.schemaCompare(this.operationId, this.sourceEndpointInfo, this.targetEndpointInfo, azdata.TaskExecutionMode.execute, this.deploymentOptions);
if (!this.comparisonResult || !this.comparisonResult.success) {
TelemetryReporter.createErrorEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonFailed', undefined, getTelemetryErrorType(this.comparisonResult?.errorMessage))
.withAdditionalProperties({
operationId: this.comparisonResult.operationId
}).send();
vscode.window.showErrorMessage(loc.compareErrorMessage(this.comparisonResult?.errorMessage));
// reset state so a new comparison can be made
this.resetWindow();
return;
}
TelemetryReporter.createActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonFinished')
.withAdditionalProperties({
operationId: this.comparisonResult.operationId
'endTime': Date.now().toString(),
'operationId': this.comparisonResult.operationId
}).send();
vscode.window.showErrorMessage(loc.compareErrorMessage(this.comparisonResult?.errorMessage));
// reset state so a new comparison can be made
this.resetWindow();
return;
}
TelemetryReporter.createActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonFinished')
.withAdditionalProperties({
'endTime': Date.now().toString(),
'operationId': this.comparisonResult.operationId
}).send();
let data = this.getAllDifferences(this.comparisonResult.differences);
@@ -363,9 +419,15 @@ export class SchemaCompareMainWindow {
// only enable generate script button if the target is a db
if (this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
this.generateScriptButton.enabled = true;
this.applyButton.enabled = true;
} else {
this.generateScriptButton.title = loc.generateScriptDisabled;
}
// only enable apply button if the target is a db or a project
if (this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database ||
this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Project) {
this.applyButton.enabled = true;
} else {
this.applyButton.title = loc.applyDisabled;
}
} else {
@@ -762,7 +824,6 @@ export class SchemaCompareMainWindow {
}
public async publishChanges(): Promise<void> {
// need only yes button - since the modal dialog has a default cancel
const yesString = loc.YesButtonText;
await vscode.window.showWarningMessage(loc.applyConfirmation, { modal: true }, yesString).then(async (result) => {
@@ -776,14 +837,26 @@ export class SchemaCompareMainWindow {
// disable apply and generate script buttons because the results are no longer valid after applying the changes
this.setButtonsForRecompare();
const service = await this.getService();
const result = await service.schemaComparePublishChanges(this.comparisonResult.operationId, this.targetEndpointInfo.serverName, this.targetEndpointInfo.databaseName, azdata.TaskExecutionMode.execute);
const service: mssql.ISchemaCompareService = await this.getService();
let result: azdata.ResultStatus | undefined = undefined;
switch (this.targetEndpointInfo.endpointType) {
case mssql.SchemaCompareEndpointType.Database:
result = await service.schemaComparePublishDatabaseChanges(this.comparisonResult.operationId, this.targetEndpointInfo.serverName, this.targetEndpointInfo.databaseName, azdata.TaskExecutionMode.execute);
break;
case mssql.SchemaCompareEndpointType.Project: // Project apply needs sql-database-projects updates in (circular dependency; coming next) // TODO: re-add this and show project logic below
case mssql.SchemaCompareEndpointType.Dacpac: // Dacpac is an invalid publish target
default:
throw new Error(`Unsupported SchemaCompareEndpointType: ${getSchemaCompareEndpointString(this.targetEndpointInfo.endpointType)}`);
}
if (!result || !result.success) {
TelemetryReporter.createErrorEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaCompareApplyFailed', undefined, getTelemetryErrorType(result.errorMessage))
TelemetryReporter.createErrorEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaCompareApplyFailed', undefined, getTelemetryErrorType(result?.errorMessage))
.withAdditionalProperties({
'operationId': this.comparisonResult.operationId
}).send();
vscode.window.showErrorMessage(loc.applyErrorMessage(result.errorMessage));
vscode.window.showErrorMessage(loc.applyErrorMessage(result?.errorMessage));
// reenable generate script and apply buttons if apply failed
this.generateScriptButton.enabled = true;
@@ -791,6 +864,7 @@ export class SchemaCompareMainWindow {
this.applyButton.enabled = true;
this.applyButton.title = loc.applyEnabledMessage;
}
TelemetryReporter.createActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaCompareApplyEnded')
.withAdditionalProperties({
'endTime': Date.now().toString(),
@@ -1082,11 +1156,15 @@ export class SchemaCompareMainWindow {
}
private setButtonStatesForNoChanges(enableButtons: boolean): void {
// generate script and apply can only be enabled if the target is a database
if (this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
// generate script and apply can only be enabled if the target is a database or project
if (this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database ||
this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Project) {
this.applyButton.enabled = enableButtons;
this.generateScriptButton.enabled = enableButtons;
this.applyButton.title = enableButtons ? loc.applyEnabledMessage : loc.applyNoChangesMessage;
}
if (this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
this.generateScriptButton.enabled = enableButtons;
this.generateScriptButton.title = enableButtons ? loc.generateScriptEnabledMessage : loc.generateScriptNoChangesMessage;
}
}

View File

@@ -110,7 +110,7 @@ describe('SchemaCompareMainWindow.results @DacFx@', function (): void {
it('Should show error if publish changes fails', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
service.setup(x => x.schemaComparePublishDatabaseChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: false,
errorMessage: 'error1'
}));
@@ -121,7 +121,7 @@ describe('SchemaCompareMainWindow.results @DacFx@', function (): void {
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
schemaCompareResult.targetEndpointInfo = setDatabaseEndpointInfo();
await schemaCompareResult.execute();
await schemaCompareResult.publishChanges();
@@ -131,7 +131,7 @@ describe('SchemaCompareMainWindow.results @DacFx@', function (): void {
it('Should show not error if publish changes succeed', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
service.setup(x => x.schemaComparePublishDatabaseChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: true,
errorMessage: ''
}));
@@ -140,7 +140,7 @@ describe('SchemaCompareMainWindow.results @DacFx@', function (): void {
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
schemaCompareResult.targetEndpointInfo = setDatabaseEndpointInfo();
await schemaCompareResult.execute();
await schemaCompareResult.publishChanges();
should(showErrorMessageSpy.notCalled).be.true();
@@ -343,7 +343,7 @@ describe('SchemaCompareMainWindow.results @DacFx@', function (): void {
it('Should not show error if user does not want to publish', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
service.setup(x => x.schemaComparePublishDatabaseChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: true,
errorMessage: ''
}));

View File

@@ -24,6 +24,14 @@ export class SchemaCompareTestService implements mssql.ISchemaCompareService {
throw new Error('Method not implemented.');
}
schemaComparePublishDatabaseChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
throw new Error('Method not implemented.');
}
schemaComparePublishProjectChanges(operationId: string, targetProjectPath: string, targetFolderStructure: mssql.ExtractTarget, taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.SchemaComparePublishProjectResult> {
throw new Error('Method not implemented.');
}
schemaCompareGetDefaultOptions(): Thenable<mssql.SchemaCompareOptionsResult> {
let result: mssql.SchemaCompareOptionsResult = {
defaultDeploymentOptions: undefined,
@@ -42,7 +50,6 @@ export class SchemaCompareTestService implements mssql.ISchemaCompareService {
throw new Error('Method not implemented.');
}
schemaCompareSaveScmp(sourceEndpointInfo: mssql.SchemaCompareEndpointInfo, targetEndpointInfo: mssql.SchemaCompareEndpointInfo, taskExecutionMode: azdata.TaskExecutionMode, deploymentOptions: mssql.DeploymentOptions, scmpFilePath: string, excludedSourceObjects: mssql.SchemaCompareObjectId[], excludedTargetObjects: mssql.SchemaCompareObjectId[]): Thenable<azdata.ResultStatus> {
throw new Error('Method not implemented.');
}

View File

@@ -94,7 +94,11 @@ export const mockDacpacEndpoint: mssql.SchemaCompareEndpointInfo = {
databaseName: '',
ownerUri: '',
packageFilePath: mockFilePath,
connectionDetails: undefined
connectionDetails: undefined,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
};
export const mockDatabaseEndpoint: mssql.SchemaCompareEndpointInfo = {
@@ -104,7 +108,11 @@ export const mockDatabaseEndpoint: mssql.SchemaCompareEndpointInfo = {
databaseName: '',
ownerUri: '',
packageFilePath: '',
connectionDetails: undefined
connectionDetails: undefined,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
};
export async function shouldThrowSpecificError(block: Function, expectedMessage: string, details?: string) {

View File

@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import type * as azdataType from 'azdata'; // eslint-disable-line no-duplicate-imports
import * as vscode from 'vscode';
import * as mssql from '../../mssql';
import * as os from 'os';
@@ -39,6 +40,19 @@ export function getTelemetryErrorType(msg: string): string {
}
}
export function getSchemaCompareEndpointString(endpointType: mssql.SchemaCompareEndpointType): string {
switch (endpointType) {
case mssql.SchemaCompareEndpointType.Database:
return 'Database';
case mssql.SchemaCompareEndpointType.Dacpac:
return 'Dacpac';
case mssql.SchemaCompareEndpointType.Project:
return 'Project';
default:
return `Unknown: ${endpointType}`;
}
}
/**
* Return the appropriate endpoint name depending on if the endpoint is a dacpac or a database
* @param endpoint endpoint to get the name of
@@ -64,8 +78,11 @@ export function getEndpointName(endpoint: mssql.SchemaCompareEndpointInfo): stri
return ' ';
}
} else {
} else if (endpoint.endpointType === mssql.SchemaCompareEndpointType.Dacpac) {
return endpoint.packageFilePath;
} else {
return endpoint.projectFilePath;
}
}
@@ -144,3 +161,24 @@ export async function exists(path: string): Promise<boolean> {
return false;
}
}
// Try to load the azdata API - but gracefully handle the failure in case we're running
// in a context where the API doesn't exist (such as VS Code)
let azdataApi: typeof azdataType | undefined = undefined;
try {
azdataApi = require('azdata');
if (!azdataApi?.version) {
// webpacking makes the require return an empty object instead of throwing an error so make sure we clear the var
azdataApi = undefined;
}
} catch {
// no-op
}
/**
* Gets the azdata API if it's available in the context this extension is running in.
* @returns The azdata API if it's available
*/
export function getAzdataApi(): typeof azdataType | undefined {
return azdataApi;
}

View File

@@ -19,6 +19,12 @@
"*"
],
"main": "./out/extension",
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"forceReload": true,
"contributes": {
"commands": [

View File

@@ -15,6 +15,12 @@
"activationEvents": [
"onDashboardOpen"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"main": "./out/main",
"repository": {
"type": "git",

View File

@@ -4,14 +4,11 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
// Note for debugging the VS Code version of the extension, currently you will need to modify
// the package.json and manually copy over the values from package.vscode.json into package.json
// (otherwise you'll get errors since other extensions depend on an extension with the name
// data-workspace-vscode, not data-workspace)
// This task is meant for running the VS Code version of the extension. See VSCODE_DEVELOPMENT.md for more information
{
"type": "extensionHost",
"request": "launch",
"name": "Launch Extension",
"name": "Launch Extension in VS Code",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
@@ -21,4 +18,4 @@
]
}
]
}
}

View File

@@ -1,9 +1,17 @@
# Microsoft SQL Server Database Projects for Azure Data Studio and VS Code
Microsoft SQL Server Database Projects for Azure Data Studio and VS Code includes:
## Overview
Microsoft SQL Server Database Projects for Azure Data Studio and VS Code provides a way to design, edit, and publish schemas for SQL databases from a source controlled project.
### VS Code
This extension is bundled into the `SQL Server (MSSQL)` extension for VS Code and will be installed automatically when that extension is updated or installed.
### Azure Data Studio
This extension is provided as a separate extension in the marketplace.
## Database Projects
The Database Projects extension provides a way to design, edit, and publish schemas for SQL databases from a source controlled project.
Please report issues and feature requests [here.](https://github.com/microsoft/azuredatastudio/issues)
@@ -11,7 +19,8 @@ Please report issues and feature requests [here.](https://github.com/microsoft/a
* Create a new database project by going to the **Projects** viewlet or by searching **Projects: New** in the command palette.
* Existing database projects can be opened by going to the **Projects** viewlet or by searching **Projects: Open Existing** in the command palette.
* Start from an existing database by using **Create Project From Database** from the command palette or database context menu.
* Start from an existing database by using the **Create Project from Database** from the command palette or database context menu.
* Start from an OpenAPI/Swagger spec by using the **Generate SQL Project from OpenAPI/Swagger spec** command.
## Code of Conduct

View File

@@ -0,0 +1,15 @@
# VS Code Extension Development
For working on the VS Code version of the package follow these steps for local development/testing.
1. Copy the values from [package.vscode.json](./package.vscode.json) into [package.json](./package.json) (overwriting the properties with the same name there)
2. Delete the following properties (this includes their arrays of values as well) from the `contributes/menus` property in the [package.json](./package.json)
* `objectExplorer/item/context`
* `dataExplorer/context`
* `dashboard/toolbar`
3. Compile Azure Data Studio as normal and wait for it to finish
4. Run `code <PathToAzureDataStudioSource>/extensions/sql-database-projects` from the command line to open a new VS Code instance at the `sql-database-projects` folder
5. Run the `Launch Extension in VS Code` launch target from the `Run and Debug` view
6. This should launch an `Extension Development Host` version of VS Code that is running the extension from sources.
If you have the compilation running as watch then once you make changes you can just reload the window to pick up the latest changes being made.

View File

@@ -1,8 +1,8 @@
{
"name": "sql-database-projects",
"displayName": "SQL Database Projects",
"description": "The SQL Database Projects extension for Azure Data Studio and VS Code allows users to develop and publish database schemas.",
"version": "0.13.0",
"description": "Enables users to develop and publish database schemas for MSSQL Databases",
"version": "0.14.0",
"publisher": "Microsoft",
"preview": true,
"engines": {
@@ -17,6 +17,7 @@
"onCommand:sqlDatabaseProjects.open",
"onCommand:sqlDatabaseProjects.createProjectFromDatabase",
"onCommand:sqlDatabaseProjects.generateProjectFromOpenApiSpec",
"onCommand:sqlDatabaseProjects.addSqlBinding",
"workspaceContains:**/*.sqlproj",
"onView:dataworkspace.views.main"
],
@@ -29,6 +30,12 @@
"Microsoft.mssql",
"Microsoft.schema-compare"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"projects": [
"sqlproj"
@@ -37,9 +44,9 @@
{
"title": "%sqlDatabaseProjects.Settings%",
"properties": {
"sqlDatabaseProjects.netCoreSDKLocation": {
"sqlDatabaseProjects.dotnetSDK Location": {
"type": "string",
"description": "%sqlDatabaseProjects.netCoreInstallLocation%"
"description": "%sqlDatabaseProjects.dotnetInstallLocation%"
},
"sqlDatabaseProjects.netCoreDoNotAsk": {
"type": "boolean",
@@ -158,6 +165,11 @@
"title": "%sqlDatabaseProjects.editProjectFile%",
"category": "%sqlDatabaseProjects.displayName%"
},
{
"command": "sqlDatabaseProjects.addSqlBinding",
"title": "%sqlDatabaseProjects.addSqlBinding%",
"category": "MS SQL"
},
{
"command": "sqlDatabaseProjects.changeTargetPlatform",
"title": "%sqlDatabaseProjects.changeTargetPlatform%",
@@ -258,6 +270,10 @@
"command": "sqlDatabaseProjects.editProjectFile",
"when": "false"
},
{
"command": "sqlDatabaseProjects.addSqlBinding",
"when": "editorLangId == csharp && !azdataAvailable && resourceScheme != untitled"
},
{
"command": "sqlDatabaseProjects.exclude",
"when": "false"

View File

@@ -33,11 +33,11 @@
"sqlDatabaseProjects.generateProjectFromOpenApiSpec": "Generate SQL Project from OpenAPI/Swagger spec",
"sqlDatabaseProjects.Settings": "Database Projects",
"sqlDatabaseProjects.netCoreInstallLocation": "Full path to .NET Core SDK on the machine.",
"sqlDatabaseProjects.dotnetInstallLocation": "Full path to .NET SDK on the machine.",
"sqlDatabaseProjects.netCoreDoNotAsk": "Whether to prompt the user to install .NET Core when not detected.",
"sqlDatabaseProjects.nodejsDoNotAsk": "Whether to prompt the user to install Node.js when not detected.",
"sqlDatabaseProjects.autorestSqlVersion": "Which version of Autorest.Sql to use from NPM. Latest will be used if not set.",
"sqlDatabaseProjects.welcome": "No database projects currently open.\n[New Project](command:sqlDatabaseProjects.new)\n[Open Project](command:sqlDatabaseProjects.open)\n[Create Project From Database](command:sqlDatabaseProjects.importDatabase)",
"sqlDatabaseProjects.addSqlBinding":"Add SQL Binding"
"sqlDatabaseProjects.addSqlBinding":"Add SQL Binding (preview)"
}

Some files were not shown because too many files have changed in this diff Show More