From 9ab6a337d3324388ba3202b046c80f4e01ee3c78 Mon Sep 17 00:00:00 2001 From: Barry Low Date: Tue, 18 Sep 2018 00:06:55 -0700 Subject: [PATCH 1/4] Client: Upload and crop image --- client/.env.sample | 2 + client/package-lock.json | 825 ++++++++++++++---- client/package.json | 5 + client/src/views/common/UploadImage.js | 247 ++++++ client/src/views/common/index.js | 3 +- .../dashboard/components/ManageTeamEdit.js | 3 + client/tools/webpack/webpack.dev.config.js | 3 +- client/tools/webpack/webpack.prod.config.js | 7 +- 8 files changed, 902 insertions(+), 193 deletions(-) create mode 100644 client/src/views/common/UploadImage.js diff --git a/client/.env.sample b/client/.env.sample index 789a271c6..4a54c8fd9 100644 --- a/client/.env.sample +++ b/client/.env.sample @@ -9,3 +9,5 @@ AUTH0_AUDIENCE= AUTH0_ISSUER= AUTH0_CLIENTID= AUTH0_CALLBACKURL= + +AZURE_STORAGE_CONNECTION_STRING= diff --git a/client/package-lock.json b/client/package-lock.json index 8f803109b..219ddf2b8 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -2626,7 +2626,6 @@ "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, "requires": { "co": "^4.6.0", "fast-deep-equal": "^1.0.0", @@ -2682,14 +2681,12 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -2832,8 +2829,7 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "arch": { "version": "2.1.1", @@ -2845,7 +2841,6 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -2894,6 +2889,11 @@ "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", "dev": true }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" + }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -2910,6 +2910,16 @@ "es-abstract": "^1.7.0" } }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=" + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -2946,7 +2956,6 @@ "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.0" } @@ -2991,8 +3000,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "assign-symbols": { "version": "1.0.0", @@ -3046,6 +3054,14 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "attr-accept": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.3.tgz", + "integrity": "sha512-iT40nudw8zmCweivz6j58g+RT33I4KbaIvRUhjNmDwO2WmsQUxFEZZYZ5w3vXe5x5MX9D7mfvA/XaLOZYFR9EQ==", + "requires": { + "core-js": "^2.5.0" + } + }, "auth0-js": { "version": "9.7.3", "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.7.3.tgz", @@ -3207,14 +3223,12 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, "axobject-query": { "version": "2.0.1", @@ -3225,6 +3239,59 @@ "ast-types-flow": "0.0.7" } }, + "azure-storage": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/azure-storage/-/azure-storage-2.10.1.tgz", + "integrity": "sha512-rnFo1uMIPtilusRCpK91tfY3P4Q7qRsDNwriXdp+OeTIGkGt0cTxL4mhqYfNPYPK+WBQmBdGWhOk+iROM05dcw==", + "requires": { + "browserify-mime": "~1.2.9", + "extend": "~1.2.1", + "json-edm-parser": "0.1.2", + "md5.js": "1.3.4", + "readable-stream": "~2.0.0", + "request": "^2.86.0", + "underscore": "~1.8.3", + "uuid": "^3.0.0", + "validator": "~9.4.1", + "xml2js": "0.2.8", + "xmlbuilder": "0.4.3" + }, + "dependencies": { + "extend": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-1.2.1.tgz", + "integrity": "sha1-oPX9bPyDpf5J72mNYOyKYk3UV2w=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + } + } + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -4480,8 +4547,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base": { "version": "0.11.2", @@ -4547,7 +4613,6 @@ "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": { "tweetnacl": "^0.14.3" @@ -4571,6 +4636,15 @@ "integrity": "sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA==", "dev": true }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", @@ -4630,7 +4704,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4713,6 +4786,11 @@ "safe-buffer": "^5.1.2" } }, + "browserify-mime": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/browserify-mime/-/browserify-mime-1.2.9.tgz", + "integrity": "sha1-rrGvKN5sDXpqLOQK22j/GEIq8x8=" + }, "browserify-rsa": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", @@ -4787,7 +4865,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" @@ -4796,14 +4873,12 @@ "buffer-alloc-unsafe": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" }, "buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" }, "buffer-from": { "version": "1.0.0", @@ -4820,8 +4895,7 @@ "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" }, "builtin-status-codes": { "version": "3.0.0", @@ -5037,14 +5111,12 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -5086,8 +5158,7 @@ "chownr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", - "dev": true + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" }, "chrome-trace-event": { "version": "1.0.0", @@ -5426,8 +5497,7 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, "coa": { "version": "1.0.4", @@ -5441,8 +5511,7 @@ "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 + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "collection-visit": { "version": "1.0.0", @@ -5469,7 +5538,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "dev": true, "requires": { "color-name": "^1.1.1" } @@ -5477,8 +5545,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { "version": "0.3.0", @@ -5543,8 +5610,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.2", @@ -5603,8 +5669,7 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "constants-browserify": { "version": "1.0.0", @@ -6044,7 +6109,6 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -6106,7 +6170,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, "requires": { "mimic-response": "^1.0.0" } @@ -6120,8 +6183,7 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "deep-is": { "version": "0.1.3", @@ -6138,7 +6200,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", - "dev": true, "requires": { "foreach": "^2.0.5", "object-keys": "^1.0.8" @@ -6214,8 +6275,7 @@ "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "depd": { "version": "1.1.2", @@ -6254,6 +6314,11 @@ "repeating": "^2.0.0" } }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -6406,6 +6471,11 @@ "dotenv": "^5.0.1" } }, + "duplexer": { + "version": "0.1.1", + "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -6428,7 +6498,6 @@ "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.0", @@ -6504,7 +6573,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -6555,7 +6623,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -6570,7 +6637,6 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.11.0.tgz", "integrity": "sha512-ZnQrE/lXTTQ39ulXZ+J1DTFazV9qBy61x2bY071B+qGco8Z8q1QddsLdt/EF8Ai9hcWH72dWS0kFqXLxOxqslA==", - "dev": true, "requires": { "es-to-primitive": "^1.1.1", "function-bind": "^1.1.1", @@ -6583,7 +6649,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, "requires": { "is-callable": "^1.1.1", "is-date-object": "^1.0.1", @@ -6631,8 +6696,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { "version": "5.5.0", @@ -7141,6 +7205,21 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, + "event-stream": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz", + "integrity": "sha512-dGXNg4F/FgVzlApjzItL+7naHutA3fDqbV/zAZqDDlXTjiMnQmZKu+prImWKszeBM5UQeGvAl3u1wBiKeDh61g==", + "requires": { + "duplexer": "^0.1.1", + "flatmap-stream": "^0.1.0", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" + } + }, "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", @@ -7278,6 +7357,11 @@ } } }, + "expand-template": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.1.tgz", + "integrity": "sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg==" + }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -7392,14 +7476,12 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "fast-deep-equal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" }, "fast-diff": { "version": "1.1.2", @@ -7561,6 +7643,11 @@ "write": "^0.2.1" } }, + "flatmap-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.0.tgz", + "integrity": "sha512-Nlic4ZRYxikqnK5rj3YoxDVKGGtUjcNDUtvQ7XsdGLZmMwdUYnXf10o1zcXtzEZTBgc6GxeRpQxV/Wu3WPIIHA==" + }, "flatten": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", @@ -7601,14 +7688,12 @@ "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { "version": "2.3.2", @@ -7640,6 +7725,11 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" + }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", @@ -7650,6 +7740,16 @@ "readable-stream": "^2.0.0" } }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-copy-file-sync": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz", + "integrity": "sha512-2QY5eeqVv4m2PfyMiEuy9adxNP+ajf+8AR05cEi+OAzPcOj90hvFImeZhTmKLBgSd9EvG33jsD7ZRxsx9dThkQ==" + }, "fs-extra": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", @@ -7661,6 +7761,14 @@ "universalify": "^0.1.0" } }, + "fs-minipass": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "requires": { + "minipass": "^2.2.1" + } + }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -8223,8 +8331,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -8236,7 +8343,6 @@ "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -8252,7 +8358,6 @@ "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.0" } @@ -8261,7 +8366,6 @@ "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.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -8272,7 +8376,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -8322,7 +8425,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -8385,6 +8487,11 @@ } } }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" + }, "github-username": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/github-username/-/github-username-4.1.0.tgz", @@ -8598,8 +8705,7 @@ "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, "graphql": { "version": "0.13.2", @@ -8634,14 +8740,12 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "dev": true, "requires": { "ajv": "^5.1.0", "har-schema": "^2.0.0" @@ -8651,7 +8755,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", - "dev": true, "requires": { "function-bind": "^1.0.2" } @@ -8674,8 +8777,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbol-support-x": { "version": "1.4.2", @@ -8701,8 +8803,7 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, "has-value": { "version": "1.0.0", @@ -8740,7 +8841,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -8828,8 +8928,7 @@ "hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", - "dev": true + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" }, "html-comment-regex": { "version": "1.1.1", @@ -9003,7 +9102,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -9213,8 +9311,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "inquirer": { "version": "3.3.0", @@ -9297,8 +9394,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-binary-path": { "version": "1.0.1", @@ -9319,7 +9415,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, "requires": { "builtin-modules": "^1.0.0" } @@ -9327,8 +9422,7 @@ "is-callable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", - "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", - "dev": true + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" }, "is-ci": { "version": "1.2.0", @@ -9362,8 +9456,7 @@ "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" }, "is-descriptor": { "version": "0.1.6", @@ -9429,8 +9522,7 @@ "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 + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-function": { "version": "1.0.1", @@ -9588,7 +9680,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, "requires": { "has": "^1.0.1" } @@ -9631,14 +9722,12 @@ "is-symbol": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-utf8": { "version": "0.2.1", @@ -9692,8 +9781,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", @@ -9712,8 +9800,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istextorbinary": { "version": "2.2.1", @@ -9921,23 +10008,28 @@ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", "dev": true }, + "json-edm-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/json-edm-parser/-/json-edm-parser-0.1.2.tgz", + "integrity": "sha1-HmCw/vG8CvZ7wNFG393lSGzWFbQ=", + "requires": { + "jsonparse": "~1.2.0" + } + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -9948,8 +10040,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { "version": "0.5.1", @@ -9966,6 +10057,11 @@ "graceful-fs": "^4.1.6" } }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, "jsonp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/jsonp/-/jsonp-0.2.1.tgz", @@ -9984,11 +10080,15 @@ } } }, + "jsonparse": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.2.0.tgz", + "integrity": "sha1-XAxWhRBxYOcv50ib3eoLRMK8Z70=" + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -10899,6 +10999,11 @@ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true }, + "map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=" + }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", @@ -10924,7 +11029,6 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", - "dev": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -11039,6 +11143,11 @@ "readable-stream": "^2.0.1" } }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" + }, "meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", @@ -11248,8 +11357,7 @@ "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" }, "mini-css-extract-plugin": { "version": "0.4.2", @@ -11330,7 +11438,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -11338,8 +11445,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "minimist-options": { "version": "3.0.2", @@ -11351,6 +11457,30 @@ "is-plain-obj": "^1.1.0" } }, + "minipass": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.4.tgz", + "integrity": "sha512-mlouk1OHlaUE8Odt1drMtG1bAJA4ZA6B/ehysgV0LUIrDHdKgo1KorZq3pK0b/7Z7LJIQ12MNM6aC+Tn6lUZ5w==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + }, + "dependencies": { + "yallist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" + } + } + }, + "minizlib": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", + "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", + "requires": { + "minipass": "^2.2.1" + } + }, "mississippi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", @@ -11412,7 +11542,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" } @@ -11468,8 +11597,7 @@ "nan": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.0.tgz", - "integrity": "sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==", - "dev": true + "integrity": "sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==" }, "nanoassert": { "version": "1.1.0", @@ -11552,8 +11680,7 @@ "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "no-case": { "version": "2.3.2", @@ -11564,6 +11691,14 @@ "lower-case": "^1.1.1" } }, + "node-abi": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.3.tgz", + "integrity": "sha512-b656V5C0628gOOA2kwcpNA/bxdlqYF9FvxJ+qqVX0ctdXNVZpS8J6xEUYir3WAKc7U0BH/NRlSpNbGsy+azjeg==", + "requires": { + "semver": "^5.4.1" + } + }, "node-dir": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.8.tgz", @@ -11755,6 +11890,11 @@ } } }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -11768,7 +11908,6 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, "requires": { "hosted-git-info": "^2.1.4", "is-builtin-module": "^1.0.0", @@ -11808,6 +11947,79 @@ "sort-keys": "^1.0.0" } }, + "npm-run-all": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.3.tgz", + "integrity": "sha512-aOG0N3Eo/WW+q6sUIdzcV2COS8VnTZCmdji0VQIAZF3b+a3YWb0AD0vFIyjKec18A7beLGbaQ5jFTNI2bPt9Cg==", + "requires": { + "ansi-styles": "^3.2.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.4", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "ps-tree": "^1.1.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + } + } + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -11821,7 +12033,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -11847,14 +12058,12 @@ "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 + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "oauth-sign": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" }, "object-assign": { "version": "4.1.1", @@ -11895,8 +12104,7 @@ "object-keys": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", - "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", - "dev": true + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=" }, "object-visit": { "version": "1.0.1", @@ -11961,7 +12169,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -12035,8 +12242,7 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { "version": "1.4.0", @@ -12319,8 +12525,7 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { "version": "1.0.5", @@ -12352,6 +12557,14 @@ "pify": "^2.0.0" } }, + "pause-stream": { + "version": "0.0.11", + "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "requires": { + "through": "~2.3" + } + }, "pbkdf2": { "version": "3.0.16", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", @@ -12368,8 +12581,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { "version": "2.3.0", @@ -12934,6 +13146,35 @@ "uniqs": "^2.0.0" } }, + "prebuild-install": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-4.0.0.tgz", + "integrity": "sha512-7tayxeYboJX0RbVzdnKyGl2vhQRWr6qfClEXDhOkXjuaOKCw2q8aiuFhONRYVsG/czia7KhpykIlI2S2VaPunA==", + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^1.0.2", + "github-from-package": "0.0.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-abi": "^2.2.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "os-homedir": "^1.0.1", + "pump": "^2.0.1", + "rc": "^1.1.6", + "simple-get": "^2.7.0", + "tar-fs": "^1.13.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -13324,6 +13565,14 @@ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, + "ps-tree": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz", + "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=", + "requires": { + "event-stream": "~3.3.0" + } + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -13347,7 +13596,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -13367,8 +13615,7 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" }, "q": { "version": "1.5.1", @@ -13457,7 +13704,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -13468,8 +13714,7 @@ "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" } } }, @@ -13528,6 +13773,15 @@ "schedule": "^0.3.0" } }, + "react-dropzone": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-5.1.0.tgz", + "integrity": "sha512-cIYp3GCm0I4fckmQJhrFSKq/W91Ma1BZTCXMr7hg1jnVYmERsa6bruJroci4Lq9QvdoAnh+6r6SVQ2v6CVQ6Hg==", + "requires": { + "attr-accept": "^1.1.3", + "prop-types": "^15.6.2" + } + }, "react-event-listener": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.6.3.tgz", @@ -13553,6 +13807,30 @@ } } }, + "react-image-crop": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-image-crop/-/react-image-crop-5.0.0.tgz", + "integrity": "sha512-MBT18tcHeEpmrhbSS6hx00MmfNgrnlhZuwY96cGRPhUmNeabxM7UBCcoU+oJCZXB0iGZk38zy/YGoZ4ELVp/LQ==" + }, + "react-image-cropper": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-image-cropper/-/react-image-cropper-1.3.0.tgz", + "integrity": "sha512-OPEMv66xXQdNsAixqxhlsSX3+D3KVRQMYc6YHmgGINeKx433xB9l04hMFynngPuUa+ChiKal6aQmbzpg79iJ+Q==", + "requires": { + "deep-extend": "^0.4.1", + "npm-run-all": "^4.1.1", + "prop-types": "^15.6.0", + "react": "^16.2.0", + "react-dom": "^16.2.0" + }, + "dependencies": { + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" + } + } + }, "react-jss": { "version": "8.6.1", "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.6.1.tgz", @@ -13999,7 +14277,6 @@ "version": "2.87.0", "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", - "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.6.0", @@ -14026,8 +14303,7 @@ "qs": { "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 + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" } } }, @@ -14375,8 +14651,7 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" }, "semver-diff": { "version": "2.1.0", @@ -14396,8 +14671,7 @@ "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 + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-immediate-shim": { "version": "1.0.1", @@ -14468,11 +14742,71 @@ } } }, + "sharp": { + "version": "0.20.8", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.20.8.tgz", + "integrity": "sha512-A8NaPGWRDKpmHTi8sl2xzozYXhTQWBb/GaJ8ZPU7L/vKW8wVvd4Yq+isJ0c7p9sX5gnjPQcM3eOfHuvvnZ2fOQ==", + "requires": { + "color": "^3.0.0", + "detect-libc": "^1.0.3", + "fs-copy-file-sync": "^1.1.1", + "nan": "^2.11.0", + "npmlog": "^4.1.2", + "prebuild-install": "^4.0.0", + "semver": "^5.5.1", + "simple-get": "^2.8.1", + "tar": "^4.4.6", + "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "color": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "semver": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==" + }, + "tar": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.6.tgz", + "integrity": "sha512-tMkTnh9EdzxyfW+6GK6fCahagXsnYk6kE6S9Gr9pjVdys769+laCTbodXDhPAjzVtEBazRgP0gYqOjnk9dQzLg==", + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.3", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" + } + } + }, "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": { "shebang-regex": "^1.0.0" } @@ -14480,8 +14814,18 @@ "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 + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "requires": { + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" + } }, "shelljs": { "version": "0.8.2", @@ -14497,8 +14841,37 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + }, + "simple-get": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", + "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } }, "slash": { "version": "1.0.0", @@ -14690,7 +15063,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", - "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -14699,14 +15071,12 @@ "spdx-exceptions": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", - "dev": true + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==" }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -14715,8 +15085,15 @@ "spdx-license-ids": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", - "dev": true + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==" + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } }, "split-string": { "version": "3.1.0", @@ -14737,7 +15114,6 @@ "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", "assert-plus": "^1.0.0", @@ -14805,6 +15181,15 @@ "readable-stream": "^2.0.2" } }, + "stream-combiner": { + "version": "0.2.2", + "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", + "requires": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, "stream-each": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", @@ -14850,12 +15235,21 @@ "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" } }, + "string.prototype.padend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", + "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.4.3", + "function-bind": "^1.0.2" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -14868,7 +15262,6 @@ "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" }, @@ -14876,16 +15269,14 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" } } }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" }, "strip-bom-stream": { "version": "2.0.0", @@ -14926,8 +15317,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "style-loader": { "version": "0.21.0", @@ -14979,7 +15369,6 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -15080,6 +15469,42 @@ "inherits": "2" } }, + "tar-fs": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "requires": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + }, + "dependencies": { + "pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "tar-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", + "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.1.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.0", + "xtend": "^4.0.0" + } + }, "temp": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", @@ -15151,8 +15576,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "2.0.3", @@ -15200,6 +15624,11 @@ "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", "dev": true }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -15273,7 +15702,6 @@ "version": "2.3.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "dev": true, "requires": { "punycode": "^1.4.1" } @@ -15320,7 +15748,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -15329,7 +15756,6 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, "optional": true }, "type-check": { @@ -15731,8 +16157,7 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8-compile-cache": { "version": "2.0.2", @@ -15744,12 +16169,16 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, + "validator": { + "version": "9.4.1", + "resolved": "http://registry.npmjs.org/validator/-/validator-9.4.1.tgz", + "integrity": "sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==" + }, "value-equal": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz", @@ -15771,7 +16200,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -16578,7 +17006,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -16589,11 +17016,15 @@ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, "requires": { "string-width": "^1.0.2 || 2" } @@ -16831,8 +17262,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "0.2.1", @@ -16868,11 +17298,30 @@ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, + "xml2js": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.8.tgz", + "integrity": "sha1-m4FpCTFjH/CdGVdUn69U9PmAs8I=", + "requires": { + "sax": "0.5.x" + }, + "dependencies": { + "sax": { + "version": "0.5.8", + "resolved": "http://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" + } + } + }, + "xmlbuilder": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-0.4.3.tgz", + "integrity": "sha1-xGFLp04K0ZbmCcknLNnh3bKKilg=" + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { "version": "3.2.1", diff --git a/client/package.json b/client/package.json index 27b67cb88..3fb9b227e 100644 --- a/client/package.json +++ b/client/package.json @@ -78,6 +78,7 @@ "apollo-link-ws": "^1.0.8", "apollo-utilities": "^1.0.20", "auth0-lock": "^11.9.0", + "azure-storage": "^2.10.1", "babel-polyfill": "^6.26.0", "classnames": "^2.2.6", "cross-fetch": "^2.2.2", @@ -88,8 +89,12 @@ "react": "^16.5.0", "react-apollo": "^2.1.11", "react-dom": "^16.5.0", + "react-dropzone": "^5.1.0", + "react-image-crop": "^5.0.0", + "react-image-cropper": "^1.3.0", "react-router-dom": "^4.3.1", "recompose": "^0.30.0", + "sharp": "^0.20.8", "subscriptions-transport-ws": "^0.9.14" }, "standard": { diff --git a/client/src/views/common/UploadImage.js b/client/src/views/common/UploadImage.js new file mode 100644 index 000000000..f5b625c8f --- /dev/null +++ b/client/src/views/common/UploadImage.js @@ -0,0 +1,247 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Dropzone from 'react-dropzone' +// import ReactCrop from 'react-image-crop' +import { Cropper } from 'react-image-cropper' +// import azure from 'azure-storage' +import { withStyles } from '@material-ui/core/styles' + +import Dialog from '@material-ui/core/Dialog' +import DialogActions from '@material-ui/core/DialogActions' +import DialogContent from '@material-ui/core/DialogContent' +import Button from '@material-ui/core/Button' + +const styles = theme => ({ + dropzoneContainer: { + display: 'block', + margin: '1em', + minWidth: 200, + height: 200 + }, + dropzone: { + display: 'block', + padding: '3em', + minWidth: 200, + height: 200, + borderWidth: 2, + borderColor: '#999', + backgroundColor: '#eee' + }, + dropzoneText: { + textAlign: 'center' + }, + cropPreview: { + width: 200, + height: 200 + }, + cropBox: { + width: 350, + height: 350 + }, + reactCrop: { + } +}) + +class UploadImage extends Component { + constructor (props) { + super(props) + + // this.saveToStorage = this.saveToStorage.bind(this) + this.onDrop = this.onDrop.bind(this) + this.handleCrop = this.handleCrop.bind(this) + this.onCropComplete = this.onCropComplete.bind(this) + this.onCropChange = this.onCropChange.bind(this) + this.getCroppedImg = this.getCroppedImg.bind(this) + this.handleClickOpen = this.handleClickOpen.bind(this) + this.handleClose = this.handleClose.bind(this) + + this.state = { + open: false, + file: null, + src: null, + crop: { + x: 10, + y: 10, + width: 200, + height: 200 + }, + cropped: null, + rejected: null + } + } + + render () { + const { classes, team, authId } = this.props + console.log('UploadImage', team, authId, this.state) + return ( +
+ {this.state.src === null && ( + +

Drag-and-drop team avater here or click to select files.
Only *.jpeg and *.png images

+
+ )} + {this.state.cropped !== null && ( + Crop Preview + )} + {this.state.src !== null && ( + +
+ +
+ { this.cropper = ref }} + onImgLoad={this.onImageLoaded} + /> +
+
+ + + + +
+
+ )} +
+ ) + } + + onDrop (file) { + console.log('onDrop', file) + this.onSelectFile(file) + this.setState({ + file + }) + } + + onSelectFile (file) { + if (file && file.length > 0) { + const reader = new window.FileReader() + reader.addEventListener( + 'load', + () => + this.setState({ + src: reader.result, + open: true + }), + false + ) + reader.readAsDataURL(file[0]) + } + } + + handleCrop () { + console.log('handleCrop', this.cropper) + this.setState({ cropped: this.cropper.crop(), open: false }) + } + + onCropComplete (crop, pixelCrop) { + console.log('onCropComplete', crop, pixelCrop, this.state) + const cropped = this.getCroppedImg(crop, pixelCrop, this.state.src) + this.setState({ cropped }) + } + + onCropChange (crop) { + this.setState({ crop }) + } + + getCroppedImg (image, pixelCrop, fileName) { + const canvas = document.createElement('canvas') + canvas.width = pixelCrop.width + canvas.height = pixelCrop.height + const ctx = canvas.getContext('2d') + + ctx.drawImage( + image, + pixelCrop.x, + pixelCrop.y, + pixelCrop.width, + pixelCrop.height, + 0, + 0, + pixelCrop.width, + pixelCrop.height + ) + + // As Base64 string + return canvas.toDataURL('image/jpeg') + + // As a blob + /* + return new Promise((resolve, reject) => { + canvas.toBlob(file => { + file.name = fileName + resolve(file) + }, 'image/jpeg') + }); + */ + } + + handleClickOpen () { + this.setState({ open: true }) + } + + handleClose () { + this.setState({ open: false, src: null }) + } + /* + saveToStorage (xhr) { + const blobService = azure.createBlobService() + const container = '' + const Stream = require('stream') + const readable = new Stream.Readable() + readable.push(xhr.responseText) + readable.push(null) + + blobService.createBlockBlobFromStream( + container, + this.state.accepted[0].name, + readable, + xhr.responseText.length, + (error, result, response) => { + if (error) return (

{error}

) + return 'Success' + } + ) + xhr.send() + } + */ +} + +UploadImage.propTypes = { + classes: PropTypes.object.isRequired, + team: PropTypes.object, + authId: PropTypes.string.isRequired +} + +export default withStyles(styles)(UploadImage) + +/* + +*/ diff --git a/client/src/views/common/index.js b/client/src/views/common/index.js index fe07e8f49..12cfe68a0 100644 --- a/client/src/views/common/index.js +++ b/client/src/views/common/index.js @@ -1,3 +1,4 @@ import MessageCard from './MessageCard' +import UploadImage from './UploadImage' -export { MessageCard } +export { MessageCard, UploadImage } diff --git a/client/src/views/dashboard/components/ManageTeamEdit.js b/client/src/views/dashboard/components/ManageTeamEdit.js index 7d10e1a7a..9630c04be 100644 --- a/client/src/views/dashboard/components/ManageTeamEdit.js +++ b/client/src/views/dashboard/components/ManageTeamEdit.js @@ -20,6 +20,8 @@ import GET_TEAMS_BY_OWNER from '../../../graphql/teams/GetTeamsByOwnerQuery' import { checkGraphQLError } from '../../../utils/graphql-errors' +import { UploadImage } from '../../common' + const styles = theme => ({ dialogContainer: { display: 'block', @@ -101,6 +103,7 @@ export class ManageTeamEdit extends Component { Edit Team Details + Date: Thu, 20 Sep 2018 08:24:35 -0700 Subject: [PATCH 2/4] Basic file upload to Azure BlockBLob --- api/package-lock.json | 456 +++++++++++++++--- api/package.json | 6 +- api/src/index.js | 74 ++- api/src/schema.graphql | 1 + api/src/storage/azure.js | 133 +++++ client/package-lock.json | 171 ++++++- client/package.json | 2 + .../src/graphql/teams/GetAzureSASMutation.js | 10 + client/src/views/common/UploadImage.js | 81 +++- 9 files changed, 850 insertions(+), 84 deletions(-) create mode 100644 api/src/storage/azure.js create mode 100644 client/src/graphql/teams/GetAzureSASMutation.js diff --git a/api/package-lock.json b/api/package-lock.json index 81ed969ea..6d1c72d4f 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -3,6 +3,14 @@ "requires": true, "lockfileVersion": 1, "dependencies": { + "@azure/storage-blob": { + "version": "10.0.0-preview", + "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-10.0.0-preview.tgz", + "integrity": "sha512-PFXKm+gipKDfg5h08hPiEr0Za4RMiFzzte+ewh4ACZeRQa0XZK55NAZxW67ZytGBd7WXdQq6pcAgo5dBnwQANQ==", + "requires": { + "ms-rest-js": "0.21.413" + } + }, "@babel/generator": { "version": "7.0.0-beta.38", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.38.tgz", @@ -213,6 +221,14 @@ "@types/express": "*" } }, + "@types/form-data": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", + "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", + "requires": { + "@types/node": "*" + } + }, "@types/graphql": { "version": "0.12.6", "resolved": "http://registry.npmjs.org/@types/graphql/-/graphql-0.12.6.tgz", @@ -247,6 +263,14 @@ "@types/mime": "*" } }, + "@types/uuid": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.4.tgz", + "integrity": "sha512-tPIgT0GUmdJQNSHxp0X2jnpQfBSTfGxUMc/2CXBU2mnyTFVYVa2ojpoQ74w0U2yn2vw3jnC640+77lkFFpdVDw==", + "requires": { + "@types/node": "*" + } + }, "@types/zen-observable": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.5.4.tgz", @@ -808,6 +832,86 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, + "axios": { + "version": "0.18.0", + "resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz", + "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", + "requires": { + "follow-redirects": "^1.3.0", + "is-buffer": "^1.1.5" + } + }, + "azure-storage": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/azure-storage/-/azure-storage-2.10.1.tgz", + "integrity": "sha512-rnFo1uMIPtilusRCpK91tfY3P4Q7qRsDNwriXdp+OeTIGkGt0cTxL4mhqYfNPYPK+WBQmBdGWhOk+iROM05dcw==", + "requires": { + "browserify-mime": "~1.2.9", + "extend": "~1.2.1", + "json-edm-parser": "0.1.2", + "md5.js": "1.3.4", + "readable-stream": "~2.0.0", + "request": "^2.86.0", + "underscore": "~1.8.3", + "uuid": "^3.0.0", + "validator": "~9.4.1", + "xml2js": "0.2.8", + "xmlbuilder": "0.4.3" + }, + "dependencies": { + "extend": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-1.2.1.tgz", + "integrity": "sha1-oPX9bPyDpf5J72mNYOyKYk3UV2w=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "sax": { + "version": "0.5.8", + "resolved": "http://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" + }, + "validator": { + "version": "9.4.1", + "resolved": "http://registry.npmjs.org/validator/-/validator-9.4.1.tgz", + "integrity": "sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==" + }, + "xml2js": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.8.tgz", + "integrity": "sha1-m4FpCTFjH/CdGVdUn69U9PmAs8I=", + "requires": { + "sax": "0.5.x" + } + }, + "xmlbuilder": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-0.4.3.tgz", + "integrity": "sha1-xGFLp04K0ZbmCcknLNnh3bKKilg=" + } + } + }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -968,6 +1072,21 @@ "qs": "6.5.2", "raw-body": "2.3.3", "type-is": "~1.6.16" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "body-parser-graphql": { @@ -1028,6 +1147,11 @@ } } }, + "browserify-mime": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/browserify-mime/-/browserify-mime-1.2.9.tgz", + "integrity": "sha1-rrGvKN5sDXpqLOQK22j/GEIq8x8=" + }, "buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", @@ -1746,18 +1870,11 @@ "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==" }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.0.1.tgz", + "integrity": "sha512-K23FHJ/Mt404FSlp6gSZCevIbTMLX0j3fmHhUEhQ3Wq0FMODW3+cUSoLdy1Gx4polAf4t/lphhmHH35BB8cLYw==", "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } + "ms": "^2.1.1" } }, "decamelize": { @@ -2271,6 +2388,14 @@ "to-regex": "^3.0.1" }, "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -2286,6 +2411,11 @@ "requires": { "is-extendable": "^0.1.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -2409,11 +2539,24 @@ "type-is": "~1.6.15" } }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "qs": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", @@ -2680,6 +2823,14 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, + "fast-xml-parser": { + "version": "3.12.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.12.5.tgz", + "integrity": "sha512-g8TSGUF1a2vdFmQ29vKcYBNnwuJQQuyr6It3cjGsiD3dkUXqVWuXZQvjEkgrrCe5K8D30X125ACyxaj7XaaH8g==", + "requires": { + "nimnjs": "^1.3.2" + } + }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -2762,6 +2913,19 @@ "unpipe": "~1.0.0" }, "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -2786,6 +2950,29 @@ "locate-path": "^2.0.0" } }, + "follow-redirects": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.8.tgz", + "integrity": "sha512-sy1mXPmv7kLAMKW/8XofG7o9T+6gAjzdZK4AJF6ryqQYUa/hnzgiypoeUecZ53x7XiqKNEpNqLtS97MshW2nxg==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -4225,6 +4412,15 @@ } } }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "header-case": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", @@ -4822,6 +5018,14 @@ "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=", "dev": true }, + "json-edm-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/json-edm-parser/-/json-edm-parser-0.1.2.tgz", + "integrity": "sha1-HmCw/vG8CvZ7wNFG393lSGzWFbQ=", + "requires": { + "jsonparse": "~1.2.0" + } + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -4898,6 +5102,11 @@ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "dev": true }, + "jsonparse": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.2.0.tgz", + "integrity": "sha1-XAxWhRBxYOcv50ib3eoLRMK8Z70=" + }, "jsonwebtoken": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz", @@ -4946,6 +5155,23 @@ "lru-memoizer": "^1.6.0", "ms": "^2.0.0", "request": "^2.73.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + } } }, "jws": { @@ -5405,6 +5631,15 @@ "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", "dev": true }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -5419,9 +5654,9 @@ } }, "memfs": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-2.9.4.tgz", - "integrity": "sha512-wstvgqSTBGf9rQHoaRpX3wJiGzB/sj649XaO+byuHiPZQaR3Y/mOgU6n9iMFLtAHlR4BwwBWFgA4hobiU6EcCg==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-2.10.0.tgz", + "integrity": "sha512-GuQXfXghDdDdkokv6cwaWLh8bOD9Ots4z11qUR9yKiCeO7oMPhBjFjKVc991DIHTXFbonqKYOEDAVTa4CvvkJg==", "dev": true, "requires": { "fast-extend": "0.0.2", @@ -5555,6 +5790,30 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" }, + "ms-rest-js": { + "version": "0.21.413", + "resolved": "https://registry.npmjs.org/ms-rest-js/-/ms-rest-js-0.21.413.tgz", + "integrity": "sha512-eX+M98Y9s+zo85Unt83TYkpuJkW4d0wuiHrpWjAxx/7YzZd3uVq8HRhJHXGDqCd22nlEvtwlchfgwILmBcWnOg==", + "requires": { + "@types/express": "^4.11.1", + "@types/form-data": "^2.2.1", + "@types/node": "^9.4.6", + "@types/uuid": "^3.4.3", + "axios": "^0.18.0", + "form-data": "^2.3.2", + "tough-cookie": "^2.4.3", + "tslib": "^1.9.2", + "uuid": "^3.2.1", + "xml2js": "^0.4.19" + }, + "dependencies": { + "@types/node": { + "version": "9.6.31", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.31.tgz", + "integrity": "sha512-kIVlvUBizL51ALNMPbmcZoM7quHyB7J6fLRwQe22JsMp39nrVSHdBeVVS3fnQCK1orxI3O8LScmb8cuiihkAfA==" + } + } + }, "multimatch": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", @@ -5608,6 +5867,25 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "nimn-date-parser": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nimn-date-parser/-/nimn-date-parser-1.0.0.tgz", + "integrity": "sha512-1Nf+x3EeMvHUiHsVuEhiZnwA8RMeOBVTQWfB1S2n9+i6PYCofHd2HRMD+WOHIHYshy4T4Gk8wQoCol7Hq3av8Q==" + }, + "nimn_schema_builder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nimn_schema_builder/-/nimn_schema_builder-1.1.0.tgz", + "integrity": "sha512-DK5/B8CM4qwzG2URy130avcwPev4uO0ev836FbQyKo1ms6I9z/i6EJyiZ+d9xtgloxUri0W+5gfR8YbPq7SheA==" + }, + "nimnjs": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/nimnjs/-/nimnjs-1.3.2.tgz", + "integrity": "sha512-TIOtI4iqkQrUM1tiM76AtTQem0c7e56SkDZ7sj1d1MfUsqRcq2ZWQvej/O+HBTZV7u/VKnwlKTDugK/75IRPPw==", + "requires": { + "nimn-date-parser": "^1.0.0", + "nimn_schema_builder": "^1.0.0" + } + }, "no-case": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", @@ -6330,6 +6608,23 @@ "async": "^1.5.2", "debug": "^2.2.0", "mkdirp": "0.5.x" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "posix-character-classes": { @@ -6338,9 +6633,9 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postgres-array": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.2.tgz", - "integrity": "sha1-jgsy6wO/d6XAp4UeBEHBaaJWojg=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.3.tgz", + "integrity": "sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ==", "dev": true }, "postgres-bytea": { @@ -6376,14 +6671,14 @@ "dev": true }, "prisma": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-1.16.0.tgz", - "integrity": "sha512-8jZYCrkd1xjy+JJbQi81f8PBOLe8LLWwSu0fK0cqekm3FeafBd8xk5b0RWcIsHyVd6ypKCQt3tnZEMVzmbKrdQ==", + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-1.16.4.tgz", + "integrity": "sha512-ha+SJDnJ+NVtkoP4nivcmnKV/PmkbQiXVJUPEdYfkQPpuite1kOuFp9seolE4DJFaz3m8DlF24AQf7aePf09AQ==", "dev": true, "requires": { "fs-extra": "^5.0.0", - "prisma-cli-core": "1.0.76", - "prisma-cli-engine": "1.0.79", + "prisma-cli-core": "1.0.79", + "prisma-cli-engine": "1.0.82", "semver": "^5.4.1", "source-map-support": "^0.4.18" }, @@ -6502,9 +6797,9 @@ } }, "prisma-cli-core": { - "version": "1.0.76", - "resolved": "https://registry.npmjs.org/prisma-cli-core/-/prisma-cli-core-1.0.76.tgz", - "integrity": "sha512-HtHn/RM2GlJi23KoIXHoboP97aC54SYDqr7B4uT/80JP6A6nQp5HLt4sJgNfKapaHFZVzXYM7M3LEfGq3tgQbw==", + "version": "1.0.79", + "resolved": "https://registry.npmjs.org/prisma-cli-core/-/prisma-cli-core-1.0.79.tgz", + "integrity": "sha512-3xaFE0wK48nZ8LOqx62gMoFgjIob121Uo6RHOnXNXMcCOdtGM7VfGw4o6gyDVwNDvu66fz0EVLaQGcJb5hnTpA==", "dev": true, "requires": { "adm-zip": "^0.4.7", @@ -6538,9 +6833,9 @@ "opn": "^5.1.0", "pause": "^0.1.0", "portfinder": "^1.0.13", - "prisma-db-introspection": "0.0.46", + "prisma-db-introspection": "0.0.50", "prisma-json-schema": "0.0.4", - "prisma-yml": "1.0.96", + "prisma-yml": "1.0.100", "scuid": "^1.0.2", "semver": "^5.4.1", "sillyname": "^0.1.0", @@ -6646,12 +6941,12 @@ } }, "graphql-config": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-2.1.0.tgz", - "integrity": "sha512-LWpkME3x+KSFMVuMpRmDHTIZLyQQsBoKtMXJrT4RgXk6y0GRf0lsJ81R3S2FmT1CKZQOJfFsOpUfPpAcfmoN/A==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-2.2.1.tgz", + "integrity": "sha512-U8+1IAhw9m6WkZRRcyj8ZarK96R6lQBQ0an4lp76Ps9FyhOXENC5YQOxOFGm5CxPrX2rD0g3Je4zG5xdNJjwzQ==", "dev": true, "requires": { - "graphql-import": "^0.4.4", + "graphql-import": "^0.7.1", "graphql-request": "^1.5.0", "js-yaml": "^3.10.0", "lodash": "^4.17.4", @@ -6697,12 +6992,13 @@ } }, "graphql-import": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.4.5.tgz", - "integrity": "sha512-G/+I08Qp6/QGTb9qapknCm3yPHV0ZL7wbaalWFpxsfR8ZhZoTBe//LsbsCKlbALQpcMegchpJhpTSKiJjhaVqQ==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.7.1.tgz", + "integrity": "sha512-YpwpaPjRUVlw2SN3OPljpWbVRWAhMAyfSba5U47qGMOSsPLi2gYeJtngGpymjm9nk57RFWEpjqwh4+dpYuFAPw==", "dev": true, "requires": { - "lodash": "^4.17.4" + "lodash": "^4.17.4", + "resolve-from": "^4.0.0" } }, "inquirer": { @@ -6778,9 +7074,9 @@ "dev": true }, "prisma-yml": { - "version": "1.0.96", - "resolved": "https://registry.npmjs.org/prisma-yml/-/prisma-yml-1.0.96.tgz", - "integrity": "sha512-w3XGzJHUq5pwBoFy/amkGOcTDj4XoHh8UFUUUZcHo5fSyoF8AWeRTu1yWINaPVGxbcmpwKNetntAW4ijiq7M5g==", + "version": "1.0.100", + "resolved": "https://registry.npmjs.org/prisma-yml/-/prisma-yml-1.0.100.tgz", + "integrity": "sha512-W2a0dpfbXyapc3WZqcvUBqtsl2r9upQRUR2p53AqQR4tQz+/6nsMcqe30vqgnOW/WmNAnknqQT3Z5P0rsq4K3Q==", "dev": true, "requires": { "ajv": "5", @@ -6803,6 +7099,12 @@ "yaml-ast-parser": "^0.0.40" } }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -6827,9 +7129,9 @@ } }, "prisma-cli-engine": { - "version": "1.0.79", - "resolved": "https://registry.npmjs.org/prisma-cli-engine/-/prisma-cli-engine-1.0.79.tgz", - "integrity": "sha512-CdEIJs4ld1IiQQt2CFFPmeDypN4Ct4sTgmFODVjJix790mpEtxMagzCcA+mhfnRL65P6xiHn76Gdxbz60GyYBA==", + "version": "1.0.82", + "resolved": "https://registry.npmjs.org/prisma-cli-engine/-/prisma-cli-engine-1.0.82.tgz", + "integrity": "sha512-kEqNtH0bjzVX17Vcs77UiAwk0Ei9Za03bOINcrpIjNUyI9GOOU5p+6ss8cePfK21lxvy5RSlYwthBFLkXE73Gg==", "dev": true, "requires": { "@heroku/linewrap": "^1.0.0", @@ -6872,7 +7174,7 @@ "memfs": "^2.5.3", "opn": "^5.1.0", "prisma-json-schema": "0.0.4", - "prisma-yml": "1.0.96", + "prisma-yml": "1.0.100", "raven": "2.3.0", "replaceall": "^0.1.6", "rwlockfile": "^1.4.8", @@ -6937,9 +7239,9 @@ "dev": true }, "prisma-yml": { - "version": "1.0.96", - "resolved": "https://registry.npmjs.org/prisma-yml/-/prisma-yml-1.0.96.tgz", - "integrity": "sha512-w3XGzJHUq5pwBoFy/amkGOcTDj4XoHh8UFUUUZcHo5fSyoF8AWeRTu1yWINaPVGxbcmpwKNetntAW4ijiq7M5g==", + "version": "1.0.100", + "resolved": "https://registry.npmjs.org/prisma-yml/-/prisma-yml-1.0.100.tgz", + "integrity": "sha512-W2a0dpfbXyapc3WZqcvUBqtsl2r9upQRUR2p53AqQR4tQz+/6nsMcqe30vqgnOW/WmNAnknqQT3Z5P0rsq4K3Q==", "dev": true, "requires": { "ajv": "5", @@ -6995,9 +7297,9 @@ } }, "prisma-db-introspection": { - "version": "0.0.46", - "resolved": "https://registry.npmjs.org/prisma-db-introspection/-/prisma-db-introspection-0.0.46.tgz", - "integrity": "sha512-/b7evS9b5xKS7UrcOERkCmV+IWC6OAgFtInFsvdwn4MeLEaVbkOfzRakdOo+t2gb+N7Yy8Eey9eKYgB5jiJAbA==", + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/prisma-db-introspection/-/prisma-db-introspection-0.0.50.tgz", + "integrity": "sha512-coeJ3SRumezVnsQwc/kwNzxWFUBKHNwnD+keUJeZFFY3j7EDtRFHoL5DD7vTREvMEugoWOiovc+MYHFkDt0l+w==", "dev": true, "requires": { "ajv": "5", @@ -7637,6 +7939,14 @@ "statuses": "~1.4.0" }, "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -7799,6 +8109,14 @@ "use": "^3.1.0" }, "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -7815,6 +8133,11 @@ "is-extendable": "^0.1.0" } }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -8061,9 +8384,9 @@ "dev": true }, "string-similarity": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-1.2.1.tgz", - "integrity": "sha512-XqC6lRZF3UIYdxBRHjIfJwU2nYzPm+E8udKFHjIplnRQflkXP1A1Ie3HoEv04W/zY1wGnV6TQpklM2WwZO3gIA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-1.2.2.tgz", + "integrity": "sha512-IoHUjcw3Srl8nsPlW04U3qwWPk3oG2ffLM0tN853d/E/JlIvcmZmDY2Kz5HzKp4lEi2T7QD7Zuvjq/1rDw+XcQ==", "dev": true, "requires": { "lodash.every": "^4.6.0", @@ -8463,6 +8786,11 @@ "yn": "^2.0.0" } }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -8492,9 +8820,9 @@ "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" }, "unbzip2-stream": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz", - "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.0.tgz", + "integrity": "sha512-kE2WkurNnPUMcryNioS68DDbhoPB8Qxsd8btHSj+sd5Pjh2GsjmeHLzMSqV9HHziAo8FzVxVCJl9ZYhk7yY1pA==", "dev": true, "requires": { "buffer": "^3.0.1", @@ -8532,8 +8860,28 @@ "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", "requires": { "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, "union-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", diff --git a/api/package.json b/api/package.json index 784b66264..9e5311fb1 100644 --- a/api/package.json +++ b/api/package.json @@ -7,9 +7,13 @@ "dev": "npm-run-all --parallel debug playground" }, "dependencies": { + "@azure/storage-blob": "^10.0.0-preview", + "azure-storage": "^2.10.1", "cors": "^2.8.4", + "debug": "^4.0.1", "dotenv": "^6.0.0", "express-jwt": "^5.3.1", + "fast-xml-parser": "^3.12.5", "graphql-import": "^0.6.0", "graphql-tag": "^2.9.2", "graphql-tools": "3.1.1", @@ -23,6 +27,6 @@ "devDependencies": { "graphql-cli": "^2.16.5", "npm-run-all": "4.1.3", - "prisma": "^1.16.0" + "prisma": "^1.16.4" } } diff --git a/api/src/index.js b/api/src/index.js index d640b8682..792f8505e 100644 --- a/api/src/index.js +++ b/api/src/index.js @@ -7,11 +7,32 @@ const { } = require('prisma-binding') const { makeExecutableSchema } = require('graphql-tools') const { importSchema } = require('graphql-import') +const parser = require('fast-xml-parser') const checkJwt = require('./auth/middleware/jwt') const { getMember } = require('./auth/middleware/getMember') const { validateIdToken } = require('./auth/validateIdToken') const { directiveResolvers } = require('./auth/authDirectives') +const { + createStoragePipline, + createServiceURL, + listContainers, + createContainer, + createBlob, + uploadBlob, + downloadBlob, + deleteBlob, + deleteContainer +} = require('./storage/azure') +//var azure = require('azure-storage') +const Azure = require("@azure/storage-blob") +const azureAccount = process.env.AZURE_STORAGE_ACCOUNT +const azureKey = process.env.AZURE_STORAGE_ACCESS_KEY +const azureStorageUrl = process.env.AZURE_STORAGE_URL + +var debug = require('debug')('http') + , http = require('http') + , name = 'My App'; const TEAMS_FRAGMENT = require('./graphql/TeamsFragment') const TEAMS_CONNECTIONS_FRAGMENT = require('./graphql/TeamsConnectionsFragment') @@ -115,6 +136,57 @@ const resolvers = { return error.message }) }) + }, + async getAzureSAS(parent, { teamSlug }, ctx, info) { + // Create start and expiry times + let today = new Date() + let tomorrow = new Date() + tomorrow.setDate(today.getDate() + 7) + // Create SharedKeyCredential and attach to pipline + const SKC = new Azure.SharedKeyCredential(azureAccount, azureKey) + const pipeline = Azure.StorageURL.newPipeline(SKC) + // Create container URL + const serviceURL = new Azure.ServiceURL(azureStorageUrl, pipeline) + const containerName = teamSlug + const containerURL = Azure.ContainerURL.fromServiceURL(serviceURL, containerName) + + let marker + let containerCheck = null + do { + const listContainersResponse = await serviceURL.listContainersSegment( + Azure.Aborter.None, + marker, + ) + console.log(`ContainerCheck marker: `, listContainersResponse) + marker = listContainersResponse.marker; + for (const container of listContainersResponse.containerItems) { + console.log(`ContainerCheck: ${container.name} | ${containerName} | ${marker}`) + if(container.name === containerName){ + containerCheck = container.name + } + } + } while (marker) + let newContainer + if(containerCheck === null){ + newContainer = await containerURL.create(Azure.Aborter.None, { access: 'blob' }) + } + console.log('getAzureSAS container: ', containerURL, containerCheck, newContainer) + + // Set permissions for service, resource types and containers + const SASServicePerms = Azure.AccountSASServices.parse('b') + const SASResourceTypes = Azure.AccountSASResourceTypes.parse('co') + const SASContainerPerms = Azure.ContainerSASPermissions.parse('rwl') + // Generate SAS url + const SASQueryParameters = Azure.generateAccountSASQueryParameters( + { + containerName, + permissions: SASContainerPerms, + startTime: today, + expiryTime: tomorrow, + services: SASServicePerms, + resourceTypes: SASResourceTypes + }, SKC ) + return SASQueryParameters } } } @@ -148,7 +220,7 @@ server.express.use( server.options.endpoint, checkJwt, function (err, req, res, next) { - console.log('checkJwt: ', err, req) + // console.log('checkJwt: ', err, req) if (err) { return res.status(201).send(err.message) } else { diff --git a/api/src/schema.graphql b/api/src/schema.graphql index 1450c6000..731948163 100644 --- a/api/src/schema.graphql +++ b/api/src/schema.graphql @@ -21,6 +21,7 @@ type Mutation { createTeam(name: String!, slug: String!, owner: String!): Team @isAuthenticated updateTeamProfile(slug: String!, owner: String!, description: String, motto: String, avatar: String): Team @isAuthenticated deleteTeam(slug: String!): Team @isAuthenticated @isOwner(type: "Team") + getAzureSAS(teamSlug: String!):String } input MemberProfileInput { diff --git a/api/src/storage/azure.js b/api/src/storage/azure.js new file mode 100644 index 000000000..324181b04 --- /dev/null +++ b/api/src/storage/azure.js @@ -0,0 +1,133 @@ +const Azure = require('@azure/storage-blob') + +/* Create Azure Storage pipeline +* @accountName: Azure Blob Storage account name (required) - Environment variable +* @accountKey: Azure Blob Storage storage key (required) - Environment variable +*/ +const createStoragePipline = async (accountNAme, accountKey) => { + return Azure.StorageURL.newPipeline( + new Azure.SharedKeyCredential(accountName, accountKey) + ) +} + +/* Create Azure Storage Service URL +* @storageURL: URL for Azure Storage endpoint (required) - Environment variable +* @pipeline: Azure Storage Pipline (required) - created using createStoragePipeline() +*/ +const createServiceURL = async (storageURL, pipeline) => { + return new Azure.ServiceURL( + storageURL, + pipeline + ) +} + +/* List containers +* @pipeline: Azure Storage Pipline (required) - created using createServiceURL +* @service_url: URL for Azure Storage endpoint (required) - Environment variable +*/ +const listContainers = async (serviceURL) => { + let marker; + do { + const listContainersResponse = await serviceURL.listContainersSegment( + Azure.Aborter.None, + marker, + ); + + marker = listContainersResponse.marker; + for (const container of listContainersResponse.containerItems) { + console.log(`Container: ${container.name}`); + } + } while (marker); +} + + +/* Create containers +* @serviceURL: URL for Azure Storage endpoint (required) - created using createServiceURL +* @containerName: Container Name +* Returns: containerURL +*/ +const createContainer = async (serviceURL, containerName) => { + const containerURL = ContainerURL.fromServiceURL(serviceURL, containerName) + + const createContainerResponse = await containerURL.create(Aborter.None) + + console.log( + `Created container ${containerName} successfully`, + await createContainerResponse.requestId + ) + return containerURL +} + +/* Create containers +* @containerURL: continer URL (required) - created using createContainer +* @blobName: Blob Name +* Returns: blobURL +*/ +const createBlob = async (containerURL, blobName) => { + const blobURL = Azure.BlobURL.fromContainerURL(containerURL, blobName) + console.log(`created blob successfully`, await blobURL) + return blobURL +} + +/* Upload Blob +* @blobURL: blobURL (required) - created using createBlob +* @blobContent: Blob Content +* Returns: uploadBlobResponse +*/ +const uploadBlob = async (blobURL, blobContent) => { + const blockBlobURL = Azure.BlockBlobURL.fromBlobURL(blobURL) + const uploadBlobResponse = await blockBlobURL.upload( + Azure.Aborter.None, + blobContent, + blobContent.length + ); + console.log(`Upload block blob ${blobName} successfully`, await uploadBlobResponse) + return uploadBlobResponse +} + +/* Download Blob +* @blobURL: blobURL (required) - created using createBlob +* @blobContent: Blob Content +* Returns: downloadBlockBlobResponse +*/ +const downloadBlob = async (blobURL, blobContent) => { + const downloadBlockBlobResponse = await blobURL.download(Azure.Aborter.None, 0) + console.log( + "Downloaded blob content", + downloadBlockBlobResponse.readableStreamBody.read(content.length).toString() + ) + console.log(`BlockBlobResponse: ${downloadBlockBlobResponse}`) + return downloadBlockBlobResponse +} + +/* Delete Blob +* @blobURL: blobURL (required) - created using createBlob +* Returns: bool +*/ +const deleteBlob = async (blobrURL) => { + await blobrURL.delete(Azure.Aborter.None); + console.log("deleted blob", blobrURL); + return true +} + +/* Delete Container +* @containerURL: continer URL (required) - created using createContainer +* Returns: bool +*/ +const deleteContainer = async (containerURL) => { + await containerURL.delete(Azure.Aborter.None); + console.log("deleted container", containerURL); + return true +} + +module.exports = { + createStoragePipline, + createServiceURL, + listContainers, + createContainer, + createBlob, + uploadBlob, + downloadBlob, + deleteBlob, + deleteContainer +} diff --git a/client/package-lock.json b/client/package-lock.json index 219ddf2b8..52252110b 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -4,6 +4,14 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@azure/storage-blob": { + "version": "10.0.0-preview", + "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-10.0.0-preview.tgz", + "integrity": "sha512-PFXKm+gipKDfg5h08hPiEr0Za4RMiFzzte+ewh4ACZeRQa0XZK55NAZxW67ZytGBd7WXdQq6pcAgo5dBnwQANQ==", + "requires": { + "ms-rest-js": "0.21.413" + } + }, "@babel/code-frame": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", @@ -2204,6 +2212,56 @@ "integrity": "sha512-Benr3i5odUkvpFkOpzGqrltGdbSs+EVCkEBGXbuR7uT0VzhXKIkhem6PDzHdx5EonA+rfbB3QvP6aDOw5+zp5Q==", "optional": true }, + "@types/body-parser": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz", + "integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", + "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", + "requires": { + "@types/node": "*" + } + }, + "@types/events": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", + "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==" + }, + "@types/express": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.16.0.tgz", + "integrity": "sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz", + "integrity": "sha512-lTeoCu5NxJU4OD9moCgm0ESZzweAx0YqsAcab6OB0EB3+As1OaHtKnaGJvcngQxYsi9UNv0abn4/DRavrRxt4w==", + "requires": { + "@types/events": "*", + "@types/node": "*", + "@types/range-parser": "*" + } + }, + "@types/form-data": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", + "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", + "requires": { + "@types/node": "*" + } + }, "@types/graphql": { "version": "0.12.6", "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-0.12.6.tgz", @@ -2218,11 +2276,15 @@ "indefinite-observable": "^1.0.1" } }, + "@types/mime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", + "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==" + }, "@types/node": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.0.tgz", - "integrity": "sha512-hWzNviaVFIr1TqcRA8ou49JaSHp+Rfabmnqg2kNvusKqLhPU0rIsGPUj5WJJ7ld4Bb7qdgLmIhLfCD1qS08IVA==", - "dev": true + "integrity": "sha512-hWzNviaVFIr1TqcRA8ou49JaSHp+Rfabmnqg2kNvusKqLhPU0rIsGPUj5WJJ7ld4Bb7qdgLmIhLfCD1qS08IVA==" }, "@types/prop-types": { "version": "15.5.5", @@ -2232,6 +2294,11 @@ "@types/react": "*" } }, + "@types/range-parser": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.2.tgz", + "integrity": "sha512-HtKGu+qG1NPvYe1z7ezLsyIaXYyi8SoAVqWDZgDQ8dLrsZvSzUNCwZyfX33uhWxL/SU0ZDQZ3nwZ0nimt507Kw==" + }, "@types/react": { "version": "16.4.14", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.4.14.tgz", @@ -2249,6 +2316,15 @@ "@types/react": "*" } }, + "@types/serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==", + "requires": { + "@types/express-serve-static-core": "*", + "@types/mime": "*" + } + }, "@types/tapable": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-0.2.5.tgz", @@ -2272,6 +2348,14 @@ } } }, + "@types/uuid": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.4.tgz", + "integrity": "sha512-tPIgT0GUmdJQNSHxp0X2jnpQfBSTfGxUMc/2CXBU2mnyTFVYVa2ojpoQ74w0U2yn2vw3jnC640+77lkFFpdVDw==", + "requires": { + "@types/node": "*" + } + }, "@types/webpack": { "version": "3.8.12", "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-3.8.12.tgz", @@ -3230,6 +3314,15 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, + "axios": { + "version": "0.18.0", + "resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz", + "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", + "requires": { + "follow-redirects": "^1.3.0", + "is-buffer": "^1.1.5" + } + }, "axobject-query": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.1.tgz", @@ -4645,6 +4738,11 @@ "safe-buffer": "^5.1.1" } }, + "blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==" + }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", @@ -7670,6 +7768,14 @@ "readable-stream": "^2.0.4" } }, + "follow-redirects": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.8.tgz", + "integrity": "sha512-sy1mXPmv7kLAMKW/8XofG7o9T+6gAjzdZK4AJF6ryqQYUa/hnzgiypoeUecZ53x7XiqKNEpNqLtS97MshW2nxg==", + "requires": { + "debug": "=3.1.0" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -9408,8 +9514,7 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-builtin-module": { "version": "1.0.0", @@ -11565,6 +11670,53 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "ms-rest-js": { + "version": "0.21.413", + "resolved": "https://registry.npmjs.org/ms-rest-js/-/ms-rest-js-0.21.413.tgz", + "integrity": "sha512-eX+M98Y9s+zo85Unt83TYkpuJkW4d0wuiHrpWjAxx/7YzZd3uVq8HRhJHXGDqCd22nlEvtwlchfgwILmBcWnOg==", + "requires": { + "@types/express": "^4.11.1", + "@types/form-data": "^2.2.1", + "@types/node": "^9.4.6", + "@types/uuid": "^3.4.3", + "axios": "^0.18.0", + "form-data": "^2.3.2", + "tough-cookie": "^2.4.3", + "tslib": "^1.9.2", + "uuid": "^3.2.1", + "xml2js": "^0.4.19" + }, + "dependencies": { + "@types/node": { + "version": "9.6.31", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.31.tgz", + "integrity": "sha512-kIVlvUBizL51ALNMPbmcZoM7quHyB7J6fLRwQe22JsMp39nrVSHdBeVVS3fnQCK1orxI3O8LScmb8cuiihkAfA==" + }, + "tough-cookie": { + "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==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + } + } + }, "multimatch": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", @@ -13579,6 +13731,11 @@ "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==" + }, "public-encrypt": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", @@ -14565,8 +14722,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "schedule": { "version": "0.3.0", @@ -15735,8 +15891,7 @@ "tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "dev": true + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" }, "tty-browserify": { "version": "0.0.0", diff --git a/client/package.json b/client/package.json index 3fb9b227e..f40fe138f 100644 --- a/client/package.json +++ b/client/package.json @@ -67,6 +67,7 @@ "workbox-cli": "^3.4.1" }, "dependencies": { + "@azure/storage-blob": "^10.0.0-preview", "@material-ui/core": "^3.0.3", "@material-ui/icons": "^3.0.1", "apollo-cache-inmemory": "^1.2.9", @@ -80,6 +81,7 @@ "auth0-lock": "^11.9.0", "azure-storage": "^2.10.1", "babel-polyfill": "^6.26.0", + "blob-util": "^2.0.2", "classnames": "^2.2.6", "cross-fetch": "^2.2.2", "dotenv-webpack": "^1.5.7", diff --git a/client/src/graphql/teams/GetAzureSASMutation.js b/client/src/graphql/teams/GetAzureSASMutation.js new file mode 100644 index 000000000..abb9ffef3 --- /dev/null +++ b/client/src/graphql/teams/GetAzureSASMutation.js @@ -0,0 +1,10 @@ +/* eslint-disable no-unused-vars */ +import gql from 'graphql-tag' + +export const GET_AZURE_SAS = gql` + mutation getAzureSAS($teamSlug: String!) { + getAzureSAS(teamSlug: $teamSlug) + } +` + +export default GET_AZURE_SAS diff --git a/client/src/views/common/UploadImage.js b/client/src/views/common/UploadImage.js index f5b625c8f..e9662db08 100644 --- a/client/src/views/common/UploadImage.js +++ b/client/src/views/common/UploadImage.js @@ -1,9 +1,10 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' +import { Mutation } from 'react-apollo' import Dropzone from 'react-dropzone' -// import ReactCrop from 'react-image-crop' import { Cropper } from 'react-image-cropper' -// import azure from 'azure-storage' +import * as Azure from '@azure/storage-blob' +import { imgSrcToBlob } from 'blob-util' import { withStyles } from '@material-ui/core/styles' import Dialog from '@material-ui/core/Dialog' @@ -11,6 +12,8 @@ import DialogActions from '@material-ui/core/DialogActions' import DialogContent from '@material-ui/core/DialogContent' import Button from '@material-ui/core/Button' +import GET_AZURE_SAS from '../../graphql/teams/GetAzureSASMutation' + const styles = theme => ({ dropzoneContainer: { display: 'block', @@ -54,6 +57,8 @@ class UploadImage extends Component { this.getCroppedImg = this.getCroppedImg.bind(this) this.handleClickOpen = this.handleClickOpen.bind(this) this.handleClose = this.handleClose.bind(this) + this.handleSubmit = this.handleSubmit.bind(this) + this.saveAvatar = this.saveAvatar.bind(this) this.state = { open: false, @@ -86,7 +91,21 @@ class UploadImage extends Component { )} {this.state.cropped !== null && ( - Crop Preview + + {(getAzureSAS, { loading, error, data }) => { + console.log('getAzureSAS: ', error, data) + console.log('getAzureSAS keys: ', process.env.AZURE_STORAGE_URL, process.env.AZURE_SAS) + if (data !== undefined && data.getAzureSAS !== null) { + this.saveAvatar(data.getAzureSAS, team.slug) + } + return ( +
+ Crop Preview + +
+ ) + }} +
)} {this.state.src !== null && ( { - if (error) return (

{error}

) - return 'Success' - } - ) - xhr.send() + await uploadBrowserDataToBlockBlob(Aborter.None, file, blockBlobURL, { + blockSize: 4 * 1024 * 1024, // 4MB block size + parallelism: 20, // 20 concurrency + progress: ev => console.log(ev) + }); } */ } From ecc538648e1ebd33fe94fd3d768b6eb740acf659 Mon Sep 17 00:00:00 2001 From: Barry Low Date: Thu, 20 Sep 2018 17:51:41 -0700 Subject: [PATCH 3/4] Save uploaded avatar to team --- api/database/datamodel.graphql | 1 + api/src/generated/prisma.graphql | 77 +++++- api/src/graphql/TeamsFragment.js | 1 + api/src/index.js | 13 +- api/src/schema.graphql | 7 +- client/package-lock.json | 5 + client/package.json | 1 + client/src/graphql/teams/GetAllTeamsQuery.js | 1 + .../src/graphql/teams/GetTeamsByOwnerQuery.js | 1 + client/src/graphql/teams/Teams.js | 1 + .../teams/UpdateTeamProfileMutation.js | 19 +- client/src/views/common/UploadImage.js | 232 ++++++++---------- .../dashboard/components/ManageTeamEdit.js | 19 +- .../dashboard/components/ManageTeamsItem.js | 61 +++-- 14 files changed, 255 insertions(+), 184 deletions(-) diff --git a/api/database/datamodel.graphql b/api/database/datamodel.graphql index ddc89814c..b5627825e 100644 --- a/api/database/datamodel.graphql +++ b/api/database/datamodel.graphql @@ -41,6 +41,7 @@ type TeamProfile { description: String motto: String avatar: String + banner: String updatedAt: DateTime! createdAt: DateTime! } diff --git a/api/src/generated/prisma.graphql b/api/src/generated/prisma.graphql index 6d118e29a..99d9f7562 100644 --- a/api/src/generated/prisma.graphql +++ b/api/src/generated/prisma.graphql @@ -1,5 +1,5 @@ # source: http://localhost:4466 -# timestamp: Wed Sep 12 2018 08:41:57 GMT-0700 (Pacific Daylight Time) +# timestamp: Thu Sep 20 2018 16:52:44 GMT-0700 (Pacific Daylight Time) type AggregateFBStatus { count: Int! @@ -1400,7 +1400,9 @@ type TeamProfile { description: String motto: String avatar: String + banner: String updatedAt: DateTime! + createdAt: DateTime! } """A connection to a list of items.""" @@ -1417,6 +1419,7 @@ input TeamProfileCreateInput { description: String motto: String avatar: String + banner: String } input TeamProfileCreateOneInput { @@ -1439,19 +1442,23 @@ enum TeamProfileOrderByInput { motto_DESC avatar_ASC avatar_DESC + banner_ASC + banner_DESC updatedAt_ASC updatedAt_DESC - id_ASC - id_DESC createdAt_ASC createdAt_DESC + id_ASC + id_DESC } type TeamProfilePreviousValues { description: String motto: String avatar: String + banner: String updatedAt: DateTime! + createdAt: DateTime! } type TeamProfileSubscriptionPayload { @@ -1497,12 +1504,14 @@ input TeamProfileUpdateDataInput { description: String motto: String avatar: String + banner: String } input TeamProfileUpdateInput { description: String motto: String avatar: String + banner: String } input TeamProfileUpdateOneInput { @@ -1647,6 +1656,46 @@ input TeamProfileWhereInput { """All values not ending with the given string.""" avatar_not_ends_with: String + banner: String + + """All values that are not equal to given value.""" + banner_not: String + + """All values that are contained in given list.""" + banner_in: [String!] + + """All values that are not contained in given list.""" + banner_not_in: [String!] + + """All values less than the given value.""" + banner_lt: String + + """All values less than or equal the given value.""" + banner_lte: String + + """All values greater than the given value.""" + banner_gt: String + + """All values greater than or equal the given value.""" + banner_gte: String + + """All values containing the given string.""" + banner_contains: String + + """All values not containing the given string.""" + banner_not_contains: String + + """All values starting with the given string.""" + banner_starts_with: String + + """All values not starting with the given string.""" + banner_not_starts_with: String + + """All values ending with the given string.""" + banner_ends_with: String + + """All values not ending with the given string.""" + banner_not_ends_with: String updatedAt: DateTime """All values that are not equal to given value.""" @@ -1669,6 +1718,28 @@ input TeamProfileWhereInput { """All values greater than or equal the given value.""" updatedAt_gte: DateTime + createdAt: DateTime + + """All values that are not equal to given value.""" + createdAt_not: DateTime + + """All values that are contained in given list.""" + createdAt_in: [DateTime!] + + """All values that are not contained in given list.""" + createdAt_not_in: [DateTime!] + + """All values less than the given value.""" + createdAt_lt: DateTime + + """All values less than or equal the given value.""" + createdAt_lte: DateTime + + """All values greater than the given value.""" + createdAt_gt: DateTime + + """All values greater than or equal the given value.""" + createdAt_gte: DateTime } type TeamStatus { diff --git a/api/src/graphql/TeamsFragment.js b/api/src/graphql/TeamsFragment.js index e75ce8382..f243480f2 100644 --- a/api/src/graphql/TeamsFragment.js +++ b/api/src/graphql/TeamsFragment.js @@ -13,6 +13,7 @@ const TEAMS_FRAGMENT = gql`{ createdAt profile { avatar + banner description motto updatedAt diff --git a/api/src/index.js b/api/src/index.js index 792f8505e..04eab61d7 100644 --- a/api/src/index.js +++ b/api/src/index.js @@ -121,8 +121,8 @@ const resolvers = { return err }) }, - async updateTeamProfile(parent, { slug, owner, description, motto, avatar }, ctx, info) { - return ctx.db.mutation.updateTeam({data:{profile: {update: {description: description, motto: motto, avatar: avatar}}}, where:{slug: slug}}, TEAMS_FRAGMENT) + async updateTeamProfile(parent, { slug, owner, description, motto, avatar, banner }, ctx, info) { + return ctx.db.mutation.updateTeam({data:{profile: {update: {description: description, motto: motto, avatar: avatar, banner: banner}}}, where:{slug: slug}}, TEAMS_FRAGMENT) .catch((err) => { console.log('createTeam error: ', err) return err @@ -140,8 +140,8 @@ const resolvers = { async getAzureSAS(parent, { teamSlug }, ctx, info) { // Create start and expiry times let today = new Date() - let tomorrow = new Date() - tomorrow.setDate(today.getDate() + 7) + let week = new Date() + week.setDate(today.getDate() + 7) // Create SharedKeyCredential and attach to pipline const SKC = new Azure.SharedKeyCredential(azureAccount, azureKey) const pipeline = Azure.StorageURL.newPipeline(SKC) @@ -179,10 +179,11 @@ const resolvers = { // Generate SAS url const SASQueryParameters = Azure.generateAccountSASQueryParameters( { - containerName, + version: '2017-11-09', permissions: SASContainerPerms, startTime: today, - expiryTime: tomorrow, + expiryTime: week, + protocol: 'https', services: SASServicePerms, resourceTypes: SASResourceTypes }, SKC ) diff --git a/api/src/schema.graphql b/api/src/schema.graphql index 731948163..f27657ccb 100644 --- a/api/src/schema.graphql +++ b/api/src/schema.graphql @@ -19,16 +19,11 @@ type Query { type Mutation { authenticate(idToken: String!): Member createTeam(name: String!, slug: String!, owner: String!): Team @isAuthenticated - updateTeamProfile(slug: String!, owner: String!, description: String, motto: String, avatar: String): Team @isAuthenticated + updateTeamProfile(slug: String!, owner: String!, description: String, motto: String, avatar: String, banner: String): Team @isAuthenticated deleteTeam(slug: String!): Team @isAuthenticated @isOwner(type: "Team") getAzureSAS(teamSlug: String!):String } -input MemberProfileInput { - authId: String! - alias: String! -} - fragment MemberInfo on Member { id authId diff --git a/client/package-lock.json b/client/package-lock.json index 52252110b..c0fbda736 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -4847,6 +4847,11 @@ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, + "browser-image-resizer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browser-image-resizer/-/browser-image-resizer-1.2.0.tgz", + "integrity": "sha512-xMiB6BnRsD6RWmkD6Av90qXY7uaAOXJPaS5D8cSazyao/bx6ENCm67XGl6BIhn1ETjK52yEs8A/atmMPp74M4A==" + }, "browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", diff --git a/client/package.json b/client/package.json index f40fe138f..34a09ec19 100644 --- a/client/package.json +++ b/client/package.json @@ -82,6 +82,7 @@ "azure-storage": "^2.10.1", "babel-polyfill": "^6.26.0", "blob-util": "^2.0.2", + "browser-image-resizer": "^1.2.0", "classnames": "^2.2.6", "cross-fetch": "^2.2.2", "dotenv-webpack": "^1.5.7", diff --git a/client/src/graphql/teams/GetAllTeamsQuery.js b/client/src/graphql/teams/GetAllTeamsQuery.js index a2aab251a..0bd9ed522 100644 --- a/client/src/graphql/teams/GetAllTeamsQuery.js +++ b/client/src/graphql/teams/GetAllTeamsQuery.js @@ -18,6 +18,7 @@ export const GET_ALL_TEAMS_QUERY = gql` createdAt profile { avatar + banner description motto updatedAt diff --git a/client/src/graphql/teams/GetTeamsByOwnerQuery.js b/client/src/graphql/teams/GetTeamsByOwnerQuery.js index d2f60c882..d15834b34 100644 --- a/client/src/graphql/teams/GetTeamsByOwnerQuery.js +++ b/client/src/graphql/teams/GetTeamsByOwnerQuery.js @@ -16,6 +16,7 @@ export const GET_TEAMS_BY_OWNER = gql` createdAt profile { avatar + banner description motto updatedAt diff --git a/client/src/graphql/teams/Teams.js b/client/src/graphql/teams/Teams.js index 76c60bbb8..ce0a6f36b 100644 --- a/client/src/graphql/teams/Teams.js +++ b/client/src/graphql/teams/Teams.js @@ -15,6 +15,7 @@ export const TEAMS_FRAGMENT = gql` createdAt profile { avatar + banner description motto updatedAt diff --git a/client/src/graphql/teams/UpdateTeamProfileMutation.js b/client/src/graphql/teams/UpdateTeamProfileMutation.js index 4a63adffe..cd5e26256 100644 --- a/client/src/graphql/teams/UpdateTeamProfileMutation.js +++ b/client/src/graphql/teams/UpdateTeamProfileMutation.js @@ -3,16 +3,20 @@ import gql from 'graphql-tag' const UPDATE_TEAM_PROFILE = gql` mutation UpdateTeamProfileMutation( - $slug: String! - $owner: String! - $description: String - $motto: String + $slug: String!, + $owner: String!, + $description: String, + $motto: String, + $avatar: String, + $banner: String ) { updateTeamProfile( - slug: $slug - owner: $owner - description: $description + slug: $slug, + owner: $owner, + description: $description, motto: $motto + avatar: $avatar, + banner: $banner ) { id name @@ -26,6 +30,7 @@ const UPDATE_TEAM_PROFILE = gql` createdAt profile { avatar + banner description motto updatedAt diff --git a/client/src/views/common/UploadImage.js b/client/src/views/common/UploadImage.js index e9662db08..94a9c9643 100644 --- a/client/src/views/common/UploadImage.js +++ b/client/src/views/common/UploadImage.js @@ -4,6 +4,7 @@ import { Mutation } from 'react-apollo' import Dropzone from 'react-dropzone' import { Cropper } from 'react-image-cropper' import * as Azure from '@azure/storage-blob' +import readAndCompressImage from 'browser-image-resizer' import { imgSrcToBlob } from 'blob-util' import { withStyles } from '@material-ui/core/styles' @@ -12,6 +13,8 @@ import DialogActions from '@material-ui/core/DialogActions' import DialogContent from '@material-ui/core/DialogContent' import Button from '@material-ui/core/Button' +import MessageCard from './MessageCard' + import GET_AZURE_SAS from '../../graphql/teams/GetAzureSASMutation' const styles = theme => ({ @@ -45,16 +48,21 @@ const styles = theme => ({ } }) +const imageConfig = { + quality: 0.5, + maxWidth: 200, + maxHeight: 200, + autoRotate: true, + debug: true, + mimeType: 'image/jpeg' +} + class UploadImage extends Component { constructor (props) { super(props) - // this.saveToStorage = this.saveToStorage.bind(this) this.onDrop = this.onDrop.bind(this) this.handleCrop = this.handleCrop.bind(this) - this.onCropComplete = this.onCropComplete.bind(this) - this.onCropChange = this.onCropChange.bind(this) - this.getCroppedImg = this.getCroppedImg.bind(this) this.handleClickOpen = this.handleClickOpen.bind(this) this.handleClose = this.handleClose.bind(this) this.handleSubmit = this.handleSubmit.bind(this) @@ -70,17 +78,27 @@ class UploadImage extends Component { width: 200, height: 200 }, + cropping: false, cropped: null, - rejected: null + rejected: null, + uploaded: false, + image: '' } } render () { - const { classes, team, authId } = this.props - console.log('UploadImage', team, authId, this.state) + const { classes, team, authId, handleAvatar } = this.props + let avatar = null + if (team.profile !== null && team.profile.avatar !== undefined && team.profile.avatar !== null && team.profile.avatar !== 'a') { + avatar = team.profile.avatar + } else { + if (this.state.image !== '') avatar = this.state.image + } + + console.log('UploadImage', team, avatar, authId, this.state) return (
- {this.state.src === null && ( + {avatar === null && this.state.src === null && ( Drag-and-drop team avater here or click to select files.
Only *.jpeg and *.png images

)} - {this.state.cropped !== null && ( + {(avatar !== null || this.state.src !== null) && ( {(getAzureSAS, { loading, error, data }) => { console.log('getAzureSAS: ', error, data) - console.log('getAzureSAS keys: ', process.env.AZURE_STORAGE_URL, process.env.AZURE_SAS) - if (data !== undefined && data.getAzureSAS !== null) { - this.saveAvatar(data.getAzureSAS, team.slug) + if (!this.state.uploaded) { + if (data !== undefined && data.getAzureSAS !== null) { + this.saveAvatar(data.getAzureSAS, team.slug, handleAvatar) + } + // this.handleSubmit(getAzureSAS, team.slug) + } + if (this.state.cropping) { + return ( +
+ +
+ ) + } else { + return ( + +
+ Crop Preview +
+ +
+ +
+ { this.cropper = ref }} + onImgLoad={this.onImageLoaded} + /> +
+
+ + + + +
+
+
+ ) } - return ( -
- Crop Preview - -
- ) }}
)} - {this.state.src !== null && ( - -
- -
- { this.cropper = ref }} - onImgLoad={this.onImageLoaded} - /> -
-
- - - - -
-
- )}
) } @@ -167,29 +194,30 @@ class UploadImage extends Component { } } - handleCrop () { - console.log('handleCrop', this.cropper) - this.setState({ cropped: this.cropper.crop(), open: false }) + async handleCrop (e, getAzureSAS, teamSlug, handleAvatar) { + e.preventDefault() + const data = await getAzureSAS({ variables: { teamSlug } }) + console.log('handleCrop', this.cropper, data) + const cropped = this.cropper.crop() + const croppedBlob = await imgSrcToBlob(cropped, 'image/png', 'Anonymous') + let resizedBlob = await readAndCompressImage(croppedBlob, imageConfig) + + return this.setState({ cropped: resizedBlob, cropping: true, open: false }, () => { + this.saveAvatar(data.getAzureSAS, teamSlug, handleAvatar) + }) } async handleSubmit (e, getAzureSAS, teamSlug) { e.preventDefault() - await getAzureSAS({ variables: { teamSlug } }) } - async saveAvatar (SASQueryParameters, teamSlug) { - const blob = await imgSrcToBlob(this.state.cropped, 'image/png', 'Anonymous') - console.log('handleSubmit0:', await blob, await blob.type) - const type = blob.type - let ext - if (type === 'image/jpeg') ext = 'jpg' - if (type === 'image/png') ext = 'png' - const fileName = `${teamSlug}-avatar.${ext}` + async saveAvatar (SASQueryParameters, teamSlug, handleAvatar) { + const fileName = `${teamSlug}-avatar.jpg` console.log('saveAvatar SASurl', process.env.AZURE_SAS_URL) - // const SASurl = `${process.env.AZURE_STORAGE_URL}?${SASQueryParameters}` + const SASurl2 = `${process.env.AZURE_STORAGE_URL}?${SASQueryParameters}` const SASurl = process.env.AZURE_SAS_URL - + console.log('getAzureSAS2 SASurl: ', SASurl2, SASurl) const pipeline = Azure.StorageURL.newPipeline(new Azure.AnonymousCredential()) const serviceURL = new Azure.ServiceURL(SASurl, pipeline) console.log('getAzureSAS2: ', serviceURL) @@ -198,54 +226,15 @@ class UploadImage extends Component { console.log('getAzureSAS3: ', containerURL) const blockBlobURL = Azure.BlockBlobURL.fromContainerURL(containerURL, fileName) - console.log(Azure.Aborter.None, await blob, blockBlobURL) - const avatar = await Azure.uploadBrowserDataToBlockBlob(Azure.Aborter.None, blob, blockBlobURL) + console.log('getAzureSAS34: ', blockBlobURL) + const avatar = await Azure.uploadBrowserDataToBlockBlob(Azure.Aborter.None, this.state.cropped, blockBlobURL) console.log('saveAvatar: ', avatar) + const image = `${process.env.AZURE_STORAGE_URL}${teamSlug}/${fileName}` + handleAvatar(image) + this.setState({ cropping: false, uploaded: true, image: image }) return avatar } - onCropComplete (crop, pixelCrop) { - console.log('onCropComplete', crop, pixelCrop, this.state) - const cropped = this.getCroppedImg(crop, pixelCrop, this.state.src) - this.setState({ cropped }) - } - - onCropChange (crop) { - this.setState({ crop }) - } - - getCroppedImg (image, pixelCrop, fileName) { - const canvas = document.createElement('canvas') - canvas.width = pixelCrop.width - canvas.height = pixelCrop.height - const ctx = canvas.getContext('2d') - - ctx.drawImage( - image, - pixelCrop.x, - pixelCrop.y, - pixelCrop.width, - pixelCrop.height, - 0, - 0, - pixelCrop.width, - pixelCrop.height - ) - - // As Base64 string - return canvas.toDataURL('image/jpeg') - - // As a blob - /* - return new Promise((resolve, reject) => { - canvas.toBlob(file => { - file.name = fileName - resolve(file) - }, 'image/jpeg') - }); - */ - } - handleClickOpen () { this.setState({ open: true }) } @@ -253,36 +242,13 @@ class UploadImage extends Component { handleClose () { this.setState({ open: false, src: null }) } - /* - async saveToStorage (file) { - const blobService = Azure.createBlobService() - const container = '' - - await uploadBrowserDataToBlockBlob(Aborter.None, file, blockBlobURL, { - blockSize: 4 * 1024 * 1024, // 4MB block size - parallelism: 20, // 20 concurrency - progress: ev => console.log(ev) - }); - } - */ } UploadImage.propTypes = { classes: PropTypes.object.isRequired, team: PropTypes.object, - authId: PropTypes.string.isRequired + authId: PropTypes.string.isRequired, + handleAvatar: PropTypes.func.isRequired } export default withStyles(styles)(UploadImage) - -/* - -*/ diff --git a/client/src/views/dashboard/components/ManageTeamEdit.js b/client/src/views/dashboard/components/ManageTeamEdit.js index 9630c04be..5a257cb4a 100644 --- a/client/src/views/dashboard/components/ManageTeamEdit.js +++ b/client/src/views/dashboard/components/ManageTeamEdit.js @@ -41,13 +41,18 @@ export class ManageTeamEdit extends Component { this.handleClose = this.handleClose.bind(this) this.handleChange = this.handleChange.bind(this) this.handleSubmit = this.handleSubmit.bind(this) + this.handleAvatar = this.handleAvatar.bind(this) console.log('ManageTeamEdit', props.team) const motto = props.team.profile.motto || '' const description = props.team.profile.description || '' + const avatar = props.team.profile.avatar || '' + const banner = props.team.profile.banner || '' this.state = { open: false, motto: motto, - description: description + description: description, + avatar: avatar, + banner: banner } } @@ -103,7 +108,7 @@ export class ManageTeamEdit extends Component { Edit Team Details - + ( - - -
- - - - {team.name} - - - {team.createdAt} | Members: {team.members.length} - - - - - - - -
-
-
-) +export const ManageTeamsItem = ({ classes, team, authId }) => { + console.log('ManageTeamsItem', team, team.profile, team.profile.avatar) + let avatar + if (team.profile.avatar !== undefined && team.profile.avatar !== 'a') { + avatar = team.profile.avatar + } else { + avatar = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22288%22%20height%3D%22225%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20288%20225%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_164edaf95ee%22%3E%3Crect%20width%3D%22288%22%20height%3D%22225%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2296.32500076293945%22%20y%3D%22118.8%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E' + } + return ( + + +
+ + + + {team.name} + + + {team.createdAt} | Members: {team.members.length} + + + + + + + +
+
+
+ ) +} ManageTeamsItem.propTypes = { classes: PropTypes.object.isRequired, From 177f804c42de91e6991414529defbdb8477a7d27 Mon Sep 17 00:00:00 2001 From: Barry Low Date: Fri, 21 Sep 2018 00:45:45 -0700 Subject: [PATCH 4/4] Add banner image insert and update --- client/src/views/common/UploadImage.js | 283 ++++++++++++------ .../dashboard/components/ManageTeamDetails.js | 142 ++++++--- .../dashboard/components/ManageTeamEdit.js | 15 +- 3 files changed, 298 insertions(+), 142 deletions(-) diff --git a/client/src/views/common/UploadImage.js b/client/src/views/common/UploadImage.js index 94a9c9643..9aff6ce47 100644 --- a/client/src/views/common/UploadImage.js +++ b/client/src/views/common/UploadImage.js @@ -12,6 +12,7 @@ import Dialog from '@material-ui/core/Dialog' import DialogActions from '@material-ui/core/DialogActions' import DialogContent from '@material-ui/core/DialogContent' import Button from '@material-ui/core/Button' +import Typography from '@material-ui/core/Typography' import MessageCard from './MessageCard' @@ -36,20 +37,28 @@ const styles = theme => ({ dropzoneText: { textAlign: 'center' }, - cropPreview: { - width: 200, - height: 200 + cropAvatarPreview: { + width: 100, + height: 100 }, - cropBox: { + cropBannerPreview: { + width: 400, + height: 100 + }, + cropAvatarBox: { width: 350, height: 350 }, + cropBannerBox: { + width: 650, + height: 350 + }, reactCrop: { } }) -const imageConfig = { - quality: 0.5, +const imageAvatarConfig = { + quality: 0.6, maxWidth: 200, maxHeight: 200, autoRotate: true, @@ -57,6 +66,15 @@ const imageConfig = { mimeType: 'image/jpeg' } +const imageBannerConfig = { + quality: 0.6, + maxWidth: 800, + maxHeight: 200, + autoRotate: true, + debug: true, + mimeType: 'image/jpeg' +} + class UploadImage extends Component { constructor (props) { super(props) @@ -66,10 +84,14 @@ class UploadImage extends Component { this.handleClickOpen = this.handleClickOpen.bind(this) this.handleClose = this.handleClose.bind(this) this.handleSubmit = this.handleSubmit.bind(this) - this.saveAvatar = this.saveAvatar.bind(this) + this.handleChangeImage = this.handleChangeImage.bind(this) + this.cancelChangeImage = this.cancelChangeImage.bind(this) + this.saveImage = this.saveImage.bind(this) this.state = { open: false, + edit: 'avatar', + change: false, file: null, src: null, crop: { @@ -82,103 +104,147 @@ class UploadImage extends Component { cropped: null, rejected: null, uploaded: false, - image: '' + avatarImage: null, + bannerImage: null, + sasqr: null } } render () { - const { classes, team, authId, handleAvatar } = this.props + const { classes, team, authId, handleAvatar, handleBanner } = this.props let avatar = null - if (team.profile !== null && team.profile.avatar !== undefined && team.profile.avatar !== null && team.profile.avatar !== 'a') { - avatar = team.profile.avatar + let banner = null + if ((team.profile !== null && team.profile.avatar !== undefined && team.profile.avatar !== null && team.profile.avatar !== 'a') || this.state.avatarImage !== null) { + avatar = this.state.avatarImage !== null ? this.state.avatarImage : `${team.profile.avatar}?${Math.random()}` } else { - if (this.state.image !== '') avatar = this.state.image + avatar = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22288%22%20height%3D%22225%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20288%20225%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_164edaf95ee%22%3E%3Crect%20width%3D%22288%22%20height%3D%22225%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2296.32500076293945%22%20y%3D%22118.8%22%3EAvatar%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E' + } + if ((team.profile !== null && team.profile.banner !== undefined && team.profile.banner !== null && team.profile.banner !== '') || this.state.bannerImage !== null) { + banner = this.state.bannerImage !== null ? this.state.bannerImage : `${team.profile.banner}?${Math.random()}` + } else { + banner = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22800%22%20height%3D%22200%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Asvg%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23banner_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%3E%3Ctitle%3EBanner%20Placeholder%3C%2Ftitle%3E%3Crect%20stroke%3D%22null%22%20id%3D%22svg_1%22%20fill%3D%22%2355595c%22%20height%3D%22200%22%20width%3D%22800%22%2F%3E%3Cg%20stroke%3D%22null%22%20id%3D%22banner_164edaf95ee%22%3E%3Ctext%20stroke%3D%22null%22%20id%3D%22svg_3%22%20y%3D%22106.5%22%20x%3D%22367.73438%22%3EBanner%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E' } - console.log('UploadImage', team, avatar, authId, this.state) + let handleImage + this.state.edit === 'avatar' ? handleImage = handleAvatar : handleImage = handleBanner + + console.log('UploadImage', team, avatar, banner, authId, this.state) return (
- {avatar === null && this.state.src === null && ( - -

Drag-and-drop team avater here or click to select files.
Only *.jpeg and *.png images

-
- )} - {(avatar !== null || this.state.src !== null) && ( - - {(getAzureSAS, { loading, error, data }) => { - console.log('getAzureSAS: ', error, data) - if (!this.state.uploaded) { - if (data !== undefined && data.getAzureSAS !== null) { - this.saveAvatar(data.getAzureSAS, team.slug, handleAvatar) - } - // this.handleSubmit(getAzureSAS, team.slug) + + {(getAzureSAS, { loading, error, data }) => { + console.log('getAzureSAS: ', error, data) + if (!this.state.uploaded) { + if (data !== undefined && data.getAzureSAS !== null) { + this.saveImage(data.getAzureSAS, team.slug, handleImage) } - if (this.state.cropping) { - return ( + // this.handleSubmit(getAzureSAS, team.slug) + } + if (this.state.cropping) { + return ( +
+ +
+ ) + } else { + return ( +
- + {(this.state.change || (avatar === null && banner === null && this.state.src === null)) && ( + + this.onDrop(e, this.state.edit)} + className={classes.dropzone} + multiple={false} + > +

Drag-and-drop team {this.state.edit} here or click to select files.
Only *.jpeg and *.png images

+
+ +
+ )} + {!this.state.change && ( + + Banner Crop Preview + + + )} + {!this.state.change && ( + + AvatarCrop Preview + + + )} + {(this.state.avatarImage !== null || this.state.bannerImage !== null) && ( + Click Update Team to save image changes! + )}
- ) - } else { - return ( - -
- Crop Preview -
- -
- -
+ +
+ +
+ {this.state.src !== null && ( { this.cropper = ref }} onImgLoad={this.onImageLoaded} + ratio={this.state.edit === 'avatar' ? 1 : 4} /> -
-
- - - - -
-
- - ) - } - }} - - )} + )} +
+
+ + + + +
+
+
+ ) + } + }} +
) } - onDrop (file) { + onDrop (file, editImageType) { console.log('onDrop', file) - this.onSelectFile(file) + this.onSelectFile(file, editImageType) this.setState({ file }) } - onSelectFile (file) { + onSelectFile (file, editImageType) { if (file && file.length > 0) { const reader = new window.FileReader() reader.addEventListener( @@ -194,53 +260,77 @@ class UploadImage extends Component { } } - async handleCrop (e, getAzureSAS, teamSlug, handleAvatar) { + async handleCrop (e, getAzureSAS, teamSlug, handleImage) { e.preventDefault() const data = await getAzureSAS({ variables: { teamSlug } }) console.log('handleCrop', this.cropper, data) const cropped = this.cropper.crop() const croppedBlob = await imgSrcToBlob(cropped, 'image/png', 'Anonymous') + let imageConfig = this.state.edit === 'avatar' ? imageAvatarConfig : imageBannerConfig let resizedBlob = await readAndCompressImage(croppedBlob, imageConfig) return this.setState({ cropped: resizedBlob, cropping: true, open: false }, () => { - this.saveAvatar(data.getAzureSAS, teamSlug, handleAvatar) + this.saveImage(data.getAzureSAS, teamSlug, handleImage) }) } async handleSubmit (e, getAzureSAS, teamSlug) { e.preventDefault() - await getAzureSAS({ variables: { teamSlug } }) + let SAS = await getAzureSAS({ variables: { teamSlug } }) + console.log('handleSubmit: ', await SAS) + return this.setState({ sasqr: SAS }) } - async saveAvatar (SASQueryParameters, teamSlug, handleAvatar) { - const fileName = `${teamSlug}-avatar.jpg` - console.log('saveAvatar SASurl', process.env.AZURE_SAS_URL) - const SASurl2 = `${process.env.AZURE_STORAGE_URL}?${SASQueryParameters}` - const SASurl = process.env.AZURE_SAS_URL - console.log('getAzureSAS2 SASurl: ', SASurl2, SASurl) + async saveImage (SASQueryParameters, teamSlug, handleImage) { + const fileName = this.state.edit === 'avatar' ? `${teamSlug}-avatar.jpg` : `${teamSlug}-banner.jpg` + let SASurl + if (this.state.sasqr === null) { + SASurl = process.env.AZURE_SAS_URL + } else { + SASurl = `${process.env.AZURE_STORAGE_URL}?${this.state.sasqr}` + } + console.log('getAzureSAS2 SASurl: ', SASurl, this.state.sasqr) + const pipeline = Azure.StorageURL.newPipeline(new Azure.AnonymousCredential()) const serviceURL = new Azure.ServiceURL(SASurl, pipeline) - console.log('getAzureSAS2: ', serviceURL) + const containerName = teamSlug const containerURL = Azure.ContainerURL.fromServiceURL(serviceURL, containerName) - console.log('getAzureSAS3: ', containerURL) const blockBlobURL = Azure.BlockBlobURL.fromContainerURL(containerURL, fileName) - console.log('getAzureSAS34: ', blockBlobURL) - const avatar = await Azure.uploadBrowserDataToBlockBlob(Azure.Aborter.None, this.state.cropped, blockBlobURL) - console.log('saveAvatar: ', avatar) - const image = `${process.env.AZURE_STORAGE_URL}${teamSlug}/${fileName}` - handleAvatar(image) - this.setState({ cropping: false, uploaded: true, image: image }) - return avatar + await Azure.uploadBrowserDataToBlockBlob(Azure.Aborter.None, this.state.cropped, blockBlobURL) + + const image = `${process.env.AZURE_STORAGE_URL}${teamSlug}/${fileName}?${Math.random()}` + handleImage(image) + let avatarImage = this.state.edit === 'avatar' ? image : null + let bannerImage = this.state.edit === 'banner' ? image : null + this.setState({ cropping: false, uploaded: true, change: false, avatarImage: avatarImage, bannerImage: bannerImage }) + return image } - handleClickOpen () { - this.setState({ open: true }) + handleChangeImage (e, editImageType) { + e.preventDefault() + let crop = editImageType === 'avatar' ? { x: 10, y: 10, width: 200, height: 200 } : { x: 10, y: 10, width: 800, height: 200 } + this.setState({ + edit: editImageType, + change: true, + crop: crop + }) + } + + cancelChangeImage () { + this.setState({ change: false }) + } + + handleClickOpen (e, editImageType) { + e.preventDefault() + this.setState({ + open: true + }) } handleClose () { - this.setState({ open: false, src: null }) + this.setState({ open: false, src: null, change: false }) } } @@ -248,7 +338,8 @@ UploadImage.propTypes = { classes: PropTypes.object.isRequired, team: PropTypes.object, authId: PropTypes.string.isRequired, - handleAvatar: PropTypes.func.isRequired + handleAvatar: PropTypes.func.isRequired, + handleBanner: PropTypes.func.isRequired } export default withStyles(styles)(UploadImage) diff --git a/client/src/views/dashboard/components/ManageTeamDetails.js b/client/src/views/dashboard/components/ManageTeamDetails.js index b4a736166..33eac05ed 100644 --- a/client/src/views/dashboard/components/ManageTeamDetails.js +++ b/client/src/views/dashboard/components/ManageTeamDetails.js @@ -5,10 +5,11 @@ import { withStyles } from '@material-ui/core/styles' import Button from '@material-ui/core/Button' import DetailsIcon from '@material-ui/icons/Details' import Dialog from '@material-ui/core/Dialog' -import DialogActions from '@material-ui/core/DialogActions' -import DialogContent from '@material-ui/core/DialogContent' -import DialogTitle from '@material-ui/core/DialogTitle' import Typography from '@material-ui/core/Typography' +import Card from '@material-ui/core/Card' +import CardContent from '@material-ui/core/CardContent' +import CardActions from '@material-ui/core/CardActions' +import CardMedia from '@material-ui/core/CardMedia' const styles = theme => ({ dialogContainer: { @@ -18,6 +19,33 @@ const styles = theme => ({ }, buttonRight: { justifyContent: 'flex-end' + }, + cardGrid: { + padding: `${theme.spacing.unit * 8}px 0` + }, + card: { + display: 'flex', + width: '100%' + }, + cardDetails: { + display: 'flex', + flex: 1 + }, + cardContent: { + flex: 1 + }, + cardAvatarMedia: { + flex: 1, + width: 100, + height: 100, + maxWidth: 100, + justifyContent: 'flex-start' + }, + cardBannerMedia: { + flex: 1, + width: 600, + height: 150, + justifyContent: 'flex-start' } }) @@ -35,7 +63,20 @@ export class ManageTeamDetails extends Component { render () { console.log(this.props.team) + const { classes } = this.props const { name, members, profile, createdAt } = this.props.team + let avatar + let banner + if (profile.avatar !== undefined && profile.avatar !== 'a') { + avatar = profile.avatar + } else { + avatar = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22288%22%20height%3D%22225%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20288%20225%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_164edaf95ee%22%3E%3Crect%20width%3D%22288%22%20height%3D%22225%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2296.32500076293945%22%20y%3D%22118.8%22%3EAvatar%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E' + } + if (profile.banner !== undefined && profile.banner !== 'a') { + banner = profile.banner + } else { + banner = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22800%22%20height%3D%22200%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Asvg%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23banner_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%3E%3Ctitle%3EBanner%20Placeholder%3C%2Ftitle%3E%3Crect%20stroke%3D%22null%22%20id%3D%22svg_1%22%20fill%3D%22%2355595c%22%20height%3D%22200%22%20width%3D%22800%22%2F%3E%3Cg%20stroke%3D%22null%22%20id%3D%22banner_164edaf95ee%22%3E%3Ctext%20stroke%3D%22null%22%20id%3D%22svg_3%22%20y%3D%22106.5%22%20x%3D%22367.73438%22%3EBanner%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E' + } return (
- + })} + + + + + +
diff --git a/client/src/views/dashboard/components/ManageTeamEdit.js b/client/src/views/dashboard/components/ManageTeamEdit.js index 5a257cb4a..6cb6596b8 100644 --- a/client/src/views/dashboard/components/ManageTeamEdit.js +++ b/client/src/views/dashboard/components/ManageTeamEdit.js @@ -42,11 +42,14 @@ export class ManageTeamEdit extends Component { this.handleChange = this.handleChange.bind(this) this.handleSubmit = this.handleSubmit.bind(this) this.handleAvatar = this.handleAvatar.bind(this) + this.handleBanner = this.handleBanner.bind(this) + console.log('ManageTeamEdit', props.team) const motto = props.team.profile.motto || '' const description = props.team.profile.description || '' const avatar = props.team.profile.avatar || '' const banner = props.team.profile.banner || '' + this.state = { open: false, motto: motto, @@ -108,7 +111,12 @@ export class ManageTeamEdit extends Component { Edit Team Details - +