diff --git a/package-lock.json b/package-lock.json index 710a4f7e0..21498f499 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "@azure/arm-cosmosdb": "^9.1.0", - "@azure/arm-postgresql": "^4.4.0", + "@azure/arm-postgresql": "^5.0.0", + "@azure/arm-postgresql-flexible": "^2.0.0", "@azure/cosmos": "^3.6.3", "antlr4ts": "^0.4.1-alpha.0", "bson": "^1.1.3", @@ -90,50 +91,24 @@ } }, "node_modules/@azure/arm-postgresql": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@azure/arm-postgresql/-/arm-postgresql-4.4.0.tgz", - "integrity": "sha512-gO5Y13bnp4OiKBDywhAz/tQXqb+KDY9EH7K8FnS2MzlgWeTzgu5RwtIS7L7J4O09gwA0lVLDEOwiVk0WDNmnEQ==", - "dependencies": { - "@azure/ms-rest-azure-js": "^1.3.2", - "@azure/ms-rest-js": "^1.8.1", - "tslib": "^1.9.3" - } - }, - "node_modules/@azure/arm-postgresql/node_modules/@azure/ms-rest-azure-js": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@azure/ms-rest-azure-js/-/ms-rest-azure-js-1.4.0.tgz", - "integrity": "sha512-ul1wfkzwU9wYg6kFKD/AuQfVRJU4utEjDcfa0hvXqDS99yRuJqUrt/Ojv3duZMwskBIrD3CV5d9TjLBOV7/pQw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@azure/arm-postgresql/-/arm-postgresql-5.0.0.tgz", + "integrity": "sha512-BUbhj4+xQfTSEKNQI6C8OCfp/V8QigmGdhATC8wqHgOnaCMFYi7bD9TdvR6nGPlBrkwa8l/AILCay7X4m7lOwQ==", "dependencies": { - "@azure/core-auth": "^1.1.4", - "@azure/ms-rest-js": "^1.10.0", - "tslib": "^1.9.3" + "@azure/ms-rest-azure-js": "^2.0.1", + "@azure/ms-rest-js": "^2.0.4", + "tslib": "^1.10.0" } }, - "node_modules/@azure/arm-postgresql/node_modules/@azure/ms-rest-js": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-1.11.2.tgz", - "integrity": "sha512-2AyQ1IKmLGKW7DU3/x3TsTBzZLcbC9YRI+yuDPuXAQrv3zar340K9wsxU413kHFIDjkWNCo9T0w5VtwcyWxhbQ==", + "node_modules/@azure/arm-postgresql-flexible": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@azure/arm-postgresql-flexible/-/arm-postgresql-flexible-2.0.0.tgz", + "integrity": "sha512-h0sLNg9luDZDkdSkzbVjHyVhiCW+gumA6mIZyaVOHeaS2l2tdiS+l4NnjgXYNkmzJjOv5TSG0TfpNdAfAojixA==", "dependencies": { "@azure/core-auth": "^1.1.4", - "axios": "^0.21.1", - "form-data": "^2.3.2", - "tough-cookie": "^2.4.3", - "tslib": "^1.9.2", - "tunnel": "0.0.6", - "uuid": "^3.2.1", - "xml2js": "^0.4.19" - } - }, - "node_modules/@azure/arm-postgresql/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" + "@azure/ms-rest-azure-js": "^2.1.0", + "@azure/ms-rest-js": "^2.2.0", + "tslib": "^1.10.0" } }, "node_modules/@azure/arm-resources": { @@ -441,6 +416,9 @@ }, "bin": { "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@sindresorhus/is": { @@ -2186,6 +2164,7 @@ "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", "dev": true, "dependencies": { "anymatch": "^2.0.0", @@ -2272,6 +2251,9 @@ }, "engines": { "node": ">=8.9.0" + }, + "peerDependencies": { + "webpack": "*" } }, "node_modules/cliui": { @@ -2545,6 +2527,13 @@ }, "engines": { "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" } }, "node_modules/copy-webpack-plugin/node_modules/cacache": { @@ -2587,6 +2576,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, "node_modules/copy-webpack-plugin/node_modules/glob-parent": { @@ -2625,6 +2617,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/copy-webpack-plugin/node_modules/mkdirp": { @@ -2649,6 +2644,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/copy-webpack-plugin/node_modules/rimraf": { @@ -2661,6 +2659,9 @@ }, "bin": { "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/copy-webpack-plugin/node_modules/semver": { @@ -3376,6 +3377,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es5-ext": { @@ -4641,6 +4645,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "deprecated": "Fixed a prototype pollution security issue in 4.1.0, please upgrade to ^4.1.1 or ^5.0.1.", "dev": true, "dependencies": { "is-buffer": "~2.0.3" @@ -4720,8 +4725,19 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz", "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "engines": { "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, "node_modules/for-in": { @@ -4938,6 +4954,9 @@ }, "engines": { "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { @@ -5202,6 +5221,7 @@ "version": "5.1.5", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", "dev": true, "dependencies": { "ajv": "^6.12.3", @@ -5703,6 +5723,9 @@ "dev": true, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-descriptor": { @@ -5955,6 +5978,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-typedarray": { @@ -6153,7 +6179,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dependencies": { + "optionalDependencies": { "graceful-fs": "^4.1.6" } }, @@ -6883,6 +6909,10 @@ }, "engines": { "node": ">= 8.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha-junit-reporter": { @@ -6896,6 +6926,9 @@ "mkdirp": "~0.5.1", "strip-ansi": "^4.0.0", "xml": "^1.0.0" + }, + "peerDependencies": { + "mocha": ">=2.2.5" } }, "node_modules/mocha-junit-reporter/node_modules/ansi-regex": { @@ -7050,6 +7083,7 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", "dev": true, "dependencies": { "ms": "^2.1.1" @@ -7631,6 +7665,9 @@ }, "engines": { "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.map": { @@ -7838,6 +7875,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { @@ -7862,6 +7902,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { @@ -8097,7 +8140,10 @@ "node_modules/pg-pool": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", - "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==" + "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==", + "peerDependencies": { + "pg": ">=8.0" + } }, "node_modules/pg-protocol": { "version": "1.2.5", @@ -8161,6 +8207,9 @@ "dev": true, "engines": { "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pify": { @@ -8368,6 +8417,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/pump": { @@ -8664,6 +8716,7 @@ "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "dev": true, "dependencies": { "aws-sign2": "~0.7.0", @@ -8830,6 +8883,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", "dev": true }, "node_modules/responselike": { @@ -8875,7 +8929,21 @@ "version": "1.1.10", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", - "dev": true + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/safe-buffer": { "version": "5.1.2", @@ -10004,6 +10072,9 @@ }, "engines": { "node": ">=6.11.5" + }, + "peerDependencies": { + "typescript": "*" } }, "node_modules/ts-loader/node_modules/semver": { @@ -10075,14 +10146,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -10379,6 +10442,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", "dev": true }, "node_modules/url-join": { @@ -10416,6 +10480,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "bin": { "uuid": "bin/uuid" } @@ -11168,6 +11233,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/word-wrap": { @@ -11473,6 +11541,9 @@ "dev": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } } }, @@ -11503,49 +11574,24 @@ } }, "@azure/arm-postgresql": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@azure/arm-postgresql/-/arm-postgresql-4.4.0.tgz", - "integrity": "sha512-gO5Y13bnp4OiKBDywhAz/tQXqb+KDY9EH7K8FnS2MzlgWeTzgu5RwtIS7L7J4O09gwA0lVLDEOwiVk0WDNmnEQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@azure/arm-postgresql/-/arm-postgresql-5.0.0.tgz", + "integrity": "sha512-BUbhj4+xQfTSEKNQI6C8OCfp/V8QigmGdhATC8wqHgOnaCMFYi7bD9TdvR6nGPlBrkwa8l/AILCay7X4m7lOwQ==", "requires": { - "@azure/ms-rest-azure-js": "^1.3.2", - "@azure/ms-rest-js": "^1.8.1", - "tslib": "^1.9.3" - }, - "dependencies": { - "@azure/ms-rest-azure-js": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@azure/ms-rest-azure-js/-/ms-rest-azure-js-1.4.0.tgz", - "integrity": "sha512-ul1wfkzwU9wYg6kFKD/AuQfVRJU4utEjDcfa0hvXqDS99yRuJqUrt/Ojv3duZMwskBIrD3CV5d9TjLBOV7/pQw==", - "requires": { - "@azure/core-auth": "^1.1.4", - "@azure/ms-rest-js": "^1.10.0", - "tslib": "^1.9.3" - } - }, - "@azure/ms-rest-js": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-1.11.2.tgz", - "integrity": "sha512-2AyQ1IKmLGKW7DU3/x3TsTBzZLcbC9YRI+yuDPuXAQrv3zar340K9wsxU413kHFIDjkWNCo9T0w5VtwcyWxhbQ==", - "requires": { - "@azure/core-auth": "^1.1.4", - "axios": "^0.21.1", - "form-data": "^2.3.2", - "tough-cookie": "^2.4.3", - "tslib": "^1.9.2", - "tunnel": "0.0.6", - "uuid": "^3.2.1", - "xml2js": "^0.4.19" - } - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - } + "@azure/ms-rest-azure-js": "^2.0.1", + "@azure/ms-rest-js": "^2.0.4", + "tslib": "^1.10.0" + } + }, + "@azure/arm-postgresql-flexible": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@azure/arm-postgresql-flexible/-/arm-postgresql-flexible-2.0.0.tgz", + "integrity": "sha512-h0sLNg9luDZDkdSkzbVjHyVhiCW+gumA6mIZyaVOHeaS2l2tdiS+l4NnjgXYNkmzJjOv5TSG0TfpNdAfAojixA==", + "requires": { + "@azure/core-auth": "^1.1.4", + "@azure/ms-rest-azure-js": "^2.1.0", + "@azure/ms-rest-js": "^2.2.0", + "tslib": "^1.10.0" } }, "@azure/arm-resources": { @@ -17929,7 +17975,8 @@ "pg-pool": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", - "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==" + "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==", + "requires": {} }, "pg-protocol": { "version": "1.2.5", @@ -19514,11 +19561,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", diff --git a/package.json b/package.json index c4812d66b..a1f12bb00 100644 --- a/package.json +++ b/package.json @@ -1100,7 +1100,8 @@ }, "dependencies": { "@azure/arm-cosmosdb": "^9.1.0", - "@azure/arm-postgresql": "^4.4.0", + "@azure/arm-postgresql": "^5.0.0", + "@azure/arm-postgresql-flexible": "^2.0.0", "@azure/cosmos": "^3.6.3", "antlr4ts": "^0.4.1-alpha.0", "bson": "^1.1.3", diff --git a/src/AzureDBExperiences.ts b/src/AzureDBExperiences.ts index 459b31a09..1612d6e4f 100644 --- a/src/AzureDBExperiences.ts +++ b/src/AzureDBExperiences.ts @@ -12,7 +12,8 @@ export enum API { Graph = 'Graph', Table = 'Table', Core = 'Core', - Postgres = 'Postgres' + PostgresSingle = 'PostgresSingle', + PostgresFlexible = 'PostgresFlexible' } export enum DBAccountKind { @@ -109,8 +110,9 @@ const CoreExperience: Experience = { api: API.Core, longName: "Core", descriptio export const MongoExperience: Experience = { api: API.MongoDB, longName: "Azure Cosmos DB for MongoDB API", shortName: "MongoDB", kind: DBAccountKind.MongoDB, tag: "Azure Cosmos DB for MongoDB API" }; const TableExperience: Experience = { api: API.Table, longName: "Azure Table", shortName: "Table", kind: DBAccountKind.GlobalDocumentDB, capability: 'EnableTable', tag: "Azure Table" }; const GremlinExperience: Experience = { api: API.Graph, longName: "Gremlin", description: "(graph)", shortName: "Gremlin", kind: DBAccountKind.GlobalDocumentDB, capability: 'EnableGremlin', tag: "Gremlin (graph)" }; -const PostgresExperience: Experience = { api: API.Postgres, longName: "PostgreSQL", shortName: "PostgreSQL" }; +const PostgresSingleExperience: Experience = { api: API.PostgresSingle, longName: "PostgreSQL Single Server", shortName: "PostgreSQLSingle"}; +const PostgresFlexibleExperience: Experience = { api: API.PostgresFlexible, longName: "PostgreSQL Flexible Server (Preview)", shortName: "PostgreSQLFlexible"}; const cosmosExperiencesArray: Experience[] = [CoreExperience, MongoExperience, TableExperience, GremlinExperience]; -const experiencesArray: Experience[] = [...cosmosExperiencesArray, PostgresExperience]; +const experiencesArray: Experience[] = [...cosmosExperiencesArray, PostgresSingleExperience, PostgresFlexibleExperience]; const experiencesMap = new Map(experiencesArray.map((info: Experience): [API, Experience] => [info.api, info])); diff --git a/src/commands/api/DatabaseAccountTreeItemInternal.ts b/src/commands/api/DatabaseAccountTreeItemInternal.ts index 156584397..e45bbb71a 100644 --- a/src/commands/api/DatabaseAccountTreeItemInternal.ts +++ b/src/commands/api/DatabaseAccountTreeItemInternal.ts @@ -94,7 +94,7 @@ export class DatabaseAccountTreeItemInternal implements DatabaseAccountTreeItem if (this._parsedCS instanceof ParsedMongoConnectionString) { apiType = API.MongoDB; } else if (this._parsedCS instanceof ParsedPostgresConnectionString) { - apiType = API.Postgres; + apiType = API.PostgresSingle; } else { apiType = API.Core; } diff --git a/src/postgres/abstract/AbstractPostgresClient.ts b/src/postgres/abstract/AbstractPostgresClient.ts new file mode 100644 index 000000000..e2d694ddd --- /dev/null +++ b/src/postgres/abstract/AbstractPostgresClient.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { PostgreSQLManagementClient } from "@azure/arm-postgresql"; +import { PostgreSQLManagementClient as PostgreSQLFlexibleManagementClient } from "@azure/arm-postgresql-flexible"; +import { createAzureClient, ISubscriptionContext } from "vscode-azureextensionui"; +import { PostgresServerType } from "./models"; + +export type AbstractPostgresClient = PostgreSQLFlexibleManagementClient | PostgreSQLManagementClient; + +export function createAbstractPostgresClient(serverType: PostgresServerType, clientInfo: ISubscriptionContext): AbstractPostgresClient { + switch (serverType) { + case PostgresServerType.Flexible: + return createAzureClient(clientInfo, PostgreSQLFlexibleManagementClient); + case PostgresServerType.Single: + return createAzureClient(clientInfo, PostgreSQLManagementClient); + default: + throw new Error("Service not implemented."); + } +} diff --git a/src/postgres/abstract/models.ts b/src/postgres/abstract/models.ts new file mode 100644 index 000000000..0535d1b40 --- /dev/null +++ b/src/postgres/abstract/models.ts @@ -0,0 +1,55 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { PostgreSQLManagementModels as SingleModels } from "@azure/arm-postgresql"; +import { PostgreSQLManagementModels as FlexibleModels } from "@azure/arm-postgresql-flexible"; + +export enum PostgresServerType { + Flexible, + Single +} + +export type PostgresAbstractServer = (SingleModels.Server | FlexibleModels.Server) & { serverType?: PostgresServerType; } + +export type PostgresAbstractDatabase = SingleModels.Database | FlexibleModels.Database; + +/** + * Billing information related properties of a server. + */ + export interface AbstractSku { + /** + * The name of the sku, typically, tier + family + cores, e.g. B_Gen4_1, GP_Gen5_8. + */ + name: string; + /** + * The tier of the particular SKU, e.g. Basic. Possible values include: 'Basic', + * 'GeneralPurpose', 'MemoryOptimized' + */ + tier?: SingleModels.SkuTier | FlexibleModels.SkuTier; + /** + * The scale up/out capacity, representing server's compute units. + */ + capacity?: number; + /** + * The size code, to be interpreted by resource as appropriate. + */ + size?: string; + /** + * The family of hardware. + */ + family?: string; +} + +export interface AbstractServerCreate { + location: string; + sku: AbstractSku; + administratorLogin: string; + administratorLoginPassword: string; + storageMB: number; +} + +export type AbstractNameAvailability = SingleModels.NameAvailability | FlexibleModels.NameAvailability; + +export type AbstractFirewallRule = SingleModels.FirewallRule | FlexibleModels.FirewallRule; diff --git a/src/postgres/commands/configurePostgresFirewall.ts b/src/postgres/commands/configurePostgresFirewall.ts index 28ba93383..e0e6ab383 100644 --- a/src/postgres/commands/configurePostgresFirewall.ts +++ b/src/postgres/commands/configurePostgresFirewall.ts @@ -3,14 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { PostgreSQLManagementClient } from '@azure/arm-postgresql'; -import { FirewallRule } from '@azure/arm-postgresql/src/models'; import * as publicIp from 'public-ip'; import * as vscode from 'vscode'; -import { createAzureClient, DialogResponses, IActionContext } from "vscode-azureextensionui"; +import { DialogResponses, IActionContext } from "vscode-azureextensionui"; import { ext } from "../../extensionVariables"; import { localize } from "../../utils/localize"; import { nonNullProp } from '../../utils/nonNull'; +import { createAbstractPostgresClient } from '../abstract/AbstractPostgresClient'; +import { AbstractFirewallRule, PostgresServerType } from '../abstract/models'; import { PostgresServerTreeItem } from "../tree/PostgresServerTreeItem"; export async function configurePostgresFirewall(context: IActionContext, treeItem?: PostgresServerTreeItem): Promise { @@ -30,12 +30,14 @@ export async function configurePostgresFirewall(context: IActionContext, treeIte export async function setFirewallRule(context: IActionContext, treeItem: PostgresServerTreeItem, ip: string): Promise { - const client: PostgreSQLManagementClient = createAzureClient(treeItem.root, PostgreSQLManagementClient); + const serverType: PostgresServerType = nonNullProp(treeItem, 'serverType'); + const client = createAbstractPostgresClient(serverType, treeItem.root); const resourceGroup: string = nonNullProp(treeItem, 'resourceGroup'); const serverName: string = nonNullProp(treeItem, 'azureName'); + const firewallRuleName: string = "azureDatabasesForVSCode-publicIp"; - const newFirewallRule: FirewallRule = { + const newFirewallRule: AbstractFirewallRule = { startIpAddress: ip, endIpAddress: ip }; diff --git a/src/postgres/commands/createPostgresServer/IPostgresServerWizardContext.ts b/src/postgres/commands/createPostgresServer/IPostgresServerWizardContext.ts index 96278d3b9..b4ef31e7d 100644 --- a/src/postgres/commands/createPostgresServer/IPostgresServerWizardContext.ts +++ b/src/postgres/commands/createPostgresServer/IPostgresServerWizardContext.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Server, Sku } from "@azure/arm-postgresql/src/models"; import { IAzureDBWizardContext } from "../../../tree/IAzureDBWizardContext"; +import { AbstractSku, PostgresAbstractServer, PostgresServerType } from "../../abstract/models"; export interface IPostgresServerWizardContext extends IAzureDBWizardContext { /** @@ -17,6 +17,7 @@ export interface IPostgresServerWizardContext extends IAzureDBWizardContext { longUserName?: string; adminPassword?: string; - server?: Server; - sku?: Sku; + server?: PostgresAbstractServer; + sku?: AbstractSku; + serverType?: PostgresServerType; } diff --git a/src/postgres/commands/createPostgresServer/steps/PostgresServerCreateStep.ts b/src/postgres/commands/createPostgresServer/steps/PostgresServerCreateStep.ts index 0cf70077d..eb512dd1f 100644 --- a/src/postgres/commands/createPostgresServer/steps/PostgresServerCreateStep.ts +++ b/src/postgres/commands/createPostgresServer/steps/PostgresServerCreateStep.ts @@ -2,13 +2,14 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { PostgreSQLManagementClient } from '@azure/arm-postgresql'; -import { ServerForCreate } from '@azure/arm-postgresql/src/models'; +import { PostgreSQLManagementClient, PostgreSQLManagementModels as SingleModels } from "@azure/arm-postgresql"; +import { PostgreSQLManagementClient as PostgreSQLFlexibleManagementClient, PostgreSQLManagementModels as FlexibleModels } from "@azure/arm-postgresql-flexible"; import { Progress } from 'vscode'; import { AzureWizardExecuteStep, callWithMaskHandling, createAzureClient, LocationListStep } from 'vscode-azureextensionui'; import { ext } from '../../../../extensionVariables'; import { localize } from '../../../../utils/localize'; import { nonNullProp } from '../../../../utils/nonNull'; +import { AbstractServerCreate, PostgresServerType } from '../../../abstract/models'; import { IPostgresServerWizardContext } from '../IPostgresServerWizardContext'; export class PostgresServerCreateStep extends AzureWizardExecuteStep { @@ -24,26 +25,30 @@ export class PostgresServerCreateStep extends AzureWizardExecuteStep { - const client: PostgreSQLManagementClient = createAzureClient(context, PostgreSQLManagementClient); + const serverType = nonNullProp(context, 'serverType'); const createMessage: string = localize('creatingPostgresServer', 'Creating PostgreSQL Server "{0}"... It should be ready in several minutes.', context.newServerName); + ext.outputChannel.appendLog(createMessage); progress.report({ message: createMessage }); - const options: ServerForCreate = { + const options: AbstractServerCreate = { location: locationName, sku: nonNullProp(context, 'sku'), - properties: { - administratorLogin: nonNullProp(context, 'shortUserName'), - administratorLoginPassword: password, - sslEnforcement: "Enabled", - createMode: "Default", - version: "10", - storageProfile: { - storageMB: parseInt(storageMB) - } - }, + administratorLogin: nonNullProp(context, 'shortUserName'), + administratorLoginPassword: password, + storageMB: parseInt(storageMB) }; - context.server = await client.servers.create(rgName, newServerName, options); + switch (serverType){ + case PostgresServerType.Single: + const singleClient = createAzureClient(context, PostgreSQLManagementClient); + context.server = await singleClient.servers.create(rgName, newServerName, this.asSingleParameters(options)); + break; + case PostgresServerType.Flexible: + const flexiClient = createAzureClient(context, PostgreSQLFlexibleManagementClient); + context.server = await flexiClient.servers.create(rgName, newServerName, this.asFlexibleParameters(options)); + break; + } + context.server.serverType = serverType; }, password); } @@ -51,4 +56,45 @@ export class PostgresServerCreateStep extends AzureWizardExecuteStep { public async prompt(context: IPostgresServerWizardContext): Promise { - const client: PostgreSQLManagementClient = createAzureClient(context, PostgreSQLManagementClient); + const client = createAbstractPostgresClient(nonNullProp(context, "serverType"), context); context.newServerName = (await context.ui.showInputBox({ placeHolder: localize('serverNamePlaceholder', 'Server name'), prompt: localize('enterServerNamePrompt', 'Provide a name for the PostgreSQL Server.'), - validateInput: (name: string) => validatePostgresServerName(name, client) + validateInput: (name: string) => validatePostgresServerName(name, client, nonNullProp(context, "serverType")) })).trim(); context.valuesToMask.push(context.newServerName); context.relatedNameTask = this.generateRelatedName(context, context.newServerName, resourceGroupNamingRules); @@ -31,7 +32,7 @@ export class PostgresServerNameStep extends AzureNameStep { +async function validatePostgresServerName(name: string, client: AbstractPostgresClient, serverType: PostgresServerType): Promise { name = name ? name.trim() : ''; const min = 3; @@ -44,14 +45,13 @@ async function validatePostgresServerName(name: string, client: PostgreSQLManage } else if (name.startsWith('-') || name.endsWith('-')) { return localize('serverNamePrefixSuffixCheck', 'Server name must not start or end in a hyphen.'); } - - const availabilityRequest: NameAvailabilityRequest = { name: name, type: "Microsoft.DBforPostgreSQL" }; - const availability: NameAvailability = (await client.checkNameAvailability.execute(availabilityRequest)); + const resourceType = serverType === PostgresServerType.Single ? "Microsoft.DBforPostgreSQL" : "Microsoft.DBforPostgreSQL/flexibleServers"; + const availability: AbstractNameAvailability = await client.checkNameAvailability.execute({name: name, type: resourceType}); if (!availability.nameAvailable) { - if (availability.reason === 'AlreadyExists') { - return localize('serverNameAvailabilityCheck', 'A server named "{0}" already exists.', name); - } + return availability.message ? + availability.message : + localize('serverNameAvailabilityCheck', 'Server name "{0}" is not available.', name); } return undefined; diff --git a/src/postgres/commands/createPostgresServer/steps/PostgresServerSetCredentialsStep.ts b/src/postgres/commands/createPostgresServer/steps/PostgresServerSetCredentialsStep.ts index 1475d716e..fa08facde 100644 --- a/src/postgres/commands/createPostgresServer/steps/PostgresServerSetCredentialsStep.ts +++ b/src/postgres/commands/createPostgresServer/steps/PostgresServerSetCredentialsStep.ts @@ -3,13 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Server } from '@azure/arm-postgresql/src/models'; import * as vscode from 'vscode'; import { Progress } from 'vscode'; import { AzureWizardExecuteStep } from 'vscode-azureextensionui'; import { ext } from '../../../../extensionVariables'; import { localize } from '../../../../utils/localize'; import { nonNullProp } from '../../../../utils/nonNull'; +import { PostgresAbstractServer } from '../../../abstract/models'; import { setPostgresCredentials } from '../../setPostgresCredentials'; import { IPostgresServerWizardContext } from '../IPostgresServerWizardContext'; @@ -25,7 +25,7 @@ export class PostgresServerSetCredentialsStep extends AzureWizardExecuteStep { - public async prompt(context: IPostgresServerWizardContext): Promise { - const placeHolder: string = localize("selectPostgresSku", "Select the Postgres SKU and options."); - const pricingTiers: IAzureQuickPickItem[] = await this.getPicks(); + public async prompt( + context: IPostgresServerWizardContext + ): Promise { + const placeHolder: string = localize( + "selectPostgresSku", + "Select the Postgres SKU and options." + ); + const pricingTiers: IAzureQuickPickItem[] = await this.getPicks(nonNullProp(context, 'serverType')); pricingTiers.push({ label: localize('ShowPricingCalculator', '$(link-external) Show pricing information...'), onPicked: async () => { @@ -34,9 +39,11 @@ export class PostgresServerSkuStep extends AzureWizardPromptStep[]> { - const options: IAzureQuickPickItem[] = []; - availableSkus.forEach((option) => { + public async getPicks(serverType: PostgresServerType): Promise[]> { + const options: IAzureQuickPickItem[] = []; + const skuOptions: ISkuOption[] = serverType === PostgresServerType.Single ? singleServerSkus : flexibleServerSkus ; + + skuOptions.forEach((option) => { options.push({ label: option.label, description: localize( @@ -52,7 +59,7 @@ export class PostgresServerSkuStep extends AzureWizardPromptStep { let dbNames: (string | undefined)[]; if (this.azureName) { - const client: PostgreSQLManagementClient = createAzureClient(this.root, PostgreSQLManagementClient); - const listOfDatabases: DatabaseListResult = await client.databases.listByServer(nonNullProp(this, 'resourceGroup'), nonNullProp(this, 'azureName')); + const client = createAbstractPostgresClient(this.serverType, this.root); + const listOfDatabases = await client.databases.listByServer(nonNullProp(this, 'resourceGroup'), nonNullProp(this, 'azureName')); dbNames = listOfDatabases.map(db => db?.name); } else if (this.partialConnectionString.databaseName) { dbNames = [this.partialConnectionString.databaseName]; @@ -136,7 +146,7 @@ export class PostgresServerTreeItem extends AzureParentTreeItem { - const client: PostgreSQLManagementClient = createAzureClient(this.root, PostgreSQLManagementClient); + const client = createAbstractPostgresClient(this.serverType, this.root); const deletingMessage: string = `Deleting server "${this.label}"...`; await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: deletingMessage }, async () => { await client.servers.deleteMethod(nonNullProp(this, 'resourceGroup'), nonNullProp(this, 'azureName')); diff --git a/src/tree/AttachedAccountsTreeItem.ts b/src/tree/AttachedAccountsTreeItem.ts index 862c645b7..11b0690bf 100644 --- a/src/tree/AttachedAccountsTreeItem.ts +++ b/src/tree/AttachedAccountsTreeItem.ts @@ -155,7 +155,7 @@ export class AttachedAccountsTreeItem extends AzureParentTreeItem { defaultValue = placeholder = localMongoConnectionString; } validateInput = AttachedAccountsTreeItem.validateMongoConnectionString; - } else if (defaultExperience.api === API.Postgres) { + } else if (defaultExperience.api === API.PostgresSingle || defaultExperience.api === API.PostgresFlexible) { placeholder = localize('attachedPostgresPlaceholder', '"postgres://username:password@host" or "postgres://username:password@host/database"'); validateInput = AttachedAccountsTreeItem.validatePostgresConnectionString; } else { @@ -174,7 +174,7 @@ export class AttachedAccountsTreeItem extends AzureParentTreeItem { await this.attachAccount(context, treeItem, connectionString); } - public async attachConnectionString(context: IActionContext, connectionString: string, api: API.MongoDB | API.Core | API.Postgres): Promise { + public async attachConnectionString(context: IActionContext, connectionString: string, api: API.MongoDB | API.Core | API.PostgresSingle): Promise { const treeItem = await this.createTreeItem(connectionString, api); await this.attachAccount(context, treeItem, connectionString); await this.refresh(context); @@ -326,7 +326,7 @@ export class AttachedAccountsTreeItem extends AzureParentTreeItem { label = label || `${id} (${getExperienceFromApi(api).shortName})`; treeItem = new MongoAccountTreeItem(this, id, label, connectionString, isEmulator); - } else if (api === API.Postgres) { + } else if (api === API.PostgresSingle || api === API.PostgresFlexible) { const parsedPostgresConnString = parsePostgresConnectionString(connectionString); treeItem = new PostgresServerTreeItem(this, parsedPostgresConnString); } else { @@ -368,7 +368,7 @@ export class AttachedAccountsTreeItem extends AzureParentTreeItem { } else if (node instanceof DocDBAccountTreeItem) { api = API.Core; } else if (node instanceof PostgresServerTreeItem) { - api = API.Postgres; + api = API.PostgresSingle; } else { throw new Error(`Unexpected account node "${node.constructor.name}".`); } diff --git a/src/tree/AzureDBAPIStep.ts b/src/tree/AzureDBAPIStep.ts index 3c3b6eee8..14e559430 100644 --- a/src/tree/AzureDBAPIStep.ts +++ b/src/tree/AzureDBAPIStep.ts @@ -5,6 +5,7 @@ import { AzureWizardExecuteStep, AzureWizardPromptStep, IAzureQuickPickItem, IWizardOptions, VerifyProvidersStep } from 'vscode-azureextensionui'; import { API, Experience, getExperienceQuickPicks } from '../AzureDBExperiences'; +import { PostgresServerType } from '../postgres/abstract/models'; import { IPostgresServerWizardContext } from '../postgres/commands/createPostgresServer/IPostgresServerWizardContext'; import { PostgresServerConfirmPWStep } from '../postgres/commands/createPostgresServer/steps/PostgresServerConfirmPWStep'; import { PostgresServerCreateStep } from '../postgres/commands/createPostgresServer/steps/PostgresServerCreateStep'; @@ -34,7 +35,15 @@ export class AzureDBAPIStep extends AzureWizardPromptStep> { let promptSteps: AzureWizardPromptStep[]; let executeSteps: AzureWizardExecuteStep[]; - if (context.defaultExperience?.api === API.Postgres) { + if (context.defaultExperience?.api === API.PostgresSingle || context.defaultExperience?.api === API.PostgresFlexible) { + switch (context.defaultExperience?.api){ + case API.PostgresFlexible: + (context as IPostgresServerWizardContext).serverType = PostgresServerType.Flexible; + break; + case API.PostgresSingle: + (context as IPostgresServerWizardContext).serverType = PostgresServerType.Single; + break; + } promptSteps = [ new PostgresServerNameStep(), new PostgresServerSkuStep(), diff --git a/src/tree/SubscriptionTreeItem.ts b/src/tree/SubscriptionTreeItem.ts index adde20941..a45162e49 100644 --- a/src/tree/SubscriptionTreeItem.ts +++ b/src/tree/SubscriptionTreeItem.ts @@ -6,7 +6,7 @@ import { CosmosDBManagementClient } from '@azure/arm-cosmosdb'; import { DatabaseAccountGetResults, DatabaseAccountListKeysResult, DatabaseAccountsListResponse, DatabaseAccountsListResult } from '@azure/arm-cosmosdb/src/models'; import { PostgreSQLManagementClient } from '@azure/arm-postgresql'; -import { Server, ServerListResult } from '@azure/arm-postgresql/src/models'; +import { PostgreSQLManagementClient as PostgreSQLFlexibleManagementClient } from '@azure/arm-postgresql-flexible'; import * as vscode from 'vscode'; import { AzExtTreeItem, AzureTreeItem, AzureWizard, AzureWizardPromptStep, createAzureClient, ICreateChildImplContext, ILocationWizardContext, LocationListStep, ResourceGroupListStep, SubscriptionTreeItemBase } from 'vscode-azureextensionui'; import { API, Experience, getExperienceLabel, tryGetExperience } from '../AzureDBExperiences'; @@ -15,6 +15,7 @@ import { ext } from '../extensionVariables'; import { tryGetGremlinEndpointFromAzure } from '../graph/gremlinEndpoints'; import { GraphAccountTreeItem } from "../graph/tree/GraphAccountTreeItem"; import { MongoAccountTreeItem } from '../mongo/tree/MongoAccountTreeItem'; +import { PostgresAbstractServer, PostgresServerType } from '../postgres/abstract/models'; import { IPostgresServerWizardContext } from '../postgres/commands/createPostgresServer/IPostgresServerWizardContext'; import { createPostgresConnectionString, ParsedPostgresConnectionString, parsePostgresConnectionString } from '../postgres/postgresConnectionStrings'; import { PostgresServerTreeItem } from '../postgres/tree/PostgresServerTreeItem'; @@ -35,13 +36,18 @@ export class SubscriptionTreeItem extends SubscriptionTreeItemBase { public async loadMoreChildrenImpl(_clearCache: boolean): Promise { //Postgres - const postgresClient: PostgreSQLManagementClient = createAzureClient(this.root, PostgreSQLManagementClient); - const postgresServers: ServerListResult = await postgresClient.servers.list(); + const postgresSingleClient = createAzureClient(this.root, PostgreSQLManagementClient); + const postgresFlexibleClient = createAzureClient(this.root, PostgreSQLFlexibleManagementClient); + const postgresServers: PostgresAbstractServer[] = [ + ...(await postgresSingleClient.servers.list()).map(s => Object.assign(s, { serverType: PostgresServerType.Single })), + ...(await postgresFlexibleClient.servers.list()).map(s => Object.assign(s, { serverType: PostgresServerType.Flexible })), + ]; + const treeItemPostgres: AzExtTreeItem[] = await this.createTreeItemsWithErrorHandling( postgresServers, 'invalidPostgreSQLAccount', - async (server: Server) => await this.initPostgresChild(server), - (server: Server) => server.name + async (server: PostgresAbstractServer) => await this.initPostgresChild(server), + (server: PostgresAbstractServer) => server.name ); //CosmosDB @@ -82,7 +88,7 @@ export class SubscriptionTreeItem extends SubscriptionTreeItemBase { const newServerName: string = nonNullProp(wizardContext, 'newServerName'); context.showCreatingTreeItem(newServerName); await wizard.execute(); - if (wizardContext.defaultExperience?.api === API.Postgres) { + if (wizardContext.defaultExperience?.api === API.PostgresSingle || wizardContext.defaultExperience?.api === API.PostgresFlexible) { const createMessage: string = localize('createdServerOutput', 'Successfully created PostgreSQL server "{0}".', wizardContext.newServerName); void vscode.window.showInformationMessage(createMessage); ext.outputChannel.appendLog(createMessage); @@ -143,7 +149,7 @@ export class SubscriptionTreeItem extends SubscriptionTreeItemBase { } } } - private async initPostgresChild(server: Server): Promise { + private async initPostgresChild(server: PostgresAbstractServer): Promise { const connectionString: string = createPostgresConnectionString(nonNullProp(server, 'fullyQualifiedDomainName')); const parsedCS: ParsedPostgresConnectionString = parsePostgresConnectionString(connectionString); return new PostgresServerTreeItem(this, parsedCS, server);