Enable Policy Debugging Feature (#118)
* debug refactor * temp * connect to cloud * temp * fix bugs * connect to cloud update * temp change * Use bearer token * Refactor code * temp change * comment code * UpdateOne * Change dogfood endpoint * Fix more issues * temp changes * Neat code * Fix lint error
This commit is contained in:
Родитель
552cd501bd
Коммит
d6d6304d3e
|
@ -90,6 +90,20 @@
|
|||
"NODE_DEBUG": "",
|
||||
"ENABLE_LONG_RUNNING_TESTS": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Server",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"program": "${workspaceFolder}/resources/debug/debugAdapter.js",
|
||||
"args": [ "--server=4711" ]
|
||||
},
|
||||
],
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Extension + Server",
|
||||
"configurations": [ "Launch Extension (no build)", "Server" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -5,29 +5,35 @@
|
|||
"requires": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
|
||||
"integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
|
||||
"version": "7.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
|
||||
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/highlight": "^7.0.0"
|
||||
"@babel/highlight": "^7.8.3"
|
||||
}
|
||||
},
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz",
|
||||
"integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/highlight": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
|
||||
"integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
|
||||
"integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.9.0",
|
||||
"chalk": "^2.0.0",
|
||||
"esutils": "^2.0.2",
|
||||
"js-tokens": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@types/bluebird": {
|
||||
"version": "3.5.27",
|
||||
"resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.27.tgz",
|
||||
"integrity": "sha512-6BmYWSBea18+tSjjSC3QIyV93ZKAeNWGM7R6aYt1ryTZXrlHF+QLV0G2yV0viEGVyRkyQsWfMoJ0k/YghBX5sQ==",
|
||||
"version": "3.5.30",
|
||||
"resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.30.tgz",
|
||||
"integrity": "sha512-8LhzvcjIoqoi1TghEkRMkbbmM+jhHnBokPGkJWjclMK+Ks0MxEBow3/p2/iFTZ+OIbJHQDSfpgdZEb+af3gfVw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/caseless": {
|
||||
|
@ -42,15 +48,6 @@
|
|||
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/form-data": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz",
|
||||
"integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/fs-extra": {
|
||||
"version": "4.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.9.tgz",
|
||||
|
@ -105,32 +102,54 @@
|
|||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "10.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.17.tgz",
|
||||
"integrity": "sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q=="
|
||||
"version": "8.10.62",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.62.tgz",
|
||||
"integrity": "sha512-76fupxOYVxk36kb7O/6KtrAPZ9jnSK3+qisAX4tQMEuGNdlvl7ycwatlHqjoE6jHfVtXFM3pCrCixZOidc5cuw=="
|
||||
},
|
||||
"@types/request": {
|
||||
"version": "2.48.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz",
|
||||
"integrity": "sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg==",
|
||||
"version": "2.48.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.4.tgz",
|
||||
"integrity": "sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/caseless": "*",
|
||||
"@types/form-data": "*",
|
||||
"@types/node": "*",
|
||||
"@types/tough-cookie": "*"
|
||||
"@types/tough-cookie": "*",
|
||||
"form-data": "^2.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"form-data": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
|
||||
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/request-promise": {
|
||||
"version": "4.1.44",
|
||||
"resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.44.tgz",
|
||||
"integrity": "sha512-RId7eFsUKxfal1LirDDIcOp9u3MM3NXFDBcC3sqIMcmu7f4U6DsCEMD8RbLZtnPrQlN5Jc79di/WPsIEDO4keg==",
|
||||
"version": "4.1.46",
|
||||
"resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.46.tgz",
|
||||
"integrity": "sha512-3Thpj2Va5m0ji3spaCk8YKrjkZyZc6RqUVOphA0n/Xet66AW/AiOAs5vfXhQIL5NmkaO7Jnun7Nl9NEjJ2zBaw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/bluebird": "*",
|
||||
"@types/request": "*"
|
||||
}
|
||||
},
|
||||
"@types/request-promise-native": {
|
||||
"version": "1.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/request-promise-native/-/request-promise-native-1.0.17.tgz",
|
||||
"integrity": "sha512-05/d0WbmuwjtGMYEdHIBZ0tqMJJQ2AD9LG2F6rKNBGX1SSFR27XveajH//2N/XYtual8T9Axwl+4v7oBtPUZqg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/request": "*"
|
||||
}
|
||||
},
|
||||
"@types/swagger-parser": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/swagger-parser/-/swagger-parser-4.0.3.tgz",
|
||||
|
@ -147,9 +166,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@types/tough-cookie": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz",
|
||||
"integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==",
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.6.tgz",
|
||||
"integrity": "sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/undertaker": {
|
||||
|
@ -187,10 +206,19 @@
|
|||
"@types/vinyl": "*"
|
||||
}
|
||||
},
|
||||
"@types/ws": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz",
|
||||
"integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/xml": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/xml/-/xml-1.0.3.tgz",
|
||||
"integrity": "sha512-qeqQIjDfSLjmWR0noFQmcPKCtqn0L68MchoEi1Zj33unPfC83Op3j2mBH2g4hAgOaWUobv/O86w7LObo6p4sDQ==",
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/xml/-/xml-1.0.4.tgz",
|
||||
"integrity": "sha512-l9RTwMnKc7WTHpARC9A1CoeF40U5xi6ZOQePDvkeTr6RZpzck/Y54i9YCYe2fgrWZiOxfJ4wnBbDd3g/7HYtug==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
|
@ -906,6 +934,11 @@
|
|||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||
"dev": true
|
||||
},
|
||||
"await-notify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/await-notify/-/await-notify-1.0.1.tgz",
|
||||
"integrity": "sha1-C0gTOyLlJBgeEVV2ZRhfKi885Hw="
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
|
@ -1347,9 +1380,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"cacache": {
|
||||
"version": "11.3.3",
|
||||
"resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz",
|
||||
"integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==",
|
||||
"version": "12.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz",
|
||||
"integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bluebird": "^3.5.5",
|
||||
|
@ -1357,6 +1390,7 @@
|
|||
"figgy-pudding": "^3.5.1",
|
||||
"glob": "^7.1.4",
|
||||
"graceful-fs": "^4.1.15",
|
||||
"infer-owner": "^1.0.3",
|
||||
"lru-cache": "^5.1.1",
|
||||
"mississippi": "^3.0.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
|
@ -1461,9 +1495,9 @@
|
|||
}
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
|
||||
"integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==",
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
||||
"dev": true
|
||||
},
|
||||
"chrome-trace-event": {
|
||||
|
@ -2175,9 +2209,9 @@
|
|||
"optional": true
|
||||
},
|
||||
"cyclist": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
|
||||
"integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
|
||||
"integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
|
||||
"dev": true
|
||||
},
|
||||
"d": {
|
||||
|
@ -2758,12 +2792,6 @@
|
|||
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
|
||||
"dev": true
|
||||
},
|
||||
"esutils": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
|
||||
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
|
||||
"dev": true
|
||||
},
|
||||
"events": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz",
|
||||
|
@ -3283,9 +3311,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
|
@ -3347,9 +3375,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
|
@ -4623,6 +4651,12 @@
|
|||
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
|
||||
"dev": true
|
||||
},
|
||||
"infer-owner": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
|
||||
"integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
|
||||
"dev": true
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
|
@ -5052,9 +5086,9 @@
|
|||
}
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
|
||||
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||
"dev": true
|
||||
},
|
||||
"last-run": {
|
||||
|
@ -5137,9 +5171,9 @@
|
|||
}
|
||||
},
|
||||
"linkify-it": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz",
|
||||
"integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
|
||||
"integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"uc.micro": "^1.0.1"
|
||||
|
@ -5706,7 +5740,6 @@
|
|||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
},
|
||||
|
@ -5714,8 +5747,7 @@
|
|||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5776,9 +5808,9 @@
|
|||
}
|
||||
},
|
||||
"mocha-junit-reporter": {
|
||||
"version": "1.23.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-1.23.0.tgz",
|
||||
"integrity": "sha512-pmpnEO4iDTmLfrT2RKqPsc5relG4crnDSGmXPuGogdda27A7kLujDNJV4EbTbXlVBCZXggN9rQYPEWMkOv4AAA==",
|
||||
"version": "1.23.3",
|
||||
"resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-1.23.3.tgz",
|
||||
"integrity": "sha512-ed8LqbRj1RxZfjt/oC9t12sfrWsjZ3gNnbhV1nuj9R/Jb5/P3Xb4duv2eCfCDMYH+fEu0mqca7m4wsiVjsxsvA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^2.2.0",
|
||||
|
@ -6420,20 +6452,20 @@
|
|||
"dev": true
|
||||
},
|
||||
"parallel-transform": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz",
|
||||
"integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz",
|
||||
"integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cyclist": "~0.2.2",
|
||||
"cyclist": "^1.0.1",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^2.1.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
|
@ -7013,9 +7045,9 @@
|
|||
}
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
||||
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
||||
"version": "2.88.2",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
|
||||
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
|
@ -7024,7 +7056,7 @@
|
|||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.0",
|
||||
"har-validator": "~5.1.3",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
|
@ -7034,9 +7066,20 @@
|
|||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.4.3",
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"request-progress": {
|
||||
|
@ -7049,22 +7092,54 @@
|
|||
}
|
||||
},
|
||||
"request-promise": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.4.tgz",
|
||||
"integrity": "sha512-8wgMrvE546PzbR5WbYxUQogUnUDfM0S7QIFZMID+J73vdFARkFy+HElj4T+MWYhpXwlLp0EQ8Zoj8xUA0he4Vg==",
|
||||
"version": "4.2.5",
|
||||
"resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz",
|
||||
"integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==",
|
||||
"requires": {
|
||||
"bluebird": "^3.5.0",
|
||||
"request-promise-core": "1.1.2",
|
||||
"request-promise-core": "1.1.3",
|
||||
"stealthy-require": "^1.1.1",
|
||||
"tough-cookie": "^2.3.3"
|
||||
}
|
||||
},
|
||||
"request-promise-core": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz",
|
||||
"integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==",
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
|
||||
"integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.11"
|
||||
"lodash": "^4.17.15"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"request-promise-native": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz",
|
||||
"integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==",
|
||||
"requires": {
|
||||
"request-promise-core": "1.1.3",
|
||||
"stealthy-require": "^1.1.1",
|
||||
"tough-cookie": "^2.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
},
|
||||
"request-promise-core": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
|
||||
"integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.15"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"require-directory": {
|
||||
|
@ -7233,9 +7308,9 @@
|
|||
}
|
||||
},
|
||||
"serialize-javascript": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz",
|
||||
"integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
|
||||
"integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==",
|
||||
"dev": true
|
||||
},
|
||||
"set-blocking": {
|
||||
|
@ -7932,14 +8007,14 @@
|
|||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.0.0.tgz",
|
||||
"integrity": "sha512-dOapGTU0hETFl1tCo4t56FN+2jffoKyER9qBGoUFyZ6y7WLoKT0bF+lAYi6B6YsILcGF3q1C2FBh8QcKSCgkgA==",
|
||||
"version": "4.6.6",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.6.6.tgz",
|
||||
"integrity": "sha512-4lYPyeNmstjIIESr/ysHg2vUPRGf2tzF9z2yYwnowXVuVzLEamPN1Gfrz7f8I9uEPuHcbFlW4PLIAsJoxXyJ1g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commander": "^2.19.0",
|
||||
"commander": "^2.20.0",
|
||||
"source-map": "~0.6.1",
|
||||
"source-map-support": "~0.5.10"
|
||||
"source-map-support": "~0.5.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
|
@ -7951,20 +8026,19 @@
|
|||
}
|
||||
},
|
||||
"terser-webpack-plugin": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz",
|
||||
"integrity": "sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==",
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
|
||||
"integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cacache": "^11.3.2",
|
||||
"find-cache-dir": "^2.0.0",
|
||||
"cacache": "^12.0.2",
|
||||
"find-cache-dir": "^2.1.0",
|
||||
"is-wsl": "^1.1.0",
|
||||
"loader-utils": "^1.2.3",
|
||||
"schema-utils": "^1.0.0",
|
||||
"serialize-javascript": "^1.7.0",
|
||||
"serialize-javascript": "^2.1.2",
|
||||
"source-map": "^0.6.1",
|
||||
"terser": "^4.0.0",
|
||||
"webpack-sources": "^1.3.0",
|
||||
"terser": "^4.1.2",
|
||||
"webpack-sources": "^1.4.0",
|
||||
"worker-farm": "^1.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -7973,6 +8047,16 @@
|
|||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
},
|
||||
"webpack-sources": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
|
||||
"integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"source-list-map": "^2.0.0",
|
||||
"source-map": "~0.6.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -8190,16 +8274,16 @@
|
|||
"dev": true
|
||||
},
|
||||
"tslint": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz",
|
||||
"integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==",
|
||||
"version": "5.20.1",
|
||||
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz",
|
||||
"integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"builtin-modules": "^1.1.1",
|
||||
"chalk": "^2.3.0",
|
||||
"commander": "^2.12.1",
|
||||
"diff": "^3.2.0",
|
||||
"diff": "^4.0.1",
|
||||
"glob": "^7.1.1",
|
||||
"js-yaml": "^3.13.1",
|
||||
"minimatch": "^3.0.4",
|
||||
|
@ -8208,6 +8292,14 @@
|
|||
"semver": "^5.3.0",
|
||||
"tslib": "^1.8.0",
|
||||
"tsutils": "^2.29.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tslint-microsoft-contrib": {
|
||||
|
@ -8297,9 +8389,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.2.tgz",
|
||||
"integrity": "sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA==",
|
||||
"version": "3.8.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
|
||||
"integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
|
||||
"dev": true
|
||||
},
|
||||
"uc.micro": {
|
||||
|
@ -8668,9 +8760,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"vsce": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/vsce/-/vsce-1.64.0.tgz",
|
||||
"integrity": "sha512-t3R7QTe2nAXQZs2kD+nA8GjdlX8pAQlnzxaNTG2976i5cyQ8r+ZsMNa/f9PDt7bhjcQM+u/fL+LkNuw+hwoy2A==",
|
||||
"version": "1.74.0",
|
||||
"resolved": "https://registry.npmjs.org/vsce/-/vsce-1.74.0.tgz",
|
||||
"integrity": "sha512-8zWM9bZBNn9my40kkxAxdY4nhb9ADfazXsyDgx1thbRaLPbmPTlmqQ55vCAyWYFEi6XbJv8w599vzVUqsU1gHg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"azure-devops-node-api": "^7.2.0",
|
||||
|
@ -8680,7 +8772,7 @@
|
|||
"denodeify": "^1.2.1",
|
||||
"didyoumean": "^1.2.1",
|
||||
"glob": "^7.0.6",
|
||||
"lodash": "^4.17.10",
|
||||
"lodash": "^4.17.15",
|
||||
"markdown-it": "^8.3.1",
|
||||
"mime": "^1.3.4",
|
||||
"minimatch": "^3.0.3",
|
||||
|
@ -8693,111 +8785,29 @@
|
|||
"url-join": "^1.1.0",
|
||||
"yauzl": "^2.3.1",
|
||||
"yazl": "^2.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"vscode": {
|
||||
"version": "1.1.34",
|
||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.34.tgz",
|
||||
"integrity": "sha512-GuT3tCT2N5Qp26VG4C+iGmWMgg/MuqtY5G5TSOT3U/X6pgjM9LFulJEeqpyf6gdzpI4VyU3ZN/lWPo54UFPuQg==",
|
||||
"version": "1.1.36",
|
||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.36.tgz",
|
||||
"integrity": "sha512-cGFh9jmGLcTapCpPCKvn8aG/j9zVQ+0x5hzYJq5h5YyUXVGa1iamOaB2M2PZXoumQPES4qeAP1FwkI0b6tL4bQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.2",
|
||||
"mocha": "^4.0.1",
|
||||
"mocha": "^5.2.0",
|
||||
"request": "^2.88.0",
|
||||
"semver": "^5.4.1",
|
||||
"source-map-support": "^0.5.0",
|
||||
"url-parse": "^1.4.4",
|
||||
"vscode-test": "^0.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"browser-stdout": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
|
||||
"integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
|
||||
"dev": true
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
|
||||
"integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
|
||||
"dev": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"diff": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz",
|
||||
"integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==",
|
||||
"dev": true
|
||||
},
|
||||
"growl": {
|
||||
"version": "1.10.3",
|
||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz",
|
||||
"integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==",
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
|
||||
"integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
|
||||
"dev": true
|
||||
},
|
||||
"he": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
|
||||
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
|
||||
"dev": true
|
||||
},
|
||||
"mocha": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz",
|
||||
"integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browser-stdout": "1.3.0",
|
||||
"commander": "2.11.0",
|
||||
"debug": "3.1.0",
|
||||
"diff": "3.3.1",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"glob": "7.1.2",
|
||||
"growl": "1.10.3",
|
||||
"he": "1.1.1",
|
||||
"mkdirp": "0.5.1",
|
||||
"supports-color": "4.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
|
||||
"integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vscode-azureextensiondev": {
|
||||
|
@ -8843,6 +8853,52 @@
|
|||
"ajv-keywords": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
},
|
||||
"terser-webpack-plugin": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
|
||||
"integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cacache": "^12.0.2",
|
||||
"find-cache-dir": "^2.1.0",
|
||||
"is-wsl": "^1.1.0",
|
||||
"schema-utils": "^1.0.0",
|
||||
"serialize-javascript": "^2.1.2",
|
||||
"source-map": "^0.6.1",
|
||||
"terser": "^4.1.2",
|
||||
"webpack-sources": "^1.4.0",
|
||||
"worker-farm": "^1.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"schema-utils": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
|
||||
"integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.1.0",
|
||||
"ajv-errors": "^1.0.0",
|
||||
"ajv-keywords": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"webpack-sources": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
|
||||
"integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"source-list-map": "^2.0.0",
|
||||
"source-map": "~0.6.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz",
|
||||
|
@ -8912,6 +8968,29 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"vscode-debugadapter": {
|
||||
"version": "1.39.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugadapter/-/vscode-debugadapter-1.39.1.tgz",
|
||||
"integrity": "sha512-+WYpOcY0PiAEBILf6nIwbNVF8ig8gugWTKWhQ7Ds1884JXpVL336pG0xH66Nc1Z1W/KSzuXarm1gtccdwl6PKw==",
|
||||
"requires": {
|
||||
"mkdirp": "^0.5.1",
|
||||
"vscode-debugprotocol": "1.39.0"
|
||||
}
|
||||
},
|
||||
"vscode-debugadapter-testsupport": {
|
||||
"version": "1.40.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugadapter-testsupport/-/vscode-debugadapter-testsupport-1.40.2.tgz",
|
||||
"integrity": "sha512-HN1KoQUtFwCfPz2r1XaOtw3aUPpkgDPPRpLSGjCbOGRYhUJKlnLEwSaq4djVvZsfav6Zfd9QaBoaBNy03eBTvg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"vscode-debugprotocol": "1.39.0"
|
||||
}
|
||||
},
|
||||
"vscode-debugprotocol": {
|
||||
"version": "1.39.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.39.0.tgz",
|
||||
"integrity": "sha512-Wkvgtuz90vjtQBcvw9Z+BYa4dA6W+sHwHMpqvJVNmwWSuT3JZdl0XDhZNLqtMXkVF4okxtAe0MmbupPSt+gnAQ=="
|
||||
},
|
||||
"vscode-extension-telemetry": {
|
||||
"version": "0.0.18",
|
||||
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz",
|
||||
|
@ -8935,9 +9014,9 @@
|
|||
}
|
||||
},
|
||||
"vscode-nls": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz",
|
||||
"integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A=="
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz",
|
||||
"integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw=="
|
||||
},
|
||||
"vscode-test": {
|
||||
"version": "0.4.3",
|
||||
|
@ -9189,9 +9268,9 @@
|
|||
}
|
||||
},
|
||||
"webpack-cli": {
|
||||
"version": "3.3.5",
|
||||
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.5.tgz",
|
||||
"integrity": "sha512-w0j/s42c5UhchwTmV/45MLQnTVwRoaUTu9fM5LuyOd/8lFoCNCELDogFoecx5NzRUndO0yD/gF2b02XKMnmAWQ==",
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz",
|
||||
"integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "2.4.2",
|
||||
|
@ -9375,9 +9454,9 @@
|
|||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "13.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
|
||||
"integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
|
||||
"version": "13.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
|
||||
"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
|
@ -9449,6 +9528,11 @@
|
|||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
|
||||
"integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ=="
|
||||
},
|
||||
"xml": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
|
||||
|
@ -9478,9 +9562,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
|
||||
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
|
|
101
package.json
101
package.json
|
@ -33,6 +33,7 @@
|
|||
"onCommand:azureApiManagement.selectSubscriptions",
|
||||
"onView:azureApiManagementExplorer",
|
||||
"onLanguage:policy",
|
||||
"onLanguage:apim-policy",
|
||||
"onCommand:azureApiManagement.createService",
|
||||
"onCommand:azureApiManagement.deleteService",
|
||||
"onCommand:azureApiManagement.copySubscriptionKey",
|
||||
|
@ -67,10 +68,50 @@
|
|||
"onCommand:azureApiManagement.importWebAppToApi",
|
||||
"onCommand:azureApiManagement.copyDockerRunCommand",
|
||||
"onCommand:azureApiManagement.generateKubernetesDeployment",
|
||||
"onCommand:azureApiManagement.generateNewGatewayToken"
|
||||
"onCommand:azureApiManagement.generateNewGatewayToken",
|
||||
"onCommand:azureApiManagement.debugPolicy"
|
||||
],
|
||||
"main": "main",
|
||||
"contributes": {
|
||||
"breakpoints": [
|
||||
{
|
||||
"language": "apim-policy"
|
||||
}
|
||||
],
|
||||
"languages": [
|
||||
{
|
||||
"id": "apim-policy",
|
||||
"mimetypes": [
|
||||
"application/vnd.ms-azure-apim.policy.raw+xml"
|
||||
]
|
||||
}
|
||||
],
|
||||
"debuggers": [
|
||||
{
|
||||
"type": "apim-policy",
|
||||
"label": "Attach to APIM",
|
||||
"runtime": "node",
|
||||
"configurationAttributes": {
|
||||
"launch": {
|
||||
"properties": {
|
||||
"stopOnEntry": {
|
||||
"type": "boolean",
|
||||
"description": "Automatically stop after launch.",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"initialConfigurations": [
|
||||
{
|
||||
"type": "apim-policy",
|
||||
"request": "launch",
|
||||
"name": "Attach to APIM",
|
||||
"stopOnEntry": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"jsonValidation": [
|
||||
{
|
||||
"fileMatch": "/*-api-arm.json",
|
||||
|
@ -274,6 +315,11 @@
|
|||
"title": "%azureApiManagement.importWebAppToApi%",
|
||||
"category": "Azure API Management"
|
||||
},
|
||||
{
|
||||
"command": "azureApiManagement.debugPolicy",
|
||||
"title": "%azureApiManagement.debugPolicy%",
|
||||
"category": "Azure API Management"
|
||||
},
|
||||
{
|
||||
"command": "azureApiManagement.copyDockerRunCommand",
|
||||
"title": "%azureApiManagement.copyDockerRunCommand%",
|
||||
|
@ -443,6 +489,11 @@
|
|||
"when": "view == azureApiManagementExplorer && viewItem == azureApiManagementApiOperation",
|
||||
"group": "1@1"
|
||||
},
|
||||
{
|
||||
"command": "azureApiManagement.debugPolicy",
|
||||
"when": "view == azureApiManagementExplorer && viewItem == azureApiManagementApiOperation",
|
||||
"group": "2@1"
|
||||
},
|
||||
{
|
||||
"command": "azureApiManagement.createNamedValue",
|
||||
"when": "view == azureApiManagementExplorer && viewItem == azureApiManagementNamedValues",
|
||||
|
@ -542,38 +593,46 @@
|
|||
"devDependencies": {
|
||||
"@types/fs-extra": "^4.0.3",
|
||||
"@types/gulp": "^4.0.6",
|
||||
"@types/node": "^10.0.0",
|
||||
"@types/request": "^2.47.0",
|
||||
"@types/request-promise": "^4.1.43",
|
||||
"@types/swagger-parser": "^4.0.3",
|
||||
"@types/mocha": "^5.2.6",
|
||||
"tslint": "^5.7.0",
|
||||
"typescript": "^3.3.1",
|
||||
"ts-node": "^7.0.1",
|
||||
"tslint-microsoft-contrib": "5.0.1",
|
||||
"vscode-extension-telemetry": "^0.0.18",
|
||||
"@types/node": "^8.10.59",
|
||||
"@types/request": "^2.48.4",
|
||||
"@types/request-promise": "^4.1.46",
|
||||
"@types/request-promise-native": "^1.0.17",
|
||||
"@types/swagger-parser": "^4.0.3",
|
||||
"@types/ws": "^6.0.4",
|
||||
"gulp": "^4.0.0",
|
||||
"vsce": "^1.59.0",
|
||||
"vscode": "^1.1.33",
|
||||
"vscode-azureextensiondev": "0.1.8",
|
||||
"webpack": "4.29.6",
|
||||
"webpack-cli": "^3.3.0",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha-junit-reporter": "^1.18.0",
|
||||
"mocha-multi-reporters": "^1.1.7"
|
||||
"mocha-junit-reporter": "^1.23.3",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"ts-node": "^7.0.1",
|
||||
"tslint": "^5.20.1",
|
||||
"tslint-microsoft-contrib": "5.0.1",
|
||||
"typescript": "^3.8.3",
|
||||
"vsce": "^1.74.0",
|
||||
"vscode": "^1.1.36",
|
||||
"vscode-azureextensiondev": "0.1.8",
|
||||
"vscode-debugadapter-testsupport": "1.40.2",
|
||||
"vscode-extension-telemetry": "^0.0.18",
|
||||
"webpack": "4.29.6",
|
||||
"webpack-cli": "^3.3.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/xml": "^1.0.3",
|
||||
"@types/xml": "^1.0.4",
|
||||
"await-notify": "1.0.1",
|
||||
"azure-arm-apimanagement": "^6.0.0",
|
||||
"azure-arm-resource": "^3.0.0-preview",
|
||||
"azure-arm-website": "5.7.0",
|
||||
"fs-extra": "^4.0.2",
|
||||
"opn": "^5.3.0",
|
||||
"request": "^2.83.0",
|
||||
"request-promise": "^4.2.2",
|
||||
"request": "^2.88.2",
|
||||
"request-promise": "^4.2.5",
|
||||
"request-promise-native": "^1.0.8",
|
||||
"swagger-parser": "^6.0.5",
|
||||
"vscode-azureextensionui": "^0.23.3",
|
||||
"vscode-nls": "^4.1.0"
|
||||
"vscode-debugadapter": "^1.39.1",
|
||||
"vscode-debugprotocol": "^1.39.0",
|
||||
"vscode-nls": "^4.1.2",
|
||||
"ws": "^7.2.3"
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"ms-vscode.azure-account",
|
||||
|
|
|
@ -37,5 +37,6 @@
|
|||
"azureApiManagement.importWebAppToApi": "Import Azure App Service",
|
||||
"azureApiManagement.copyDockerRunCommand": "Copy Docker Run Command",
|
||||
"azureApiManagement.generateKubernetesDeployment": "Generate Kubernetes Deployment File",
|
||||
"azureApiManagement.generateNewGatewayToken": "Generate New Gateway Token"
|
||||
"azureApiManagement.generateNewGatewayToken": "Generate New Gateway Token",
|
||||
"azureApiManagement.debugPolicy": "Start Policy Debugging"
|
||||
}
|
|
@ -61,6 +61,11 @@ export class ApimService {
|
|||
return res.value;
|
||||
}
|
||||
|
||||
public async getSubscriptionMasterkey(): Promise<string> {
|
||||
const masterKeyUrl = `${this.baseUrl}/subscriptions/master?api-version=${this.apiVersion}`;
|
||||
return await requestUtil(masterKeyUrl, this.credentials, 'GET');
|
||||
}
|
||||
|
||||
private genSiteUrl(endPointUrl: string, subscriptionId: string, resourceGroup: string, serviceName: string): string {
|
||||
return `${endPointUrl}/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.ApiManagement/service/${serviceName}`;
|
||||
}
|
||||
|
|
|
@ -30,3 +30,15 @@ export interface IGatewayTokenList {
|
|||
primary: string;
|
||||
secondary: string;
|
||||
}
|
||||
|
||||
export interface IMasterSubscription {
|
||||
id : string;
|
||||
name : string;
|
||||
properties: ISubscriptionProperty;
|
||||
}
|
||||
|
||||
export interface ISubscriptionProperty {
|
||||
displayName: string;
|
||||
primaryKey: string;
|
||||
secondaryKey: string;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { ApiOperationTreeItem } from '../../explorer/ApiOperationTreeItem';
|
||||
import { IOperationTreeRoot } from '../../explorer/IOperationTreeRoot';
|
||||
import { ext } from "../../extensionVariables";
|
||||
import { nameUtil } from '../../utils/nameUtil';
|
||||
|
||||
export async function debugPolicy(node?: ApiOperationTreeItem): Promise<void> {
|
||||
if (!node) {
|
||||
node = <ApiOperationTreeItem>await ext.tree.showTreeItemPicker(ApiOperationTreeItem.contextValue);
|
||||
}
|
||||
|
||||
const operationData = await node.getOperationDebugInfo();
|
||||
const debugConfig: vscode.DebugConfiguration = {
|
||||
type: "apim-policy",
|
||||
request: "launch",
|
||||
name: "Attach to APIM",
|
||||
stopOnEntry: true,
|
||||
// tslint:disable-next-line: no-non-null-assertion
|
||||
gatewayAddress: getDebugGatewayAddressUrl(node!.root.serviceName),
|
||||
managementAddress: getManagementUrl(node.root),
|
||||
subscriptionId: node.root.subscriptionId,
|
||||
operationData: operationData,
|
||||
fileName: `${nameUtil(node.root)}.http`
|
||||
};
|
||||
|
||||
// const debugConfig3: vscode.DebugConfiguration = {
|
||||
// type: "apim-policy",
|
||||
// request: "launch",
|
||||
// name: "Attach to APIM",
|
||||
// stopOnEntry: true,
|
||||
// gatewayAddress: 'wss://proxy.apim.net/debug-0123456789abcdef',
|
||||
// managementAddress: 'https://management.apim.net/subscriptions/x/resourceGroups/x/providers/microsoft.apimanagement/service/x',
|
||||
// managementAuth: '',
|
||||
// operationData: getLocalDebugOperationData2(),
|
||||
// fileName: `${nameUtil(node.root)}.http`
|
||||
// };
|
||||
|
||||
if (!vscode.debug.activeDebugSession) {
|
||||
await vscode.debug.startDebugging(undefined, debugConfig);
|
||||
// await vscode.debug.startDebugging(undefined, debugConfig3);
|
||||
vscode.debug.onDidTerminateDebugSession(_ => {
|
||||
const editors = vscode.window.visibleTextEditors;
|
||||
editors.forEach(editor => {
|
||||
editor.hide();
|
||||
});
|
||||
}, vscode.debug.activeDebugSession);
|
||||
}
|
||||
}
|
||||
|
||||
function getManagementUrl(root: IOperationTreeRoot): string {
|
||||
return `${root.environment.resourceManagerEndpointUrl}/subscriptions/${root.subscriptionId}/resourceGroups/${root.resourceGroupName}/providers/microsoft.apimanagement/service/${root.serviceName}`;
|
||||
}
|
||||
|
||||
function getDebugGatewayAddressUrl(serviceName: string): string {
|
||||
return `wss://${serviceName}.azure-api.net/debug-0123456789abcdef`;
|
||||
}
|
||||
|
||||
// function getLocalDebugOperationData2(): string {
|
||||
// return `
|
||||
// GET https://proxy.apim.net/echo/resource
|
||||
// Ocp-Apim-Subscription-Key:
|
||||
// Ocp-Apim-Debug:`;
|
||||
// }
|
|
@ -155,7 +155,7 @@ export function createXmlPolicyForSwaggerOperations(backendId: string): string {
|
|||
export async function setAppBackendEntity(node: ApisTreeItem | ApiTreeItem, backendId: string, appName: string, appPath: string, appResourceGroup: string, webAppName: string, BackendCredentials?: BackendCredentialsContract): Promise<void> {
|
||||
const nbackend: BackendContract = {
|
||||
description: `${appName}`,
|
||||
resourceId: getWebAppResourceId(node.root.environment.managementEndpointUrl, node.root.subscriptionId, appResourceGroup, webAppName),
|
||||
resourceId: getWebAppResourceId(node.root.environment.resourceManagerEndpointUrl, node.root.subscriptionId, appResourceGroup, webAppName),
|
||||
url: appPath,
|
||||
id: backendId,
|
||||
name: backendId,
|
||||
|
|
|
@ -14,13 +14,28 @@ export async function testOperation(node?: ApiOperationTreeItem): Promise<void>
|
|||
if (!node) {
|
||||
node = <ApiOperationTreeItem>await ext.tree.showTreeItemPicker(ApiOperationTreeItem.contextValue);
|
||||
}
|
||||
// tslint:disable-next-line: no-non-null-assertion
|
||||
await createOperationTestFile(node!, OperationRunMode.test);
|
||||
}
|
||||
|
||||
export async function createOperationTestFile(node: ApiOperationTreeItem, mode: OperationRunMode): Promise<vscode.TextEditor> {
|
||||
// using https://github.com/Huachao/vscode-restclient
|
||||
const fileName = `${nameUtil(node.root)}.http`;
|
||||
const localFilePath: string = await createTemporaryFile(fileName);
|
||||
const data: string = await node.getOperationTestInfo();
|
||||
let data: string;
|
||||
if (mode === OperationRunMode.debug) {
|
||||
data = await node.getOperationDebugInfo();
|
||||
} else {
|
||||
data = await node.getOperationTestInfo();
|
||||
}
|
||||
const document: vscode.TextDocument = await vscode.workspace.openTextDocument(localFilePath);
|
||||
const textEditor: vscode.TextEditor = await vscode.window.showTextDocument(document);
|
||||
await writeToEditor(textEditor, data);
|
||||
await textEditor.document.save();
|
||||
return textEditor;
|
||||
}
|
||||
|
||||
export enum OperationRunMode {
|
||||
debug = "debug",
|
||||
test = "test"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,515 @@
|
|||
/*---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
import { ServiceClientCredentials } from "ms-rest";
|
||||
import * as request from 'request-promise-native';
|
||||
import * as vscode from 'vscode';
|
||||
import { Breakpoint, Handles, InitializedEvent, Logger, logger, LoggingDebugSession, OutputEvent, Scope, StackFrame, StoppedEvent, TerminatedEvent, Thread, ThreadEvent, Variable } from 'vscode-debugadapter';
|
||||
import { DebugProtocol } from 'vscode-debugprotocol';
|
||||
import { createTemporaryFile } from "../utils/fsUtil";
|
||||
import { getBearerToken } from '../utils/requestUtil';
|
||||
import { writeToEditor } from '../utils/vscodeUtils';
|
||||
import { DebuggerConnection, RequestContract } from './debuggerConnection';
|
||||
import { PolicySource } from './policySource';
|
||||
import { UiRequest } from './uiRequest';
|
||||
import { UiThread } from './uiThread';
|
||||
|
||||
// tslint:disable: no-unsafe-any
|
||||
// tslint:disable: indent
|
||||
// tslint:disable: export-name
|
||||
// tslint:disable: strict-boolean-expressions
|
||||
// tslint:disable: typedef
|
||||
// tslint:disable: no-non-null-assertion
|
||||
// tslint:disable: no-for-in
|
||||
// tslint:disable: forin
|
||||
// tslint:disable: no-var-requires
|
||||
const { Subject } = require('await-notify');
|
||||
|
||||
interface ILaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
|
||||
gatewayAddress: string;
|
||||
managementAddress: string;
|
||||
managementAuth: string;
|
||||
subscriptionId: string;
|
||||
operationData: string;
|
||||
fileName: string;
|
||||
stopOnEntry?: boolean;
|
||||
}
|
||||
|
||||
export class ApimDebugSession extends LoggingDebugSession {
|
||||
private availablePolicies: string[];
|
||||
private runtime: DebuggerConnection;
|
||||
private configurationDone = new Subject();
|
||||
private requests: UiRequest[] = [];
|
||||
private policySource: PolicySource;
|
||||
private variablesHandles = new Handles<string>();
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
|
||||
this.setDebuggerLinesStartAt1(false);
|
||||
this.setDebuggerColumnsStartAt1(false);
|
||||
|
||||
this.runtime = new DebuggerConnection();
|
||||
|
||||
this.runtime.on('stopOnEntry', (requestId, threadId, operationId, apiId, productId) => this.onStop('entry', requestId, threadId, operationId, apiId, productId));
|
||||
this.runtime.on('stopOnStep', (requestId, threadId, operationId, apiId, productId) => this.onStop('step', requestId, threadId, operationId, apiId, productId));
|
||||
this.runtime.on('stopOnBreakpoint', (requestId, threadId, operationId, apiId, productId) => this.onStop('breakpoint', requestId, threadId, operationId, apiId, productId));
|
||||
this.runtime.on('stopOnException', (requestId, threadId, operationId, apiId, productId, message) => this.onStop('exception', requestId, threadId, operationId, apiId, productId, message));
|
||||
this.runtime.on('threadExited', (requestId, threadId) => this.onThreadExited(requestId, threadId));
|
||||
this.runtime.on('end', message => {
|
||||
this.requests = [];
|
||||
if (message) {
|
||||
this.sendEvent(new OutputEvent(message, 'stderr'));
|
||||
}
|
||||
this.sendEvent(new TerminatedEvent());
|
||||
});
|
||||
}
|
||||
|
||||
protected initializeRequest(response: DebugProtocol.InitializeResponse, _args: DebugProtocol.InitializeRequestArguments): void {
|
||||
response.body = response.body || {};
|
||||
response.body.supportsConfigurationDoneRequest = true;
|
||||
|
||||
response.body.supportsRestartRequest = false;
|
||||
response.body.supportsRestartFrame = false;
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
protected configurationDoneRequest(response: DebugProtocol.ConfigurationDoneResponse, args: DebugProtocol.ConfigurationDoneArguments): void {
|
||||
super.configurationDoneRequest(response, args);
|
||||
this.configurationDone.notify();
|
||||
}
|
||||
|
||||
protected async launchRequest(response: DebugProtocol.LaunchResponse, args: ILaunchRequestArguments): Promise<void> {
|
||||
logger.setup(Logger.LogLevel.Verbose, false);
|
||||
let masterKey;
|
||||
if (args.managementAuth) {
|
||||
this.policySource = new PolicySource(args.managementAddress, undefined, args.managementAuth);
|
||||
masterKey = await this.getMasterSubscriptionKey(args.managementAddress, undefined, args.managementAuth);
|
||||
this.availablePolicies = await this.getAvailablePolicies(args.managementAddress, undefined, args.managementAuth);
|
||||
} else {
|
||||
const credential = await this.getAccountCredentials(args.subscriptionId);
|
||||
this.policySource = new PolicySource(args.managementAddress, credential);
|
||||
masterKey = await this.getMasterSubscriptionKey(args.managementAddress, credential);
|
||||
this.availablePolicies = await this.getAvailablePolicies(args.managementAddress, credential);
|
||||
}
|
||||
|
||||
await this.runtime.attach(args.gatewayAddress, masterKey, !!args.stopOnEntry);
|
||||
this.sendEvent(new InitializedEvent());
|
||||
await this.configurationDone.wait(1000);
|
||||
this.sendResponse(response);
|
||||
this.updateRequests(await this.runtime.getRequests(), true);
|
||||
await this.createTestOperationFile(args.operationData, args.fileName);
|
||||
}
|
||||
|
||||
protected async threadsRequest(response: DebugProtocol.ThreadsResponse) {
|
||||
if (this.runtime.isConnected()) {
|
||||
this.updateRequests(await this.runtime.getRequests(), true);
|
||||
}
|
||||
|
||||
const threads: Thread[] = [];
|
||||
for (const nRequest of this.requests) {
|
||||
for (const thread of nRequest.threads) {
|
||||
threads.push(new Thread(thread.uiId, `${nRequest.id} (${thread.id})`));
|
||||
}
|
||||
}
|
||||
|
||||
response.body = {
|
||||
threads: threads
|
||||
};
|
||||
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
protected async terminateThreadsRequest(response: DebugProtocol.TerminateThreadsResponse, args: DebugProtocol.TerminateThreadsArguments, _request?: DebugProtocol.Request) {
|
||||
const requests = args.threadIds!.map(id => this.findThreadByUiId(id));
|
||||
|
||||
if (requests.length) {
|
||||
await this.runtime.terminateRequests(requests.map(r => r![0].id).filter((value, index, self) => self.indexOf(value) === index));
|
||||
}
|
||||
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
protected async stackTraceRequest(response: DebugProtocol.StackTraceResponse, args: DebugProtocol.StackTraceArguments) {
|
||||
let stack: StackFrame[] = [];
|
||||
if (this.runtime.isConnected()) {
|
||||
const nRequest = this.findThreadByUiId(args.threadId);
|
||||
if (nRequest) {
|
||||
const requestStack = await this.runtime.getStackTrace(nRequest[0].id, nRequest[1].id);
|
||||
stack = await nRequest[1].getStackFrames(requestStack);
|
||||
|
||||
for (const item of <DebugProtocol.StackFrame[]>stack) {
|
||||
if (item.line) {
|
||||
item.line = this.convertDebuggerLineToClient(item.line);
|
||||
}
|
||||
if (item.column) {
|
||||
item.column = this.convertDebuggerColumnToClient(item.column);
|
||||
}
|
||||
if (item.endLine) {
|
||||
item.endLine = this.convertDebuggerLineToClient(item.endLine);
|
||||
}
|
||||
if (item.endColumn) {
|
||||
item.endColumn = this.convertDebuggerColumnToClient(item.endColumn) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response.body = {
|
||||
stackFrames: stack,
|
||||
totalFrames: stack.length
|
||||
};
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
protected async sourceRequest(response: DebugProtocol.SourceResponse, args: DebugProtocol.SourceArguments) {
|
||||
const policy = this.policySource.getPolicyBySourceReference(args.sourceReference);
|
||||
|
||||
if (policy !== null && policy.xml !== null) {
|
||||
response.body = {
|
||||
content: policy && policy.xml,
|
||||
mimeType: 'application/vnd.ms-azure-apim.policy.raw+xml'
|
||||
};
|
||||
this.sendResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
protected async continueRequest(response: DebugProtocol.ContinueResponse, args: DebugProtocol.ContinueArguments) {
|
||||
const nRequest = this.findThreadByUiId(args.threadId);
|
||||
if (nRequest && this.runtime.isConnected()) {
|
||||
await this.runtime.continue(nRequest[0].id, nRequest[1].id);
|
||||
}
|
||||
|
||||
response.body = {
|
||||
allThreadsContinued: false
|
||||
};
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
protected async nextRequest(response: DebugProtocol.NextResponse, args: DebugProtocol.NextArguments) {
|
||||
const nRequest = this.findThreadByUiId(args.threadId);
|
||||
if (nRequest && this.runtime.isConnected()) {
|
||||
await this.runtime.stepOver(nRequest[0].id, nRequest[1].id);
|
||||
}
|
||||
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
protected async stepInRequest(response: DebugProtocol.StepInResponse, args: DebugProtocol.StepInArguments) {
|
||||
const nRequest = this.findThreadByUiId(args.threadId);
|
||||
if (nRequest && this.runtime.isConnected()) {
|
||||
await this.runtime.stepIn(nRequest[0].id, nRequest[1].id);
|
||||
}
|
||||
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
protected async stepOutRequest(response: DebugProtocol.StepOutResponse, args: DebugProtocol.StepOutArguments) {
|
||||
const nRequest = this.findThreadByUiId(args.threadId);
|
||||
if (nRequest && this.runtime.isConnected()) {
|
||||
await this.runtime.stepOut(nRequest[0].id, nRequest[1].id);
|
||||
}
|
||||
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
protected async pauseRequest(response: DebugProtocol.PauseResponse, args: DebugProtocol.PauseArguments) {
|
||||
const nRequest = this.findThreadByUiId(args.threadId);
|
||||
if (nRequest && this.runtime.isConnected()) {
|
||||
await this.runtime.pause(nRequest[0].id, nRequest[1].id);
|
||||
}
|
||||
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
protected scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments) {
|
||||
let scopes: Scope[] = [];
|
||||
|
||||
const nRequest = this.findThreadByStackFrameId(args.frameId);
|
||||
if (nRequest) {
|
||||
scopes = [new Scope("Request", this.variablesHandles.create(`${nRequest[0].id}|${nRequest[1].id}`), true)];
|
||||
}
|
||||
|
||||
response.body = {
|
||||
scopes: scopes || []
|
||||
};
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
protected async variablesRequest(response: DebugProtocol.VariablesResponse, args: DebugProtocol.VariablesArguments) {
|
||||
let variables: Variable[] = [];
|
||||
|
||||
if (this.runtime.isConnected()) {
|
||||
const variableScope = this.variablesHandles.get(args.variablesReference);
|
||||
const scopeParts = variableScope.split('|');
|
||||
if (scopeParts.length >= 2) {
|
||||
const vars = await this.runtime.getVariables(scopeParts[0], +scopeParts[1], scopeParts.slice(2).join('.'));
|
||||
variables = vars.map(v => {
|
||||
const variable = new Variable(v.name, v.value || "", v.nestedCount ? this.variablesHandles.create(`${variableScope}|${v.name}`) : 0);
|
||||
(<DebugProtocol.Variable>variable).type = v.type;
|
||||
(<DebugProtocol.Variable>variable).namedVariables = v.nestedCount;
|
||||
(<DebugProtocol.Variable>variable).presentationHint = {
|
||||
kind: 'property',
|
||||
visibility: 'public'
|
||||
};
|
||||
return variable;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
response.body = {
|
||||
variables: variables || []
|
||||
|
||||
};
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
protected async setBreakPointsRequest(response: DebugProtocol.SetBreakpointsResponse, args: DebugProtocol.SetBreakpointsArguments) {
|
||||
const breakpoints = await this.setBreakpoints(args);
|
||||
const nBreakpoints: Breakpoint[] = (breakpoints.length !== 0) ? breakpoints : (args.breakpoints) ? args.breakpoints.map(_b => new Breakpoint(false)) : [];
|
||||
response.body = {
|
||||
breakpoints: nBreakpoints
|
||||
};
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
private async createTestOperationFile(operationData: string, fileName: string) {
|
||||
const localFilePath: string = await createTemporaryFile(fileName);
|
||||
const document: vscode.TextDocument = await vscode.workspace.openTextDocument(localFilePath);
|
||||
const textEditor: vscode.TextEditor = await vscode.window.showTextDocument(document);
|
||||
await writeToEditor(textEditor, operationData);
|
||||
await textEditor.document.save();
|
||||
}
|
||||
|
||||
private async setBreakpoints(args: DebugProtocol.SetBreakpointsArguments): Promise<Breakpoint[]> {
|
||||
let breakpoints: Breakpoint[] = [];
|
||||
const breakpointsToSet: {
|
||||
path: string,
|
||||
scopeId: string
|
||||
}[] = [];
|
||||
let policy = this.policySource.getPolicyBySourceReference(args.source.sourceReference);
|
||||
if (!policy && args.source.name) {
|
||||
policy = this.policySource.getPolicy(args.source.name) || await this.policySource.fetchPolicy(args.source.name);
|
||||
}
|
||||
if (args.breakpoints && args.breakpoints.length) {
|
||||
// set breakpoints if has policy otherwise check if it's initialization
|
||||
if (policy && policy !== null) {
|
||||
breakpoints = args.breakpoints.map(b => {
|
||||
let position = {
|
||||
line: -1,
|
||||
column: -1,
|
||||
endLine: -1,
|
||||
endColumn: -1
|
||||
};
|
||||
|
||||
let path: string | null = null;
|
||||
const breakpointLine = this.convertClientLineToDebugger(b.line);
|
||||
const breakpointColumn = b.column && this.convertClientColumnToDebugger(b.column);
|
||||
for (const key in policy!.map) {
|
||||
const mapEntry = policy!.map[key];
|
||||
if (mapEntry.line === breakpointLine
|
||||
&& (!breakpointColumn || breakpointColumn >= mapEntry.column && breakpointColumn <= mapEntry.endColumn)
|
||||
&& (position.line === -1 || mapEntry.column < position.column)) {
|
||||
path = key;
|
||||
position = mapEntry;
|
||||
}
|
||||
}
|
||||
if (position.line === -1) {
|
||||
return new Breakpoint(false);
|
||||
}
|
||||
|
||||
if (path === null) {
|
||||
throw new Error("Path is null");
|
||||
}
|
||||
let policyName = path.substring(path.lastIndexOf('/') + 1);
|
||||
if (policyName.indexOf('[') !== -1) {
|
||||
policyName = policyName.substring(0, policyName.lastIndexOf('['));
|
||||
}
|
||||
|
||||
if (this.availablePolicies.indexOf(policyName) === -1) {
|
||||
return new Breakpoint(false);
|
||||
}
|
||||
|
||||
breakpointsToSet.push({
|
||||
path: path.substr(path.indexOf('/') + 1), //Remove 'policies/' prefix
|
||||
scopeId: policy!.scopeId
|
||||
});
|
||||
const breakpoint = new Breakpoint(true, this.convertDebuggerLineToClient(position.line), this.convertDebuggerColumnToClient(position.column), policy!.source);
|
||||
(<DebugProtocol.Breakpoint>breakpoint).endLine = this.convertDebuggerLineToClient(position.endLine);
|
||||
(<DebugProtocol.Breakpoint>breakpoint).endColumn = this.convertDebuggerColumnToClient(position.endColumn);
|
||||
return breakpoint;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await this.runtime.setBreakpoints(breakpointsToSet, policy!.scopeId);
|
||||
return breakpoints;
|
||||
}
|
||||
|
||||
private onThreadExited(requestId: string, threadId: number) {
|
||||
const nRequest = this.requests.find(r => r.id === requestId);
|
||||
const thread = nRequest && nRequest.findThreadById(threadId);
|
||||
|
||||
if (thread) {
|
||||
this.sendEvent(new ThreadEvent('exited', thread.uiId));
|
||||
}
|
||||
}
|
||||
|
||||
private onStop(event: string, requestId: string, threadId: number, operationId: string, apiId: string, productId: string, exceptionText?: string) {
|
||||
this.updateRequests([
|
||||
{
|
||||
id: requestId,
|
||||
threads: [threadId],
|
||||
operationId: operationId,
|
||||
apiId: apiId,
|
||||
productId: productId
|
||||
}
|
||||
], false);
|
||||
const nRequest = this.requests.find(r => r.id === requestId);
|
||||
const thread = nRequest && nRequest.findThreadById(threadId);
|
||||
|
||||
if (thread) {
|
||||
this.sendEvent(new StoppedEvent(event, thread.uiId, exceptionText));
|
||||
}
|
||||
}
|
||||
|
||||
private async getAccountCredentials(subscriptionId: string): Promise<ServiceClientCredentials> {
|
||||
const azureAccountExtension = vscode.extensions.getExtension('ms-vscode.azure-account');
|
||||
const azureAccount = azureAccountExtension!.exports;
|
||||
await azureAccount.waitForFilters();
|
||||
if (azureAccount.status !== 'LoggedIn') {
|
||||
throw new Error("ERROR!");
|
||||
}
|
||||
const creds = azureAccount.filters.filter(filter => filter.subscription.subscriptionId === subscriptionId).map(filter => filter.session.credentials);
|
||||
return creds[0];
|
||||
}
|
||||
|
||||
private async getMasterSubscriptionKey(managementAddress: string, credential?: ServiceClientCredentials, managementAuth?: string) {
|
||||
const resourceUrl = `${managementAddress}/subscriptions/master?api-version=2019-01-01`;
|
||||
const authToken = managementAuth ? managementAuth : await getBearerToken(resourceUrl, "GET", credential!);
|
||||
const subscription: IApimSubscription = await request.get(resourceUrl, {
|
||||
headers: {
|
||||
Authorization: authToken
|
||||
},
|
||||
strictSSL: false,
|
||||
json: true
|
||||
}).on('error', _e => {
|
||||
this.sendEvent(new TerminatedEvent());
|
||||
}).on('response', e => {
|
||||
if (e.statusCode !== 200) {
|
||||
this.sendEvent(new OutputEvent(`Error fetching master subscription: ${e.statusCode} ${e.statusMessage}`, 'stderr'));
|
||||
this.sendEvent(new TerminatedEvent());
|
||||
}
|
||||
});
|
||||
|
||||
return subscription.properties.primaryKey;
|
||||
}
|
||||
|
||||
private async getAvailablePolicies(managementAddress: string, credential?: ServiceClientCredentials, managementAuth?: string) {
|
||||
const resourceUrl = `${managementAddress}/policysnippets?api-version=2019-01-01`;
|
||||
const authToken = managementAuth ? managementAuth : await getBearerToken(resourceUrl, "GET", credential!);
|
||||
const snippets: IPolicySnippet[] = await request.get(resourceUrl, {
|
||||
headers: {
|
||||
Authorization: authToken
|
||||
},
|
||||
strictSSL: false,
|
||||
json: true
|
||||
}).on('error', _e => {
|
||||
this.sendEvent(new TerminatedEvent());
|
||||
}).on('response', e => {
|
||||
if (e.statusCode !== 200) {
|
||||
this.sendEvent(new OutputEvent(`Error fetching policy definitions: ${e.statusCode} ${e.statusMessage}`, 'stderr'));
|
||||
this.sendEvent(new TerminatedEvent());
|
||||
}
|
||||
});
|
||||
|
||||
return snippets.map(s => s.content.substring(1, /[\s>/]/.exec(s.content)!.index));
|
||||
}
|
||||
|
||||
private findThreadByUiId(id: number): [UiRequest, UiThread] | null {
|
||||
for (const uiRequest of this.requests) {
|
||||
const uiThread = uiRequest.findThreadByUiId(id);
|
||||
if (uiThread) {
|
||||
return [uiRequest, uiThread];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private findThreadByStackFrameId(id: number): [UiRequest, UiThread] | null {
|
||||
for (const uiRequest of this.requests) {
|
||||
const uiThread = uiRequest.findThreadByStackFrameId(id);
|
||||
if (uiThread) {
|
||||
return [uiRequest, uiThread];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private updateRequests(gatewayRequests: RequestContract[], clean: boolean) {
|
||||
if (clean) {
|
||||
let requestIndex = 0;
|
||||
while (requestIndex < this.requests.length) {
|
||||
const uiRequest = this.requests[requestIndex];
|
||||
const gatewayRequest = gatewayRequests.find(r => r.id === uiRequest.id);
|
||||
if (!gatewayRequest) {
|
||||
for (const thread of uiRequest.threads) {
|
||||
this.sendEvent(new ThreadEvent('exited', thread.uiId));
|
||||
}
|
||||
|
||||
this.requests.splice(requestIndex, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
let threadIndex = 0;
|
||||
while (threadIndex < uiRequest.threads.length) {
|
||||
const uiThread = uiRequest.threads[threadIndex];
|
||||
if (gatewayRequest.threads.indexOf(uiThread.id) < 0) {
|
||||
this.sendEvent(new ThreadEvent('exited', uiThread.uiId));
|
||||
uiRequest.threads.splice(threadIndex, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
threadIndex++;
|
||||
}
|
||||
|
||||
if (!uiRequest.threads.length) {
|
||||
this.requests.splice(requestIndex, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
requestIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
for (const gatewayRequest of gatewayRequests) {
|
||||
let uiRequest = this.requests.find(r => r.id === gatewayRequest.id);
|
||||
if (!uiRequest) {
|
||||
this.requests.push(uiRequest = new UiRequest(gatewayRequest.id, gatewayRequest.operationId, gatewayRequest.apiId, gatewayRequest.productId));
|
||||
}
|
||||
|
||||
for (const gatewayThread of gatewayRequest.threads) {
|
||||
let uiThread = uiRequest.threads.find(t => t.id === gatewayThread);
|
||||
if (!uiThread) {
|
||||
uiThread = uiRequest.addNewThread(gatewayThread, this.policySource);
|
||||
|
||||
this.sendEvent(new ThreadEvent('started', uiThread.uiId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IApimSubscription {
|
||||
properties: {
|
||||
primaryKey: string;
|
||||
secondaryKey: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface IPolicySnippet {
|
||||
content: string;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/*---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
import { ApimDebugSession } from './apimDebug';
|
||||
|
||||
ApimDebugSession.run(ApimDebugSession);
|
|
@ -0,0 +1,219 @@
|
|||
/*---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
import { EventEmitter } from 'events';
|
||||
import * as WebSocket from "ws";
|
||||
|
||||
// tslint:disable: no-unsafe-any
|
||||
// tslint:disable: indent
|
||||
// tslint:disable: export-name
|
||||
// tslint:disable: strict-boolean-expressions
|
||||
// tslint:disable: typedef
|
||||
// tslint:disable: no-non-null-assertion
|
||||
// tslint:disable: no-any
|
||||
// tslint:disable: no-reserved-keywords
|
||||
// tslint:disable: interface-name
|
||||
|
||||
export interface MockBreakpoint {
|
||||
id: number;
|
||||
line: number;
|
||||
verified: boolean;
|
||||
}
|
||||
|
||||
export class DebuggerConnection extends EventEmitter {
|
||||
private connection: WebSocket | null;
|
||||
private responseAwaiters: {
|
||||
[key: string]: ((value: any) => void)[]
|
||||
} = {};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
||||
}
|
||||
|
||||
public isConnected() {
|
||||
return this.connection != null;
|
||||
}
|
||||
|
||||
public async attach(address: string, key: string, stopOnEntry: boolean) {
|
||||
let connection: WebSocket;
|
||||
return new Promise((resolve, reject) => {
|
||||
connection = new WebSocket(`${address}?key=${key}`)
|
||||
.on('error', e => {
|
||||
if (this.connection == null || this.connection === connection) {
|
||||
this.connection = null;
|
||||
this.sendEvent('end', `Can't connect to gateway: ${e.message}.`);
|
||||
}
|
||||
reject();
|
||||
})
|
||||
.on('open', () => {
|
||||
this.connection = connection;
|
||||
this.sendCommand('attach', {
|
||||
break: stopOnEntry
|
||||
});
|
||||
resolve();
|
||||
})
|
||||
.on('message', e => {
|
||||
this.parseResponse(e.toString());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async getRequests() {
|
||||
return this.waitForResponse<RequestContract[]>(() => this.sendCommand('getRequests'), 'requests');
|
||||
}
|
||||
|
||||
public async getStackTrace(requestId: string, threadId: number) {
|
||||
return this.waitForResponse<StackFrameContract[]>(() => this.sendCommand('getStackTrace', {
|
||||
requestId: requestId,
|
||||
threadId: threadId
|
||||
}), 'stackTrace');
|
||||
}
|
||||
|
||||
public async getVariables(requestId: string, threadId: number, path?: string) {
|
||||
return this.waitForResponse<VariableContract[]>(() => this.sendCommand('getVariables', {
|
||||
requestId: requestId,
|
||||
threadId: threadId,
|
||||
path: path
|
||||
}), 'variables');
|
||||
}
|
||||
|
||||
public async setBreakpoints(breakpoints: { path: string, scopeId: string}[], scopeId: string) {
|
||||
this.sendCommand('setBreakpoints', {
|
||||
scopeId: scopeId,
|
||||
breakpoints: breakpoints
|
||||
});
|
||||
}
|
||||
|
||||
public async stepOver(requestId: string, threadId: number) {
|
||||
this.sendCommand('stepOver', {
|
||||
requestId: requestId,
|
||||
threadId: threadId
|
||||
});
|
||||
}
|
||||
|
||||
public async stepIn(requestId: string, threadId: number) {
|
||||
this.sendCommand('stepIn', {
|
||||
requestId: requestId,
|
||||
threadId: threadId
|
||||
});
|
||||
}
|
||||
|
||||
public async stepOut(requestId: string, threadId: number) {
|
||||
this.sendCommand('stepOut', {
|
||||
requestId: requestId,
|
||||
threadId: threadId
|
||||
});
|
||||
}
|
||||
|
||||
public async continue(requestId: string, threadId: number) {
|
||||
this.sendCommand('continue', {
|
||||
requestId: requestId,
|
||||
threadId: threadId
|
||||
});
|
||||
}
|
||||
|
||||
public async pause(requestId: string, threadId: number) {
|
||||
this.sendCommand('pause', {
|
||||
requestId: requestId,
|
||||
threadId: threadId
|
||||
});
|
||||
}
|
||||
|
||||
public async terminateRequests(requests: string[]) {
|
||||
this.sendCommand('terminateRequests', {
|
||||
requests: requests
|
||||
});
|
||||
}
|
||||
|
||||
private sendCommand(name: string, args?: any) {
|
||||
if (this.connection == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.connection.send(JSON.stringify({
|
||||
name: name,
|
||||
arguments: args
|
||||
}));
|
||||
}
|
||||
|
||||
private parseResponse(data: string) {
|
||||
try {
|
||||
// tslint:disable-next-line: no-banned-terms
|
||||
const event: { name: string, arguments: any } = JSON.parse(data.trim());
|
||||
// tslint:disable-next-line: switch-default
|
||||
switch (event.name) {
|
||||
case 'stopOnEntry':
|
||||
this.sendEvent(event.name, event.arguments.requestId, event.arguments.threadId, event.arguments.operationId, event.arguments.apiId, event.arguments.productId);
|
||||
break;
|
||||
case 'stopOnStep':
|
||||
this.sendEvent(event.name, event.arguments.requestId, event.arguments.threadId, event.arguments.operationId, event.arguments.apiId, event.arguments.productId);
|
||||
break;
|
||||
case 'stopOnException':
|
||||
this.sendEvent(event.name, event.arguments.requestId, event.arguments.threadId, event.arguments.operationId, event.arguments.apiId, event.arguments.productId, event.arguments.message);
|
||||
break;
|
||||
case 'stopOnBreakpoint':
|
||||
this.sendEvent(event.name, event.arguments.requestId, event.arguments.threadId, event.arguments.operationId, event.arguments.apiId, event.arguments.productId);
|
||||
break;
|
||||
case 'threadExited':
|
||||
this.sendEvent(event.name, event.arguments.requestId, event.arguments.threadId, event.arguments.operationId, event.arguments.apiId, event.arguments.productId);
|
||||
break;
|
||||
}
|
||||
|
||||
const awaiters = this.responseAwaiters[event.name];
|
||||
if (awaiters) {
|
||||
for (const awaiter of awaiters) {
|
||||
awaiter(event.arguments);
|
||||
}
|
||||
|
||||
delete this.responseAwaiters[event.name];
|
||||
}
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private async waitForResponse<T>(sendCommand: () => void, name: string) {
|
||||
return new Promise<T>(resolve => {
|
||||
(this.responseAwaiters[name] || (this.responseAwaiters[name] = [])).push(resolve);
|
||||
sendCommand();
|
||||
});
|
||||
}
|
||||
|
||||
private sendEvent(event: string, ...args: any[]) {
|
||||
setImmediate(_ => {
|
||||
this.emit(event, ...args);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface RequestContract {
|
||||
id: string;
|
||||
threads: number[];
|
||||
operationId: string;
|
||||
apiId: string;
|
||||
productId: string;
|
||||
}
|
||||
|
||||
export interface StackFrameContract {
|
||||
scopeId: string;
|
||||
index: number;
|
||||
name: string;
|
||||
section: string;
|
||||
}
|
||||
|
||||
export enum StackFrameScopeContract {
|
||||
operation = '/operations',
|
||||
api = '/apis',
|
||||
product = '/products',
|
||||
tenant = '/tenant'
|
||||
}
|
||||
|
||||
export interface VariableContract {
|
||||
name: string;
|
||||
type: string;
|
||||
value: any;
|
||||
nestedCount: any;
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
'use strict';
|
||||
|
||||
import * as Net from 'net';
|
||||
import * as vscode from 'vscode';
|
||||
import { CancellationToken, DebugConfiguration, ProviderResult, WorkspaceFolder } from 'vscode';
|
||||
import { ApimDebugSession } from './apimDebug';
|
||||
|
||||
// tslint:disable: no-unsafe-any
|
||||
// tslint:disable: indent
|
||||
// tslint:disable: export-name
|
||||
// tslint:disable: strict-boolean-expressions
|
||||
// tslint:disable: typedef
|
||||
// tslint:disable: no-non-null-assertion
|
||||
// tslint:disable: no-any
|
||||
// tslint:disable: no-empty
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
const provider = new ApimPolicyConfigurationProvider();
|
||||
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('apim-policy', provider));
|
||||
|
||||
const factory = new ApimPolicyDebugAdapterDescriptorFactory();
|
||||
context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory('apim-policy', factory));
|
||||
context.subscriptions.push(factory);
|
||||
}
|
||||
|
||||
export function deactivate() {}
|
||||
|
||||
class ApimPolicyConfigurationProvider implements vscode.DebugConfigurationProvider {
|
||||
public resolveDebugConfiguration(_folder: WorkspaceFolder | undefined, config: DebugConfiguration, _token?: CancellationToken): ProviderResult<DebugConfiguration> {
|
||||
if (!config.type && !config.request && !config.name) {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (editor && editor.document.languageId === 'apim-policy') {
|
||||
config.type = 'apim-policy';
|
||||
config.name = 'Debug open APIM policy';
|
||||
config.request = 'launch';
|
||||
config.stopOnEntry = true;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
class ApimPolicyDebugAdapterDescriptorFactory implements vscode.DebugAdapterDescriptorFactory {
|
||||
|
||||
private server?: Net.Server;
|
||||
|
||||
public createDebugAdapterDescriptor(_session: vscode.DebugSession, _executable: vscode.DebugAdapterExecutable | undefined): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
|
||||
if (!this.server) {
|
||||
// start listening on a random port
|
||||
this.server = Net.createServer(socket => {
|
||||
const session = new ApimDebugSession();
|
||||
session.setRunAsServer(true);
|
||||
session.start(<NodeJS.ReadableStream>socket, socket);
|
||||
}).listen(0);
|
||||
}
|
||||
|
||||
// make VS Code connect to debug server
|
||||
return new vscode.DebugAdapterServer(this.server.address().port);
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
if (this.server) {
|
||||
this.server.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,405 @@
|
|||
|
||||
// tslint:disable: no-unsafe-any
|
||||
// tslint:disable: indent
|
||||
// tslint:disable: export-name
|
||||
// tslint:disable: strict-boolean-expressions
|
||||
// tslint:disable: typedef
|
||||
// tslint:disable: no-non-null-assertion
|
||||
// tslint:disable: no-for-in
|
||||
// tslint:disable: forin
|
||||
// tslint:disable: no-any
|
||||
// tslint:disable: no-reserved-keywords
|
||||
// tslint:disable: interface-name
|
||||
// tslint:disable: no-empty
|
||||
// tslint:disable: prefer-template
|
||||
|
||||
export class PolicyMapper {
|
||||
public static WhiteSpaceCharacters = " \r\n\t";
|
||||
public static NameCharacters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-:";
|
||||
|
||||
private index: number;
|
||||
private xml: string;
|
||||
private map: PolicyMap;
|
||||
private count: {
|
||||
[key: string]: number
|
||||
};
|
||||
private stack: string[];
|
||||
private line: number;
|
||||
private column: number;
|
||||
private capturedLocation: {
|
||||
line: number,
|
||||
column: number,
|
||||
index: number;
|
||||
};
|
||||
|
||||
public mapPolicy(xml: string) {
|
||||
this.index = 0;
|
||||
this.xml = xml;
|
||||
this.count = {};
|
||||
this.map = {};
|
||||
this.stack = [];
|
||||
this.line = 0;
|
||||
this.column = 0;
|
||||
|
||||
while (this.index < this.xml.length && (this.xmlComment() || this.element())) { }
|
||||
|
||||
return this.map;
|
||||
}
|
||||
|
||||
// tslint:disable: cyclomatic-complexity
|
||||
// tslint:disable: max-func-body-length
|
||||
private element() {
|
||||
this.captureLocation();
|
||||
|
||||
let nameStart = -1;
|
||||
let name: string | null = null;
|
||||
let start: [number, number] | null = null;
|
||||
let end: [number, number] | null = null;
|
||||
let selfClosing = false;
|
||||
let closing = false;
|
||||
while (this.index < this.xml.length) {
|
||||
const char = this.xml[this.index];
|
||||
if (char === '<') {
|
||||
if (!start) {
|
||||
start = [this.line, this.column];
|
||||
}
|
||||
} else if (char === '/') {
|
||||
if (!name) {
|
||||
if (nameStart > 0 && !name) {
|
||||
name = this.xml.substring(nameStart, this.index);
|
||||
const curkey = this.stack.length === 0 ? `${name}[1]` : this.stack.join('/') + `/${name}[1]`;
|
||||
//const curkey = this.stack.reduce((a, b) => `${a}/${b}`) + `${name}[1]`;
|
||||
if (this.count[curkey]) {
|
||||
this.stack.push(name + `[${this.count[curkey] + 1}]`);
|
||||
this.count[curkey]++;
|
||||
} else {
|
||||
this.stack.push(name + `[1]`);
|
||||
this.count[curkey] = 1;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!end) {
|
||||
selfClosing = true;
|
||||
} else {
|
||||
closing = true;
|
||||
}
|
||||
} else if (char === '>') {
|
||||
if (nameStart > 0 && !name) {
|
||||
name = this.xml.substring(nameStart, this.index);
|
||||
const curkey = this.stack.length === 0 ? `${name}[1]` : this.stack.join('/') + `/${name}[1]`;
|
||||
if (this.count[curkey]) {
|
||||
this.stack.push(name + `[${this.count[curkey] + 1}]`);
|
||||
this.count[curkey]++;
|
||||
} else {
|
||||
this.stack.push(name + `[1]`);
|
||||
this.count[curkey] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!end && start !== null) {
|
||||
end = [this.line, this.column];
|
||||
this.addElementToMap(start, end);
|
||||
}
|
||||
|
||||
this.advance();
|
||||
if (closing || selfClosing) {
|
||||
this.stack.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.elementValue()) {
|
||||
continue;
|
||||
}
|
||||
} else if (char === '<') {
|
||||
if (end) {
|
||||
closing = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (PolicyMapper.WhiteSpaceCharacters.indexOf(char) >= 0) {
|
||||
if (nameStart >= 0 && !name) {
|
||||
name = this.xml.substring(nameStart, this.index);
|
||||
const curkey = this.stack.length === 0 ? `${name}[1]` : this.stack.join('/') + `/${name}[1]`;
|
||||
if (this.count[curkey]) {
|
||||
this.stack.push(name + `[${this.count[curkey] + 1}]`);
|
||||
this.count[curkey]++;
|
||||
} else {
|
||||
this.stack.push(name + `[1]`);
|
||||
this.count[curkey] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (name && !end && this.attributes()) {
|
||||
continue;
|
||||
}
|
||||
} else if (PolicyMapper.NameCharacters.indexOf(char) >= 0) {
|
||||
if (start && nameStart < 0) {
|
||||
nameStart = this.index;
|
||||
} else if (name && !closing) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
this.advance();
|
||||
}
|
||||
|
||||
this.backtrack();
|
||||
return false;
|
||||
}
|
||||
|
||||
private xmlComment() {
|
||||
this.captureLocation();
|
||||
|
||||
let openCount = 0;
|
||||
let closeCount = 0;
|
||||
while (this.index < this.xml.length) {
|
||||
const char = this.xml[this.index];
|
||||
if (char === '<') {
|
||||
if (openCount === 0) {
|
||||
openCount++;
|
||||
}
|
||||
} else if (char === '!') {
|
||||
if (openCount === 1) {
|
||||
openCount++;
|
||||
} else {
|
||||
openCount = 0;
|
||||
}
|
||||
} else if (char === '-') {
|
||||
if (openCount === 2 || openCount === 3) {
|
||||
openCount++;
|
||||
} else if (openCount === 4) {
|
||||
if (closeCount < 2) {
|
||||
closeCount++;
|
||||
} else {
|
||||
closeCount = 0;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (char === '>') {
|
||||
if (closeCount === 2) {
|
||||
this.advance();
|
||||
return true;
|
||||
}
|
||||
} else if (PolicyMapper.WhiteSpaceCharacters.indexOf(char) >= 0) {
|
||||
if (openCount > 0 && openCount < 4) {
|
||||
break;
|
||||
}
|
||||
|
||||
closeCount = 0;
|
||||
} else {
|
||||
if (openCount < 4) {
|
||||
break;
|
||||
}
|
||||
|
||||
closeCount = 0;
|
||||
}
|
||||
|
||||
this.advance();
|
||||
}
|
||||
|
||||
this.backtrack();
|
||||
return false;
|
||||
}
|
||||
|
||||
private attributes() {
|
||||
let flag = false;
|
||||
while (this.attribute()) {
|
||||
flag = true;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
private attribute() {
|
||||
this.captureLocation();
|
||||
|
||||
let nameStart = -1;
|
||||
let name: string | null = null;
|
||||
let hasValue = false;
|
||||
while (this.index < this.xml.length) {
|
||||
const char = this.xml[this.index];
|
||||
if (char === '=') {
|
||||
if (nameStart >= 0 && !name) {
|
||||
name = this.xml.substring(nameStart, this.index);
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
break;
|
||||
}
|
||||
} else if (char === '"') {
|
||||
if (!name) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasValue) {
|
||||
this.advance();
|
||||
return true;
|
||||
}
|
||||
|
||||
this.advance();
|
||||
if (this.expression()) {
|
||||
hasValue = true;
|
||||
}
|
||||
if (this.simpleValue('"', true)) {
|
||||
hasValue = true;
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (PolicyMapper.WhiteSpaceCharacters.indexOf(char) >= 0) {
|
||||
if (hasValue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nameStart >= 0) {
|
||||
name = this.xml.substring(nameStart, this.index);
|
||||
}
|
||||
} else if (PolicyMapper.NameCharacters.indexOf(char) >= 0) {
|
||||
if (nameStart < 0) {
|
||||
nameStart = this.index;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
this.advance();
|
||||
}
|
||||
|
||||
this.backtrack();
|
||||
return false;
|
||||
}
|
||||
|
||||
private expression() {
|
||||
this.captureLocation();
|
||||
|
||||
let at = false;
|
||||
let openingBracket: string | null = null;
|
||||
let closingBracket: string | null = null;
|
||||
let bracketDepth = -1;
|
||||
while (this.index < this.xml.length) {
|
||||
const char = this.xml[this.index];
|
||||
|
||||
if (char === '@') {
|
||||
if (at) {
|
||||
break;
|
||||
}
|
||||
|
||||
at = true;
|
||||
} else if (char === '{' || char === '(') {
|
||||
if (!at) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!openingBracket) {
|
||||
openingBracket = char;
|
||||
closingBracket = char === '{' ? '}' : ')';
|
||||
bracketDepth = 0;
|
||||
} else if (openingBracket === char) {
|
||||
bracketDepth++;
|
||||
}
|
||||
} else if (char === '}' || char === ')') {
|
||||
if (!openingBracket) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (closingBracket === char && --bracketDepth <= 0) {
|
||||
this.advance();
|
||||
return true;
|
||||
}
|
||||
} else if (bracketDepth >= 0) {
|
||||
// Just advance.
|
||||
} else if (PolicyMapper.WhiteSpaceCharacters.indexOf(char) >= 0) {
|
||||
// Just advance.
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
this.advance();
|
||||
}
|
||||
|
||||
this.backtrack();
|
||||
return false;
|
||||
}
|
||||
|
||||
private simpleValue(terminator: string, allowEmpty: boolean) {
|
||||
this.captureLocation();
|
||||
|
||||
let empty = true;
|
||||
while (this.index < this.xml.length) {
|
||||
const char = this.xml[this.index];
|
||||
|
||||
if (char === terminator) {
|
||||
if (empty && !allowEmpty) {
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
} else if (PolicyMapper.WhiteSpaceCharacters.indexOf(char) < 0) {
|
||||
empty = false;
|
||||
}
|
||||
|
||||
this.advance();
|
||||
}
|
||||
|
||||
this.backtrack();
|
||||
return false;
|
||||
}
|
||||
|
||||
private elementValue() {
|
||||
let flag = false;
|
||||
while (this.expression() || this.xmlComment() || this.element() || this.simpleValue('<', false)) {
|
||||
flag = true;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
private advance() {
|
||||
if (this.xml[this.index] === '\n') {
|
||||
this.line++;
|
||||
this.column = 0;
|
||||
} else {
|
||||
this.column++;
|
||||
}
|
||||
this.index++;
|
||||
}
|
||||
|
||||
private addElementToMap(start: [number, number], end: [number, number]) {
|
||||
const key = this.stack.reduce((a, b) => `${a}/${b}`);
|
||||
|
||||
this.map[key] = {
|
||||
line: start[0],
|
||||
endLine: end[0],
|
||||
column: start[1],
|
||||
endColumn: end[1]
|
||||
};
|
||||
}
|
||||
|
||||
private captureLocation() {
|
||||
this.capturedLocation = {
|
||||
line: this.line,
|
||||
column: this.column,
|
||||
index: this.index
|
||||
};
|
||||
}
|
||||
|
||||
private backtrack() {
|
||||
this.line = this.capturedLocation.line;
|
||||
this.column = this.capturedLocation.column;
|
||||
this.index = this.capturedLocation.index;
|
||||
}
|
||||
}
|
||||
|
||||
export interface PolicyMap {
|
||||
[path: string]: PolicyLocation;
|
||||
}
|
||||
|
||||
export interface PolicyLocation {
|
||||
line: number;
|
||||
endLine: number;
|
||||
column: number;
|
||||
endColumn: number;
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
import { ServiceClientCredentials } from 'ms-rest';
|
||||
import * as path from 'path';
|
||||
import * as request from 'request-promise-native';
|
||||
import { Source } from 'vscode-debugadapter';
|
||||
import { getBearerToken } from '../utils/requestUtil';
|
||||
import { StackFrameScopeContract } from './debuggerConnection';
|
||||
import { PolicyLocation, PolicyMap, PolicyMapper } from './policyMapper';
|
||||
|
||||
// tslint:disable: no-unsafe-any
|
||||
// tslint:disable: indent
|
||||
// tslint:disable: export-name
|
||||
// tslint:disable: strict-boolean-expressions
|
||||
// tslint:disable: no-non-null-assertion
|
||||
// tslint:disable: no-for-in
|
||||
// tslint:disable: forin
|
||||
// tslint:disable: no-shadowed-variable
|
||||
// tslint:disable: interface-name
|
||||
|
||||
export class PolicySource {
|
||||
private static NextSourceReference : number = 1;
|
||||
|
||||
private managementAddress: string;
|
||||
private credential: ServiceClientCredentials | undefined;
|
||||
private auth: string | undefined;
|
||||
private policies: { [key: string]: Policy } = {};
|
||||
|
||||
constructor(managementAddress: string, credential?: ServiceClientCredentials, auth?: string) {
|
||||
this.managementAddress = managementAddress;
|
||||
this.credential = credential;
|
||||
this.auth = auth;
|
||||
if (!credential && !auth) {
|
||||
throw new Error("Missing credentials!");
|
||||
}
|
||||
}
|
||||
|
||||
public getPolicyLocation(scopeId: string, path: string): PolicyLocation | null {
|
||||
const policy = this.policies[this.normalizeScopeId(scopeId)];
|
||||
if (!policy) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Object.keys(policy.map).includes(path)) {
|
||||
return policy.map[path];
|
||||
}
|
||||
|
||||
const paths = path.split("/");
|
||||
const mapKeys = Object.keys(policy.map).map(s => s.split("/")).filter(s => s.length === paths.length);
|
||||
|
||||
for (const curKey of mapKeys) {
|
||||
let isEqual = true;
|
||||
// tslint:disable-next-line: prefer-for-of
|
||||
for (let idx = 0; idx < paths.length; idx++) {
|
||||
if (paths[idx] === curKey[idx]) {
|
||||
continue;
|
||||
} else {
|
||||
isEqual = false;
|
||||
}
|
||||
}
|
||||
if (isEqual === true) {
|
||||
return policy.map[curKey.join("/")];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public async fetchPolicies(scopes: string[]): Promise<void> {
|
||||
const policiesToRequest = scopes.map(s => this.normalizeScopeId(s)).filter(s => !this.policies[s]);
|
||||
|
||||
if (policiesToRequest.length) {
|
||||
// Batching goes here
|
||||
await Promise.all(policiesToRequest.map(s => this.fetchPolicy(s).catch(_e => null)));
|
||||
}
|
||||
}
|
||||
|
||||
public getPolicyBySourceReference(id: number | undefined): Policy | null {
|
||||
for (const scope in this.policies) {
|
||||
const policy = this.policies[scope];
|
||||
if (policy && policy.source && policy.source.sourceReference === id) {
|
||||
return policy;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public getPolicy(scopeId: string): Policy {
|
||||
return this.policies[this.normalizeScopeId(scopeId)];
|
||||
}
|
||||
|
||||
public async fetchPolicy(scopeId: string): Promise<Policy | null> {
|
||||
scopeId = this.normalizeScopeId(scopeId);
|
||||
const policyUrl = this.getPolicyUrl(scopeId);
|
||||
if (!policyUrl) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let authToken;
|
||||
if (this.auth) {
|
||||
authToken = this.auth;
|
||||
} else {
|
||||
authToken = await getBearerToken(policyUrl, "GET", this.credential!);
|
||||
}
|
||||
const policyContract: PolicyContract = await request.get(policyUrl, {
|
||||
headers: {
|
||||
Authorization: authToken
|
||||
},
|
||||
strictSSL: false,
|
||||
json: true
|
||||
}).on('error', _e => {
|
||||
//const a = 5;
|
||||
}).on('response', _e => {
|
||||
//const a = 5;
|
||||
});
|
||||
|
||||
const policy = this.policies[scopeId] || (this.policies[scopeId] = {
|
||||
scopeId: scopeId,
|
||||
xml: null,
|
||||
source: new Source(scopeId, path.normalize(scopeId), PolicySource.NextSourceReference++),
|
||||
map: {}
|
||||
});
|
||||
policy.xml = policyContract.properties.value;
|
||||
|
||||
this.mapPolicy(policy);
|
||||
|
||||
return policy;
|
||||
}
|
||||
|
||||
private normalizeScopeId(scopeId: string): string {
|
||||
return scopeId.replace(/\\/g, '/');
|
||||
}
|
||||
|
||||
private mapPolicy(policy: Policy): void {
|
||||
if (!policy || !policy.xml) {
|
||||
return;
|
||||
}
|
||||
|
||||
policy.map = new PolicyMapper().mapPolicy(policy.xml);
|
||||
}
|
||||
|
||||
private getPolicyUrl(scopeId: string): string {
|
||||
if (scopeId === StackFrameScopeContract.tenant) {
|
||||
return `${this.managementAddress}/policies/policy?api-version=2019-01-01&format=xml-raw`;
|
||||
} else {
|
||||
return `${this.managementAddress}/${scopeId}/policies/policy?api-version=2019-01-01&format=xml-raw`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface PolicyContract {
|
||||
properties: {
|
||||
format: string,
|
||||
value: string
|
||||
};
|
||||
}
|
||||
|
||||
interface Policy {
|
||||
scopeId: string;
|
||||
xml: string | null;
|
||||
source: Source;
|
||||
map: PolicyMap;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
import { PolicySource } from "./policySource";
|
||||
import { UiThread } from "./uiThread";
|
||||
|
||||
// tslint:disable: indent
|
||||
// tslint:disable: export-name
|
||||
|
||||
export class UiRequest {
|
||||
|
||||
public id: string;
|
||||
public threads: UiThread[];
|
||||
private operationId: string;
|
||||
private apiId: string;
|
||||
private productId: string;
|
||||
|
||||
constructor(id: string, operationId: string, apiId: string, productId: string) {
|
||||
this.id = id;
|
||||
this.threads = [];
|
||||
|
||||
this.operationId = operationId;
|
||||
this.apiId = apiId;
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public addNewThread(gatewayThread: number, policySource: PolicySource): UiThread {
|
||||
let thread: UiThread;
|
||||
this.threads.push(thread = new UiThread(gatewayThread, this.operationId, this.apiId, this.productId, policySource));
|
||||
return thread;
|
||||
}
|
||||
|
||||
public findThreadByStackFrameId(id: number): UiThread | null {
|
||||
for (const thread of this.threads) {
|
||||
if (thread.containsStackFrame(id)) {
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public findThreadById(id: number): UiThread | null {
|
||||
for (const thread of this.threads) {
|
||||
if (thread.id === id) {
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public findThreadByUiId(uiId: number): UiThread | null {
|
||||
for (const thread of this.threads) {
|
||||
if (thread.uiId === uiId) {
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
import { StackFrame } from 'vscode-debugadapter';
|
||||
import { DebugProtocol } from 'vscode-debugprotocol';
|
||||
import { StackFrameContract, StackFrameScopeContract } from './debuggerConnection';
|
||||
import { PolicySource } from './policySource';
|
||||
|
||||
// tslint:disable: indent
|
||||
// tslint:disable: export-name
|
||||
// tslint:disable: strict-boolean-expressions
|
||||
// tslint:disable: no-non-null-assertion
|
||||
// tslint:disable: no-for-in
|
||||
// tslint:disable: forin
|
||||
// tslint:disable: interface-name
|
||||
|
||||
interface PendingSource {
|
||||
scopeId: string;
|
||||
stackFrames: StackFrame[];
|
||||
}
|
||||
|
||||
export class UiThread {
|
||||
private static NextThreadId: number = 1;
|
||||
private static NextStackFrameId: number = 1;
|
||||
|
||||
public id: number;
|
||||
public uiId: number;
|
||||
|
||||
private operationId: string;
|
||||
private apiId: string;
|
||||
private productId: string;
|
||||
private stackFrames: {
|
||||
[key: string]: StackFrame
|
||||
} = {};
|
||||
private policySource: PolicySource;
|
||||
|
||||
constructor(id: number, operationId: string, apiId: string, productId: string, policySource: PolicySource) {
|
||||
this.id = id;
|
||||
this.uiId = UiThread.NextThreadId++;
|
||||
|
||||
this.operationId = operationId;
|
||||
this.apiId = apiId;
|
||||
this.productId = productId;
|
||||
this.policySource = policySource;
|
||||
}
|
||||
|
||||
private static addPendingSource(pendingSources: PendingSource[], frame: StackFrameContract, stackFrame: StackFrame): void {
|
||||
let pendingSource = pendingSources.find(s => s.scopeId === frame.scopeId);
|
||||
if (!pendingSource) {
|
||||
pendingSources.push(pendingSource = {
|
||||
scopeId: frame.scopeId,
|
||||
stackFrames: []
|
||||
});
|
||||
}
|
||||
|
||||
pendingSource.stackFrames.push(stackFrame);
|
||||
}
|
||||
|
||||
public containsStackFrame(id: number): boolean {
|
||||
for (const key in this.stackFrames) {
|
||||
if (this.stackFrames[key].id === id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: cyclomatic-complexity
|
||||
public async getStackFrames(frames: StackFrameContract[]): Promise<StackFrame[]> {
|
||||
if (!frames.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Create UI stack frames
|
||||
const stack: {
|
||||
key: string,
|
||||
frame: StackFrameContract,
|
||||
isVirtual?: boolean,
|
||||
stackFrame: StackFrame
|
||||
}[] = [];
|
||||
const allFrames = this.addVirtualStack(frames);
|
||||
const pendingSources: PendingSource[] = [];
|
||||
let prevFrame: StackFrameContract | null = null;
|
||||
let path: string[] = [];
|
||||
for (const frame of allFrames.reverse()) {
|
||||
if (!path.length || prevFrame && (prevFrame.scopeId !== frame.scopeId)) {
|
||||
// tslint:disable-next-line: prefer-template
|
||||
path = ['policies[1]', frame.section + "[1]"];
|
||||
}
|
||||
prevFrame = frame;
|
||||
if (!frame.name.endsWith(']')) {
|
||||
path.push(`${frame.name}[${frame.index || 1}]`);
|
||||
} else {
|
||||
path.push(`${frame.name}`);
|
||||
}
|
||||
const stackFrameKey = path.join('/');
|
||||
|
||||
stack.push({
|
||||
key: stackFrameKey,
|
||||
frame: frame,
|
||||
isVirtual: frame.isVirtual,
|
||||
stackFrame: this.getStackFrame(frame, stackFrameKey, pendingSources)
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch any sources if necessary
|
||||
if (pendingSources.length > 0) {
|
||||
await this.policySource.fetchPolicies(pendingSources.map(p => p.scopeId));
|
||||
}
|
||||
|
||||
// Assign source line numbers as per scope, name, and index
|
||||
for (const item of stack) {
|
||||
const frame = item.frame;
|
||||
const stackFrame = <DebugProtocol.StackFrame>item.stackFrame;
|
||||
|
||||
if (!stackFrame.source) {
|
||||
const policy = this.policySource.getPolicy(frame.scopeId);
|
||||
stackFrame.source = policy && policy.source;
|
||||
}
|
||||
|
||||
const location = this.policySource.getPolicyLocation(frame.scopeId, item.key);
|
||||
if (location) {
|
||||
stackFrame.line = location.line;
|
||||
stackFrame.column = location.column;
|
||||
stackFrame.endLine = location.endLine;
|
||||
stackFrame.endColumn = location.endColumn;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any 'virtual' UI stack frames if no policy present
|
||||
for (let index = 0; index < stack.length;) {
|
||||
if (stack[index].isVirtual && (!stack[index].stackFrame.source || !stack[index].stackFrame.line && !stack[index].stackFrame.column)) {
|
||||
stack.splice(index, 1);
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return stack.map(s => s.stackFrame).reverse();
|
||||
}
|
||||
|
||||
private addVirtualStack(frames: StackFrameContract[]): (StackFrameContract & { isVirtual?: true })[] {
|
||||
const allFrames: (StackFrameContract & { isVirtual?: true })[] = [...frames];
|
||||
|
||||
let lastFrame = allFrames[frames.length - 1];
|
||||
if (lastFrame.scopeId === StackFrameScopeContract.tenant && this.productId) {
|
||||
allFrames.push(lastFrame = {
|
||||
scopeId: `/products/${this.productId}`,
|
||||
name: 'base',
|
||||
section: lastFrame.section,
|
||||
index: 0,
|
||||
isVirtual: true
|
||||
});
|
||||
}
|
||||
|
||||
if ((lastFrame.scopeId === StackFrameScopeContract.tenant || lastFrame.scopeId.startsWith(StackFrameScopeContract.product)) && this.apiId) {
|
||||
allFrames.push(lastFrame = {
|
||||
scopeId: `/apis/${this.apiId}`,
|
||||
name: 'base',
|
||||
section: lastFrame.section,
|
||||
index: 0,
|
||||
isVirtual: true
|
||||
});
|
||||
}
|
||||
|
||||
if (lastFrame.scopeId.startsWith(StackFrameScopeContract.api) && !lastFrame.scopeId.includes('/operations/') && this.apiId && this.operationId) {
|
||||
allFrames.push(lastFrame = {
|
||||
scopeId: `/apis/${this.apiId}/operations/${this.operationId}`,
|
||||
name: 'base',
|
||||
section: lastFrame.section,
|
||||
index: 0,
|
||||
isVirtual: true
|
||||
});
|
||||
}
|
||||
|
||||
return allFrames;
|
||||
}
|
||||
|
||||
private getStackFrame(frame: StackFrameContract, path: string, pendingSources: PendingSource[]): StackFrame {
|
||||
const frameKey = `${frame.scopeId}/${path}`;
|
||||
let stackFrame = this.stackFrames[frameKey];
|
||||
if (!stackFrame) {
|
||||
this.stackFrames[frameKey] = stackFrame = new StackFrame(UiThread.NextStackFrameId++, frame.name);
|
||||
const policy = this.policySource.getPolicy(frame.scopeId);
|
||||
stackFrame.source = policy && policy.source;
|
||||
if (!stackFrame.source) {
|
||||
UiThread.addPendingSource(pendingSources, frame, stackFrame);
|
||||
}
|
||||
}
|
||||
|
||||
return stackFrame;
|
||||
}
|
||||
}
|
|
@ -80,6 +80,10 @@ export class ApiOperationTreeItem extends AzureParentTreeItem<IOperationTreeRoot
|
|||
return await new OperationConsole().buildRequestInfo(this.root);
|
||||
}
|
||||
|
||||
public async getOperationDebugInfo(): Promise<string> {
|
||||
return await new OperationConsole().buildDebugRequestInfo(this.root);
|
||||
}
|
||||
|
||||
private createRoot(subRoot: ISubscriptionRoot): IOperationTreeRoot {
|
||||
return Object.assign({}, <IApiTreeRoot>subRoot, {
|
||||
opName : nonNullProp(this.operationContract, 'name')
|
||||
|
|
|
@ -12,6 +12,7 @@ import { addApiToGateway } from './commands/addApiToGateway';
|
|||
import { addApiToProduct } from './commands/addApiToProduct';
|
||||
import { copySubscriptionKey } from './commands/copySubscriptionKey';
|
||||
import { createService } from './commands/createService';
|
||||
import { debugPolicy } from './commands/debugPolicies/debugPolicy';
|
||||
import { deleteNode } from './commands/deleteNode';
|
||||
import { copyDockerRunCommand, generateKubernetesDeployment } from './commands/deployGateway';
|
||||
import { extractAPI, extractService } from './commands/extract';
|
||||
|
@ -26,6 +27,7 @@ import { openWorkingFolder } from './commands/openWorkingFolder';
|
|||
import { setupWorkingFolder } from './commands/setupWorkingFolder';
|
||||
import { testOperation } from './commands/testOperation';
|
||||
import { doubleClickDebounceDelay } from './constants';
|
||||
import { activate } from './debugger/extension';
|
||||
import { ApiManagementProvider } from './explorer/ApiManagementProvider';
|
||||
import { ApiOperationTreeItem } from './explorer/ApiOperationTreeItem';
|
||||
import { ApiPolicyTreeItem } from './explorer/ApiPolicyTreeItem';
|
||||
|
@ -99,11 +101,14 @@ export function activateInternal(context: vscode.ExtensionContext) {
|
|||
registerCommand('azureApiManagement.copyDockerRunCommand', async (node: GatewayTreeItem) => await copyDockerRunCommand(node));
|
||||
registerCommand('azureApiManagement.generateKubernetesDeployment', async (node: GatewayTreeItem) => await generateKubernetesDeployment(node));
|
||||
registerCommand('azureApiManagement.generateNewGatewayToken', async (node: GatewayTreeItem) => await generateNewGatewayToken(node));
|
||||
registerCommand('azureApiManagement.debugPolicy', async (node: ApiOperationTreeItem) => await debugPolicy(node));
|
||||
|
||||
registerCommand('azureApiManagement.openExtensionWorkspaceFolder', openWorkingFolder);
|
||||
registerCommand('azureApiManagement.initializeExtensionWorkspaceFolder', setupWorkingFolder);
|
||||
|
||||
registerEditors(context);
|
||||
|
||||
activate(context); // activeta debug context
|
||||
}
|
||||
|
||||
function registerEditors(context: vscode.ExtensionContext) : void {
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ApiContract, ApiRevisionContract } from "azure-arm-apimanagement/lib/models";
|
||||
import { ApimService } from "../azure/apim/ApimService";
|
||||
import { IMasterSubscription } from "../azure/apim/contracts";
|
||||
import { IOperationTreeRoot } from "../explorer/IOperationTreeRoot";
|
||||
import { nonNullOrEmptyValue, nonNullProp } from "../utils/nonNull";
|
||||
import { ConsoleOperation } from "./ConsoleOperation";
|
||||
|
@ -45,6 +47,77 @@ export class OperationConsole {
|
|||
return requestSummary;
|
||||
}
|
||||
|
||||
public async buildDebugRequestInfo(root: IOperationTreeRoot): Promise<string> {
|
||||
const results = await Promise.all([
|
||||
root.client.apiManagementService.get(root.resourceGroupName, root.serviceName),
|
||||
root.client.api.get(root.resourceGroupName, root.serviceName, root.apiName),
|
||||
root.client.apiOperation.get(root.resourceGroupName, root.serviceName, root.apiName, root.opName),
|
||||
root.client.apiRevision.listByService(root.resourceGroupName, root.serviceName, root.apiName)]);
|
||||
|
||||
const service = results[0];
|
||||
const api = results[1];
|
||||
const operation = results[2];
|
||||
|
||||
const hostName = nonNullProp(service, "gatewayUrl").split("/")[2];
|
||||
const consoleOperation = new ConsoleOperation(hostName, operation);
|
||||
let revision: ApiRevisionContract | undefined;
|
||||
|
||||
if (api.apiRevision) {
|
||||
const revisions = results[3];
|
||||
revision = revisions.find((r) => r.apiRevision === api.apiRevision);
|
||||
}
|
||||
|
||||
const url = `${this.getRequestUrl(consoleOperation, api, revision)}`;
|
||||
const method = consoleOperation.method;
|
||||
|
||||
let requestSummary = `${method} ${url} HTTP/1.1\n`;
|
||||
|
||||
const headers = this.getDebugHeaders();
|
||||
const apimService = new ApimService(root.credentials, root.environment.resourceManagerEndpointUrl, root.subscriptionId, root.resourceGroupName, root.serviceName);
|
||||
const masterSubscriptionObj = await apimService.getSubscriptionMasterkey();
|
||||
const masterSubscription = <IMasterSubscription>JSON.parse(masterSubscriptionObj);
|
||||
headers.forEach(header => {
|
||||
requestSummary += `${header}: ${masterSubscription.properties.primaryKey}\n`;
|
||||
});
|
||||
requestSummary += "Ocp-Apim-Trace: true\n";
|
||||
if (consoleOperation.request.body) {
|
||||
requestSummary += `\n\n${consoleOperation.request.body}`;
|
||||
}
|
||||
|
||||
return requestSummary;
|
||||
}
|
||||
|
||||
// public async buildDebugRequestInfo(root: IOperationTreeRoot): Promise<string> {
|
||||
// const operation = await root.client.apiOperation.get(root.resourceGroupName, root.serviceName, root.apiName, root.opName);
|
||||
// const url = getAPIHostUrl(root.serviceName);
|
||||
// const method = operation.method;
|
||||
// let body: string | undefined;
|
||||
// if (operation.request && operation.request.representations && operation.request.representations.length > 0) {
|
||||
// if (operation.request.representations[0].sample) {
|
||||
// body = operation.request.representations[0].sample;
|
||||
// }
|
||||
// }
|
||||
// let requestSummary = `${method} ${url} HTTP/1.1\n`;
|
||||
|
||||
// const headers = this.getDebugHeaders();
|
||||
// const apimService = new ApimService(root.credentials, root.environment.resourceManagerEndpointUrl, root.subscriptionId, root.resourceGroupName, root.serviceName);
|
||||
// const masterSubscriptionObj = await apimService.getSubscriptionMasterkey();
|
||||
// const masterSubscription = <IMasterSubscription>JSON.parse(masterSubscriptionObj);
|
||||
// headers.forEach(header => {
|
||||
// requestSummary += `${header}: ${masterSubscription.properties.primaryKey}\n`;
|
||||
// });
|
||||
|
||||
// if (body) {
|
||||
// requestSummary += `\n\n${body}`;
|
||||
// }
|
||||
|
||||
// return requestSummary;
|
||||
// }
|
||||
|
||||
private getDebugHeaders(): string[] {
|
||||
return ["Ocp-Apim-Subscription-Key", "Ocp-Apim-Debug"];
|
||||
}
|
||||
|
||||
private getRequestUrl(consoleOperation: ConsoleOperation, api: ApiContract, revision: ApiRevisionContract | undefined): string {
|
||||
const protocol = nonNullProp(api, "protocols").indexOf("https") !== -1 ? "https" : "http";
|
||||
let urlTemplate = this.requestUrl(consoleOperation, api, revision);
|
||||
|
|
|
@ -39,3 +39,20 @@ export async function requestUtil<T>(url: string, credentials?: ServiceClientCre
|
|||
export async function sendRequest<T>(httpReq: nRequest): Promise<T> {
|
||||
return await <Thenable<T>>request(httpReq).promise();
|
||||
}
|
||||
|
||||
export async function getBearerToken(url: string, method: HttpMethods, credentials: ServiceClientCredentials): Promise<string> {
|
||||
const requestOptions: WebResource = new WebResource();
|
||||
requestOptions.headers = {
|
||||
['User-Agent']: appendExtensionUserAgent()
|
||||
};
|
||||
requestOptions.url = url;
|
||||
requestOptions.method = method;
|
||||
try {
|
||||
await signRequest(requestOptions, credentials);
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
const headers = requestOptions.headers;
|
||||
// tslint:disable-next-line: no-string-literal
|
||||
return headers['authorization'];
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
},
|
||||
"linterOptions": {
|
||||
"exclude": [
|
||||
"src/test/**" // Enable back when tests are ready.
|
||||
"src/test/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче