diff --git a/.circleci/config.yml b/.circleci/config.yml index d723a4d47b..0e54b4a9b5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -282,7 +282,7 @@ workflows: filters: branches: only: - - free + - gsheet-contentful-develop # This is alternate dev env for parallel testing - "build-qa": context : org-global diff --git a/Dockerfile b/Dockerfile index 59d39c94bc..343cd978b6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -65,6 +65,7 @@ ARG TC_M2M_AUTH0_URL ARG AUTH_SECRET ARG COMMUNITY_APP_URL +ARG GSHEETS_API_KEY ################################################################################ # Setting of environment variables in the Docker image. @@ -120,6 +121,7 @@ ENV CONTENTFUL_EDU_CDN_API_KEY=$CONTENTFUL_EDU_CDN_API_KEY ENV CONTENTFUL_EDU_PREVIEW_API_KEY=$CONTENTFUL_EDU_PREVIEW_API_KEY ENV RECRUITCRM_API_KEY=$RECRUITCRM_API_KEY ENV COMMUNITY_APP_URL=$COMMUNITY_APP_URL +ENV GSHEETS_API_KEY=$GSHEETS_API_KEY ################################################################################ # Testing and build of the application inside the container. diff --git a/build.sh b/build.sh index 8c4660937b..865bd28537 100755 --- a/build.sh +++ b/build.sh @@ -44,6 +44,7 @@ docker build -t $TAG \ --build-arg CONTENTFUL_COMCAST_CDN_API_KEY=$CONTENTFUL_COMCAST_CDN_API_KEY \ --build-arg CONTENTFUL_COMCAST_PREVIEW_API_KEY=$CONTENTFUL_COMCAST_PREVIEW_API_KEY \ --build-arg RECRUITCRM_API_KEY=$RECRUITCRM_API_KEY \ + --build-arg GSHEETS_API_KEY=$GSHEETS_API_KEY \ --build-arg COMMUNITY_APP_URL=$COMMUNITY_APP_URL . # Copies "node_modules" from the created image, if necessary for caching. diff --git a/config/custom-environment-variables.js b/config/custom-environment-variables.js index 51264f7d73..ffb0182dda 100644 --- a/config/custom-environment-variables.js +++ b/config/custom-environment-variables.js @@ -104,4 +104,5 @@ module.exports = { AUTH0_PROXY_SERVER_URL: 'TC_M2M_AUTH0_PROXY_SERVER_URL', TOKEN_CACHE_TIME: 'TOKEN_CACHE_TIME', }, + GSHEETS_API_KEY: 'GSHEETS_API_KEY', }; diff --git a/config/default.js b/config/default.js index 9f7fed509e..9aa6c934d8 100644 --- a/config/default.js +++ b/config/default.js @@ -249,6 +249,8 @@ module.exports = { RECRUITCRM_API_KEY: '', }, + GSHEETS_API_KEY: 'AIzaSyBRdKySN5JNCb2H6ZxJdTTvp3cWU51jiOQ', + AUTH_CONFIG: { AUTH0_URL: 'TC_M2M_AUTH0_URL', AUTH0_AUDIENCE: 'TC_M2M_AUDIENCE', diff --git a/package-lock.json b/package-lock.json index 1e5adfca69..40807f5499 100644 --- a/package-lock.json +++ b/package-lock.json @@ -703,17 +703,22 @@ "dev": true }, "@babel/register": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.9.0.tgz", - "integrity": "sha512-Tv8Zyi2J2VRR8g7pC5gTeIN8Ihultbmk0ocyNz8H2nEZbmhp1N6q0A1UGsQbDvGP/sNinQKUHf3SqXwqjtFv4Q==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.12.13.tgz", + "integrity": "sha512-fnCeRXj970S9seY+973oPALQg61TRvAaW0nRDe1f4ytKqM3fZgsNXewTZWmqZedg74LFIRpg/11dsrPZZvYs2g==", "requires": { - "find-cache-dir": "2.1.0", - "lodash": "4.17.15", - "make-dir": "2.1.0", - "pirates": "4.0.1", - "source-map-support": "0.5.19" + "find-cache-dir": "^2.0.0", + "lodash": "^4.17.19", + "make-dir": "^2.1.0", + "pirates": "^4.0.0", + "source-map-support": "^0.5.16" }, "dependencies": { + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -724,8 +729,8 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "requires": { - "buffer-from": "1.1.1", - "source-map": "0.6.1" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } } } @@ -1333,6 +1338,11 @@ "resolved": "https://registry.npmjs.org/@tanem/svg-injector/-/svg-injector-1.2.1.tgz", "integrity": "sha512-mA5Q5ulPoGQ+e08Vts1R6xw2QU0BKEnMH/KcqoYoS7Gk6imvMTpyFPeu1g+NOZObSIoAzA3/kRzY8m96cEBA2A==" }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, "@topcoder-platform/tc-auth-lib": { "version": "github:topcoder-platform/tc-auth-lib#68fdc22464810c51b703a33e529cdbd6d09437de", "requires": { @@ -1351,7 +1361,7 @@ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", "requires": { - "@types/connect": "3.4.33", + "@types/connect": "3.4.34", "@types/node": "14.0.1" } }, @@ -1362,11 +1372,11 @@ "dev": true }, "@types/connect": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", - "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==", + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", "requires": { - "@types/node": "14.0.1" + "@types/node": "*" } }, "@types/events": { @@ -1376,14 +1386,14 @@ "dev": true }, "@types/express": { - "version": "4.17.6", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.6.tgz", - "integrity": "sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w==", + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", + "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", "requires": { - "@types/body-parser": "1.19.0", - "@types/express-serve-static-core": "4.17.7", - "@types/qs": "6.9.2", - "@types/serve-static": "1.13.3" + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" } }, "@types/express-jwt": { @@ -1391,18 +1401,18 @@ "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", "requires": { - "@types/express": "4.17.6", + "@types/express": "4.17.11", "@types/express-unless": "0.5.1" } }, "@types/express-serve-static-core": { - "version": "4.17.7", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.7.tgz", - "integrity": "sha512-EMgTj/DF9qpgLXyc+Btimg+XoH7A2liE8uKul8qSmMTHCeNYzydDKFdsJskDvw42UsesCnhO63dO0Grbj8J4Dw==", + "version": "4.17.18", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz", + "integrity": "sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA==", "requires": { - "@types/node": "14.0.1", - "@types/qs": "6.9.2", - "@types/range-parser": "1.2.3" + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" } }, "@types/express-unless": { @@ -1410,7 +1420,7 @@ "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.1.tgz", "integrity": "sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==", "requires": { - "@types/express": "4.17.6" + "@types/express": "4.17.11" } }, "@types/glob": { @@ -1425,9 +1435,9 @@ } }, "@types/mime": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.2.tgz", - "integrity": "sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q==" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "@types/minimatch": { "version": "3.0.3", @@ -1459,9 +1469,9 @@ "dev": true }, "@types/qs": { - "version": "6.9.2", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.2.tgz", - "integrity": "sha512-a9bDi4Z3zCZf4Lv1X/vwnvbbDYSNz59h3i3KdyuYYN+YrLjSeJD0dnphdULDfySvUv6Exy/O0K6wX/kQpnPQ+A==" + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", + "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==" }, "@types/range-parser": { "version": "1.2.3", @@ -1469,12 +1479,12 @@ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" }, "@types/serve-static": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", - "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", + "version": "1.13.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", + "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", "requires": { - "@types/express-serve-static-core": "4.17.7", - "@types/mime": "2.0.2" + "@types/mime": "^1", + "@types/node": "*" } }, "@types/unist": { @@ -1712,6 +1722,14 @@ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -1838,6 +1856,29 @@ } } }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "airbnb-prop-types": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.15.0.tgz", @@ -2100,8 +2141,7 @@ "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" }, "asap": { "version": "2.0.6", @@ -2258,17 +2298,86 @@ "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==" }, "auth0-js": { - "version": "9.13.2", - "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.13.2.tgz", - "integrity": "sha512-gWlf+X3XhCT9JboYpGviflv0pHcaHFPGtkLXiebyJohHDKddiu2rZkezp9kZHEoXqxhtNqgWuuaXkcla5JtnXg==", + "version": "9.14.3", + "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.14.3.tgz", + "integrity": "sha512-UO/fGv9641PUpYjz2nkPaUHzzrhNaJKupJOqt8blj1pD6wBgpZtxUSXBox6Y8md3eTBzpxeWxV+6RKzzERvr1g==", "requires": { - "base64-js": "1.3.1", - "idtoken-verifier": "2.0.3", - "js-cookie": "2.2.1", - "qs": "6.9.4", - "superagent": "3.8.3", - "url-join": "4.0.1", - "winchan": "0.2.2" + "base64-js": "^1.3.0", + "idtoken-verifier": "^2.0.3", + "js-cookie": "^2.2.0", + "qs": "^6.7.0", + "superagent": "^5.3.1", + "url-join": "^4.0.1", + "winchan": "^0.2.2" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "mime": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.0.tgz", + "integrity": "sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "superagent": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-5.3.1.tgz", + "integrity": "sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==", + "requires": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } } }, "autoprefixer": { @@ -3916,14 +4025,14 @@ "dev": true }, "bunyan": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", - "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=", + "version": "1.8.15", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", + "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==", "requires": { - "dtrace-provider": "0.8.8", - "moment": "2.25.3", - "mv": "2.1.1", - "safe-json-stringify": "1.2.0" + "dtrace-provider": "~0.8", + "moment": "^2.19.3", + "mv": "~2", + "safe-json-stringify": "~1" } }, "busboy": { @@ -7098,7 +7207,6 @@ "version": "0.8.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, "requires": { "nan": "2.14.1" } @@ -7833,6 +7941,11 @@ "resolved": "https://registry.npmjs.org/event-lite/-/event-lite-0.1.2.tgz", "integrity": "sha512-HnSYx1BsJ87/p6swwzv+2v6B4X+uxUteoDfRxsAb1S1BePzQqOLevVmkdA15GHJVd9A9Ok6wygUR18Hu0YeV9g==" }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, "eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", @@ -8400,6 +8513,11 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" }, + "fast-text-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", + "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==" + }, "fastparse": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", @@ -9220,8 +9338,8 @@ "dev": true, "optional": true, "requires": { - "bindings": "1.5.0", - "nan": "2.14.1" + "bindings": "^1.5.0", + "nan": "^2.12.1" } }, "fstream": { @@ -9277,6 +9395,30 @@ "wide-align": "1.1.3" } }, + "gaxios": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.1.0.tgz", + "integrity": "sha512-vb0to8xzGnA2qcgywAjtshOKKVDf2eQhJoiL6fHhgW5tVN7wNk7egnYIO9zotfn3lQ3De1VPdf7V5/BWfCtCmg==", + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + }, + "dependencies": { + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + } + } + }, "gaze": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", @@ -9286,6 +9428,15 @@ "globule": "1.3.1" } }, + "gcp-metadata": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.1.tgz", + "integrity": "sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw==", + "requires": { + "gaxios": "^4.0.0", + "json-bigint": "^1.0.0" + } + }, "generic-names": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-1.0.3.tgz", @@ -10067,6 +10218,82 @@ "delegate": "3.2.0" } }, + "google-auth-library": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", + "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "google-p12-pem": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz", + "integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==", + "requires": { + "node-forge": "^0.10.0" + }, + "dependencies": { + "node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" + } + } + }, + "google-spreadsheet": { + "version": "3.1.15", + "resolved": "https://registry.npmjs.org/google-spreadsheet/-/google-spreadsheet-3.1.15.tgz", + "integrity": "sha512-S5477f3Gf3Mz6AXgCw7dbaYnzu5aHou1AX4sDqrGboQWnAytkxqJGKQiXN+zzRTTcYzSTJCe0g7KqCPZO9xiOw==", + "requires": { + "axios": "^0.21.1", + "google-auth-library": "^6.1.3", + "lodash": "^4.17.20" + }, + "dependencies": { + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "follow-redirects": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz", + "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==" + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + } + } + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -10078,6 +10305,16 @@ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "dev": true }, + "gtoken": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.2.1.tgz", + "integrity": "sha512-OY0BfPKe3QnMsY9MzTHTSKn+Vl2l1CcLe6BwDEQj00mbbkl5nyQ/7EUREstg4fQNZ8iYE7br4JJ7TdKeDOPWmw==", + "requires": { + "gaxios": "^4.0.0", + "google-p12-pem": "^3.0.3", + "jws": "^4.0.0" + } + }, "handlebars": { "version": "4.7.6", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", @@ -10583,6 +10820,31 @@ "toidentifier": "1.0.0" } }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -10621,6 +10883,30 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "husky": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/husky/-/husky-4.2.5.tgz", @@ -10829,16 +11115,16 @@ } }, "idtoken-verifier": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-2.0.3.tgz", - "integrity": "sha512-X1izD2ZTMoo+2tw2RKVUvvCSw2B6UOCNMJ0bgHRH758LFTMwBf4JZfCZm61MPBaBW2CIuhkcSnKCZP6jXpSDmw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-2.1.0.tgz", + "integrity": "sha512-X0423UM4Rc5bFb39Ai0YHr35rcexlu4oakKdYzSGZxtoPy84P86hhAbzlpgbgomcLOFRgzgKRvhY7YjO5g8OPA==", "requires": { - "base64-js": "1.3.1", - "crypto-js": "3.3.0", - "es6-promise": "4.2.8", - "jsbn": "1.1.0", - "unfetch": "4.1.0", - "url-join": "4.0.1" + "base64-js": "^1.3.0", + "crypto-js": "^3.2.1", + "es6-promise": "^4.2.8", + "jsbn": "^1.1.0", + "unfetch": "^4.1.0", + "url-join": "^4.0.1" } }, "ieee754": { @@ -13094,6 +13380,21 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" }, + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "requires": { + "bignumber.js": "^9.0.0" + }, + "dependencies": { + "bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" + } + } + }, "json-fallback": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/json-fallback/-/json-fallback-0.0.1.tgz", @@ -13194,14 +13495,33 @@ "lodash.isplainobject": "4.0.6", "lodash.isstring": "4.0.1", "lodash.once": "4.1.1", - "ms": "2.1.2", + "ms": "2.1.3", "semver": "5.7.1" }, "dependencies": { + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, @@ -13259,51 +13579,74 @@ "integrity": "sha512-mjzgSOFzlrurlURaHVjnQodyPNvrHrf1TbQP2XU9NSqBtHQPuHZ+Eb6TAJP7ASeJN9h9K0KXoRTs8u6ouHBKvg==" }, "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", "requires": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "5.1.2" + "safe-buffer": "^5.0.1" } }, "jwks-rsa": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-1.8.0.tgz", - "integrity": "sha512-+HYROHD5fsYQCNrJ37RSr2NjbN2/V9YT+yVF3oJxLmPIZWrmp1SOl1hMw2RcuNh+LGA2bGZIhRKGiMjhQa/b7Q==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-1.12.2.tgz", + "integrity": "sha512-6gPo/mQUxXJt75oPtjhM3Jm3FSXnmwg73QDA8dpgP7YmIKlIY+2StngFxt4w4Y1podtSbtV3jttNOdctuxAX1Q==", "requires": { "@types/express-jwt": "0.0.42", - "axios": "0.19.2", - "debug": "4.1.1", - "jsonwebtoken": "8.5.1", - "limiter": "1.1.5", - "lru-memoizer": "2.1.2", - "ms": "2.1.2" + "axios": "^0.21.1", + "debug": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "jsonwebtoken": "^8.5.1", + "limiter": "^1.1.5", + "lru-memoizer": "^2.1.2", + "ms": "^2.1.2", + "proxy-from-env": "^1.1.0" }, "dependencies": { + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, + "follow-redirects": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz", + "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==" + }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", "requires": { - "jwa": "1.4.1", - "safe-buffer": "5.1.2" + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" } }, "kapellmeister": { @@ -13878,12 +14221,12 @@ } }, "lru-memoizer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.2.tgz", - "integrity": "sha512-N5L5xlnVcbIinNn/TJ17vHBZwBMt9t7aJDz2n97moWubjNl6VO9Ao2XuAGBBddkYdjrwR9HfzXbT6NfMZXAZ/A==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.4.tgz", + "integrity": "sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==", "requires": { - "lodash.clonedeep": "4.5.0", - "lru-cache": "4.0.2" + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" }, "dependencies": { "lru-cache": { @@ -13891,8 +14234,8 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" } } } @@ -14610,7 +14953,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "optional": true, "requires": { "mkdirp": "0.5.5", "ncp": "2.0.0", @@ -14621,7 +14963,6 @@ "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "optional": true, "requires": { "inflight": "1.0.6", "inherits": "2.0.3", @@ -14634,7 +14975,6 @@ "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "optional": true, "requires": { "glob": "6.0.4" } @@ -14706,7 +15046,7 @@ "resolved": "https://registry.npmjs.org/config/-/config-3.3.3.tgz", "integrity": "sha512-T3RmZQEAji5KYqUQpziWtyGJFli6Khz7h0rpxDwYNjSkr5ynyTWwO7WpfjHzTXclNCDfSWQRcwMb+NwxJesCKw==", "requires": { - "json5": "2.1.3" + "json5": "^2.1.1" } }, "hoist-non-react-statics": { @@ -14714,15 +15054,15 @@ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "requires": { - "react-is": "16.13.1" + "react-is": "^16.7.0" } }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "requires": { - "minimist": "1.2.5" + "minimist": "^1.2.5" } }, "react-redux": { @@ -14730,12 +15070,12 @@ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-6.0.1.tgz", "integrity": "sha512-T52I52Kxhbqy/6TEfBv85rQSDz6+Y28V/pf52vDWs1YRXG19mcFOGfHnY2HsNFHyhP+ST34Aih98fvt6tqwVcQ==", "requires": { - "@babel/runtime": "7.9.6", - "hoist-non-react-statics": "3.3.2", - "invariant": "2.2.4", - "loose-envify": "1.4.0", - "prop-types": "15.7.2", - "react-is": "16.13.1" + "@babel/runtime": "^7.3.1", + "hoist-non-react-statics": "^3.3.0", + "invariant": "^2.2.4", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^16.8.2" } }, "redux": { @@ -14743,8 +15083,8 @@ "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", "requires": { - "loose-envify": "1.4.0", - "symbol-observable": "1.2.0" + "loose-envify": "^1.4.0", + "symbol-observable": "^1.2.0" } }, "serialize-javascript": { @@ -14757,40 +15097,40 @@ "resolved": "https://registry.npmjs.org/topcoder-react-utils/-/topcoder-react-utils-0.7.9.tgz", "integrity": "sha512-bH5t7lVTezl3rh2S1pguMWhUlJb39gOLLkCG9jwLCsMKTzri+LsOvpRJ6dOvYZPzA7GdmCgQNeGAoctiqAGb4g==", "requires": { - "@babel/register": "7.9.0", - "@babel/runtime": "7.9.6", - "body-parser": "1.19.0", - "command-line-args": "5.1.1", - "command-line-usage": "5.0.5", - "compression": "1.7.4", - "config": "3.3.3", - "cookie-parser": "1.4.5", - "cross-env": "5.2.1", - "express": "4.17.1", - "helmet": "3.22.0", - "lodash": "4.17.15", - "moment": "2.25.3", - "morgan": "1.10.0", - "node-forge": "0.7.6", - "prop-types": "15.7.2", - "raf": "3.4.1", - "react": "16.13.1", - "react-css-super-themr": "2.3.0", - "react-dom": "16.13.1", - "react-helmet": "5.2.1", - "react-redux": "6.0.1", - "react-router-dom": "4.3.1", - "redux": "4.0.5", - "redux-actions": "2.6.5", - "redux-devtools": "3.5.0", - "redux-devtools-dock-monitor": "1.1.3", - "redux-devtools-log-monitor": "1.4.0", - "redux-promise": "0.6.0", - "request-ip": "2.1.3", - "serialize-javascript": "1.9.1", - "serve-favicon": "2.5.0", - "shortid": "2.2.15", - "url-parse": "1.4.7" + "@babel/register": "^7.0.0", + "@babel/runtime": "^7.0.0", + "body-parser": "^1.18.3", + "command-line-args": "^5.0.2", + "command-line-usage": "^5.0.5", + "compression": "^1.7.3", + "config": "^3.0.1", + "cookie-parser": "^1.4.3", + "cross-env": "^5.2.0", + "express": "^4.16.4", + "helmet": "^3.15.0", + "lodash": "^4.17.11", + "moment": "^2.23.0", + "morgan": "^1.9.1", + "node-forge": "^0.7.6", + "prop-types": "^15.6.2", + "raf": "^3.4.1", + "react": "^16.7.0", + "react-css-super-themr": "^2.2.0", + "react-dom": "^16.7.0", + "react-helmet": "^5.2.0", + "react-redux": "^6.0.0", + "react-router-dom": "^4.3.1", + "redux": "^4.0.1", + "redux-actions": "^2.6.4", + "redux-devtools": "^3.5.0", + "redux-devtools-dock-monitor": "^1.1.3", + "redux-devtools-log-monitor": "^1.4.0", + "redux-promise": "^0.6.0", + "request-ip": "^2.1.3", + "serialize-javascript": "^1.6.0", + "serve-favicon": "^2.5.0", + "shortid": "^2.2.14", + "url-parse": "^1.4.4" } } } @@ -14798,8 +15138,7 @@ "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "optional": true + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=" }, "nearley": { "version": "2.19.3", @@ -17780,6 +18119,11 @@ "ipaddr.js": "1.9.1" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -20020,8 +20364,7 @@ "safe-json-stringify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", - "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", - "optional": true + "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==" }, "safe-regex": { "version": "1.1.0", @@ -22540,11 +22883,11 @@ "tc-core-library-js": { "version": "github:appirio-tech/tc-core-library-js#f45352974dafe5a10c86fc50bdd59ef399b50c65", "requires": { - "auth0-js": "9.13.2", + "auth0-js": "9.14.3", "axios": "0.19.2", - "bunyan": "1.8.12", + "bunyan": "1.8.15", "jsonwebtoken": "8.5.1", - "jwks-rsa": "1.8.0", + "jwks-rsa": "1.12.2", "le_node": "1.8.0", "lodash": "4.17.15", "millisecond": "0.1.2", @@ -23244,34 +23587,35 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, "topcoder-react-lib": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/topcoder-react-lib/-/topcoder-react-lib-1.1.5.tgz", - "integrity": "sha512-XD1QPxuaD4w6plhYhU/q4bnwAd498HYCHAANkXt6bztrm0hmmwZFHIJGOtVEozwz1B8EnOsHfVlyn12j5EtEXQ==", - "requires": { - "@topcoder-platform/tc-auth-lib": "git+https://github.com/topcoder-platform/tc-auth-lib.git#68fdc22464810c51b703a33e529cdbd6d09437de", - "auth0-js": "6.8.4", - "config": "3.3.3", - "isomorphic-fetch": "2.2.1", - "le_node": "1.8.0", - "lodash": "4.17.15", - "moment": "2.25.3", - "moment-duration-format": "2.3.2", - "moment-timezone": "0.5.31", - "qs": "6.9.4", - "react": "16.13.1", - "react-dom": "16.13.1", - "react-redux": "6.0.1", - "redux": "3.7.2", - "redux-actions": "2.6.5", - "tc-core-library-js": "github:appirio-tech/tc-core-library-js#d16413db30b1eed21c0cf426e185bedb2329ddab", - "to-capital-case": "1.0.0", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/topcoder-react-lib/-/topcoder-react-lib-1.1.6.tgz", + "integrity": "sha512-i9Btnbd9k6dq569avQA4vz0fIxz/nIUxJ9hMldN+n71JY3Qv9rNL6nVCk3ou/j7mMLwTY3zNajJsUAogjD4uIA==", + "requires": { + "@topcoder-platform/tc-auth-lib": "git+https://github.com/topcoder-platform/tc-auth-lib.git#1.0.4", + "auth0-js": "^6.8.4", + "config": "^3.2.0", + "isomorphic-fetch": "^2.2.1", + "le_node": "^1.7.0", + "lodash": "^4.17.10", + "moment": "^2.22.2", + "moment-duration-format": "^2.2.2", + "moment-timezone": "^0.5.21", + "qs": "^6.5.2", + "react": "^16.4.1", + "react-dom": "^16.4.1", + "react-redux": "^6.0.1", + "redux": "^3.7.2", + "redux-actions": "^2.4.0", + "tc-core-library-js": "github:appirio-tech/tc-core-library-js#v2.6", + "to-capital-case": "^1.0.0", "topcoder-react-utils": "0.7.5" }, "dependencies": { "@topcoder-platform/tc-auth-lib": { "version": "git+https://github.com/topcoder-platform/tc-auth-lib.git#68fdc22464810c51b703a33e529cdbd6d09437de", + "from": "git+https://github.com/topcoder-platform/tc-auth-lib.git#1.0.4", "requires": { - "lodash": "4.17.20" + "lodash": "^4.17.19" }, "dependencies": { "lodash": { @@ -23286,18 +23630,19 @@ "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-6.8.4.tgz", "integrity": "sha1-Qw3Uystk2NFdabHmIRhPmipkCmE=", "requires": { - "Base64": "0.1.4", + "Base64": "~0.1.3", "json-fallback": "0.0.1", - "jsonp": "0.0.4", - "qs": "git+https://github.com/jfromaniello/node-querystring.git#5d96513991635e3e22d7aa54a8584d6ce97cace8", - "reqwest": "1.1.6", - "trim": "0.0.1", - "winchan": "0.1.4", - "xtend": "2.1.2" + "jsonp": "~0.0.4", + "qs": "git+https://github.com/jfromaniello/node-querystring.git#fix_ie7_bug_with_arrays", + "reqwest": "^1.1.4", + "trim": "~0.0.1", + "winchan": "^0.1.1", + "xtend": "~2.1.1" }, "dependencies": { "qs": { - "version": "git+https://github.com/jfromaniello/node-querystring.git#5d96513991635e3e22d7aa54a8584d6ce97cace8" + "version": "git+https://github.com/jfromaniello/node-querystring.git#5d96513991635e3e22d7aa54a8584d6ce97cace8", + "from": "git+https://github.com/jfromaniello/node-querystring.git#fix_ie7_bug_with_arrays" } } }, @@ -23314,7 +23659,7 @@ "resolved": "https://registry.npmjs.org/config/-/config-3.3.3.tgz", "integrity": "sha512-T3RmZQEAji5KYqUQpziWtyGJFli6Khz7h0rpxDwYNjSkr5ynyTWwO7WpfjHzTXclNCDfSWQRcwMb+NwxJesCKw==", "requires": { - "json5": "2.1.3" + "json5": "^2.1.1" } }, "debug": { @@ -23330,8 +23675,8 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.7.tgz", "integrity": "sha1-NLkLqyqRGqNHVx2pDyK9NuzYqRk=", "requires": { - "debug": "2.6.9", - "stream-consume": "0.1.1" + "debug": "^2.2.0", + "stream-consume": "^0.1.0" }, "dependencies": { "debug": { @@ -23354,15 +23699,15 @@ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "requires": { - "react-is": "16.13.1" + "react-is": "^16.7.0" } }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "requires": { - "minimist": "1.2.5" + "minimist": "^1.2.5" } }, "lru-cache": { @@ -23370,13 +23715,13 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { - "yallist": "4.0.0" + "yallist": "^4.0.0" } }, "mime": { - "version": "2.4.7", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.7.tgz", - "integrity": "sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.0.tgz", + "integrity": "sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag==" }, "ms": { "version": "2.1.2", @@ -23393,12 +23738,12 @@ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-6.0.1.tgz", "integrity": "sha512-T52I52Kxhbqy/6TEfBv85rQSDz6+Y28V/pf52vDWs1YRXG19mcFOGfHnY2HsNFHyhP+ST34Aih98fvt6tqwVcQ==", "requires": { - "@babel/runtime": "7.9.6", - "hoist-non-react-statics": "3.3.2", - "invariant": "2.2.4", - "loose-envify": "1.4.0", - "prop-types": "15.7.2", - "react-is": "16.13.1" + "@babel/runtime": "^7.3.1", + "hoist-non-react-statics": "^3.3.0", + "invariant": "^2.2.4", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^16.8.2" } }, "readable-stream": { @@ -23406,9 +23751,9 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { - "inherits": "2.0.3", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, "semver": { @@ -23416,7 +23761,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", "requires": { - "lru-cache": "6.0.0" + "lru-cache": "^6.0.0" } }, "serialize-javascript": { @@ -23429,45 +23774,46 @@ "resolved": "https://registry.npmjs.org/superagent/-/superagent-5.3.1.tgz", "integrity": "sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==", "requires": { - "component-emitter": "1.3.0", - "cookiejar": "2.1.2", - "debug": "4.3.1", - "fast-safe-stringify": "2.0.7", - "form-data": "3.0.0", - "formidable": "1.2.2", - "methods": "1.1.2", - "mime": "2.4.7", - "qs": "6.9.4", - "readable-stream": "3.6.0", - "semver": "7.3.4" + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" } }, "tc-core-library-js": { "version": "github:appirio-tech/tc-core-library-js#d16413db30b1eed21c0cf426e185bedb2329ddab", - "requires": { - "auth0-js": "9.14.0", - "axios": "0.12.0", - "bunyan": "1.8.12", - "jsonwebtoken": "8.5.1", - "jwks-rsa": "1.8.0", - "le_node": "1.8.0", - "lodash": "4.17.15", - "millisecond": "0.1.2", - "request": "2.88.2" + "from": "github:appirio-tech/tc-core-library-js#v2.6", + "requires": { + "auth0-js": "^9.4.2", + "axios": "^0.12.0", + "bunyan": "^1.8.12", + "jsonwebtoken": "^8.3.0", + "jwks-rsa": "^1.3.0", + "le_node": "^1.3.1", + "lodash": "^4.17.10", + "millisecond": "^0.1.2", + "request": "^2.88.0" }, "dependencies": { "auth0-js": { - "version": "9.14.0", - "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.14.0.tgz", - "integrity": "sha512-40gIBUejmYAYse06ck6sxdNO0KU0pX+KDIQsWAkcyFtI0HU6dY5aeHxZfVYkYjtbArKr5s13LuZFdKrUiGyCqQ==", + "version": "9.14.3", + "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.14.3.tgz", + "integrity": "sha512-UO/fGv9641PUpYjz2nkPaUHzzrhNaJKupJOqt8blj1pD6wBgpZtxUSXBox6Y8md3eTBzpxeWxV+6RKzzERvr1g==", "requires": { - "base64-js": "1.3.1", - "idtoken-verifier": "2.0.3", - "js-cookie": "2.2.1", - "qs": "6.9.4", - "superagent": "5.3.1", - "url-join": "4.0.1", - "winchan": "0.2.2" + "base64-js": "^1.3.0", + "idtoken-verifier": "^2.0.3", + "js-cookie": "^2.2.0", + "qs": "^6.7.0", + "superagent": "^5.3.1", + "url-join": "^4.0.1", + "winchan": "^0.2.2" } }, "winchan": { @@ -23482,38 +23828,38 @@ "resolved": "https://registry.npmjs.org/topcoder-react-utils/-/topcoder-react-utils-0.7.5.tgz", "integrity": "sha512-/jolO/UUCC/FL/MniBMFi9d7Wc1KbzwvgT5STGs4T+7u7R26bQugGPpGVISEPuglsmW0Xybh6iRi+pT/muOkbg==", "requires": { - "babel-runtime": "6.26.0", - "body-parser": "1.19.0", - "command-line-args": "5.1.1", - "command-line-usage": "5.0.5", - "compression": "1.7.4", - "config": "1.31.0", - "cookie-parser": "1.4.5", - "express": "4.17.1", - "helmet": "3.22.0", - "lodash": "4.17.15", - "moment": "2.25.3", - "morgan": "1.10.0", - "node-forge": "0.7.6", - "prop-types": "15.7.2", - "raf": "3.4.1", - "react": "16.13.1", - "react-css-super-themr": "2.3.0", - "react-dom": "16.13.1", - "react-helmet": "5.2.1", - "react-redux": "5.1.2", - "react-router-dom": "4.3.1", - "redux": "3.7.2", - "redux-actions": "2.6.5", - "redux-devtools": "3.5.0", - "redux-devtools-dock-monitor": "1.1.3", - "redux-devtools-log-monitor": "1.4.0", - "redux-promise": "0.6.0", - "request-ip": "2.1.3", - "serialize-javascript": "1.9.1", - "serve-favicon": "2.5.0", - "shortid": "2.2.15", - "url-parse": "1.4.7" + "babel-runtime": "^6.26.0", + "body-parser": "^1.18.3", + "command-line-args": "^5.0.2", + "command-line-usage": "^5.0.5", + "compression": "^1.7.2", + "config": "^1.30.0", + "cookie-parser": "^1.4.3", + "express": "^4.16.3", + "helmet": "^3.12.1", + "lodash": "^4.17.10", + "moment": "^2.22.2", + "morgan": "^1.9.0", + "node-forge": "^0.7.5", + "prop-types": "^15.6.2", + "raf": "^3.4.0", + "react": "^16.4.1", + "react-css-super-themr": "^2.2.0", + "react-dom": "^16.4.1", + "react-helmet": "^5.2.0", + "react-redux": "^5.0.7", + "react-router-dom": "^4.3.1", + "redux": "^3.7.2", + "redux-actions": "^2.4.0", + "redux-devtools": "^3.4.1", + "redux-devtools-dock-monitor": "^1.1.3", + "redux-devtools-log-monitor": "^1.4.0", + "redux-promise": "^0.6.0", + "request-ip": "^2.0.2", + "serialize-javascript": "^1.5.0", + "serve-favicon": "^2.5.0", + "shortid": "^2.2.8", + "url-parse": "^1.4.1" }, "dependencies": { "config": { @@ -23521,7 +23867,7 @@ "resolved": "https://registry.npmjs.org/config/-/config-1.31.0.tgz", "integrity": "sha512-Ep/l9Rd1J9IPueztJfpbOqVzuKHQh4ZODMNt9xqTYdBBNRXbV4oTu34kCkkfdRVcDq0ohtpaeXGgb+c0LQxFRA==", "requires": { - "json5": "1.0.1" + "json5": "^1.0.1" } }, "json5": { @@ -23529,7 +23875,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "requires": { - "minimist": "1.2.5" + "minimist": "^1.2.0" } }, "react-redux": { @@ -23537,13 +23883,13 @@ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.1.2.tgz", "integrity": "sha512-Ns1G0XXc8hDyH/OcBHOxNgQx9ayH3SPxBnFCOidGKSle8pKihysQw2rG/PmciUQRoclhVBO8HMhiRmGXnDja9Q==", "requires": { - "@babel/runtime": "7.9.6", - "hoist-non-react-statics": "3.3.2", - "invariant": "2.2.4", - "loose-envify": "1.4.0", - "prop-types": "15.7.2", - "react-is": "16.13.1", - "react-lifecycles-compat": "3.0.4" + "@babel/runtime": "^7.1.2", + "hoist-non-react-statics": "^3.3.0", + "invariant": "^2.2.4", + "loose-envify": "^1.1.0", + "prop-types": "^15.6.1", + "react-is": "^16.6.0", + "react-lifecycles-compat": "^3.0.0" } } } @@ -23558,7 +23904,7 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", "requires": { - "object-keys": "0.4.0" + "object-keys": "~0.4.0" } }, "yallist": { @@ -23791,9 +24137,9 @@ "dev": true }, "unfetch": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.1.0.tgz", - "integrity": "sha512-crP/n3eAPUJxZXM9T80/yv0YhkTEx2K1D3h7D1AJM6fzsWZrxdyRuLN0JH/dkZh1LNH8LxCnBzoPFCPbb2iGpg==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" }, "unherit": { "version": "1.1.3", diff --git a/package.json b/package.json index a27f2f045d..246554d141 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "flag-icon-css": "^3.3.0", "focus-trap-react": "^6.0.0", "form-data": "^3.0.0", + "google-spreadsheet": "^3.1.15", "helmet": "^3.12.1", "highlight.js": "^9.18.1", "html-to-text": "^5.1.1", diff --git a/src/server/index.js b/src/server/index.js index b4892eb12f..1338e6c447 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -28,6 +28,7 @@ import mailChimpRouter from './routes/mailchimp'; import mockDocuSignFactory from './__mocks__/docu-sign-mock'; import recruitCRMRouter from './routes/recruitCRM'; import mmLeaderboardRouter from './routes/mmLeaderboard'; +import gSheetsRouter from './routes/gSheet'; /* Dome API for topcoder communities */ import tcCommunitiesDemoApi from './tc-communities'; @@ -137,6 +138,7 @@ async function onExpressJsSetup(server) { server.use('/api/mailchimp', mailChimpRouter); server.use('/api/recruit', recruitCRMRouter); server.use('/api/mml', mmLeaderboardRouter); + server.use('/api/gsheets', gSheetsRouter); // serve demo api server.use( diff --git a/src/server/routes/gSheet.js b/src/server/routes/gSheet.js new file mode 100644 index 0000000000..432dbcfb7b --- /dev/null +++ b/src/server/routes/gSheet.js @@ -0,0 +1,19 @@ +/** + * The routes related to GSheets integration + */ + +import express from 'express'; +import GSheetService from '../services/gSheet'; + +const cors = require('cors'); + +const routes = express.Router(); + +// Enables CORS on those routes according config above +// ToDo configure CORS for set of our trusted domains +routes.use(cors()); +routes.options('*', cors()); + +routes.get('/:id', (req, res) => new GSheetService().getSheet(req, res)); + +export default routes; diff --git a/src/server/services/gSheet.js b/src/server/services/gSheet.js new file mode 100644 index 0000000000..a54d6428c4 --- /dev/null +++ b/src/server/services/gSheet.js @@ -0,0 +1,52 @@ +/* eslint-disable consistent-return */ +/* eslint-disable class-methods-use-this */ +/** + * Server-side functions necessary for effective integration with gsheets + */ +import config from 'config'; + +const { GoogleSpreadsheet } = require('google-spreadsheet'); + +const getCircularReplacer = () => { + const seen = new WeakSet(); + return (key, value) => { + if (typeof value === 'object' && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); + } + return value; + }; +}; + +/** + * Auxiliary class that handles communication with mailchimp + * APIs in the same uniform manner. + */ +export default class GSheetService { + /** + * getSheet + * @param {Object} req the request + * @param {Object} res the response + */ + async getSheet(req, res) { + const { index } = req.query; + const { id } = req.params; + const doc = new GoogleSpreadsheet(id); + doc.useApiKey(config.GSHEETS_API_KEY); + try { + await doc.loadInfo(); + // the first sheet if not selected via query + const sheet = doc.sheetsByIndex[index || 0]; + const rows = await sheet.getRows(); + const rowsJson = JSON.stringify(rows, getCircularReplacer()); + return res.send({ + rows: JSON.parse(rowsJson), + }); + } catch (e) { + res.status((e.response && e.response.status) || 500); + return res.send((e.response && e.response.data) || { ...e, message: e.message }); + } + } +} diff --git a/src/shared/actions/gSheet.js b/src/shared/actions/gSheet.js new file mode 100644 index 0000000000..bd09ca5132 --- /dev/null +++ b/src/shared/actions/gSheet.js @@ -0,0 +1,33 @@ +/** + * Actions related to gsheets + */ +/* global fetch */ +import { redux } from 'topcoder-react-utils'; +import Service from 'services/gSheet'; + +/** + * Fetch init + */ +function getGsheetInit(id, index) { + return { id, index }; +} + +/** + * Fetch done + */ +async function getGsheetDone(id, index) { + const ss = new Service(); + const res = await ss.getSheet(id, index); + return { + id, + index, + data: res, + }; +} + +export default redux.createActions({ + GSHEETS: { + GET_GSHEET_INIT: getGsheetInit, + GET_GSHEET_DONE: getGsheetDone, + }, +}); diff --git a/src/shared/components/Contentful/AppComponent/index.jsx b/src/shared/components/Contentful/AppComponent/index.jsx index 47251bfcfc..5d19f81fee 100644 --- a/src/shared/components/Contentful/AppComponent/index.jsx +++ b/src/shared/components/Contentful/AppComponent/index.jsx @@ -11,6 +11,7 @@ import { errors } from 'topcoder-react-lib'; import Leaderboard from 'containers/tco/Leaderboard'; import RecruitCRMJobs from 'containers/Gigs/RecruitCRMJobs'; import EmailSubscribeForm from 'containers/EmailSubscribeForm'; +import GSheet from 'containers/GSheet'; const { fireErrorMessage } = errors; @@ -39,7 +40,10 @@ export function AppComponentSwitch(appComponent) { if (appComponent.fields.type === 'EmailSubscribeForm') { return ; } - fireErrorMessage('Unsupported app component type from contentful', ''); + if (appComponent.fields.type === 'GSheet') { + return ; + } + fireErrorMessage(`Unsupported app component type ${appComponent.fields.type}`, ''); return null; } diff --git a/src/shared/components/GSheet/index.jsx b/src/shared/components/GSheet/index.jsx new file mode 100644 index 0000000000..c09a00fa4f --- /dev/null +++ b/src/shared/components/GSheet/index.jsx @@ -0,0 +1,118 @@ +/* eslint-disable no-underscore-dangle */ +/** + * GSheet component + * renders a table with data from google sheets + */ + +import PT from 'prop-types'; +import _ from 'lodash'; +import React, { Component } from 'react'; +import { Scrollbars } from 'react-custom-scrollbars'; +import cn from 'classnames'; +import './style.scss'; + +export default class GSheet extends Component { + constructor(props) { + super(props); + + this.state = { + sortParam: { + order: '', + field: '', + }, + }; + } + + render() { + const { + sheet, config, + } = this.props; + + const { sortParam } = this.state; + let data = sheet.rows; + + if (sortParam.field) { + // Use Lodash to sort array + data = _.orderBy( + sheet.rows, + [d => Number(d[sortParam.field]) || String(d[sortParam.field]).toLowerCase()], + [sortParam.order], + ); + } + + const renderData = () => ( + + + + + { + (config.pick || sheet.rows[0]._sheet.headerValues).map(c => ( + + + {c} + { + if (!sortParam.field || sortParam.field !== c) { + sortParam.field = c; + sortParam.order = 'desc'; + } else { + sortParam.order = sortParam.order === 'asc' ? 'desc' : 'asc'; + } + this.setState({ sortParam }); + }} + type="button" + > + + + + + + )) + } + + + + { + data.map(record => ( + + { + (config.pick || sheet.rows[0]._sheet.headerValues).map(c => ( + + {c.toLowerCase() === 'handle' ? ({record[c]}) : record[c]} + + )) + } + + )) + } + + + + ); + + return ( + + { sheet.rows && sheet.rows.length ? renderData() : No data available yet.} + + ); + } +} + +GSheet.defaultProps = { + +}; + +GSheet.propTypes = { + sheet: PT.shape().isRequired, + config: PT.shape().isRequired, +}; diff --git a/src/shared/components/GSheet/style.scss b/src/shared/components/GSheet/style.scss new file mode 100644 index 0000000000..435f9e456a --- /dev/null +++ b/src/shared/components/GSheet/style.scss @@ -0,0 +1,127 @@ +@import '~styles/mixins'; + +$light-gray: #d4d4d4; + +.no-data-title { + text-align: center; +} + +.body-row, +.header-cell { + border-bottom: 1px solid $light-gray; + font-family: Roboto, sans-serif; +} + +.header-cell { + text-transform: uppercase; +} + +.sort-container > div { + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; +} + +.component-container { + min-height: 300px; + + > div:last-child { + width: 7px !important; + border-radius: 4.5px !important; + } + + > div:last-child > div { + background-color: rgba(#2a2a2a, 0.3) !important; + border-radius: 4.5px !important; + } + + /* width */ + > div:first-child::-webkit-scrollbar { + width: 7px; + } + + /* Track */ + > div:first-child::-webkit-scrollbar-track { + box-shadow: none; + } + + /* Handle */ + > div:first-child::-webkit-scrollbar-thumb { + background: rgba(#2a2a2a, 0.3); + border-radius: 4.5px; + width: 7px; + } + + /* Handle on hover */ + > div:first-child::-webkit-scrollbar-thumb:hover { + background: rgba(#2a2a2a, 0.5); + } + + .table-container { + width: 100%; + + th { + @include roboto-medium; + } + + td, + th { + padding: 0 5px; + font-size: 14px; + text-align: left; + color: #2a2a2a; + line-height: 51px; + letter-spacing: 0.5px; + + &:last-child { + padding-right: 20px; + } + } + } +} + +.header-table-content { + display: flex; + align-items: center; +} + +.sort-container { + display: flex; + flex-direction: column; + margin-left: 5px; + padding: 0; + border: none; + outline: none; + background: transparent; +} + +.sort-up { + border-bottom: 4px solid $light-gray; + margin-bottom: 2px; + + &.active { + border-bottom: 4px solid $tc-black; + } +} + +.sort-down { + border-top: 4px solid $light-gray; + + &.active { + border-top: 4px solid $tc-black; + } +} + +.handle-link { + @include roboto-medium; + + font-weight: 400; + color: #0d61bf !important; + text-decoration: underline; + font-size: 16px; + + &:hover { + text-decoration: none; + } +} diff --git a/src/shared/containers/GSheet/index.jsx b/src/shared/containers/GSheet/index.jsx new file mode 100644 index 0000000000..591ee4c3c9 --- /dev/null +++ b/src/shared/containers/GSheet/index.jsx @@ -0,0 +1,64 @@ +/** + * Google sheets container to load data from sheets + * and render it as table + */ +import React from 'react'; +import PT from 'prop-types'; +import { connect } from 'react-redux'; +import { isEmpty } from 'lodash'; +import actions from 'actions/gSheet'; +import LoadingIndicator from 'components/LoadingIndicator'; +import GSheet from 'components/GSheet'; + +class GSeetContainer extends React.Component { + componentDidMount() { + const { + id, index, sheet, getGSheet, + } = this.props; + if (isEmpty(sheet)) { + getGSheet(id, index); + } + } + + render() { + const { sheet, config } = this.props; + return isEmpty(sheet) ? : ; + } +} + +GSeetContainer.defaultProps = { + index: 0, + config: {}, + sheet: null, +}; + +GSeetContainer.propTypes = { + id: PT.string.isRequired, + index: PT.number, + sheet: PT.shape(), + getGSheet: PT.func.isRequired, + config: PT.shape(), +}; + +function mapStateToProps(state, props) { + const { id, index } = props; + return { + id: props.id, + sheet: state.gSheet ? state.gSheet[`${id}-${index === undefined ? 0 : index}`] : {}, + }; +} + +function mapDispatchToProps(dispatch) { + const a = actions.gsheets; + return { + getGSheet: (id, index) => { + dispatch(a.getGsheetInit(id, index)); + dispatch(a.getGsheetDone(id, index)); + }, + }; +} + +export default connect( + mapStateToProps, + mapDispatchToProps, +)(GSeetContainer); diff --git a/src/shared/reducers/gSheet.js b/src/shared/reducers/gSheet.js new file mode 100644 index 0000000000..31410bb31d --- /dev/null +++ b/src/shared/reducers/gSheet.js @@ -0,0 +1,44 @@ +/** + * Reducer for state.gSheet + */ +import actions from 'actions/gSheet'; +import { handleActions } from 'redux-actions'; + +/** + * Handles getMmleaderboardInit action. + * @param {Object} state Previous state. + */ +function onInit(state, { payload }) { + return { + ...state, + [`${payload.id}-${payload.index}`]: {}, + }; +} + +/** + * Handles getMmleaderboardDone action. + * @param {Object} state Previous state. + * @param {Object} action The action. + */ +function onDone(state, { payload }) { + return { + ...state, + [`${payload.id}-${payload.index}`]: payload.data, + }; +} + +/** + * Creates mmleaderboard reducer with the specified initial state. + * @param {Object} state Optional. If not given, the default one is + * generated automatically. + * @return {Function} Reducer. + */ +function create(state = {}) { + return handleActions({ + [actions.gsheets.getGsheetInit]: onInit, + [actions.gsheets.getGsheetDone]: onDone, + }, state); +} + +/* Reducer with the default initial state. */ +export default create(); diff --git a/src/shared/reducers/index.js b/src/shared/reducers/index.js index 758a8f6d6d..518f7de831 100644 --- a/src/shared/reducers/index.js +++ b/src/shared/reducers/index.js @@ -38,6 +38,7 @@ import { factory as termsFactory } from './terms'; import newsletterPreferences from './newsletterPreferences'; import mmLeaderboard from './mmLeaderboard'; import recruitCRM from './recruitCRM'; +import gSheet from './gSheet'; /** * Given HTTP request, generates options for SSR by topcoder-react-lib's reducer @@ -144,6 +145,7 @@ export function factory(req) { newsletterPreferences, recruitCRM, mmLeaderboard, + gSheet, })); } diff --git a/src/shared/services/gSheet.js b/src/shared/services/gSheet.js new file mode 100644 index 0000000000..56355fe4e2 --- /dev/null +++ b/src/shared/services/gSheet.js @@ -0,0 +1,22 @@ +import fetch from 'isomorphic-fetch'; +import { logger } from 'topcoder-react-lib'; + +const PROXY_ENDPOINT = '/api/gsheets'; + +export default class Service { + baseUrl = PROXY_ENDPOINT; + + /** + * Get gsheet by id + * @param {string} id The sheet id + * @param {number} index sheet index + */ + async getSheet(id, index) { + const res = await fetch(`${this.baseUrl}/${id}${index !== undefined ? `?index=${index}` : ''}`); + if (!res.ok) { + const error = new Error(`Failed to get gsheet ${id}`); + logger.error(error, res); + } + return res.json(); + } +}