diff --git a/appservice/package-lock.json b/appservice/package-lock.json index f5b1075cd3..52ea96dad7 100644 --- a/appservice/package-lock.json +++ b/appservice/package-lock.json @@ -1,12 +1,12 @@ { "name": "@microsoft/vscode-azext-azureappservice", - "version": "3.3.1", + "version": "3.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@microsoft/vscode-azext-azureappservice", - "version": "3.3.1", + "version": "3.4.0", "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.4", @@ -20,7 +20,7 @@ "@azure/storage-blob": "^12.3.0", "@microsoft/vscode-azext-azureutils": "^3.0.0", "@microsoft/vscode-azext-github": "^1.0.0", - "@microsoft/vscode-azext-utils": "^2.5.0", + "@microsoft/vscode-azext-utils": "^2.5.13", "dayjs": "^1.11.2", "fs-extra": "^10.0.0", "p-retry": "^3.0.1", @@ -585,71 +585,71 @@ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" }, "node_modules/@microsoft/1ds-core-js": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@microsoft/1ds-core-js/-/1ds-core-js-4.0.5.tgz", - "integrity": "sha512-uTOSUoXt/KgnLlGWED+vLLnYCFq1kDFbej+pGAbR+6tMGajCgw3Xz3Xcal0nYhk9RM2hvWWAt5gs6Bu2Si/46g==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/1ds-core-js/-/1ds-core-js-4.3.5.tgz", + "integrity": "sha512-WozEs1DB8FtqFtPcTilKhMZvhyEEw0bzehl+5S8lvncIIXcAbJx9ga6zpx6XqJ1CxmHAQen4MLgMYCLDBIzcNQ==", "dependencies": { - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "node_modules/@microsoft/1ds-post-js": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@microsoft/1ds-post-js/-/1ds-post-js-4.0.5.tgz", - "integrity": "sha512-jziJe/nXxgDhnW0sWkXbj9ZfwHXRH6UCn6eGgyWlog3iWP8FgXzna8Rugvct2r43XEqGs6c/NKxuFXAVtyGXjg==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/1ds-post-js/-/1ds-post-js-4.3.5.tgz", + "integrity": "sha512-AavxRU6qrzZuqDn2W5tiQ0bIqAWQrkyLV7VUn4ZzeB/0ekKCgfBouT69GpmfL1fu2wztlFcQaMpj/V8PXIxW+A==", "dependencies": { - "@microsoft/1ds-core-js": "4.0.5", + "@microsoft/1ds-core-js": "4.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "node_modules/@microsoft/applicationinsights-channel-js": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.7.tgz", - "integrity": "sha512-3y8ct8V2bGo7QaYVrfQcWZeOci2tUZhXkme3k7nKa2P7upSX/1d+dPF12EelxrtWVLxtfCQJkk+2W4M1AyejGQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.3.5.tgz", + "integrity": "sha512-q9iE5alabgddwnxIDxgYLwC/3OMjYNOPk87p3jY+KxO0UmJGhiv7C1uI62zpx4AHBGT2+q6pMbIZdgld9TmMrw==", "dependencies": { - "@microsoft/applicationinsights-common": "3.0.7", - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-common": "3.3.5", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" }, "peerDependencies": { - "tslib": "*" + "tslib": ">= 1.0.0" } }, "node_modules/@microsoft/applicationinsights-common": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.7.tgz", - "integrity": "sha512-boumvLA7LZu0NmwT9ThpTAI64BNYUlOkFNcjUbYeKNEaE6CBPGX/z25XXlYu+j4hHldDaCn9zC1LuN7AuoMJSA==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.3.5.tgz", + "integrity": "sha512-zZgMOY3ePBhjTrZ8+MXwAb0Y+Yi4iVDKOqIaz/KoCmj1BxX5JKFgaqYiN8Tvu5O0YPJpEKS4coYXRHbStDm/Hw==", "dependencies": { - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" }, "peerDependencies": { - "tslib": "*" + "tslib": ">= 1.0.0" } }, "node_modules/@microsoft/applicationinsights-core-js": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.7.tgz", - "integrity": "sha512-sVnnVW4fWXzZdtUTVjuwH3xGa1cj+tW7r72voMZzyuNOZ41fBOCK9AqoV0nKP5VCgNjySwn6Rpbw82I4TKKosQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.3.5.tgz", + "integrity": "sha512-8Gg18W5eOE3usXtkZ5iOqWAMU97hyjb7Oi1CtkWmxEoMUHMlQmqUD62n9BmVq/s5YfbUihGZHxc0keMJy0txAA==", "dependencies": { "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" }, "peerDependencies": { - "tslib": "*" + "tslib": ">= 1.0.0" } }, "node_modules/@microsoft/applicationinsights-shims": { @@ -661,20 +661,20 @@ } }, "node_modules/@microsoft/applicationinsights-web-basic": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.7.tgz", - "integrity": "sha512-D1Zuv/UMwm37bosZi7aZgjLt4xXTAe98ttAoSel/JThglZ2grYBixBHUjgAGzyno8u9JZElPviRHIAWWYAk3TQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.3.5.tgz", + "integrity": "sha512-nYLyxjO3p74SHxq/JctDndD6P/3YBLY1F/F+h2AdJsaMavSGudU7ylMb2IMQc1X+yqFZ4H4cUvkxljj/SiBi2g==", "dependencies": { - "@microsoft/applicationinsights-channel-js": "3.0.7", - "@microsoft/applicationinsights-common": "3.0.7", - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-channel-js": "3.3.5", + "@microsoft/applicationinsights-common": "3.3.5", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" }, "peerDependencies": { - "tslib": "*" + "tslib": ">= 1.0.0" } }, "node_modules/@microsoft/dynamicproto-js": { @@ -1062,18 +1062,18 @@ } }, "node_modules/@microsoft/vscode-azext-utils": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.5.1.tgz", - "integrity": "sha512-K9S25xSZ5jEy5ofsLGdgzdXkyqzYhdJuBNkSRMa/7Qt6S+YtspQ4qwX6gNGvlMHE3gPAXDHqxvn+yPmm4s5uYg==", + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.5.13.tgz", + "integrity": "sha512-0x9uW0VPCon/K3XwmedMuRc6F6S0b92FAlvaJHtzEi4EW1mek/1/nK8gLR2AP7rEaLOtq7sewoKdr9ejfs165g==", "dependencies": { - "@microsoft/vscode-azureresources-api": "^2.0.4", - "@vscode/extension-telemetry": "^0.9.0", + "@microsoft/vscode-azureresources-api": "^2.3.1", + "@vscode/extension-telemetry": "^0.9.6", "dayjs": "^1.11.2", "escape-string-regexp": "^2.0.0", "html-to-text": "^8.2.0", "semver": "^7.3.7", "uuid": "^9.0.0", - "vscode-tas-client": "^0.1.47", + "vscode-tas-client": "^0.1.84", "vscode-uri": "^3.0.6" }, "peerDependencies": { @@ -1089,22 +1089,25 @@ } }, "node_modules/@microsoft/vscode-azureresources-api": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azureresources-api/-/vscode-azureresources-api-2.0.4.tgz", - "integrity": "sha512-LridV1h2rCydrBzEpwy+pUIUx61GpZNwrK04G7LdlhoxHrzuM/WAoy8jXaSC/FSKSsXD1QXuE6u/YofEfsuKeg==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azureresources-api/-/vscode-azureresources-api-2.3.2.tgz", + "integrity": "sha512-hwG8Q1ywk7faPIyKLRT5Lfk9usl5i0mIxqyVEWxs4gBi5Jfq4d90WEJbHJLX72v6HS+4KQCKJ0h0XhNS7y4OZg==", + "peerDependencies": { + "@azure/ms-rest-azure-env": "^2.0.0" + } }, "node_modules/@nevware21/ts-async": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.4.0.tgz", - "integrity": "sha512-dbV826TTehQIBIJjh8GDSbwn1Z6+cnkyNbRlpcpdBPH8mROD2zabIUKqWcw9WRdTjjUIm21K+OR4DXWlAyOVTQ==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.5.4.tgz", + "integrity": "sha512-IBTyj29GwGlxfzXw2NPnzty+w0Adx61Eze1/lknH/XIVdxtF9UnOpk76tnrHXWa6j84a1RR9hsOcHQPFv9qJjA==", "dependencies": { - "@nevware21/ts-utils": ">= 0.10.0 < 2.x" + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "node_modules/@nevware21/ts-utils": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.10.4.tgz", - "integrity": "sha512-+QSEh9TZ7SFwZEEyIvP8NabL5I5WFE/gvk4LXtW4LjWyTEc/6t2Hog6r1MmY3hIQG9tLe6fARIAXjAQ/M8Kb6A==" + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.11.6.tgz", + "integrity": "sha512-OUUJTh3fnaUSzg9DEHgv3d7jC+DnPL65mIO7RaR+jWve7+MmcgIvF79gY97DPQ4frH+IpNR78YAYd/dW4gK3kg==" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -1738,13 +1741,13 @@ "dev": true }, "node_modules/@vscode/extension-telemetry": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.9.2.tgz", - "integrity": "sha512-O6VMCDkzypjULhgy2l6fih3c3fExPmSj7aewtW5jBJYgXcIIjtkJOttIfnKOCP4S8sNfc6xc1Do4MbUDmhduEw==", + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.9.8.tgz", + "integrity": "sha512-7YcKoUvmHlIB8QYCE4FNzt3ErHi9gQPhdCM3ZWtpw1bxPT0I+lMdx52KHlzTNoJzQ2NvMX7HyzyDwBEiMgTrWQ==", "dependencies": { - "@microsoft/1ds-core-js": "^4.0.3", - "@microsoft/1ds-post-js": "^4.0.3", - "@microsoft/applicationinsights-web-basic": "^3.0.6" + "@microsoft/1ds-core-js": "^4.3.4", + "@microsoft/1ds-post-js": "^4.3.4", + "@microsoft/applicationinsights-web-basic": "^3.3.4" }, "engines": { "vscode": "^1.75.0" @@ -2150,16 +2153,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3537,25 +3530,6 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -5570,11 +5544,6 @@ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", "dev": true }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -6206,12 +6175,9 @@ } }, "node_modules/tas-client": { - "version": "0.1.73", - "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.1.73.tgz", - "integrity": "sha512-UDdUF9kV2hYdlv+7AgqP2kXarVSUhjK7tg1BUflIRGEgND0/QoNpN64rcEuhEcM8AIbW65yrCopJWqRhLZ3m8w==", - "dependencies": { - "axios": "^1.6.1" - } + "version": "0.2.33", + "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.2.33.tgz", + "integrity": "sha512-V+uqV66BOQnWxvI6HjDnE4VkInmYZUQ4dgB7gzaDyFyFSK1i1nF/j7DpS9UbQAgV9NaF1XpcyuavnM1qOeiEIg==" }, "node_modules/terser": { "version": "5.16.6", @@ -6556,14 +6522,14 @@ } }, "node_modules/vscode-tas-client": { - "version": "0.1.75", - "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.75.tgz", - "integrity": "sha512-/+ALFWPI4U3obeRvLFSt39guT7P9bZQrkmcLoiS+2HtzJ/7iPKNt5Sj+XTiitGlPYVFGFc0plxX8AAp6Uxs0xQ==", + "version": "0.1.84", + "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.84.tgz", + "integrity": "sha512-rUTrUopV+70hvx1hW5ebdw1nd6djxubkLvVxjGdyD/r5v/wcVF41LIfiAtbm5qLZDtQdsMH1IaCuDoluoIa88w==", "dependencies": { - "tas-client": "0.1.73" + "tas-client": "0.2.33" }, "engines": { - "vscode": "^1.19.1" + "vscode": "^1.85.0" } }, "node_modules/vscode-uri": { @@ -7335,62 +7301,62 @@ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" }, "@microsoft/1ds-core-js": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@microsoft/1ds-core-js/-/1ds-core-js-4.0.5.tgz", - "integrity": "sha512-uTOSUoXt/KgnLlGWED+vLLnYCFq1kDFbej+pGAbR+6tMGajCgw3Xz3Xcal0nYhk9RM2hvWWAt5gs6Bu2Si/46g==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/1ds-core-js/-/1ds-core-js-4.3.5.tgz", + "integrity": "sha512-WozEs1DB8FtqFtPcTilKhMZvhyEEw0bzehl+5S8lvncIIXcAbJx9ga6zpx6XqJ1CxmHAQen4MLgMYCLDBIzcNQ==", "requires": { - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/1ds-post-js": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@microsoft/1ds-post-js/-/1ds-post-js-4.0.5.tgz", - "integrity": "sha512-jziJe/nXxgDhnW0sWkXbj9ZfwHXRH6UCn6eGgyWlog3iWP8FgXzna8Rugvct2r43XEqGs6c/NKxuFXAVtyGXjg==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/1ds-post-js/-/1ds-post-js-4.3.5.tgz", + "integrity": "sha512-AavxRU6qrzZuqDn2W5tiQ0bIqAWQrkyLV7VUn4ZzeB/0ekKCgfBouT69GpmfL1fu2wztlFcQaMpj/V8PXIxW+A==", "requires": { - "@microsoft/1ds-core-js": "4.0.5", + "@microsoft/1ds-core-js": "4.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/applicationinsights-channel-js": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.7.tgz", - "integrity": "sha512-3y8ct8V2bGo7QaYVrfQcWZeOci2tUZhXkme3k7nKa2P7upSX/1d+dPF12EelxrtWVLxtfCQJkk+2W4M1AyejGQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.3.5.tgz", + "integrity": "sha512-q9iE5alabgddwnxIDxgYLwC/3OMjYNOPk87p3jY+KxO0UmJGhiv7C1uI62zpx4AHBGT2+q6pMbIZdgld9TmMrw==", "requires": { - "@microsoft/applicationinsights-common": "3.0.7", - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-common": "3.3.5", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/applicationinsights-common": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.7.tgz", - "integrity": "sha512-boumvLA7LZu0NmwT9ThpTAI64BNYUlOkFNcjUbYeKNEaE6CBPGX/z25XXlYu+j4hHldDaCn9zC1LuN7AuoMJSA==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.3.5.tgz", + "integrity": "sha512-zZgMOY3ePBhjTrZ8+MXwAb0Y+Yi4iVDKOqIaz/KoCmj1BxX5JKFgaqYiN8Tvu5O0YPJpEKS4coYXRHbStDm/Hw==", "requires": { - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/applicationinsights-core-js": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.7.tgz", - "integrity": "sha512-sVnnVW4fWXzZdtUTVjuwH3xGa1cj+tW7r72voMZzyuNOZ41fBOCK9AqoV0nKP5VCgNjySwn6Rpbw82I4TKKosQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.3.5.tgz", + "integrity": "sha512-8Gg18W5eOE3usXtkZ5iOqWAMU97hyjb7Oi1CtkWmxEoMUHMlQmqUD62n9BmVq/s5YfbUihGZHxc0keMJy0txAA==", "requires": { "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/applicationinsights-shims": { @@ -7402,17 +7368,17 @@ } }, "@microsoft/applicationinsights-web-basic": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.7.tgz", - "integrity": "sha512-D1Zuv/UMwm37bosZi7aZgjLt4xXTAe98ttAoSel/JThglZ2grYBixBHUjgAGzyno8u9JZElPviRHIAWWYAk3TQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.3.5.tgz", + "integrity": "sha512-nYLyxjO3p74SHxq/JctDndD6P/3YBLY1F/F+h2AdJsaMavSGudU7ylMb2IMQc1X+yqFZ4H4cUvkxljj/SiBi2g==", "requires": { - "@microsoft/applicationinsights-channel-js": "3.0.7", - "@microsoft/applicationinsights-common": "3.0.7", - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-channel-js": "3.3.5", + "@microsoft/applicationinsights-common": "3.3.5", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/dynamicproto-js": { @@ -7712,18 +7678,18 @@ } }, "@microsoft/vscode-azext-utils": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.5.1.tgz", - "integrity": "sha512-K9S25xSZ5jEy5ofsLGdgzdXkyqzYhdJuBNkSRMa/7Qt6S+YtspQ4qwX6gNGvlMHE3gPAXDHqxvn+yPmm4s5uYg==", + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.5.13.tgz", + "integrity": "sha512-0x9uW0VPCon/K3XwmedMuRc6F6S0b92FAlvaJHtzEi4EW1mek/1/nK8gLR2AP7rEaLOtq7sewoKdr9ejfs165g==", "requires": { - "@microsoft/vscode-azureresources-api": "^2.0.4", - "@vscode/extension-telemetry": "^0.9.0", + "@microsoft/vscode-azureresources-api": "^2.3.1", + "@vscode/extension-telemetry": "^0.9.6", "dayjs": "^1.11.2", "escape-string-regexp": "^2.0.0", "html-to-text": "^8.2.0", "semver": "^7.3.7", "uuid": "^9.0.0", - "vscode-tas-client": "^0.1.47", + "vscode-tas-client": "^0.1.84", "vscode-uri": "^3.0.6" }, "dependencies": { @@ -7735,22 +7701,23 @@ } }, "@microsoft/vscode-azureresources-api": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azureresources-api/-/vscode-azureresources-api-2.0.4.tgz", - "integrity": "sha512-LridV1h2rCydrBzEpwy+pUIUx61GpZNwrK04G7LdlhoxHrzuM/WAoy8jXaSC/FSKSsXD1QXuE6u/YofEfsuKeg==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azureresources-api/-/vscode-azureresources-api-2.3.2.tgz", + "integrity": "sha512-hwG8Q1ywk7faPIyKLRT5Lfk9usl5i0mIxqyVEWxs4gBi5Jfq4d90WEJbHJLX72v6HS+4KQCKJ0h0XhNS7y4OZg==", + "requires": {} }, "@nevware21/ts-async": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.4.0.tgz", - "integrity": "sha512-dbV826TTehQIBIJjh8GDSbwn1Z6+cnkyNbRlpcpdBPH8mROD2zabIUKqWcw9WRdTjjUIm21K+OR4DXWlAyOVTQ==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.5.4.tgz", + "integrity": "sha512-IBTyj29GwGlxfzXw2NPnzty+w0Adx61Eze1/lknH/XIVdxtF9UnOpk76tnrHXWa6j84a1RR9hsOcHQPFv9qJjA==", "requires": { - "@nevware21/ts-utils": ">= 0.10.0 < 2.x" + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@nevware21/ts-utils": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.10.4.tgz", - "integrity": "sha512-+QSEh9TZ7SFwZEEyIvP8NabL5I5WFE/gvk4LXtW4LjWyTEc/6t2Hog6r1MmY3hIQG9tLe6fARIAXjAQ/M8Kb6A==" + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.11.6.tgz", + "integrity": "sha512-OUUJTh3fnaUSzg9DEHgv3d7jC+DnPL65mIO7RaR+jWve7+MmcgIvF79gY97DPQ4frH+IpNR78YAYd/dW4gK3kg==" }, "@nodelib/fs.scandir": { "version": "2.1.5", @@ -8236,13 +8203,13 @@ "dev": true }, "@vscode/extension-telemetry": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.9.2.tgz", - "integrity": "sha512-O6VMCDkzypjULhgy2l6fih3c3fExPmSj7aewtW5jBJYgXcIIjtkJOttIfnKOCP4S8sNfc6xc1Do4MbUDmhduEw==", + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.9.8.tgz", + "integrity": "sha512-7YcKoUvmHlIB8QYCE4FNzt3ErHi9gQPhdCM3ZWtpw1bxPT0I+lMdx52KHlzTNoJzQ2NvMX7HyzyDwBEiMgTrWQ==", "requires": { - "@microsoft/1ds-core-js": "^4.0.3", - "@microsoft/1ds-post-js": "^4.0.3", - "@microsoft/applicationinsights-web-basic": "^3.0.6" + "@microsoft/1ds-core-js": "^4.3.4", + "@microsoft/1ds-post-js": "^4.3.4", + "@microsoft/applicationinsights-web-basic": "^3.3.4" } }, "@vscode/test-electron": { @@ -8578,16 +8545,6 @@ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, - "axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "requires": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -9626,11 +9583,6 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, - "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" - }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -11097,11 +11049,6 @@ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", "dev": true }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -11536,12 +11483,9 @@ } }, "tas-client": { - "version": "0.1.73", - "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.1.73.tgz", - "integrity": "sha512-UDdUF9kV2hYdlv+7AgqP2kXarVSUhjK7tg1BUflIRGEgND0/QoNpN64rcEuhEcM8AIbW65yrCopJWqRhLZ3m8w==", - "requires": { - "axios": "^1.6.1" - } + "version": "0.2.33", + "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.2.33.tgz", + "integrity": "sha512-V+uqV66BOQnWxvI6HjDnE4VkInmYZUQ4dgB7gzaDyFyFSK1i1nF/j7DpS9UbQAgV9NaF1XpcyuavnM1qOeiEIg==" }, "terser": { "version": "5.16.6", @@ -11795,11 +11739,11 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "vscode-tas-client": { - "version": "0.1.75", - "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.75.tgz", - "integrity": "sha512-/+ALFWPI4U3obeRvLFSt39guT7P9bZQrkmcLoiS+2HtzJ/7iPKNt5Sj+XTiitGlPYVFGFc0plxX8AAp6Uxs0xQ==", + "version": "0.1.84", + "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.84.tgz", + "integrity": "sha512-rUTrUopV+70hvx1hW5ebdw1nd6djxubkLvVxjGdyD/r5v/wcVF41LIfiAtbm5qLZDtQdsMH1IaCuDoluoIa88w==", "requires": { - "tas-client": "0.1.73" + "tas-client": "0.2.33" } }, "vscode-uri": { diff --git a/appservice/package.json b/appservice/package.json index dcc2ad450a..c568cdbacf 100644 --- a/appservice/package.json +++ b/appservice/package.json @@ -1,7 +1,7 @@ { "name": "@microsoft/vscode-azext-azureappservice", "author": "Microsoft Corporation", - "version": "3.3.1", + "version": "3.4.0", "description": "Common tools for developing Azure App Service extensions for VS Code", "tags": [ "azure", @@ -42,7 +42,7 @@ "@azure/storage-blob": "^12.3.0", "@microsoft/vscode-azext-azureutils": "^3.0.0", "@microsoft/vscode-azext-github": "^1.0.0", - "@microsoft/vscode-azext-utils": "^2.5.0", + "@microsoft/vscode-azext-utils": "^2.5.13", "dayjs": "^1.11.2", "fs-extra": "^10.0.0", "p-retry": "^3.0.1", diff --git a/appservice/src/createAppService/IAppServiceWizardContext.ts b/appservice/src/createAppService/IAppServiceWizardContext.ts index 4d4294f5fb..4ad4c06751 100644 --- a/appservice/src/createAppService/IAppServiceWizardContext.ts +++ b/appservice/src/createAppService/IAppServiceWizardContext.ts @@ -8,6 +8,7 @@ import type { AppServicePlan, Site, SkuDescription } from '@azure/arm-appservice import type { Workspace } from '@azure/arm-operationalinsights'; import { IResourceGroupWizardContext, IStorageAccountWizardContext } from '@microsoft/vscode-azext-azureutils'; import { AppKind, WebsiteOS } from './AppKind'; +import { DomainNameLabelScope } from './SiteDomainNameLabelScopeStep'; export interface IAppServiceWizardContext extends IResourceGroupWizardContext, IStorageAccountWizardContext { newSiteKind: AppKind; @@ -30,6 +31,12 @@ export interface IAppServiceWizardContext extends IResourceGroupWizardContext, I */ newSiteName?: string; + /** + * The domain name label scope for the new site + * This will be defined after `SiteDomainNameLabelScopeStep.prompt` occurs. + */ + newSiteDomainNameLabelScope?: DomainNameLabelScope; + /** * The App Service plan to use. * If an existing plan is picked, this value will be defined after `AppServicePlanListStep.prompt` occurs diff --git a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts new file mode 100644 index 0000000000..2bb206b11a --- /dev/null +++ b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts @@ -0,0 +1,47 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { AzureWizardPromptStep, IAzureQuickPickItem, openUrl } from '@microsoft/vscode-azext-utils'; +import * as vscode from 'vscode'; +import { IAppServiceWizardContext } from './IAppServiceWizardContext'; + +export enum DomainNameLabelScope { + ResourceGroup = 'ResourceGroupReuse', + Subscription = 'SubscriptionReuse', + Tenant = 'TenantReuse', + Global = 'NoReuse', +} + +export class SiteDomainNameLabelScopeStep extends AzureWizardPromptStep { + public async prompt(context: T): Promise { + const picks: IAzureQuickPickItem[] = [ + // Matching the portal which doesn't yet offer ResourceGroup and Subscription level domain scope + { label: vscode.l10n.t('Secure unique default hostname'), description: vscode.l10n.t('Tenant Scope'), data: DomainNameLabelScope.Tenant }, + { label: vscode.l10n.t('Global default hostname'), description: vscode.l10n.t('Global'), data: DomainNameLabelScope.Global }, + { label: vscode.l10n.t('$(link-external) Learn more about unique default hostname'), data: undefined }, + ]; + const learnMoreUrl: string = 'https://aka.ms/AAu7lhs'; + + let result: DomainNameLabelScope | undefined; + do { + result = (await context.ui.showQuickPick(picks, { + placeHolder: vscode.l10n.t('Select default hostname format'), + suppressPersistence: true, + learnMoreLink: learnMoreUrl, + })).data; + + if (!result) { + await openUrl(learnMoreUrl); + } + } while (!result); + + context.telemetry.properties.siteDomainNameLabelScope = result; + context.newSiteDomainNameLabelScope = result; + } + + public shouldPrompt(context: T): boolean { + return !context.newSiteDomainNameLabelScope; + } +} diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index 46393782c9..37420b310b 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { ResourceNameAvailability, WebSiteManagementClient } from '@azure/arm-appservice'; -import { ResourceGroupListStep, StorageAccountListStep, resourceGroupNamingRules, storageAccountNamingRules } from '@microsoft/vscode-azext-azureutils'; -import { AgentInputBoxOptions, AzureNameStep, IAzureAgentInput, IAzureNamingRules } from '@microsoft/vscode-azext-utils'; +import type { ResourceNameAvailability, Site, WebSiteManagementClient } from '@azure/arm-appservice'; +import { createHttpHeaders, createPipelineRequest } from '@azure/core-rest-pipeline'; +import { AzExtLocation, AzExtPipelineResponse, AzExtRequestPrepareOptions, LocationListStep, ResourceGroupListStep, StorageAccountListStep, createGenericClient, resourceGroupNamingRules, storageAccountNamingRules } from '@microsoft/vscode-azext-azureutils'; +import { AgentInputBoxOptions, AzureNameStep, IAzureAgentInput, IAzureNamingRules, nonNullValue, nonNullValueAndProp } from '@microsoft/vscode-azext-utils'; import * as vscode from 'vscode'; import { createWebSiteClient } from '../utils/azureClients'; import { appInsightsNamingRules } from './AppInsightsListStep'; @@ -13,6 +14,7 @@ import { AppKind } from './AppKind'; import { AppServicePlanListStep } from './AppServicePlanListStep'; import { appServicePlanNamingRules } from './AppServicePlanNameStep'; import { IAppServiceWizardContext } from './IAppServiceWizardContext'; +import { DomainNameLabelScope } from './SiteDomainNameLabelScopeStep'; interface SiteNameStepWizardContext extends IAppServiceWizardContext { ui: IAzureAgentInput; @@ -24,6 +26,11 @@ const siteNamingRules: IAzureNamingRules = { invalidCharsRegExp: /[^a-zA-Z0-9\-]/ }; +// Selecting a regional domain name label scope actually fails if over 43 chars long, even though the CNA validation would otherwise say it's fine. +// Setting the limit to 43 chars seems to completely fix the issue and is the same number the portal is using. +// See: https://github.com/microsoft/vscode-azuretools/pull/1882#issue-2828801875 +const regionalCNAMaxLength: number = 43; + export class SiteNameStep extends AzureNameStep { private _siteFor: "functionApp" | "containerizedFunctionApp" | undefined; @@ -56,7 +63,7 @@ export class SiteNameStep extends AzureNameStep { } else if (context.newSiteKind?.includes(AppKind.workflowapp)) { prompt = vscode.l10n.t('Enter a globally unique name for the new logic app.'); } else { - prompt = vscode.l10n.t('Enter a globally unique name for the new web app.'); + prompt = vscode.l10n.t('Enter a name for the new web app.'); } const agentMetadata = this._siteFor === ("functionApp") || this._siteFor === ("containerizedFunctionApp") ? @@ -70,14 +77,17 @@ export class SiteNameStep extends AzureNameStep { const options: AgentInputBoxOptions = { prompt, placeHolder, - validateInput: (name: string): string | undefined => this.validateSiteName(name), - asyncValidationTask: async (name: string): Promise => await this.asyncValidateSiteName(client, name), + validateInput: (name: string): string | undefined => this.validateSiteName(context, name), + asyncValidationTask: async (name: string): Promise => await this.asyncValidateSiteName(context, client, name), agentMetadata: agentMetadata }; context.newSiteName = (await context.ui.showInputBox(options)).trim(); context.valuesToMask.push(context.newSiteName); + context.relatedNameTask ??= this.generateRelatedName(context, context.newSiteName, this.getRelatedResourceNamingRules(context)); + } + private getRelatedResourceNamingRules(context: SiteNameStepWizardContext): IAzureNamingRules[] { const namingRules: IAzureNamingRules[] = [resourceGroupNamingRules]; if (context.newSiteKind === AppKind.functionapp) { namingRules.push(storageAccountNamingRules); @@ -86,18 +96,18 @@ export class SiteNameStep extends AzureNameStep { } namingRules.push(appInsightsNamingRules); - context.relatedNameTask = this.generateRelatedName(context, context.newSiteName, namingRules); + return namingRules; } - public async getRelatedName(context: IAppServiceWizardContext, name: string): Promise { + public async getRelatedName(context: SiteNameStepWizardContext, name: string): Promise { return await this.generateRelatedName(context, name, appServicePlanNamingRules); } - public shouldPrompt(context: IAppServiceWizardContext): boolean { + public shouldPrompt(context: SiteNameStepWizardContext): boolean { return !context.newSiteName; } - protected async isRelatedNameAvailable(context: IAppServiceWizardContext, name: string): Promise { + protected async isRelatedNameAvailable(context: SiteNameStepWizardContext, name: string): Promise { const tasks: Promise[] = [ResourceGroupListStep.isNameAvailable(context, name)]; if (context.newSiteKind === AppKind.functionapp) { tasks.push(StorageAccountListStep.isNameAvailable(context, name)); @@ -108,11 +118,16 @@ export class SiteNameStep extends AzureNameStep { return (await Promise.all(tasks)).every((v: boolean) => v); } - private validateSiteName(name: string): string | undefined { + private validateSiteName(context: SiteNameStepWizardContext, name: string): string | undefined { name = name.trim(); - if (name.length < siteNamingRules.minLength || name.length > siteNamingRules.maxLength) { - return vscode.l10n.t('The name must be between {0} and {1} characters.', siteNamingRules.minLength, siteNamingRules.maxLength); + let maxLength: number = siteNamingRules.maxLength; + if (context.newSiteDomainNameLabelScope && context.newSiteDomainNameLabelScope !== DomainNameLabelScope.Global) { + maxLength = regionalCNAMaxLength; + } + + if (name.length < siteNamingRules.minLength || name.length > maxLength) { + return vscode.l10n.t('The name must be between {0} and {1} characters.', siteNamingRules.minLength, maxLength); } else if (this._siteFor === "containerizedFunctionApp" && (!/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(name))) { return vscode.l10n.t("A name must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character and cannot have '--'."); } else if (siteNamingRules.invalidCharsRegExp.test(name)) { @@ -122,7 +137,24 @@ export class SiteNameStep extends AzureNameStep { return undefined; } - private async asyncValidateSiteName(client: WebSiteManagementClient, name: string): Promise { + // For comprehensive breakdown of validation logic, please refer to: https://github.com/microsoft/vscode-azuretools/pull/1882#issue-2828801875 + private async asyncValidateSiteName(context: SiteNameStepWizardContext, sdkClient: WebSiteManagementClient, name: string): Promise { + name = name.trim(); + + let validationMessage: string | undefined; + if (!context.newSiteDomainNameLabelScope || context.newSiteDomainNameLabelScope === DomainNameLabelScope.Global) { + validationMessage ??= await this.asyncValidateGlobalCNA(sdkClient, name); + } + + if (context.newSiteDomainNameLabelScope) { + validationMessage ??= await this.asyncValidateRegionalCNA(context, context.newSiteDomainNameLabelScope, name, context.resourceGroup?.name ?? context.newResourceGroupName); + validationMessage ??= await this.asyncValidateUniqueARMId(context, sdkClient, name, context.resourceGroup?.name ?? context.newResourceGroupName); + } + + return validationMessage; + } + + private async asyncValidateGlobalCNA(client: WebSiteManagementClient, name: string): Promise { const nameAvailability: ResourceNameAvailability = await client.checkNameAvailability(name, 'Site'); if (!nameAvailability.nameAvailable) { return nameAvailability.message; @@ -130,4 +162,76 @@ export class SiteNameStep extends AzureNameStep { return undefined; } } + + private async asyncValidateRegionalCNA(context: SiteNameStepWizardContext, domainNameScope: DomainNameLabelScope, siteName: string, resourceGroupName?: string): Promise { + if (!LocationListStep.hasLocation(context)) { + throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with regional CNA.')); + } else if (domainNameScope === DomainNameLabelScope.ResourceGroup && !resourceGroupName) { + throw new Error(vscode.l10n.t('Internal Error: A resource group name is required for validating this level of domain name scope.')); + } + + const apiVersion: string = '2024-04-01'; + const location: AzExtLocation = await LocationListStep.getLocation(context); + const authToken: string = nonNullValueAndProp((await context.credentials.getToken() as { token?: string }), 'token'); + + // Todo: Can replace with call using SDK once the update is available + const options: AzExtRequestPrepareOptions = { + url: `${context.environment.resourceManagerEndpointUrl}subscriptions/${context.subscriptionId}/providers/Microsoft.Web/locations/${location.name}/checknameavailability?api-version=${apiVersion}`, + method: 'POST', + headers: createHttpHeaders({ + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${authToken}`, + }), + body: JSON.stringify({ + name: siteName, + type: 'Site', + autoGeneratedDomainNameLabelScope: domainNameScope, + resourceGroupName: domainNameScope === DomainNameLabelScope.ResourceGroup ? resourceGroupName : undefined, + }), + }; + + const client = await createGenericClient(context, undefined); + const pipelineResponse = await client.sendRequest(createPipelineRequest(options)) as AzExtPipelineResponse; + const checkNameResponse = pipelineResponse.parsedBody as { + hostName?: string; + message?: string; + nameAvailable?: boolean; + reason?: string; + }; + + if (!checkNameResponse.nameAvailable) { + // For global domain scope, if site name input is greater than regionalCNAMaxLength, ignore result of regional CNA because it inherently has a shorter character limit than Global CNA + if (domainNameScope === DomainNameLabelScope.Global && siteName.length > regionalCNAMaxLength) { + // Ensure the error message is the expected character validation error message before ignoring it + if (checkNameResponse.message && /must be less than \d{2} chars/i.test(checkNameResponse.message)) { + return undefined; + } + } + return checkNameResponse.message; + } + + return undefined; + } + + private async asyncValidateUniqueARMId(context: SiteNameStepWizardContext, client: WebSiteManagementClient, siteName: string, resourceGroupName?: string): Promise { + if (!resourceGroupName) { + context.relatedNameTask ??= this.generateRelatedName(context, siteName, this.getRelatedResourceNamingRules(context)); + resourceGroupName = await context.relatedNameTask; + } + + try { + const rgName: string = nonNullValue(resourceGroupName, vscode.l10n.t('Internal Error: A resource group name must be provided to verify unique site ID.')); + const site: Site = await client.webApps.get(rgName, siteName); + if (site) { + return vscode.l10n.t('A site with name "{0}" already exists in resource group "{1}".', siteName, rgName); + } + } catch (e) { + const statusCode = (e as { statusCode?: number })?.statusCode; + if (statusCode !== 404) { + return vscode.l10n.t('Failed to validate name availability for "{0}". Please try another name.', siteName); + } + } + + return undefined; + } } diff --git a/appservice/src/index.ts b/appservice/src/index.ts index 2d23220002..d051f4506f 100644 --- a/appservice/src/index.ts +++ b/appservice/src/index.ts @@ -3,9 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -export * from './KuduModels'; -export * from './SiteClient'; -export * from './TunnelProxy'; export * from './confirmOverwriteSettings'; export * from './createAppService/AppInsightsCreateStep'; export * from './createAppService/AppInsightsListStep'; @@ -17,23 +14,27 @@ export * from './createAppService/AppServicePlanSkuStep'; export * from './createAppService/CustomLocationListStep'; export * from './createAppService/IAppServiceWizardContext'; export * from './createAppService/LogAnalyticsCreateStep'; +export * from './createAppService/setLocationsTask'; +export * from './createAppService/SiteDomainNameLabelScopeStep'; export * from './createAppService/SiteNameStep'; export * from './createAppService/SiteOSStep'; -export * from './createAppService/setLocationsTask'; export * from './createSlot'; export * from './deleteSite/DeleteLastServicePlanStep'; export * from './deleteSite/DeleteSiteStep'; export * from './deleteSite/IDeleteSiteWizardContext'; -export * from './deploy/IDeployContext'; export * from './deploy/deploy'; export * from './deploy/getDeployFsPath'; export * from './deploy/getDeployNode'; +export * from './deploy/IDeployContext'; export * from './deploy/localGitDeploy'; -export { IPreDeployTaskResult, handleFailedPreDeployTask, runPreDeployTask, tryRunPreDeployTask } from './deploy/runDeployTask'; +export { handleFailedPreDeployTask, IPreDeployTaskResult, runPreDeployTask, tryRunPreDeployTask } from './deploy/runDeployTask'; export * from './deploy/showDeployConfirmation'; export { disconnectRepo } from './disconnectRepo'; export * from './editScmType'; export { registerAppServiceExtensionVariables } from './extensionVariables'; +export * from './KuduModels'; +export * from './SiteClient'; +export * from './TunnelProxy'; // export { IConnectToGitHubWizardContext } from './github/IConnectToGitHubWizardContext'; export * from './pingFunctionApp'; export * from './registerSiteCommand'; @@ -42,11 +43,12 @@ export * from './remoteDebug/startRemoteDebug'; export * from './siteFiles'; export * from './startStreamingLogs'; export * from './swapSlot'; -export * from './tree/DeploymentTreeItem'; export * from './tree/DeploymentsTreeItem'; +export * from './tree/DeploymentTreeItem'; export * from './tree/FileTreeItem'; export * from './tree/FolderTreeItem'; export * from './tree/LogFilesTreeItem'; export * from './tree/SiteFilesTreeItem'; export * from './tryGetSiteResource'; export * from './utils/azureClients'; +