diff --git a/package-lock.json b/package-lock.json index 31da63d8893..c833746e759 100644 --- a/package-lock.json +++ b/package-lock.json @@ -208,10 +208,13 @@ "dev": true }, "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "2.1.2" + } }, "assert-plus": { "version": "1.0.0", @@ -256,9 +259,9 @@ "dev": true }, "aws4": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, "babel-code-frame": { @@ -299,9 +302,9 @@ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" }, "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "optional": true, "requires": { @@ -323,15 +326,6 @@ "inherits": "2.0.3" } }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "dev": true, - "requires": { - "hoek": "4.2.1" - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -350,7 +344,7 @@ "requires": { "expand-range": "1.8.2", "preserve": "0.2.0", - "repeat-element": "1.1.2" + "repeat-element": "1.1.3" } }, "browser-stdout": { @@ -376,9 +370,9 @@ "dev": true }, "buffer-from": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", - "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "builtin-modules": { @@ -387,6 +381,12 @@ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -424,6 +424,34 @@ } } }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, "clone": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", @@ -459,6 +487,12 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, "color-convert": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", @@ -513,24 +547,15 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "boom": "5.2.0" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "dev": true, - "requires": { - "hoek": "4.2.1" - } - } + "lru-cache": "4.1.3", + "shebang-command": "1.2.0", + "which": "1.3.1" } }, "dashdash": { @@ -557,6 +582,12 @@ "ms": "2.0.0" } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, "deep-assign": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", @@ -620,9 +651,9 @@ } }, "duplexify": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz", - "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", + "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", "dev": true, "requires": { "end-of-stream": "1.4.1", @@ -632,13 +663,14 @@ } }, "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "0.1.1", + "safer-buffer": "2.1.2" } }, "end-of-stream": { @@ -688,6 +720,21 @@ "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", @@ -703,13 +750,13 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "2.2.3" + "fill-range": "2.2.4" } }, "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, "extend-shallow": { @@ -768,9 +815,9 @@ "dev": true }, "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, "requires": { "pend": "1.2.0" @@ -783,18 +830,27 @@ "dev": true }, "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "requires": { "is-number": "2.1.0", "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", + "randomatic": "3.1.0", + "repeat-element": "1.1.3", "repeat-string": "1.6.1" } }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, "first-chunk-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", @@ -830,7 +886,7 @@ "requires": { "asynckit": "0.4.0", "combined-stream": "1.0.6", - "mime-types": "2.1.18" + "mime-types": "2.1.19" } }, "from": { @@ -867,6 +923,18 @@ "rimraf": "2.6.2" } }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -942,7 +1010,7 @@ "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", "dev": true, "requires": { - "extend": "3.0.1", + "extend": "3.0.2", "glob": "5.0.15", "glob-parent": "3.1.0", "micromatch": "2.3.11", @@ -1007,7 +1075,7 @@ "integrity": "sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw==", "dev": true, "requires": { - "sparkles": "1.0.0" + "sparkles": "1.0.1" } }, "graceful-fs": { @@ -1097,15 +1165,15 @@ "requires": { "event-stream": "3.3.4", "node.extend": "1.1.6", - "request": "2.85.0", + "request": "2.88.0", "through2": "2.0.3", - "vinyl": "2.1.0" + "vinyl": "2.2.0" }, "dependencies": { "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, "clone-stats": { @@ -1115,12 +1183,12 @@ "dev": true }, "vinyl": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", - "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", "dev": true, "requires": { - "clone": "2.1.1", + "clone": "2.1.2", "clone-buffer": "1.0.0", "clone-stats": "1.0.0", "cloneable-readable": "1.1.2", @@ -1181,16 +1249,41 @@ } }, "gulp-untar": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/gulp-untar/-/gulp-untar-0.0.6.tgz", - "integrity": "sha1-1r3v3n6ajgVMnxYjhaB4LEvnQAA=", + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/gulp-untar/-/gulp-untar-0.0.7.tgz", + "integrity": "sha512-0QfbCH2a1k2qkTLWPqTX+QO4qNsHn3kC546YhAP3/n0h+nvtyGITDuDrYBMDZeW4WnFijmkOvBWa5HshTic1tw==", "dev": true, "requires": { "event-stream": "3.3.4", - "gulp-util": "3.0.8", "streamifier": "0.1.1", "tar": "2.2.1", - "through2": "2.0.3" + "through2": "2.0.3", + "vinyl": "1.2.0" + }, + "dependencies": { + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.4", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + } } }, "gulp-util": { @@ -1276,18 +1369,18 @@ "dev": true, "requires": { "event-stream": "3.3.4", - "queue": "4.4.2", + "queue": "4.5.0", "through2": "2.0.3", - "vinyl": "2.1.0", + "vinyl": "2.2.0", "vinyl-fs": "2.4.4", - "yauzl": "2.9.1", + "yauzl": "2.10.0", "yazl": "2.4.3" }, "dependencies": { "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, "clone-stats": { @@ -1297,21 +1390,21 @@ "dev": true }, "queue": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-4.4.2.tgz", - "integrity": "sha512-fSMRXbwhMwipcDZ08enW2vl+YDmAmhcNcr43sCJL8DIg+CFOsoRLG23ctxA+fwNk1w55SePSiS7oqQQSgQoVJQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/queue/-/queue-4.5.0.tgz", + "integrity": "sha512-DwxpAnqJuoQa+wyDgQuwkSshkhlqIlWEvwvdAY27fDPunZ2cVJzXU4JyjY+5l7zs7oGLaYAQm4MbLOVFAHFBzA==", "dev": true, "requires": { "inherits": "2.0.3" } }, "vinyl": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", - "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", "dev": true, "requires": { - "clone": "2.1.1", + "clone": "2.1.2", "clone-buffer": "1.0.0", "clone-stats": "1.0.0", "cloneable-readable": "1.1.2", @@ -1337,9 +1430,9 @@ "dev": true }, "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", + "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", "dev": true, "requires": { "ajv": "5.5.2", @@ -1367,19 +1460,7 @@ "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", "dev": true, "requires": { - "sparkles": "1.0.0" - } - }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "dev": true, - "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.1", - "sntp": "2.1.0" + "sparkles": "1.0.1" } }, "he": { @@ -1388,12 +1469,6 @@ "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", - "dev": true - }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -1402,7 +1477,16 @@ "requires": { "assert-plus": "1.0.0", "jsprim": "1.4.1", - "sshpk": "1.14.1" + "sshpk": "1.14.2" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": "2.1.2" } }, "ieee754": { @@ -1426,6 +1510,12 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, "is": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz", @@ -1465,6 +1555,12 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", @@ -1541,6 +1637,12 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", @@ -1652,6 +1754,25 @@ "readable-stream": "2.3.6" } }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + } + }, "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", @@ -1782,12 +1903,37 @@ "lodash.escape": "3.2.0" } }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, "map-stream": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", "dev": true }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "dev": true + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "1.2.0" + } + }, "merge-stream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", @@ -1854,20 +2000,26 @@ } }, "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", + "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==", "dev": true }, "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "version": "2.1.19", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", + "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", "dev": true, "requires": { - "mime-db": "1.33.0" + "mime-db": "1.35.0" } }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -7108,10 +7260,25 @@ } } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, "object-assign": { @@ -7149,6 +7316,47 @@ "readable-stream": "2.3.6" } }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.3.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", @@ -7184,12 +7392,24 @@ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", @@ -7242,6 +7462,18 @@ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "dev": true + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -7249,9 +7481,9 @@ "dev": true }, "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "querystring": { @@ -7275,43 +7507,27 @@ } }, "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", + "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "4.0.0", + "kind-of": "6.0.2", + "math-random": "1.0.1" }, "dependencies": { "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true }, "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true } } }, @@ -7346,9 +7562,9 @@ "dev": true }, "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", "dev": true }, "repeat-string": { @@ -7364,35 +7580,45 @@ "dev": true }, "request": { - "version": "2.85.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", - "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "dev": true, "requires": { "aws-sign2": "0.7.0", - "aws4": "1.7.0", + "aws4": "1.8.0", "caseless": "0.12.0", "combined-stream": "1.0.6", - "extend": "3.0.1", + "extend": "3.0.2", "forever-agent": "0.6.1", "form-data": "2.3.2", - "har-validator": "5.0.3", - "hawk": "6.0.2", + "har-validator": "5.1.0", "http-signature": "1.2.0", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", + "mime-types": "2.1.19", + "oauth-sign": "0.9.0", "performance-now": "2.1.0", - "qs": "6.5.1", + "qs": "6.5.2", "safe-buffer": "5.1.2", - "stringstream": "0.0.5", - "tough-cookie": "2.3.4", + "tough-cookie": "2.4.3", "tunnel-agent": "0.6.0", - "uuid": "3.2.1" + "uuid": "3.3.2" } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -7423,6 +7649,12 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", @@ -7434,15 +7666,33 @@ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { - "hoek": "4.2.1" + "shebang-regex": "1.0.0" } }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -7450,19 +7700,19 @@ "dev": true }, "source-map-support": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.5.tgz", - "integrity": "sha512-mR7/Nd5l1z6g99010shcXJiNEaf3fEtmLhRB/sBcQVJGodcHCULPp2y4Sfa43Kv2zq7T+Izmfp/WHCR6dYkQCA==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", + "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", "dev": true, "requires": { - "buffer-from": "1.0.0", + "buffer-from": "1.1.1", "source-map": "0.6.1" } }, "sparkles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", - "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", "dev": true }, "split": { @@ -7481,18 +7731,19 @@ "dev": true }, "sshpk": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", - "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", "dev": true, "requires": { - "asn1": "0.2.3", + "asn1": "0.2.4", "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", + "bcrypt-pbkdf": "1.0.2", "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", + "ecc-jsbn": "0.1.2", "getpass": "0.1.7", "jsbn": "0.1.1", + "safer-buffer": "2.1.2", "tweetnacl": "0.14.5" } }, @@ -7532,6 +7783,33 @@ "integrity": "sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8=", "dev": true }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -7541,12 +7819,6 @@ "safe-buffer": "5.1.2" } }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -7575,6 +7847,12 @@ "strip-bom": "2.0.0" } }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -7645,11 +7923,12 @@ } }, "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "dev": true, "requires": { + "psl": "1.1.29", "punycode": "1.4.1" } }, @@ -7742,9 +8021,9 @@ } }, "url-parse": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.0.tgz", - "integrity": "sha512-ERuGxDiQ6Xw/agN4tuoCRbmwRuZP0cJ1lJxJubXr5Q/5cDa78+Dc4wfvtxzhzhkm5VvmW6Mf8EVj9SPGN4l8Lg==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz", + "integrity": "sha512-rh+KuAW36YKo0vClhQzLLveoj8FwPJNu65xLb7Mrt+eZht0IPT0IXgSv8gcMegZ6NvjJUALf6Mf25POlMwD1Fw==", "dev": true, "requires": { "querystringify": "2.0.0", @@ -7758,9 +8037,9 @@ "dev": true }, "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", "dev": true }, "vali-date": { @@ -7796,7 +8075,7 @@ "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", "dev": true, "requires": { - "duplexify": "3.5.4", + "duplexify": "3.6.0", "glob-stream": "5.3.5", "graceful-fs": "4.1.11", "gulp-sourcemaps": "1.6.0", @@ -7851,9 +8130,9 @@ } }, "vscode": { - "version": "1.1.17", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.17.tgz", - "integrity": "sha512-yNMyrgEua2qyW7+trNNYhA6PeldRrBcwtLtlazkdtzcmkHMKECM/08bPF8HF2ZFuwHgD+8FQsdqd/DvJYQYjJg==", + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.21.tgz", + "integrity": "sha512-tJl9eL15ZMm6vzCYYeQ26sSYRuXGMGPsaeIAmG2rOOYRn01jdaDg6I4b9G5Ed6FISdmn6egpKThk4o4om8Ax/A==", "dev": true, "requires": { "glob": "7.1.2", @@ -7862,21 +8141,136 @@ "gulp-gunzip": "1.0.0", "gulp-remote-src-vscode": "0.5.0", "gulp-symdest": "1.1.0", - "gulp-untar": "0.0.6", + "gulp-untar": "0.0.7", "gulp-vinyl-zip": "2.1.0", "mocha": "4.1.0", - "request": "2.85.0", + "request": "2.88.0", "semver": "5.5.0", - "source-map-support": "0.5.5", - "url-parse": "1.4.0", + "source-map-support": "0.5.9", + "url-parse": "1.4.3", "vinyl-source-stream": "1.1.2" } }, + "vscode-nls": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", + "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" + }, + "vscode-nls-dev": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/vscode-nls-dev/-/vscode-nls-dev-3.2.1.tgz", + "integrity": "sha512-5VNgsI/fTJRISBLXEdfKC/A1RzpvR93pWcEYMbWjv9rvIkqpMLCdFieKaSgtaQqEAGLuTxFZkPUluR/IRzyVBA==", + "dev": true, + "requires": { + "clone": "2.1.2", + "event-stream": "3.3.4", + "glob": "7.1.2", + "gulp-util": "3.0.8", + "iconv-lite": "0.4.23", + "is": "3.2.1", + "source-map": "0.6.1", + "typescript": "2.8.3", + "vinyl": "2.2.0", + "xml2js": "0.4.19", + "yargs": "10.1.2" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dev": true, + "requires": { + "clone": "2.1.2", + "clone-buffer": "1.0.0", + "clone-stats": "1.0.0", + "cloneable-readable": "1.1.2", + "remove-trailing-separator": "1.1.0", + "replace-ext": "1.0.0" + } + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "requires": { + "sax": "1.2.1", + "xmlbuilder": "9.0.7" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true + } + } + }, "vue": { "version": "2.5.16", "resolved": "https://registry.npmjs.org/vue/-/vue-2.5.16.tgz", "integrity": "sha512-/ffmsiVuPC8PsWcFkZngdpas19ABm5mh2wA7iDqcltyCTwlgZjHGeJYOXkBMo422iPwIcviOtrTCUpSfXmToLQ==" }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -7906,14 +8300,55 @@ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", + "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", + "dev": true, + "requires": { + "cliui": "4.1.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.3", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "8.1.0" + } + }, + "yargs-parser": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", + "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + }, "yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, "requires": { "buffer-crc32": "0.2.13", - "fd-slicer": "1.0.1" + "fd-slicer": "1.1.0" } }, "yazl": { diff --git a/package.json b/package.json index f44d6dc3aa8..c1b30820037 100644 --- a/package.json +++ b/package.json @@ -5,14 +5,16 @@ "version": "0.0.1", "publisher": "amazonwebservices", "engines": { - "vscode": "^1.23.0" + "vscode": "^1.26.0" }, "categories": [ "Other" ], "activationEvents": [ - "onCommand:aws.selectProfile", - "onCommand:aws.selectRegion", + "onCommand:aws.login", + "onCommand:aws.logout", + "onCommand:aws.addExplorerRegion", + "onCommand:aws.removeExplorerRegion", "onView:lambda", "onCommand:aws.newLambda", "onCommand:aws.invokeLambda", @@ -24,17 +26,17 @@ "contributes": { "configuration": { "type": "object", - "title": "AWS Configuration", + "title": "%AWS.configuration.title%", "properties": { "aws.region": { "type": "string", "default": "", - "description": "The default region for your AWS resources" + "description": "%AWS.configuration.regionDescription%" }, "aws.profile": { "type": "string", "default": "", - "description": "The name of the credential profile to obtain credentials from" + "description": "%AWS.configuration.profileDescription%" } } }, @@ -42,7 +44,7 @@ "activitybar": [ { "id": "aws-explorer", - "title": "AWS", + "title": "%AWS.title%", "icon": "media/aws-logo.svg" } ] @@ -51,36 +53,26 @@ "aws-explorer": [ { "id": "lambda", - "name": "Lambda" + "name": "%AWS.lambda.explorerTitle%" } ] }, "menus": { "view/title": [ - { - "command": "aws.selectProfile", - "when": "view == lambda", - "group": "navigation@1" - }, - { - "command": "aws.selectRegion", - "when": "view == lambda", - "group": "navigation@2" - }, { "command": "aws.newLambda", "when": "view == lambda", - "group": "navigation@3" + "group": "navigation@2" }, { "command": "aws.deployLambda", "when": "view == lambda", - "group": "navigation@4" + "group": "navigation@3" }, { "command": "aws.invokeLambda", "when": "view == lambda", - "group": "navigation@5" + "group": "navigation@4" } ], "view/item/context": [ @@ -108,26 +100,28 @@ }, "commands": [ { - "command": "aws.selectProfile", - "title": "Select a credential profile", - "category": "AWS", - "icon": { - "light": "resources/light/select_profile.svg", - "dark": "resources/dark/select_profile.svg" - } + "command": "aws.login", + "title": "%AWS.command.login%", + "category": "AWS" }, { - "command": "aws.selectRegion", - "title": "Select a region", - "category": "AWS", - "icon": { - "light": "resources/light/select_region.svg", - "dark": "resources/dark/select_region.svg" - } + "command": "aws.logout", + "title": "%AWS.command.logout%", + "category": "AWS" + }, + { + "command": "aws.addExplorerRegion", + "title": "%AWS.command.addExplorerRegion%", + "category": "AWS" + }, + { + "command": "aws.removeExplorerRegion", + "title": "%AWS.command.removeExplorerRegion%", + "category": "AWS" }, { "command": "aws.newLambda", - "title": "%AWS.newLambda%", + "title": "%AWS.command.newLambda%", "category": "AWS", "icon": { "light": "resources/light/new_lambda.svg", @@ -136,7 +130,7 @@ }, { "command": "aws.deployLambda", - "title": "%AWS.deployLambda%", + "title": "%AWS.command.deployLambda%", "category": "AWS", "icon": { "light": "resources/light/deploy_lambda.svg", @@ -145,7 +139,7 @@ }, { "command": "aws.invokeLambda", - "title": "%AWS.invokeLambda%", + "title": "%AWS.command.invokeLambda%", "category": "AWS", "icon": { "light": "resources/light/invoke_lambda.svg", @@ -154,12 +148,12 @@ }, { "command": "aws.getLambdaConfig", - "title": "%AWS.getLambdaConfig%", + "title": "%AWS.command.getLambdaConfig%", "category": "AWS" }, { "command": "aws.getLambdaPolicy", - "title": "%AWS.getLambdaPolicy%", + "title": "%AWS.command.getLambdaPolicy%", "category": "AWS" } ] @@ -181,13 +175,15 @@ "@types/xml2js": "^0.4.3", "tslint": "^5.8.0", "typescript": "^2.6.1", - "vscode": "^1.1.6" + "vscode": "^1.1.21", + "vscode-nls-dev": "^3.2.1" }, "dependencies": { "aws-sdk": "^2.227.1", "fs-extra": "^6.0.1", "lodash": "^4.17.10", "npm": "^6.1.0", - "vue": "^2.5.16" + "vue": "^2.5.16", + "vscode-nls": "^3.2.4" } } diff --git a/package.nls.json b/package.nls.json index 3dd45791ad5..d87e8b20d6a 100644 --- a/package.nls.json +++ b/package.nls.json @@ -1,7 +1,23 @@ { - "AWS.newLambda": "New Lambda Function or Serverless App", - "AWS.deployLambda": "Deploy Lambda Function", - "AWS.invokeLambda": "Invoke Lambda Function", - "AWS.getLambdaConfig": "Get Lambda Function Configuration", - "AWS.getLambdaPolicy": "Get Lambda Function Policy" + "AWS.title": "AWS", + "AWS.configuration.regionDescription": "The regions to query for resources to display in the Explorer.", + "AWS.configuration.profileDescription": "The name of the credential profile to obtain credentials from.", + "AWS.configuration.title": "AWS Configuration", + "AWS.command.login": "Sign in to AWS", + "AWS.command.logout": "Sign out", + "AWS.command.addExplorerRegion": "Add a region to the Explorer", + "AWS.command.removeExplorerRegion": "Remove a region from the Explorer", + "AWS.command.newLambda": "New Lambda Function or Serverless App", + "AWS.command.deployLambda": "Deploy Lambda Function", + "AWS.command.invokeLambda": "Invoke Lambda Function", + "AWS.command.getLambdaConfig": "Get Lambda Function Configuration", + "AWS.command.getLambdaPolicy": "Get Lambda Function Policy", + "AWS.explorerNode.addRegion": "Add a region to view functions...", + "AWS.explorerNode.addRegion.tooltip": "Click to add a region to view functions...", + "AWS.explorerNode.lambda.noFunctions": "..no functions in this region...", + "AWS.explorerNode.signIn": "Sign in to AWS...", + "AWS.explorerNode.signIn.tooltip": "Connect to AWS using a credential profile", + "AWS.lambda.explorerTitle": "Lambda", + "AWS.message.enterProfileName": "Enter the name of the credential profile to use", + "AWS.message.selectRegion": "Select an AWS region" } \ No newline at end of file diff --git a/resources/endpoints.json b/resources/endpoints.json new file mode 100644 index 00000000000..0db1345f1f3 --- /dev/null +++ b/resources/endpoints.json @@ -0,0 +1,1010 @@ +{ + "partitions" : [ { + "defaults" : { + "hostname" : "{service}.{region}.{dnsSuffix}", + "protocols" : [ "https" ], + "signatureVersions" : [ "v4" ] + }, + "dnsSuffix" : "amazonaws.com", + "partition" : "aws", + "partitionName" : "AWS Standard", + "regionRegex" : "^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$", + "regions" : { + "ap-northeast-1" : { + "description" : "Asia Pacific (Tokyo)" + }, + "ap-northeast-2" : { + "description" : "Asia Pacific (Seoul)" + }, + "ap-south-1" : { + "description" : "Asia Pacific (Mumbai)" + }, + "ap-southeast-1" : { + "description" : "Asia Pacific (Singapore)" + }, + "ap-southeast-2" : { + "description" : "Asia Pacific (Sydney)" + }, + "ca-central-1" : { + "description" : "Canada (Central)" + }, + "eu-central-1" : { + "description" : "EU (Frankfurt)" + }, + "eu-west-1" : { + "description" : "EU (Ireland)" + }, + "eu-west-2" : { + "description" : "EU (London)" + }, + "eu-west-3" : { + "description" : "EU (Paris)" + }, + "sa-east-1" : { + "description" : "South America (Sao Paulo)" + }, + "us-east-1" : { + "description" : "US East (N. Virginia)" + }, + "us-east-2" : { + "description" : "US East (Ohio)" + }, + "us-west-1" : { + "description" : "US West (N. California)" + }, + "us-west-2" : { + "description" : "US West (Oregon)" + } + }, + "services" : { + "autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "cloudformation" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "cloudfront" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "cloudfront.amazonaws.com", + "protocols" : [ "http", "https" ] + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "codecommit" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "codedeploy" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "codestar" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "dynamodb" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "local" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "localhost:8000", + "protocols" : [ "http" ] + }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "ec2" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "ecr" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "ecs" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "elasticbeanstalk" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "elasticloadbalancing" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "events" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "iam" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "iam.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "kinesis" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "kms" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "lambda" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "logs" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "monitoring" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "opsworks" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "rds" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "sslCommonName" : "{service}.{dnsSuffix}" + }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "s3" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "signatureVersions" : [ "s3v4" ] + }, + "endpoints" : { + "ap-northeast-1" : { + "hostname" : "s3.ap-northeast-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ] + }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { + "hostname" : "s3.ap-southeast-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ] + }, + "ap-southeast-2" : { + "hostname" : "s3.ap-southeast-2.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ] + }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { + "hostname" : "s3.eu-west-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ] + }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "s3-external-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "s3-external-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ] + }, + "sa-east-1" : { + "hostname" : "s3.sa-east-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ] + }, + "us-east-1" : { + "hostname" : "s3.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ] + }, + "us-east-2" : { }, + "us-west-1" : { + "hostname" : "s3.us-west-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ] + }, + "us-west-2" : { + "hostname" : "s3.us-west-2.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ] + } + }, + "isRegionalized" : true, + "partitionEndpoint" : "us-east-1" + }, + "sdb" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "signatureVersions" : [ "v2" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-west-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "hostname" : "sdb.amazonaws.com" + }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "sns" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "sqs" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "sslCommonName" : "{region}.queue.{dnsSuffix}" + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "sqs-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "sqs-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "sqs-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "sqs-fips.us-west-2.amazonaws.com" + }, + "sa-east-1" : { }, + "us-east-1" : { + "sslCommonName" : "queue.{dnsSuffix}" + }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "streams.dynamodb" : { + "defaults" : { + "credentialScope" : { + "service" : "dynamodb" + }, + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "local" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "localhost:8000", + "protocols" : [ "http" ] + }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "xray" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + } + } + }, { + "defaults" : { + "hostname" : "{service}.{region}.{dnsSuffix}", + "protocols" : [ "https" ], + "signatureVersions" : [ "v4" ] + }, + "dnsSuffix" : "amazonaws.com.cn", + "partition" : "aws-cn", + "partitionName" : "AWS China", + "regionRegex" : "^cn\\-\\w+\\-\\d+$", + "regions" : { + "cn-north-1" : { + "description" : "China (Beijing)" + }, + "cn-northwest-1" : { + "description" : "China (Ningxia)" + } + }, + "services" : { + "autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "cloudformation" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "codedeploy" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "dynamodb" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "ec2" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "ecr" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "ecs" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "elasticbeanstalk" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "elasticloadbalancing" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "events" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "iam" : { + "endpoints" : { + "aws-cn-global" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "iam.cn-north-1.amazonaws.com.cn" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-cn-global" + }, + "kinesis" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "lambda" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "logs" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "monitoring" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "rds" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "s3" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "signatureVersions" : [ "s3v4" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "sns" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "sqs" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "sslCommonName" : "{region}.queue.{dnsSuffix}" + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "streams.dynamodb" : { + "defaults" : { + "credentialScope" : { + "service" : "dynamodb" + }, + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + } + } + }, { + "defaults" : { + "hostname" : "{service}.{region}.{dnsSuffix}", + "protocols" : [ "https" ], + "signatureVersions" : [ "v4" ] + }, + "dnsSuffix" : "amazonaws.com", + "partition" : "aws-us-gov", + "partitionName" : "AWS GovCloud (US)", + "regionRegex" : "^us\\-gov\\-\\w+\\-\\d+$", + "regions" : { + "us-gov-west-1" : { + "description" : "AWS GovCloud (US)" + } + }, + "services" : { + "autoscaling" : { + "endpoints" : { + "us-gov-west-1" : { + "protocols" : [ "http", "https" ] + } + } + }, + "cloudformation" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "codedeploy" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "dynamodb" : { + "endpoints" : { + "us-gov-west-1" : { }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "dynamodb.us-gov-west-1.amazonaws.com" + } + } + }, + "ec2" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "ecr" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "ecs" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "elasticbeanstalk" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "elasticloadbalancing" : { + "endpoints" : { + "us-gov-west-1" : { + "protocols" : [ "http", "https" ] + } + } + }, + "events" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "iam" : { + "endpoints" : { + "aws-us-gov-global" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "iam.us-gov.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-us-gov-global" + }, + "kinesis" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "kms" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "lambda" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "logs" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "monitoring" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "rds" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "s3" : { + "defaults" : { + "signatureVersions" : [ "s3", "s3v4" ] + }, + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "s3-fips-us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "hostname" : "s3.us-gov-west-1.amazonaws.com", + "protocols" : [ "http", "https" ] + } + } + }, + "sns" : { + "endpoints" : { + "us-gov-west-1" : { + "protocols" : [ "http", "https" ] + } + } + }, + "sqs" : { + "endpoints" : { + "us-gov-west-1" : { + "protocols" : [ "http", "https" ], + "sslCommonName" : "{region}.queue.{dnsSuffix}" + } + } + }, + "streams.dynamodb" : { + "defaults" : { + "credentialScope" : { + "service" : "dynamodb" + } + }, + "endpoints" : { + "us-gov-west-1" : { }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "dynamodb.us-gov-west-1.amazonaws.com" + } + } + } + } + } ], + "version" : 3 +} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 2c5931b3f4f..514efc2d178 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,26 +1,32 @@ 'use strict'; import * as vscode from 'vscode'; +import * as nls from 'vscode-nls'; import { LambdaProvider } from './lambda/lambdaProvider'; - import { AWSClientBuilder } from './shared/awsClientBuilder'; import { ext } from './shared/extensionGlobals'; import { extensionSettingsPrefix } from './shared/constants'; import { AWSContext } from './shared/awsContext'; import { SettingsConfiguration } from './shared/settingsConfiguration'; import { AWSStatusBar } from './shared/statusBar'; +import { AWSContextCommands } from './shared/awsContextCommands'; export async function activate(context: vscode.ExtensionContext) { + nls.config(process.env.VSCODE_NLS_CONFIG)(); + ext.context = context; ext.awsContext = new AWSContext(new SettingsConfiguration(extensionSettingsPrefix)); + ext.awsContextCommands = new AWSContextCommands(); ext.sdkClientBuilder = new AWSClientBuilder(ext.awsContext); - ext.statusBar = new AWSStatusBar(context); - vscode.commands.registerCommand('aws.selectProfile', async () => { await ext.sdkClientBuilder.onCommandConfigureProfile(); }); - vscode.commands.registerCommand('aws.selectRegion', async () => { await ext.sdkClientBuilder.onCommandConfigureRegion(); }); + vscode.commands.registerCommand('aws.login', async () => { await ext.awsContextCommands.onCommandLogin(); }); + vscode.commands.registerCommand('aws.logout', async () => { await ext.awsContextCommands.onCommandLogout(); }); + + vscode.commands.registerCommand('aws.addExplorerRegion', async () => { await ext.awsContextCommands.onCommandAddExplorerRegion(); }); + vscode.commands.registerCommand('aws.removeExplorerRegion', async () => { await ext.awsContextCommands.onCommandRemoveExplorerRegion(); }); const providers = [ new LambdaProvider() diff --git a/src/lambda/commands/getLambdaConfig.ts b/src/lambda/commands/getLambdaConfig.ts index 019a54fb980..d3ef83ef6df 100644 --- a/src/lambda/commands/getLambdaConfig.ts +++ b/src/lambda/commands/getLambdaConfig.ts @@ -1,14 +1,14 @@ 'use strict'; import { FunctionNode } from "../explorer/functionNode"; -import { getSelectedLambdaNode } from '../utils'; import * as vscode from 'vscode'; import _ = require("lodash"); import { BaseTemplates } from "../../shared/templates/baseTemplates"; import { LambdaTemplates } from "../templates/lambdaTemplates"; import { AWSError } from "aws-sdk"; +import { getSelectedLambdaNode } from "../utils"; -export async function getLambdaConfig(element: FunctionNode) { +export async function getLambdaConfig(element?: FunctionNode) { try { const fn: FunctionNode = await getSelectedLambdaNode(element); diff --git a/src/lambda/commands/getLambdaPolicy.ts b/src/lambda/commands/getLambdaPolicy.ts index bf5a00d9e17..49a0ed87c07 100644 --- a/src/lambda/commands/getLambdaPolicy.ts +++ b/src/lambda/commands/getLambdaPolicy.ts @@ -1,12 +1,12 @@ 'use strict'; import { FunctionNode } from "../explorer/functionNode"; -import { getSelectedLambdaNode } from '../utils'; import * as vscode from 'vscode'; import _ = require("lodash"); import { BaseTemplates } from "../../shared/templates/baseTemplates"; import { LambdaTemplates } from "../templates/lambdaTemplates"; import { AWSError } from "aws-sdk"; +import { getSelectedLambdaNode } from "../utils"; export async function getLambdaPolicy(element?: FunctionNode) { try { diff --git a/src/lambda/commands/invokeLambda.ts b/src/lambda/commands/invokeLambda.ts index 002d262b9cb..4a54fe1af45 100644 --- a/src/lambda/commands/invokeLambda.ts +++ b/src/lambda/commands/invokeLambda.ts @@ -10,7 +10,6 @@ import _ = require("lodash"); import { ext } from "../../shared/extensionGlobals"; import { LambdaTemplates } from "../templates/lambdaTemplates"; import { AWSError } from "aws-sdk"; -import Lambda = require('aws-sdk/clients/lambda'); import { ResourceFetcher } from "../../shared/resourceFetcher"; import { sampleRequestManifestPath, sampleRequestPath } from "../constants"; import { SampleRequest } from '../models/sampleRequest'; @@ -35,7 +34,6 @@ export async function invokeLambda(element?: FunctionNode) { }); // ideally need to get the client from the explorer, but the context will do for now - console.log('building template...'); const invokeTemplateFn = _.template(LambdaTemplates.InvokeTemplate); const resourcePath = path.join(ext.context.extensionPath, 'resources', 'vs-lambda-sample-request-manifest.xml'); @@ -76,7 +74,7 @@ export async function invokeLambda(element?: FunctionNode) { case 'invokeLambda': console.log('got the following payload:'); console.log(message.value); - const lambdaClient = await ext.sdkClientBuilder.createAndConfigureSdkClient(Lambda, undefined); + const lambdaClient = fn.lambda; let funcRequest = { FunctionName: fn.functionConfiguration.FunctionArn!, LogType: 'Tail' @@ -93,7 +91,7 @@ export async function invokeLambda(element?: FunctionNode) { command: 'invokedLambda', logs, payload, - statusCode: funcResponse.StatusCode + statusCode: funcResponse.StatusCode }); } catch (e) { view.webview.postMessage({ diff --git a/src/lambda/commands/quickPickLambda.ts b/src/lambda/commands/quickPickLambda.ts index fd0a199aa78..a571aae8822 100644 --- a/src/lambda/commands/quickPickLambda.ts +++ b/src/lambda/commands/quickPickLambda.ts @@ -1,5 +1,8 @@ 'use strict'; +import * as nls from 'vscode-nls'; +let localize = nls.loadMessageBundle(); + import * as vscode from 'vscode'; import { FunctionNode } from '../explorer/functionNode'; @@ -16,7 +19,7 @@ class QuickPickLambda extends FunctionNode implements vscode.QuickPickItem { export async function quickPickLambda(lambdas: FunctionNode[]): Promise { try { if (!lambdas || lambdas.length === 0) { - vscode.window.showInformationMessage('There are no lambdas in this region.'); + vscode.window.showInformationMessage(localize('AWS.explorerNode.lambda.noFunctions', '..no functions in this region...')); } else { const qpLambdas = lambdas.map(l => new QuickPickLambda(l)); return await vscode.window.showQuickPick(qpLambdas, { placeHolder: 'Choose a lambda' }); diff --git a/src/lambda/explorer/blueprintNode.ts b/src/lambda/explorer/blueprintNode.ts deleted file mode 100644 index 387408d7b4f..00000000000 --- a/src/lambda/explorer/blueprintNode.ts +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -import { TreeItem, Uri, ThemeIcon } from 'vscode'; -import * as path from 'path'; -import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; -import { Blueprint } from '../models/blueprint'; - -export class BlueprintNode extends AWSTreeNodeBase implements TreeItem { - public static contextValue: string = 'awsLambdaBlueprint'; - public contextValue: string = BlueprintNode.contextValue; - - public label?: string; - public tooltip?: string; - public iconPath?: string | Uri | { light: string | Uri; dark: string | Uri } | ThemeIcon; - - constructor( - public readonly blueprint: Blueprint - ) { - super(); - this.label = `${this.blueprint.name!}`; - this.tooltip = `${this.blueprint.description}`; - this.iconPath = { - light: path.join(__filename, '..', '..', '..', 'resources', 'light', 'lambda_function.svg'), - dark: path.join(__filename, '..', '..', '..', 'resources', 'dark', 'lambda_function.svg') - }; - } - - public getChildren(): Thenable { - return new Promise(resolve => resolve([])); - } - - public getTreeItem(): TreeItem { - return this; - } -} diff --git a/src/lambda/explorer/blueprintsLanguageNode.ts b/src/lambda/explorer/blueprintsLanguageNode.ts deleted file mode 100644 index d850d1f861d..00000000000 --- a/src/lambda/explorer/blueprintsLanguageNode.ts +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -import { TreeItem, TreeItemCollapsibleState } from 'vscode'; -import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; -import { BlueprintNode } from './blueprintNode'; -import { BlueprintsCollection } from '../models/blueprintsCollection'; -import { Blueprint } from '../models/blueprint'; - -export class BlueprintsLanguageNode extends AWSTreeNodeBase { - - constructor(public readonly language: string, public readonly blueprintsCollection: BlueprintsCollection) { - super(); - } - - public getChildren(): Thenable { - return new Promise(resolve => { - let blueprints: BlueprintNode[] = []; - this.blueprintsCollection.filterBlueprintsForLanguage(this.language).forEach((b: Blueprint) => { - blueprints.push(new BlueprintNode(b)); - }); - - resolve(blueprints); - }); - } - - public getTreeItem(): TreeItem { - const item = new TreeItem(this.language, TreeItemCollapsibleState.Collapsed); - item.tooltip = `Project blueprints for creating new projects targeting AWS Lambda in ${this.language}`; - - return item; - } -} diff --git a/src/lambda/explorer/functionNode.ts b/src/lambda/explorer/functionNode.ts index d1718b427b6..32c31242d4d 100644 --- a/src/lambda/explorer/functionNode.ts +++ b/src/lambda/explorer/functionNode.ts @@ -26,7 +26,7 @@ export class FunctionNode extends AWSTreeNodeBase implements TreeItem { }; } - public getChildren(): Thenable { + public getChildren(): Thenable { return new Promise(resolve => resolve([])); } diff --git a/src/lambda/explorer/functionsNode.ts b/src/lambda/explorer/functionsNode.ts deleted file mode 100644 index c21cba68011..00000000000 --- a/src/lambda/explorer/functionsNode.ts +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -import { TreeItem, TreeItemCollapsibleState } from 'vscode'; -import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; -import { FunctionNode } from './functionNode'; -import { ext } from '../../shared/extensionGlobals'; -import Lambda = require('aws-sdk/clients/lambda'); -import { listLambdas } from '../utils'; - -export class FunctionsNode extends AWSTreeNodeBase { - public static contextValue: string = 'awsLambdaFns'; - public readonly contextValue: string = FunctionsNode.contextValue; - public readonly label: string = 'Lambda Functions'; - - public getChildren(): Thenable { - return new Promise(resolve => { - this.queryDeployedLambdaFunctions().then((result) => resolve(result)); - }); - } - - public getTreeItem(): TreeItem { - const item = new TreeItem('Functions', TreeItemCollapsibleState.Collapsed); - item.tooltip = 'My deployed Lambda functions'; - - return item; - } - - private async queryDeployedLambdaFunctions() : Promise { - const client = await ext.sdkClientBuilder.createAndConfigureSdkClient(Lambda, undefined); - return await listLambdas(client); - } -} diff --git a/src/lambda/explorer/guideNode.ts b/src/lambda/explorer/guideNode.ts deleted file mode 100644 index 2b56bd1c4da..00000000000 --- a/src/lambda/explorer/guideNode.ts +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -import { TreeItem, TreeItemCollapsibleState } from 'vscode'; -import * as path from 'path'; -import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; -import { URL } from 'url'; - -export class GuideNode extends AWSTreeNodeBase { - - public static contextValue: string = 'awsLambdaGuide'; - public contextValue: string = GuideNode.contextValue; - - constructor( - public readonly guideName: string, - public readonly guideUri: URL - ) { - super(); - } - - public getChildren(): Thenable { - return new Promise(resolve => resolve([])); - } - - public getTreeItem(): TreeItem { - const item = new TreeItem(`${this.guideName}`, TreeItemCollapsibleState.Collapsed); - item.tooltip = `${this.guideUri}`; - item.iconPath = { - light: path.join(__filename, '..', '..', '..', 'resources', 'light', 'lambda_function.svg'), - dark: path.join(__filename, '..', '..', '..', 'resources', 'dark', 'lambda_function.svg') - }; - - return item; - } -} - diff --git a/src/lambda/explorer/guidesNode.ts b/src/lambda/explorer/guidesNode.ts deleted file mode 100644 index c22093eda51..00000000000 --- a/src/lambda/explorer/guidesNode.ts +++ /dev/null @@ -1,26 +0,0 @@ -'use strict'; - -import { TreeItem, TreeItemCollapsibleState } from 'vscode'; -import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; -import { GuideNode } from './guideNode'; -import { URL } from 'url'; - -export class GuidesNode extends AWSTreeNodeBase { - - rootNodes: AWSTreeNodeBase[] = [ - new GuideNode('Developer Guide', new URL('https://docs.aws.amazon.com/lambda/latest/dg/welcome.html')), - new GuideNode('API Reference', new URL('https://docs.aws.amazon.com/lambda/latest/dg/API_Reference.html')) - ]; - - public getChildren(): Thenable { - return new Promise(resolve => resolve(this.rootNodes)); - } - - public getTreeItem(): TreeItem { - const item = new TreeItem('Reference Guides', TreeItemCollapsibleState.Collapsed); - item.tooltip = 'Reference materials for working with AWS Lambda'; - - return item; - } -} - diff --git a/src/lambda/explorer/noFunctionsNode.ts b/src/lambda/explorer/noFunctionsNode.ts new file mode 100644 index 00000000000..f2acef9819d --- /dev/null +++ b/src/lambda/explorer/noFunctionsNode.ts @@ -0,0 +1,21 @@ +'use strict'; + +import { TreeItem } from 'vscode'; +import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; + +// Can be used to add a child node in an explorer when a region has no resources +// relevant to the explorer type. +export class NoFunctionsNode extends AWSTreeNodeBase implements TreeItem { + + constructor(public label: string, public contextValue?: string, public tooltip?: string) { + super(); + } + + public getChildren(): Thenable { + return new Promise(resolve => resolve([])); + } + + public getTreeItem(): TreeItem { + return this; + } +} diff --git a/src/lambda/explorer/projectBlueprintsNode.ts b/src/lambda/explorer/projectBlueprintsNode.ts deleted file mode 100644 index 1c5dd17d385..00000000000 --- a/src/lambda/explorer/projectBlueprintsNode.ts +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -import { TreeItem, TreeItemCollapsibleState } from 'vscode'; -import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; -import { BlueprintsCollection } from '../models/blueprintsCollection'; -import { BlueprintsLanguageNode } from './blueprintsLanguageNode'; - -export class ProjectBlueprintsNode extends AWSTreeNodeBase { - - private allBlueprints: BlueprintsCollection = new BlueprintsCollection(); - - public async getChildren(): Promise { - - await this.allBlueprints.loadAllBlueprints(); // to date we do VS blueprints only - - let languageNodes: BlueprintsLanguageNode[] = []; - let languages = this.allBlueprints.filterBlueprintLanguages(); - languages.forEach((l: string) => { - languageNodes.push(new BlueprintsLanguageNode(l, this.allBlueprints)); - }); - - return languageNodes; - } - - public getTreeItem(): TreeItem { - const item = new TreeItem('Project Blueprints', TreeItemCollapsibleState.Collapsed); - item.tooltip = 'Blueprints for creating new projects targeting AWS Lambda'; - - return item; - } -} diff --git a/src/lambda/explorer/regionNodes.ts b/src/lambda/explorer/regionNodes.ts new file mode 100644 index 00000000000..4a6a24d12e6 --- /dev/null +++ b/src/lambda/explorer/regionNodes.ts @@ -0,0 +1,42 @@ +'use strict'; + +import * as nls from 'vscode-nls'; +let localize = nls.loadMessageBundle(); + +import { AWSRegionTreeNode } from '../../shared/awsRegionTreeNode'; +import { AWSTreeNodeBase } from '../../shared/awsTreeNodeBase'; +import { getLambdaFunctionsForRegion } from '../utils'; +import { NoFunctionsNode } from './noFunctionsNode'; + +// Collects the regions the user has declared they want to work with; +// on expansion each region lists the functions the user has available +// in that region. For regions with no deployed functions we output +// a placeholder child. +export class RegionNodes extends AWSRegionTreeNode { + + constructor(regionCode:string, public regionName: string) { + super(regionCode); + } + + protected getLabel(): string { + return this.regionName; + } + + protected getTooltip(): string | undefined { + return `${this.getLabel} (${this.regionCode})`; + } + + public getChildren(): Thenable { + return new Promise(resolve => { + getLambdaFunctionsForRegion(this.regionCode).then((result) => { + const arr: AWSTreeNodeBase[] = result; + if (arr.length === 0) { + arr.push(new NoFunctionsNode(localize('AWS.explorerNode.lambda.noFunctions', '...no functions in this region...'), + 'awsLambdaNoFns')); + } + resolve(arr); + }); + }); + } + +} diff --git a/src/lambda/lambdaProvider.ts b/src/lambda/lambdaProvider.ts index 86398ba05cb..6c13471e374 100644 --- a/src/lambda/lambdaProvider.ts +++ b/src/lambda/lambdaProvider.ts @@ -1,11 +1,11 @@ 'use strict'; +import * as nls from 'vscode-nls'; +let localize = nls.loadMessageBundle(); + import * as vscode from 'vscode'; import { AWSTreeNodeBase } from '../shared/awsTreeNodeBase'; import { IRefreshableAWSTreeProvider } from '../shared/IAWSTreeProvider'; -import { FunctionsNode } from './explorer/functionsNode'; -import { GuidesNode } from './explorer/guidesNode'; -import { ProjectBlueprintsNode } from './explorer/projectBlueprintsNode'; import { FunctionNode } from './explorer/functionNode'; import { getLambdaPolicy } from './commands/getLambdaPolicy'; import { invokeLambda } from './commands/invokeLambda'; @@ -14,6 +14,8 @@ import { deployLambda }from './commands/deployLambda'; import { getLambdaConfig } from './commands/getLambdaConfig'; import { AWSContext } from '../shared/awsContext'; import { ext } from '../shared/extensionGlobals'; +import { AWSCommandTreeNode } from '../shared/awsCommandTreeNode'; +import { RegionNodes } from './explorer/regionNodes'; export class LambdaProvider implements vscode.TreeDataProvider, IRefreshableAWSTreeProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); @@ -31,12 +33,6 @@ export class LambdaProvider implements vscode.TreeDataProvider, ext.treesToRefreshOnContextChange.push(this); } - rootNodes: AWSTreeNodeBase[] = [ - new FunctionsNode(), - new GuidesNode(), - new ProjectBlueprintsNode() - ]; - getTreeItem(element: AWSTreeNodeBase): vscode.TreeItem { return element.getTreeItem(); } @@ -46,7 +42,35 @@ export class LambdaProvider implements vscode.TreeDataProvider, return element.getChildren(); } - return new Promise(resolve => resolve(this.rootNodes)); + return new Promise(resolve => { + const profileName = ext.awsContext.getCredentialProfileName(); + if (!profileName) { + resolve([ + new AWSCommandTreeNode(localize('AWS.explorerNode.signIn', 'Sign in to AWS...'), + 'aws.login', + localize('AWS.explorerNode.signIn.tooltip', 'Connect to AWS using a credential profile')) + ]); + } + + ext.awsContext.getExplorerRegions().then(regions => { + + if (regions.length !== 0) { + let regionNodes: RegionNodes[] = []; + + regions.forEach(r => { + regionNodes.push(new RegionNodes(r, r)); + }); + + resolve(regionNodes); + } else { + resolve([ + new AWSCommandTreeNode(localize('AWS.explorerNode.addRegion', 'Click to add a region to view functions...'), + 'aws.addExplorerRegion', + localize('AWS.explorerNode.addRegion.tooltip', 'Configure a region to show available functions')) + ]); + } + }); + }); } refresh(context?: AWSContext) { diff --git a/src/lambda/utils.ts b/src/lambda/utils.ts index 21901a1f9b4..6818da21898 100644 --- a/src/lambda/utils.ts +++ b/src/lambda/utils.ts @@ -2,8 +2,8 @@ import * as vscode from 'vscode'; import { isNullOrUndefined } from 'util'; -import { FunctionNode } from './explorer/functionNode'; import { ext } from '../shared/extensionGlobals'; +import { FunctionNode } from './explorer/functionNode'; import { quickPickLambda } from './commands/quickPickLambda'; import Lambda = require('aws-sdk/clients/lambda'); @@ -14,8 +14,15 @@ export async function getSelectedLambdaNode(element?: FunctionNode): Promise { + const client = await ext.sdkClientBuilder.createAndConfigureSdkClient(Lambda, undefined, regionCode); + return listLambdas(client); +} + export async function listLambdas(lambda: Lambda): Promise { - // change status message on status bar. - // don't forget to dispose to turn message off. + // TODO: this 'loading' message needs to go under each regional entry + // in the explorer, and be removed when that region's query completes const status = vscode.window.setStatusBarMessage('Loading lambdas...'); let arr: FunctionNode[] = []; @@ -52,6 +64,7 @@ export async function listLambdas(lambda: Lambda): Promise { } catch (error) { // TODO: } + status.dispose(); return arr; } diff --git a/src/shared/awsClientBuilder.ts b/src/shared/awsClientBuilder.ts index 5859c42246c..98921a7dda6 100644 --- a/src/shared/awsClientBuilder.ts +++ b/src/shared/awsClientBuilder.ts @@ -1,8 +1,5 @@ 'use strict'; -import * as vscode from 'vscode'; -import { REGIONS } from './constants'; -import { ext } from './extensionGlobals'; import { AWSContext } from './awsContext'; export class AWSClientBuilder { @@ -16,13 +13,14 @@ export class AWSClientBuilder { // centralized construction of transient AWS service clients, allowing us // to customize requests and/or user agent - public async createAndConfigureSdkClient(awsService: any, awsServiceOpts: any) : Promise { + public async createAndConfigureSdkClient(awsService: any, awsServiceOpts: any | undefined, region: string | undefined) : Promise { + if (awsServiceOpts) { if (!awsServiceOpts.credentials) { awsServiceOpts.credentials = await this.awsContext.getCredentials(); } - if (!awsServiceOpts.region) { - awsServiceOpts.region = await this.awsContext.getRegion(); + if (!awsServiceOpts.region && region) { + awsServiceOpts.region = region; } return new awsService(awsServiceOpts); @@ -30,37 +28,7 @@ export class AWSClientBuilder { return new awsService({ credentials: await this.awsContext.getCredentials(), - region: await this.awsContext.getRegion() + region: region }); } - - async onCommandConfigureProfile() { - var newProfile = await this.promptForProfileName(); - if (newProfile) { - this.awsContext.setCredentialProfileName(newProfile); - ext.treesToRefreshOnContextChange.forEach(t => { - t.refresh(this.awsContext); - }); - } - } - - async onCommandConfigureRegion() { - var newRegion = await this.promptForRegion(); - if (newRegion) { - this.awsContext.setRegion(newRegion); - ext.treesToRefreshOnContextChange.forEach(t => { - t.refresh(this.awsContext); - }); - } - } - - private async promptForProfileName(): Promise { - const input = await vscode.window.showInputBox({ placeHolder: 'Enter the name of the credential profile to use' }); - return input ? input : ""; - } - - private async promptForRegion(): Promise { - const input = await vscode.window.showQuickPick(REGIONS, { placeHolder: 'Select an AWS region' }); - return input ? input : ""; - } } \ No newline at end of file diff --git a/src/shared/awsCommandTreeNode.ts b/src/shared/awsCommandTreeNode.ts new file mode 100644 index 00000000000..83f3dc3f353 --- /dev/null +++ b/src/shared/awsCommandTreeNode.ts @@ -0,0 +1,33 @@ +'use strict'; + +import { TreeItem, TreeItemCollapsibleState } from 'vscode'; +import { AWSTreeNodeBase } from './awsTreeNodeBase'; + +export class AWSCommandTreeNode extends AWSTreeNodeBase { + + constructor( + public readonly label: string, + public commandId: string, + public tooltip?: string, + public contextValue?: string, + ) { + super(); + } + + public getChildren(): Thenable { + return new Promise(resolve => resolve([])); + } + + public getTreeItem(): TreeItem { + const item = new TreeItem(`${this.label}`, TreeItemCollapsibleState.None); + item.tooltip = this.tooltip; + item.contextValue = this.contextValue; + item.command = { + title: this.label, + command: this.commandId + }; + + return item; + } +} + diff --git a/src/shared/awsContext.ts b/src/shared/awsContext.ts index 9d62258ea1c..214b90f5e9a 100644 --- a/src/shared/awsContext.ts +++ b/src/shared/awsContext.ts @@ -7,28 +7,32 @@ import { ISettingsConfiguration } from './settingsConfiguration'; // Carries the current context data on events export class ContextChangeEventsArgs { - constructor(public profileName: string | undefined, public region: string | undefined) { + constructor(public profileName: string | undefined, public regions: string[]) { } } -// Wraps an AWS context in terms of credential profile and region. The -// context listens for configuration updates and resets the context -// accordingly. +// Wraps an AWS context in terms of credential profile and zero or more regions. The +// context listens for configuration updates and resets the context accordingly. export class AWSContext { private _onDidChangeContext: vscode.EventEmitter = new vscode.EventEmitter(); public readonly onDidChangeContext: vscode.Event = this._onDidChangeContext.event; - private region: string | undefined; + // the collection of regions the user has expressed an interest in working with in + // the current workspace + private explorerRegions: string[]; + + // the user's credential context (currently this maps to an sdk/cli credential profile) private profileName: string | undefined; constructor(public settingsConfiguration: ISettingsConfiguration) { - this.region = settingsConfiguration.readSetting(regionSettingKey, ''); this.profileName = settingsConfiguration.readSetting(profileSettingKey, ''); - - if (!this.region) { - this.region = AWS.config.region ? AWS.config.region : ''; + const persistedRegions = settingsConfiguration.readSetting(regionSettingKey, undefined); + if (persistedRegions) { + this.explorerRegions = persistedRegions.split(','); + } else { + this.explorerRegions = []; } } @@ -49,25 +53,44 @@ export class AWSContext { } // resets the context to the indicated profile, saving it into settings - public async setCredentialProfileName(profileName: string) : Promise { + public async setCredentialProfileName(profileName?: string) : Promise { this.profileName = profileName; await this.settingsConfiguration.writeSetting(profileSettingKey, profileName, vscode.ConfigurationTarget.Global); - - this._onDidChangeContext.fire(new ContextChangeEventsArgs(this.profileName, this.region)); + this._onDidChangeContext.fire(new ContextChangeEventsArgs(this.profileName, this.explorerRegions)); } // async so that we could *potentially* support other ways of obtaining // region in future - for example from instance metadata if the // user was running Code on an EC2 instance. - public async getRegion(): Promise { - return this.region; + public async getExplorerRegions(): Promise { + return this.explorerRegions; } - // resets the context to the indicated profile, saving it into settings - public async setRegion(region: string) : Promise { - this.region = region; - await this.settingsConfiguration.writeSetting(regionSettingKey, region, vscode.ConfigurationTarget.Global); + // adds one or more regions into the preferred set, persisting the set afterwards as a + // comma-separated string. + public async addExplorerRegion(region: string | string[]) : Promise { + const regionsToProcess: string[] = region instanceof Array ? region : [region]; + regionsToProcess.forEach(r => { + const index = this.explorerRegions.findIndex(r => r === region); + if (index === -1) { + this.explorerRegions.push(r); + } + }); + await this.settingsConfiguration.writeSetting(regionSettingKey, this.explorerRegions, vscode.ConfigurationTarget.Global); + this._onDidChangeContext.fire(new ContextChangeEventsArgs(this.profileName, this.explorerRegions)); + } - this._onDidChangeContext.fire(new ContextChangeEventsArgs(this.profileName, this.region)); + // removes one or more regions from the user's preferred set, persisting the set afterwards as a + // comma-separated string. + public async removeExplorerRegion(region: string | string[]) : Promise { + const regionsToProcess: string[] = region instanceof Array ? region : [region]; + regionsToProcess.forEach(r => { + const index = this.explorerRegions.findIndex(r => r === region); + if (index >= 0) { + this.explorerRegions.splice(index, 1); + } + }); + await this.settingsConfiguration.writeSetting(regionSettingKey, this.explorerRegions, vscode.ConfigurationTarget.Global); + this._onDidChangeContext.fire(new ContextChangeEventsArgs(this.profileName, this.explorerRegions)); } } diff --git a/src/shared/awsContextCommands.ts b/src/shared/awsContextCommands.ts new file mode 100644 index 00000000000..8396af04faa --- /dev/null +++ b/src/shared/awsContextCommands.ts @@ -0,0 +1,73 @@ +'use strict'; + +import * as nls from 'vscode-nls'; +let localize = nls.loadMessageBundle(); + +import * as vscode from 'vscode'; +import { ext } from './extensionGlobals'; +import { RegionHelpers } from './regionHelpers'; +//import { REGIONS } from './constants'; + +class QuickPickRegion implements vscode.QuickPickItem { + label: string; description?: string | undefined; + detail?: string | undefined; + picked?: boolean | undefined; + constructor(public regionCode: string, public regionName: string, isSelected?: boolean) { + this.label = `${regionName}`; + this.picked = isSelected; + } +} + +export class AWSContextCommands { + public async onCommandLogin() { + var newProfile = await this.promptForProfileName(); + if (newProfile) { + ext.awsContext.setCredentialProfileName(newProfile); + ext.treesToRefreshOnContextChange.forEach(t => { + t.refresh(ext.awsContext); + }); + } + } + + public async onCommandLogout() { + ext.awsContext.setCredentialProfileName(); + ext.treesToRefreshOnContextChange.forEach(t => { + t.refresh(ext.awsContext); + }); + } + + public async onCommandAddExplorerRegion() { + var newRegion = await this.promptForRegion(); + if (newRegion) { + ext.awsContext.addExplorerRegion(newRegion); + ext.treesToRefreshOnContextChange.forEach(t => { + t.refresh(ext.awsContext); + }); + } + } + + public async onCommandRemoveExplorerRegion() { + var region = await this.promptForRegion(); + if (region) { + ext.awsContext.removeExplorerRegion(region); + ext.treesToRefreshOnContextChange.forEach(t => { + t.refresh(ext.awsContext); + }); + } + } + + private async promptForProfileName(): Promise { + const input = await vscode.window.showInputBox({ placeHolder: localize('AWS.message.enterProfileName', 'Enter the name of the credential profile to use') }); + return input ? input : ""; + } + + private async promptForRegion(): Promise { + const availableRegions = await RegionHelpers.fetchLatestRegionData(); + let qpRegions: QuickPickRegion[] = []; + availableRegions.forEach(r => { + qpRegions.push(new QuickPickRegion(r.regionCode, r.regionName)); + }); + const input = await vscode.window.showQuickPick(qpRegions, { placeHolder: localize('AWS.message.selectRegion', 'Select an AWS region') }); + return input ? input.regionCode : undefined; + } +} diff --git a/src/shared/awsRegionTreeNode.ts b/src/shared/awsRegionTreeNode.ts new file mode 100644 index 00000000000..39c7dac4b3d --- /dev/null +++ b/src/shared/awsRegionTreeNode.ts @@ -0,0 +1,25 @@ +'use strict'; + +import { TreeItem, TreeItemCollapsibleState } from 'vscode'; +import { AWSTreeNodeBase } from './awsTreeNodeBase'; + +export abstract class AWSRegionTreeNode extends AWSTreeNodeBase { + public readonly contextValue: string = 'awsRegion'; + + constructor(public regionCode:string) { + super(); + } + + protected abstract getLabel(): string; + + protected getTooltip(): string | undefined { + return undefined; + } + + public getTreeItem(): TreeItem { + const item = new TreeItem(this.getLabel(), TreeItemCollapsibleState.Expanded); + item.tooltip = this.getTooltip(); + + return item; + } +} diff --git a/src/shared/constants.ts b/src/shared/constants.ts index 588cc4e079f..33d6ba50338 100644 --- a/src/shared/constants.ts +++ b/src/shared/constants.ts @@ -1,29 +1,9 @@ 'use strict'; -export const REGIONS = [ - "us-east-1", - "us-east-2", - "us-west-1", - "us-west-2", - "eu-west-1", - "eu-west-2", - "eu-west-3", - "eu-central-1", - "ca-central-1", - "ap-northeast-1", - "ap-northeast-2", - "ap-northeast-3", - "ap-south-1", - "ap-southeast-1", - "ap-southeast-2", - "cn-north-1", - "cn-northwest-1", - "sa-east-1" -]; - export const extensionSettingsPrefix: string = 'aws'; export const regionSettingKey: string = 'region'; export const profileSettingKey: string = 'profile'; export const hostedFilesBaseUrl: string = 'https://d3rrggjwfhwld2.cloudfront.net/'; +export const endpointsFileUrl:string = 'https://aws-toolkit-endpoints.s3.amazonaws.com/endpoints.json'; diff --git a/src/shared/extensionGlobals.ts b/src/shared/extensionGlobals.ts index b6966cb9eb1..84ec6fa844b 100644 --- a/src/shared/extensionGlobals.ts +++ b/src/shared/extensionGlobals.ts @@ -5,6 +5,7 @@ import { AWSClientBuilder } from './awsClientBuilder'; import { AWSContext } from './awsContext'; import { IRefreshableAWSTreeProvider } from './IAWSTreeprovider'; import { AWSStatusBar } from './statusBar'; +import { AWSContextCommands } from './awsContextCommands'; /** * Namespace for common variables used globally in the extension. @@ -14,6 +15,7 @@ export namespace ext { export let context: ExtensionContext; export let outputChannel: OutputChannel; export let awsContext: AWSContext; + export let awsContextCommands: AWSContextCommands; export let sdkClientBuilder: AWSClientBuilder; export let statusBar: AWSStatusBar; export let treesToRefreshOnContextChange: IRefreshableAWSTreeProvider[] = []; diff --git a/src/shared/regionHelpers.ts b/src/shared/regionHelpers.ts new file mode 100644 index 00000000000..e199426e86a --- /dev/null +++ b/src/shared/regionHelpers.ts @@ -0,0 +1,44 @@ +'use strict'; + +import path = require('path'); +import { ResourceFetcher } from "./resourceFetcher"; +import { endpointsFileUrl } from './constants'; +import { ext } from "./extensionGlobals"; + +export class RegionInfo { + + constructor(public regionCode: string, public regionName: string){ + } +} + +export abstract class RegionHelpers { + + // Returns an object whose keys are the region codes (us-east-1 etc) and + // the values are the long-form names. + // TODO: implement some form of cache? + public static async fetchLatestRegionData(): Promise { + let availableRegions: RegionInfo[] = []; + + try { + console.log('> Downloading latest toolkits endpoint data'); + + const resourcePath = path.join(ext.context.extensionPath, 'resources', 'endpoints.json'); + const endpointsSource = await ResourceFetcher.fetchHostedResource(endpointsFileUrl, resourcePath); + var allEndpoints = JSON.parse(endpointsSource); + + for (var p = 0; p < allEndpoints.partitions.length; p++) { + var partition = allEndpoints.partitions[p]; + + var regionKeys = Object.keys(partition.regions); + regionKeys.forEach((rk) => { + availableRegions.push(new RegionInfo(rk, `${partition.regions[rk].description}`)); + }); + } + } catch (err) { + console.log(`...error downloading endpoints: ${err}`); // TODO: now what, oneline + local failed...? + } + + return availableRegions; + } + +} \ No newline at end of file diff --git a/src/shared/settingsConfiguration.ts b/src/shared/settingsConfiguration.ts index 30faf6dcb5c..b55120c083f 100644 --- a/src/shared/settingsConfiguration.ts +++ b/src/shared/settingsConfiguration.ts @@ -7,7 +7,8 @@ import * as vscode from 'vscode'; export interface ISettingsConfiguration { readSetting(settingKey: string, defaultValue?:string) : string | undefined; - writeSetting(settingKey: string, value: string, target: vscode.ConfigurationTarget) : void; + // array values are serialized as a comma-delimited string + writeSetting(settingKey: string, value: string | string[] | undefined, target: vscode.ConfigurationTarget) : void; } // default configuration settings handler for production release @@ -27,9 +28,16 @@ export class SettingsConfiguration implements ISettingsConfiguration { return undefined; } - async writeSetting(settingKey: string, value: string, target: vscode.ConfigurationTarget): Promise { + async writeSetting(settingKey: string, value: string | string[], target: vscode.ConfigurationTarget): Promise { const settings = vscode.workspace.getConfiguration(this.extensionSettingsPrefix); - await settings.update(settingKey, value, target); + let persistedValue: string; + if (value && value instanceof Array) { + persistedValue = value.join(); + } else { + persistedValue = value; + } + + await settings.update(settingKey, persistedValue, target); } constructor(public extensionSettingsPrefix: string) { diff --git a/src/shared/statusBar.ts b/src/shared/statusBar.ts index 15a13b41fc3..b399c97300a 100644 --- a/src/shared/statusBar.ts +++ b/src/shared/statusBar.ts @@ -1,5 +1,8 @@ 'use strict'; +import * as nls from 'vscode-nls'; +let localize = nls.loadMessageBundle(); + import { ExtensionContext, window, StatusBarItem, StatusBarAlignment } from 'vscode'; import { ext } from './extensionGlobals'; import { ContextChangeEventsArgs } from './awsContext'; @@ -8,11 +11,11 @@ import { ContextChangeEventsArgs } from './awsContext'; // so wrapping in a class to allow for per-element update capability export class AWSStatusBar { - public readonly credentialAndRegionContext: StatusBarItem; + public readonly credentialContext: StatusBarItem; constructor(context: ExtensionContext) { - this.credentialAndRegionContext = window.createStatusBarItem(StatusBarAlignment.Right, 100); - context.subscriptions.push(this.credentialAndRegionContext); + this.credentialContext = window.createStatusBarItem(StatusBarAlignment.Right, 100); + context.subscriptions.push(this.credentialContext); ext.awsContext.onDidChangeContext((context) => { this.updateContext(context); @@ -21,22 +24,19 @@ export class AWSStatusBar { public async updateContext(eventContext: ContextChangeEventsArgs | undefined) { let profileName: string | undefined; - let region: string | undefined; if (eventContext) { profileName = eventContext.profileName; - region = eventContext.region; } else { profileName = ext.awsContext.getCredentialProfileName(); - region = await ext.awsContext.getRegion(); } - if (profileName && region) { - this.credentialAndRegionContext.text = 'AWS: ' + profileName + '/' + region; - this.credentialAndRegionContext.show(); + if (profileName) { + this.credentialContext.text = localize('AWS.title', 'AWS') + ':' + profileName; + this.credentialContext.show(); } else { - this.credentialAndRegionContext.hide(); + this.credentialContext.hide(); } } } \ No newline at end of file diff --git a/src/test/awsContext.test.ts b/src/test/awsContext.test.ts index 66124103f0e..69d28e9e9a9 100644 --- a/src/test/awsContext.test.ts +++ b/src/test/awsContext.test.ts @@ -6,8 +6,9 @@ import { regionSettingKey, profileSettingKey } from '../shared/constants'; suite("AWSContext Tests", function (): void { - const testRegionValue: string = 'some-region-somewhere'; - const testProfileValue: string = 'some-credential-profile'; + const testRegion1Value: string = 're-gion-1'; + const testRegion2Value: string = 're-gion-2'; + const testProfileValue: string = 'profile1'; class ContextTestsSettingsConfigurationBase implements ISettingsConfiguration { readSetting(settingKey: string, defaultValue?: string | undefined): string | undefined { @@ -36,12 +37,12 @@ suite("AWSContext Tests", function (): void { assert.equal(testContext.getCredentialProfileName(), testProfileValue); }); - test('context sets region from config on startup', async function() { + test('context gets single region from config on startup', async function() { class TestConfiguration extends ContextTestsSettingsConfigurationBase { readSetting(settingKey: string, defaultValue?: string | undefined): string | undefined { if(settingKey === regionSettingKey) { - return testRegionValue; + return testRegion1Value; } return super.readSetting(settingKey, defaultValue); @@ -50,22 +51,78 @@ suite("AWSContext Tests", function (): void { const testContext = new AWSContext(new TestConfiguration()); - assert.equal(await testContext.getRegion(), testRegionValue); + const regions = await testContext.getExplorerRegions(); + assert.equal(regions.length, 1); + assert.equal(regions[0], testRegion1Value); }); - test('context updates config on region change', function() { + test('context gets multiple regions from config on startup', async function() { + + class TestConfiguration extends ContextTestsSettingsConfigurationBase { + readSetting(settingKey: string, defaultValue?: string | undefined): string | undefined { + if(settingKey === regionSettingKey) { + return `${testRegion1Value},${testRegion2Value}`; + } + + return super.readSetting(settingKey, defaultValue); + } + } + + + const testContext = new AWSContext(new TestConfiguration()); + const regions = await testContext.getExplorerRegions(); + assert.equal(regions.length, 2); + assert.equal(regions[0], testRegion1Value); + assert.equal(regions[1], testRegion2Value); + }); + + test('context updates config on single region change', function() { + + class TestConfiguration extends ContextTestsSettingsConfigurationBase { + writeSetting(settingKey: string, value: string, target: ConfigurationTarget): void { + assert.equal(settingKey, regionSettingKey); + assert.equal(value, testRegion1Value); + assert.equal(target, ConfigurationTarget.Global); + } + } + + const testContext = new AWSContext(new TestConfiguration()); + testContext.addExplorerRegion(testRegion1Value); + }); + + test('context updates config on multiple region change', function() { class TestConfiguration extends ContextTestsSettingsConfigurationBase { writeSetting(settingKey: string, value: string, target: ConfigurationTarget): void { assert.equal(settingKey, regionSettingKey); - assert.equal(value, testRegionValue); + assert.equal(value, `${testRegion1Value}${testRegion2Value}`); assert.equal(target, ConfigurationTarget.Global); } } + const testContext = new AWSContext(new TestConfiguration()); + testContext.addExplorerRegion([ testRegion1Value, testRegion2Value ]); + }); + + test('context updates on region removal', function() { + + class TestConfiguration extends ContextTestsSettingsConfigurationBase { + readSetting(settingKey: string, defaultValue?: string | undefined): string | undefined { + if(settingKey === regionSettingKey) { + return `${testRegion1Value},${testRegion2Value}`; + } + + return super.readSetting(settingKey, defaultValue); + } + writeSetting(settingKey: string, value: string, target: ConfigurationTarget): void { + assert.equal(settingKey, regionSettingKey); + assert.equal(value, `${testRegion2Value}`); + assert.equal(target, ConfigurationTarget.Global); + } + } const testContext = new AWSContext(new TestConfiguration()); - testContext.setRegion(testRegionValue); + testContext.removeExplorerRegion([ testRegion2Value ]); }); test('context updates config on profile change', function() { @@ -79,19 +136,34 @@ suite("AWSContext Tests", function (): void { } const testContext = new AWSContext(new TestConfiguration()); - testContext.setRegion(testRegionValue); + testContext.addExplorerRegion(testRegion1Value); + }); + + test('context fires event on single region change', function(done) { + + const testContext = new AWSContext(new ContextTestsSettingsConfigurationBase()); + + testContext.onDidChangeContext((c) => { + assert.equal(c.regions.length, 1); + assert.equal(c.regions[0], testRegion1Value); + done(); + }); + + testContext.addExplorerRegion(testRegion1Value); }); - test('context fires event on region change', function(done) { + test('context fires event on multi region change', function(done) { const testContext = new AWSContext(new ContextTestsSettingsConfigurationBase()); testContext.onDidChangeContext((c) => { - assert.equal(c.region, testRegionValue); + assert.equal(c.regions.length, 2); + assert.equal(c.regions[0], testRegion1Value); + assert.equal(c.regions[1], testRegion2Value); done(); }); - testContext.setRegion(testRegionValue); + testContext.addExplorerRegion([ testRegion1Value, testRegion2Value ]); }); test('context fires event on profile change', function(done) {