Merge branch 'master' of https://github.com/Human-Connection/Human-Connection into C-1187-terms-and-conditions-confirmed-function

This commit is contained in:
ogerly 2019-08-29 13:45:12 +02:00
commit c09e9a0149
22 changed files with 817 additions and 848 deletions

View File

@ -49,7 +49,7 @@
"apollo-client": "~2.6.4",
"apollo-link-context": "~1.0.18",
"apollo-link-http": "~1.5.15",
"apollo-server": "~2.9.0",
"apollo-server": "~2.9.1",
"apollo-server-express": "^2.9.0",
"babel-plugin-transform-runtime": "^6.23.0",
"bcryptjs": "~2.4.3",
@ -68,7 +68,7 @@
"graphql-middleware-sentry": "^3.2.0",
"graphql-shield": "~6.0.6",
"graphql-tag": "~2.10.1",
"helmet": "~3.20.0",
"helmet": "~3.20.1",
"jsonwebtoken": "~8.5.1",
"linkifyjs": "~2.1.8",
"lodash": "~4.17.14",
@ -91,7 +91,7 @@
"metascraper-youtube": "^5.6.3",
"minimatch": "^3.0.4",
"neo4j-driver": "~1.7.5",
"neo4j-graphql-js": "^2.7.1",
"neo4j-graphql-js": "^2.7.2",
"neode": "^0.3.2",
"node-fetch": "~2.6.0",
"nodemailer": "^6.3.0",
@ -110,15 +110,15 @@
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
"@babel/preset-env": "~7.5.5",
"@babel/register": "~7.5.5",
"apollo-server-testing": "~2.9.0",
"apollo-server-testing": "~2.9.1",
"babel-core": "~7.0.0-0",
"babel-eslint": "~10.0.3",
"babel-jest": "~24.9.0",
"chai": "~4.2.0",
"cucumber": "~5.1.0",
"eslint": "~6.2.1",
"eslint": "~6.2.2",
"eslint-config-prettier": "~6.1.0",
"eslint-config-standard": "~14.0.1",
"eslint-config-standard": "~14.1.0",
"eslint-plugin-import": "~2.18.2",
"eslint-plugin-jest": "~22.15.2",
"eslint-plugin-node": "~9.1.0",

View File

@ -1407,7 +1407,7 @@ acorn-globals@^4.1.0:
acorn "^6.0.1"
acorn-walk "^6.0.1"
acorn-jsx@^5.0.0:
acorn-jsx@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f"
integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==
@ -1538,13 +1538,13 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
apollo-cache-control@0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.8.1.tgz#707c0b958c02c5b47ddf49a02f60ea88a64783fb"
integrity sha512-yQy5KB/OuX90PsdztWc4vfc4R//ZmW/AxNgXKWga0xW5OzEsysdJWHAsTzb40/rkJ9VNeQ+0N5wGikiS+jSCzg==
apollo-cache-control@0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.8.2.tgz#0687e323053f907fd9bb601c1921de10799e24a0"
integrity sha512-rvx4DdoAAbWhm3L0IoWrxN+Zq2Xk4uAYbaiZk0Nhuc/y4AQUww3JV/z4EfCp3O5cy5/lNMW/tPOozcqi941awA==
dependencies:
apollo-server-env "2.4.1"
graphql-extensions "0.8.1"
apollo-server-env "2.4.2"
graphql-extensions "0.10.1"
apollo-cache-inmemory@~1.6.3:
version "1.6.3"
@ -1579,13 +1579,13 @@ apollo-client@~2.6.4:
tslib "^1.9.3"
zen-observable "^0.8.0"
apollo-datasource@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.6.1.tgz#697870f564da90bee53fa30d07875cb46c4d6b06"
integrity sha512-oy7c+9Up8PSZwJ1qTK9Idh1acDpIocvw+C0zcHg14ycvNz7qWHSwLUSaAjuQMd9SYFzB3sxfyEhyfyhIogT2+Q==
apollo-datasource@0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.6.2.tgz#3eeb8f9660304a223c3f7aecfe0274376c876307"
integrity sha512-GlqTfLjKFxNYxGGACDjDXUpm/vPfvXhUI/Qc/YdkY4ess/wn7EFdrmbZGIY56RJtXD5M7qjsQIH15t132KoPmQ==
dependencies:
apollo-server-caching "0.5.0"
apollo-server-env "2.4.1"
apollo-server-env "2.4.2"
apollo-engine-reporting-protobuf@0.4.0:
version "0.4.0"
@ -1594,18 +1594,18 @@ apollo-engine-reporting-protobuf@0.4.0:
dependencies:
protobufjs "^6.8.6"
apollo-engine-reporting@1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.4.3.tgz#0fcb67de7a24bef4e7e59990981f923267ffdd00"
integrity sha512-xv27qfc9dhi1yaWOhNQRmfF+SoLy74hl+M42arpIWdkoDe22fVTmTIqxqGwo4TFR3Z2OkAV5tNzuuOI/icd0Rg==
apollo-engine-reporting@1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.4.4.tgz#ab232dcaa81fe9718fb23e9782457c66dc86e817"
integrity sha512-FOk/HooLMesoKHo/TGOPYZuc2t4q9YwoeM+z0AGRUY70hL2o5Ie3x0XiMb+I5IVibR+jBIRRKP2ngmSFJ+LqSg==
dependencies:
apollo-engine-reporting-protobuf "0.4.0"
apollo-graphql "^0.3.3"
apollo-server-caching "0.5.0"
apollo-server-env "2.4.1"
apollo-server-types "0.2.1"
apollo-server-env "2.4.2"
apollo-server-types "0.2.2"
async-retry "^1.2.1"
graphql-extensions "0.9.1"
graphql-extensions "0.10.1"
apollo-env@0.5.1:
version "0.5.1"
@ -1675,26 +1675,26 @@ apollo-server-caching@0.5.0:
dependencies:
lru-cache "^5.0.0"
apollo-server-core@2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.9.0.tgz#5db251093ee121a5f4d90a24d51aa4c21e421243"
integrity sha512-IvKIgqOqEEB8nszlpHWzlhAu4376So2PgNhFP6UrlfNTllt/WDti5YMOHnVimPWIDHmLPKFan0+wfzpsoRCRdg==
apollo-server-core@2.9.1:
version "2.9.1"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.9.1.tgz#ed876cd2f954dc3f4f1e735b997d4dbf29a629a5"
integrity sha512-ZWPGNdZv/SiPjfEU7Wwut9N9oAucGlbVT+XCnpUl93agvkg3fbeTCLYBbjAdSA0Q6opq0tvWVGzwXPLpx6jZcQ==
dependencies:
"@apollographql/apollo-tools" "^0.4.0"
"@apollographql/graphql-playground-html" "1.6.24"
"@types/graphql-upload" "^8.0.0"
"@types/ws" "^6.0.0"
apollo-cache-control "0.8.1"
apollo-datasource "0.6.1"
apollo-engine-reporting "1.4.3"
apollo-cache-control "0.8.2"
apollo-datasource "0.6.2"
apollo-engine-reporting "1.4.4"
apollo-server-caching "0.5.0"
apollo-server-env "2.4.1"
apollo-server-errors "2.3.1"
apollo-server-plugin-base "0.6.1"
apollo-server-types "0.2.1"
apollo-tracing "0.8.1"
apollo-server-env "2.4.2"
apollo-server-errors "2.3.2"
apollo-server-plugin-base "0.6.2"
apollo-server-types "0.2.2"
apollo-tracing "0.8.2"
fast-json-stable-stringify "^2.0.0"
graphql-extensions "0.10.0"
graphql-extensions "0.10.1"
graphql-tag "^2.9.2"
graphql-tools "^4.0.0"
graphql-upload "^8.0.2"
@ -1702,23 +1702,23 @@ apollo-server-core@2.9.0:
subscriptions-transport-ws "^0.9.11"
ws "^6.0.0"
apollo-server-env@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.4.1.tgz#58264ecfeb151919e0f480320b4e3769be9f18f3"
integrity sha512-J4G1Q6qyb7KjjqvQdVM5HUH3QDb52VK1Rv+MWL0rHcstJx9Fh/NK0sS+nujrMfKw57NVUs2d4KuYtl/EnW/txg==
apollo-server-env@2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.4.2.tgz#8549caa7c8f57af88aadad5c2a0bb7adbcc5f76e"
integrity sha512-Qyi8fP8CWsBRAKs0fawMFauJj03I6N3ncWcGaVTuDppYluo4zjV6LqHfZ+YPWOx6apBihFNZap19RAhSnSwJLg==
dependencies:
node-fetch "^2.1.2"
util.promisify "^1.0.0"
apollo-server-errors@2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.1.tgz#033cf331463ebb99a563f8354180b41ac6714eb6"
integrity sha512-errZvnh0vUQChecT7M4A/h94dnBSRL213dNxpM5ueMypaLYgnp4hiCTWIEaooo9E4yMGd1qA6WaNbLDG2+bjcg==
apollo-server-errors@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.2.tgz#86bbd1ff8f0b5f16bfdcbb1760398928f9fce539"
integrity sha512-twVCP8tNHFzxOzU3jf84ppBFSvjvisZVWlgF82vwG+qEEUaAE5h5DVpeJbcI1vRW4VQPuFV+B+FIsnlweFKqtQ==
apollo-server-express@2.9.0, apollo-server-express@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.9.0.tgz#9d2a2d9823422ef26bca15931669d3153dc8a08b"
integrity sha512-+057V6Ui1BX69jUlV6YDQ7Xw9CCBfowN/GauvyF09KnsjYUJ+cB1xf4mkj/HAjaz4ReXQaALJNr2qPYPXS4R6w==
apollo-server-express@2.9.1, apollo-server-express@^2.9.0:
version "2.9.1"
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.9.1.tgz#9a8cb7fba579e68ddfa1953dfd066b751bca32f0"
integrity sha512-3mmuojt9s9Gyqdf8fbdKtbw23UFYrtVQtTNASgVW8zCabZqs2WjYnijMRf1aL4u9VSl+BFMOZUPMYaeBX+u38w==
dependencies:
"@apollographql/graphql-playground-html" "1.6.24"
"@types/accepts" "^1.3.5"
@ -1726,8 +1726,8 @@ apollo-server-express@2.9.0, apollo-server-express@^2.9.0:
"@types/cors" "^2.8.4"
"@types/express" "4.17.1"
accepts "^1.3.5"
apollo-server-core "2.9.0"
apollo-server-types "0.2.1"
apollo-server-core "2.9.1"
apollo-server-types "0.2.2"
body-parser "^1.18.3"
cors "^2.8.4"
graphql-subscriptions "^1.0.0"
@ -1736,47 +1736,47 @@ apollo-server-express@2.9.0, apollo-server-express@^2.9.0:
subscriptions-transport-ws "^0.9.16"
type-is "^1.6.16"
apollo-server-plugin-base@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.6.1.tgz#b9c209aa2102a26c6134f51bfa1e4a8307b63b11"
integrity sha512-gLLF0kz4QOOyczDGWuR2ZNDfa1nHfyFNG76ue8Es0/0ujnMT9KoSokXkx1hDh0X7FFTMj/MelYYoNEqgTH88zw==
apollo-server-plugin-base@0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.6.2.tgz#807e734e130c6750db680a58cd0e572cc0794184"
integrity sha512-f7grbfoI5fPxGJDmrvG0ulWq8vFHwvJSUrcEChhiUCSMFZlpBil/1TSaxJRESiQqnoZ9s5WrVhzuwejxODGMYw==
dependencies:
apollo-server-types "0.2.1"
apollo-server-types "0.2.2"
apollo-server-testing@~2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.9.0.tgz#fb5276e0761992ed493d84e998eaa4f696914519"
integrity sha512-N6c+wx5MaDZ0mWPzA11nKkkJjX+E3ubATY3G5ejprUsN8BiHENyEQ0EZh+dO0yL9+q/mUHix3p7Utax9odxBcw==
apollo-server-testing@~2.9.1:
version "2.9.1"
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.9.1.tgz#29d2524e84722a1319d9c1524b4f9d44379d6a49"
integrity sha512-TzlHIYNZgF1OkGji/ew3zPxboifvA9aGXDwWJFu54o1400svH0Uh5L7TMhsTZ8F992syQUsUuI+KKMOFNg73+w==
dependencies:
apollo-server-core "2.9.0"
apollo-server-core "2.9.1"
apollo-server-types@0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-0.2.1.tgz#553da40ea1ad779ef0390c250ddad7eb782fdf64"
integrity sha512-ls26d6jjY7x91ctLWtbpQHGW0lcFR1LcOpDvBQUC2aCwQzuW/6yV7F3hfcEdLR9pjIxcA4yAtFQcKf5olDWVkA==
apollo-server-types@0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-0.2.2.tgz#c26ff57ca0b45d67dfd72312094097e2b1c28980"
integrity sha512-/G4yXUF4Kc6PVCIF12r+oB8AXkE4UVnJoyZHeHiPeDpXklrjwIAtov2WM2mTcSZuZe1EuEkeDci4+tj5zFD39Q==
dependencies:
apollo-engine-reporting-protobuf "0.4.0"
apollo-server-caching "0.5.0"
apollo-server-env "2.4.1"
apollo-server-env "2.4.2"
apollo-server@~2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.9.0.tgz#32685712215d420ff5f3298b3b34e972e21ec1c6"
integrity sha512-KouRjMWn8pnR4KvVsFXT1GZYzH53J0+v9KwnLUKrLNo2G4KiZu5KhP+tEkF7uTlpHzdPMQAIbwjdXKzOH/r6ew==
apollo-server@~2.9.1:
version "2.9.1"
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.9.1.tgz#16ff443d43ea38f72fe20adea0803c46037b2b3b"
integrity sha512-iCGoRBOvwTUkDz6Nq/rKguMyhDiQdL3VneF0GTjBGrelTIp3YTIxk/qBFkIr2Chtm9ZZYkS6o+ZldUnxYFKg7A==
dependencies:
apollo-server-core "2.9.0"
apollo-server-express "2.9.0"
apollo-server-core "2.9.1"
apollo-server-express "2.9.1"
express "^4.0.0"
graphql-subscriptions "^1.0.0"
graphql-tools "^4.0.0"
apollo-tracing@0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.8.1.tgz#220aeac6ad598c67f9333739155b7a56bd63ccab"
integrity sha512-zhVNC7N6hg9IJEeSEXFDxcnXD5GJQAbHxaoKVBKEolcIIsz6EGd700ORdagJgFKLReVp9O65HPrZJCg66sVx7g==
apollo-tracing@0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.8.2.tgz#2d1ebef434c4e2803f9a3adfc7d2409690b3c378"
integrity sha512-4SVxHZkKZX/7E6/4hAvEJXdHm+1BjQqtgEkv3ywyiVXoaKn0YNJL8BVIOI4GAt0qoc3KzT9MDJ1nf+SurUFjLQ==
dependencies:
apollo-server-env "2.4.1"
graphql-extensions "0.8.1"
apollo-server-env "2.4.2"
graphql-extensions "0.10.1"
apollo-utilities@1.3.2, apollo-utilities@^1.0.1, apollo-utilities@^1.3.0, apollo-utilities@^1.3.2:
version "1.3.2"
@ -2148,6 +2148,11 @@ boolbase@~1.0.0:
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
bowser@2.5.3:
version "2.5.3"
resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.5.3.tgz#811b0a24219c566c9a6ab3402bc8a13f35a18a96"
integrity sha512-aWCA+CKfKNL/WGzNgjmK+Whp57JMzboZMwJ5gy2jDj2bEIjbMCb3ImGX+V++5wsJftyFiDIbOjRXl60ycniVqg==
boxen@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
@ -3285,10 +3290,10 @@ eslint-config-prettier@~6.1.0:
dependencies:
get-stdin "^6.0.0"
eslint-config-standard@~14.0.1:
version "14.0.1"
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.0.1.tgz#375c3636fb4bd453cb95321d873de12e4eef790b"
integrity sha512-1RWsAKTDTZgA8bIM6PSC9aTGDAUlKqNkYNJlTZ5xYD/HYkIM6GlcefFvgcJ8xi0SWG5203rttKYX28zW+rKNOg==
eslint-config-standard@~14.1.0:
version "14.1.0"
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.0.tgz#b23da2b76fe5a2eba668374f246454e7058f15d4"
integrity sha512-EF6XkrrGVbvv8hL/kYa/m6vnvmUT+K82pJJc4JJVMM6+Qgqh0pnwprSxdduDLB9p/7bIxD+YV5O0wfb8lmcPbA==
eslint-import-resolver-node@^0.3.2:
version "0.3.2"
@ -3395,10 +3400,10 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
eslint@~6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.2.1.tgz#66c2e4fe8b6356b9f01e828adc3ad04030122df1"
integrity sha512-ES7BzEzr0Q6m5TK9i+/iTpKjclXitOdDK4vT07OqbkBT2/VcN/gO9EL1C4HlK3TAOXYv2ItcmbVR9jO1MR0fJg==
eslint@~6.2.2:
version "6.2.2"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.2.2.tgz#03298280e7750d81fcd31431f3d333e43d93f24f"
integrity sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw==
dependencies:
"@babel/code-frame" "^7.0.0"
ajv "^6.10.0"
@ -3409,7 +3414,7 @@ eslint@~6.2.1:
eslint-scope "^5.0.0"
eslint-utils "^1.4.2"
eslint-visitor-keys "^1.1.0"
espree "^6.1.0"
espree "^6.1.1"
esquery "^1.0.1"
esutils "^2.0.2"
file-entry-cache "^5.0.1"
@ -3438,13 +3443,13 @@ eslint@~6.2.1:
text-table "^0.2.0"
v8-compile-cache "^2.0.3"
espree@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.0.tgz#a1e8aa65bf29a331d70351ed814a80e7534e0884"
integrity sha512-boA7CHRLlVWUSg3iL5Kmlt/xT3Q+sXnKoRYYzj1YeM10A76TEJBbotV5pKbnK42hEUIr121zTv+QLRM5LsCPXQ==
espree@^6.1.1:
version "6.1.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de"
integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==
dependencies:
acorn "^7.0.0"
acorn-jsx "^5.0.0"
acorn-jsx "^5.0.2"
eslint-visitor-keys "^1.1.0"
esprima@^3.1.3:
@ -4072,32 +4077,14 @@ graphql-custom-directives@~0.2.14:
moment "^2.22.2"
numeral "^2.0.6"
graphql-extensions@0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.10.0.tgz#ceafc42e16554930b0dc90f64d5727ee2a9e9cf9"
integrity sha512-qz9Ev0NgsRxdTYqYSCpYwBWS9r1imm+vCBt3PmHzqZlE7SEpUPGddn9oKcLRB/P8uXT6dsr60hDmDHukIxiVOw==
graphql-extensions@0.10.1:
version "0.10.1"
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.10.1.tgz#9e1abd502f3f802a7ab60c3a28d2fe705e53d4cb"
integrity sha512-RIlC/jgBKZ/qyrb+cAu7oJVYLC0dJh6al35tNy8dnqE9JImNucy/gFWVOPW7q3fAaXqCHzbBEtdb+ws1L43LgQ==
dependencies:
"@apollographql/apollo-tools" "^0.4.0"
apollo-server-env "2.4.1"
apollo-server-types "0.2.1"
graphql-extensions@0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.8.1.tgz#f5f1fed5fe49620c4e70c5d08bdbd0039e91c402"
integrity sha512-d/L4x7/PPWhviJqi7jIWOVJPzfzagYgPizSQUpa+3hozbWhwpWEnfxwgL5/If5MnPUikBnqlkOLCyjHMNdipYA==
dependencies:
"@apollographql/apollo-tools" "^0.4.0"
apollo-server-env "2.4.1"
apollo-server-types "0.2.1"
graphql-extensions@0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.9.1.tgz#5d40b2c2cf57a35b686121d5e63783369dade5ef"
integrity sha512-JR/KStdwALd48B/xSG/Mi85zamuJd8THvVlzGM5juznPDN0wTYG5SARGzzvoqHxgxuUHYdzpvESwMAisORJdCQ==
dependencies:
"@apollographql/apollo-tools" "^0.4.0"
apollo-server-env "2.4.1"
apollo-server-types "0.2.1"
apollo-server-env "2.4.2"
apollo-server-types "0.2.2"
graphql-import@0.7.1:
version "0.7.1"
@ -4312,20 +4299,20 @@ helmet-crossdomain@0.4.0:
resolved "https://registry.yarnpkg.com/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz#5f1fe5a836d0325f1da0a78eaa5fd8429078894e"
integrity sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==
helmet-csp@2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/helmet-csp/-/helmet-csp-2.8.0.tgz#746d329e24ef39c4ebc00278a48abd3c209e0378"
integrity sha512-MlCPeM0Sm3pS9RACRihx70VeTHmkQwa7sum9EK1tfw1VZyvFU0dBWym9nHh3CRkTRNlyNm/WFCMvuh9zXkOjNw==
helmet-csp@2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/helmet-csp/-/helmet-csp-2.9.0.tgz#8524886b08c7f7d611cb5f36eae453dd604efd4c"
integrity sha512-DGGOQtOLM7ZQpjbf/uvUonq1yG/rFgsBuK10ZJt2AtxUJxqfkPvfmP9aLUmgH9IactiRiYoiFY72YYSPl1TLTQ==
dependencies:
bowser "2.5.3"
camelize "1.0.0"
content-security-policy-builder "2.1.0"
dasherize "2.0.0"
platform "1.3.5"
helmet@~3.20.0:
version "3.20.0"
resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.20.0.tgz#8a9383bf8230a461cafe8bc763423fbde110d2fc"
integrity sha512-Ob+TqmQFZ5f7WgP8kBbAzNPsbf6p1lOj5r+327/ymw/IILWih3wcx9u/u/S8Mwv5wbBkO7Li6x5s23t3COhUKw==
helmet@~3.20.1:
version "3.20.1"
resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.20.1.tgz#802fcb39ac6865208cbc6879d3502e582c6f777e"
integrity sha512-em+X5Wz/f0yqoRsBnpnVy3wJHSiIeskX3FQn30szBh1tILaOeSRRLkShuUVFlk/o4qTYjWxdHg4FrRe45iBWHg==
dependencies:
depd "2.0.0"
dns-prefetch-control "0.2.0"
@ -4334,7 +4321,7 @@ helmet@~3.20.0:
feature-policy "0.3.0"
frameguard "3.1.0"
helmet-crossdomain "0.4.0"
helmet-csp "2.8.0"
helmet-csp "2.9.0"
hide-powered-by "1.1.0"
hpkp "2.0.0"
hsts "2.2.0"
@ -6197,10 +6184,10 @@ neo4j-driver@^1.7.3, neo4j-driver@^1.7.5, neo4j-driver@~1.7.5:
text-encoding-utf-8 "^1.0.2"
uri-js "^4.2.2"
neo4j-graphql-js@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.7.1.tgz#2d5bd151685b64644b0cf0645434cc396a923b5d"
integrity sha512-WrtcS0q//Rh56OMGJUUKZAucODJcTjDoSoShWCViu2Ft2tSD8V6ag06yHwmvQ2pO33elsAEQ0osTvWL1+s3Xiw==
neo4j-graphql-js@^2.7.2:
version "2.7.2"
resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.7.2.tgz#6a56c63874bc41e678cb83580c6c7647e6f61ccf"
integrity sha512-nrhSmNAkiYgksNabNuHyMHYYaLloYZaVXRiYGrRVUcf84TLiwJdg5k9hIQVH9O6QQOvnK3lwBDlE7T0phpAIpg==
dependencies:
"@babel/runtime" "^7.5.5"
"@babel/runtime-corejs2" "^7.5.5"
@ -6886,11 +6873,6 @@ pkginfo@~0.4.0:
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff"
integrity sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=
platform@1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.5.tgz#fb6958c696e07e2918d2eeda0f0bc9448d733444"
integrity sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==
pn@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"

View File

@ -1,6 +1,16 @@
# End-to-End Testing
## Configure cypress
## Setup with docker
Are you running everything through docker? You're so lucky you don't have to
setup anything!
Just:
```
docker-compose up
```
## Setup without docker
First, you have to tell cypress how to connect to your local neo4j database
among other things. You can copy our template configuration and change the new
@ -11,16 +21,15 @@ Make sure you are at the root level of the project. Then:
# in the top level folder Human-Connection/
$ cp cypress.env.template.json cypress.env.json
```
## Run Tests
To run the tests, do this:
To start the services that are required for cypress testing, run this:
```bash
# in the top level folder Human-Connection/
$ yarn cypress:setup
```
## Run cypress
After verifying that there are no errors with the servers starting, open another tab in your terminal and run the following command:
```bash
@ -29,13 +38,12 @@ $ yarn cypress:run
![Console output after running cypress test](../.gitbook/assets/grafik%20%281%29.png)
After the test runs, you will also get some video footage of the test run which you can then analyse in more detail.
## Open Interactive Test Console
### Open Interactive Test Console
If you are like me, you might want to see some visual output. The interactive cypress environment also helps at debugging your tests, you can even time travel between individual steps and see the exact state of the app.
To use this feature, you will still run the `yarn cypress:setup` above, but instead of `yarn cypress:run` open another tab in your terminal and run the following command:
To use this feature, instead of `yarn cypress:run` you would run the following command:
```bash
$ yarn cypress:open

View File

@ -7,20 +7,21 @@ metadata:
kubernetes.io/ingress.class: "nginx"
certmanager.k8s.io/issuer: "letsencrypt-staging"
certmanager.k8s.io/acme-challenge-type: http01
nginx.ingress.kubernetes.io/proxy-body-size: 6m
spec:
tls:
- hosts:
# - nitro-mailserver.human-connection.org
- nitro-staging.human-connection.org
secretName: tls
- hosts:
# - nitro-mailserver.human-connection.org
- nitro-staging.human-connection.org
secretName: tls
rules:
- host: nitro-staging.human-connection.org
http:
paths:
- path: /
backend:
serviceName: nitro-web
servicePort: 3000
- host: nitro-staging.human-connection.org
http:
paths:
- path: /
backend:
serviceName: nitro-web
servicePort: 3000
# - host: nitro-mailserver.human-connection.org
# http:
# paths:

View File

@ -12,6 +12,6 @@
# On Windows this resolves to C:\Users\dornhoeschen\AppData\Local\Temp\mongo-export (MinGW)
EXPORT_PATH='/tmp/mongo-export/'
EXPORT_MONGOEXPORT_BIN='mongoexport'
MONGO_EXPORT_SPLIT_SIZE=100
MONGO_EXPORT_SPLIT_SIZE=4000
# On Windows use something like this
# EXPORT_MONGOEXPORT_BIN='C:\Program Files\MongoDB\Server\3.6\bin\mongoexport.exe'

View File

@ -16,6 +16,30 @@ services:
- webapp_node_modules:/nitro-web/node_modules
command: yarn run dev
user: root
factories:
image: humanconnection/nitro-backend:builder
build:
context: backend
target: builder
ports:
- 4001:4001
networks:
- hc-network
volumes:
- ./backend:/nitro-backend
- factories_node_modules:/nitro-backend/node_modules
- uploads:/nitro-backend/public/uploads
depends_on:
- neo4j
environment:
- NEO4J_URI=bolt://neo4j:7687
- GRAPHQL_PORT=4000
- GRAPHQL_URI=http://localhost:4000
- CLIENT_URI=http://localhost:3000
- JWT_SECRET=b/&&7b78BF&fv/Vd
- MAPBOX_TOKEN=pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ
- PRIVATE_KEY_PASSPHRASE=a7dsf78sadg87ad87sfagsadg78
command: yarn run test:before:seeder
backend:
image: humanconnection/nitro-backend:builder
build:
@ -42,5 +66,6 @@ services:
volumes:
webapp_node_modules:
backend_node_modules:
factories_node_modules:
neo4j-data:
uploads:

View File

@ -23,7 +23,7 @@
"codecov": "^3.5.0",
"cross-env": "^5.2.0",
"cypress": "^3.4.1",
"cypress-cucumber-preprocessor": "^1.15.0",
"cypress-cucumber-preprocessor": "^1.15.1",
"cypress-file-upload": "^3.3.3",
"cypress-plugin-retries": "^1.2.2",
"dotenv": "^8.1.0",

View File

@ -62,12 +62,13 @@
</template>
<script>
import gql from 'graphql-tag'
import { mapGetters, mapMutations } from 'vuex'
import HcUser from '~/components/User'
import ContentMenu from '~/components/ContentMenu'
import ContentViewer from '~/components/Editor/ContentViewer'
import HcEditCommentForm from '~/components/EditCommentForm/EditCommentForm'
import CommentMutations from '~/graphql/CommentMutations'
import PostQuery from '~/graphql/PostQuery'
export default {
data: function() {
@ -142,16 +143,23 @@ export default {
},
async deleteCommentCallback() {
try {
var gqlMutation = gql`
mutation($id: ID!) {
DeleteComment(id: $id) {
id
}
}
`
await this.$apollo.mutate({
mutation: gqlMutation,
mutation: CommentMutations(this.$i18n).DeleteComment,
variables: { id: this.comment.id },
update: async store => {
const data = await store.readQuery({
query: PostQuery(this.$i18n),
variables: { id: this.post.id },
})
const index = data.Post[0].comments.findIndex(
deletedComment => deletedComment.id === this.comment.id,
)
if (index !== -1) {
data.Post[0].comments.splice(index, 1)
}
await store.writeQuery({ query: PostQuery(this.$i18n), data })
},
})
this.$toast.success(this.$t(`delete.comment.success`))
this.$emit('deleteComment')

View File

@ -80,13 +80,13 @@ export default {
postId: this.post.id,
content: this.form.content,
},
update: (store, { data: { CreateComment } }) => {
const data = store.readQuery({
update: async (store, { data: { CreateComment } }) => {
const data = await store.readQuery({
query: PostQuery(this.$i18n),
variables: { id: this.post.id },
})
data.Post[0].comments.push(CreateComment)
store.writeQuery({ query: PostQuery(this.$i18n), data })
await store.writeQuery({ query: PostQuery(this.$i18n), data })
},
})
.then(res => {

View File

@ -23,7 +23,7 @@
/>
<small class="smallTag">{{ form.contentLength }}/{{ contentMax }}</small>
</client-only>
<ds-space margin-bottom="xxx-large" />
<ds-space margin-bottom="small" />
<hc-categories-select
model="categoryIds"
@updateCategories="updateCategories"

View File

@ -0,0 +1,95 @@
<script>
import tippy from 'tippy.js'
export default {
props: {
content: Object,
node: Object,
},
methods: {
displayContextMenu(target, content, type) {
const placement = type === 'link' ? 'right' : 'top-start'
const trigger = type === 'link' ? 'click' : 'mouseenter'
const showOnInit = type !== 'link'
if (this.menu) {
return
}
this.menu = tippy(target, {
arrow: true,
arrowType: 'round',
content: content,
duration: [400, 200],
inertia: true,
interactive: true,
placement,
showOnInit,
theme: 'human-connection',
trigger,
onMount(instance) {
const input = instance.popper.querySelector('input')
if (input) {
input.focus({ preventScroll: true })
}
},
})
// we have to update tippy whenever the DOM is updated
if (MutationObserver) {
this.observer = new MutationObserver(() => {
this.menu.popperInstance.scheduleUpdate()
})
this.observer.observe(content, {
childList: true,
subtree: true,
characterData: true,
})
}
},
hideContextMenu() {
if (this.menu) {
this.menu.destroy()
this.menu = null
}
if (this.observer) {
this.observer.disconnect()
}
},
},
render() {
return null
},
}
</script>
<style lang="scss">
.tippy-tooltip.human-connection-theme {
background-color: $color-primary;
padding: 0;
font-size: 1rem;
text-align: inherit;
color: $color-neutral-100;
.tippy-backdrop {
display: none;
}
.tippy-roundarrow {
fill: $color-primary;
}
.tippy-popper[x-placement^='top'] & .tippy-arrow {
border-top-color: $color-primary;
}
.tippy-popper[x-placement^='bottom'] & .tippy-arrow {
border-bottom-color: $color-primary;
}
.tippy-popper[x-placement^='left'] & .tippy-arrow {
border-left-color: $color-primary;
}
.tippy-popper[x-placement^='right'] & .tippy-arrow {
border-right-color: $color-primary;
}
}
</style>

View File

@ -1,203 +1,52 @@
<template>
<div class="editor">
<!-- Mention and Hashtag Suggestions Menu -->
<div v-show="showSuggestions" ref="suggestions" class="suggestion-list">
<!-- "filteredItems" array is not empty -->
<template v-if="hasResults">
<div
v-for="(item, index) in filteredItems"
:key="item.id"
class="suggestion-list__item"
:class="{ 'is-selected': navigatedItemIndex === index }"
@click="selectItem(item)"
>
<div v-if="isMention">@{{ item.slug }}</div>
<div v-if="isHashtag">#{{ item.id }}</div>
</div>
<div v-if="isHashtag">
<!-- if query is not empty and is find fully in the suggestions array ... -->
<div v-if="query && !filteredItems.find(el => el.id === query)">
<div class="suggestion-list__item is-empty">{{ $t('editor.hashtag.addHashtag') }}</div>
<div class="suggestion-list__item" @click="selectItem({ id: query })">#{{ query }}</div>
</div>
<!-- otherwise if sanitized query is empty advice the user to add a char -->
<div v-else-if="!query">
<div class="suggestion-list__item is-empty">{{ $t('editor.hashtag.addLetter') }}</div>
</div>
</div>
</template>
<!-- if "!hasResults" -->
<div v-else>
<div v-if="isMention" class="suggestion-list__item is-empty">
{{ $t('editor.mention.noUsersFound') }}
</div>
<div v-if="isHashtag">
<div v-if="query === ''" class="suggestion-list__item is-empty">
{{ $t('editor.hashtag.noHashtagsFound') }}
</div>
<!-- if "query" is not empty -->
<div v-else>
<div class="suggestion-list__item is-empty">{{ $t('editor.hashtag.addHashtag') }}</div>
<div class="suggestion-list__item" @click="selectItem({ id: query })">#{{ query }}</div>
</div>
</div>
</div>
</div>
<editor-menu-bubble :editor="editor">
<div
ref="menu"
slot-scope="{ commands, getMarkAttrs, isActive, menu }"
class="menububble tooltip"
x-placement="top"
:class="{ 'is-active': menu.isActive || linkMenuIsActive }"
:style="`left: ${menu.left}px; bottom: ${menu.bottom}px;`"
>
<div class="tooltip-wrapper">
<template v-if="linkMenuIsActive">
<ds-input
ref="linkInput"
v-model="linkUrl"
class="editor-menu-link-input"
placeholder="http://"
@blur.native.capture="hideMenu(menu.isActive)"
@keydown.native.esc.prevent="hideMenu(menu.isActive)"
@keydown.native.enter.prevent="setLinkUrl(commands.link, linkUrl)"
/>
</template>
<template v-else>
<ds-button
class="menububble__button"
size="small"
:hover="isActive.bold()"
ghost
@click.prevent="() => {}"
@mousedown.native.prevent="commands.bold"
>
<ds-icon name="bold" />
</ds-button>
<ds-button
class="menububble__button"
size="small"
:hover="isActive.italic()"
ghost
@click.prevent="() => {}"
@mousedown.native.prevent="commands.italic"
>
<ds-icon name="italic" />
</ds-button>
<ds-button
class="menububble__button"
size="small"
:hover="isActive.link()"
ghost
@click.prevent="() => {}"
@mousedown.native.prevent="showLinkMenu(getMarkAttrs('link'))"
>
<ds-icon name="link" />
</ds-button>
</template>
</div>
<div class="tooltip-arrow" />
</div>
</editor-menu-bubble>
<editor-floating-menu :editor="editor">
<div
slot-scope="{ commands, isActive, menu }"
class="editor__floating-menu"
:class="{ 'is-active': menu.isActive }"
:style="`top: ${menu.top}px`"
>
<ds-button
class="menubar__button"
size="small"
:ghost="!isActive.paragraph()"
@click.prevent="commands.paragraph()"
>
<ds-icon name="paragraph" />
</ds-button>
<ds-button
class="menubar__button"
size="small"
:ghost="!isActive.heading({ level: 3 })"
@click.prevent="commands.heading({ level: 3 })"
>
H3
</ds-button>
<ds-button
class="menubar__button"
size="small"
:ghost="!isActive.heading({ level: 4 })"
@click.prevent="commands.heading({ level: 4 })"
>
H4
</ds-button>
<ds-button
class="menubar__button"
size="small"
:ghost="!isActive.bullet_list()"
@click.prevent="commands.bullet_list()"
>
<ds-icon name="list-ul" />
</ds-button>
<ds-button
class="menubar__button"
size="small"
:ghost="!isActive.ordered_list()"
@click.prevent="commands.ordered_list()"
>
<ds-icon name="list-ol" />
</ds-button>
<ds-button
class="menubar__button"
size="small"
:ghost="!isActive.blockquote()"
@click.prevent="commands.blockquote"
>
<ds-icon name="quote-right" />
</ds-button>
<ds-button
class="menubar__button"
size="small"
:ghost="!isActive.horizontal_rule()"
@click.prevent="commands.horizontal_rule"
>
<ds-icon name="minus" />
</ds-button>
</div>
</editor-floating-menu>
<editor-content ref="editor" :editor="editor" />
<menu-bar :editor="editor" :toggleLinkInput="toggleLinkInput" />
<editor-content ref="editor" :editor="editor" class="ds-input editor-content" />
<context-menu ref="contextMenu" />
<suggestion-list
ref="suggestions"
:suggestion-type="suggestionType"
:filtered-items="filteredItems"
:navigated-item-index="navigatedItemIndex"
:query="query"
:select-item="selectItem"
/>
<link-input
v-show="isLinkInputActive"
ref="linkInput"
:toggle-link-input="toggleLinkInput"
:set-link-url="setLinkUrl"
/>
</div>
</template>
<script>
import defaultExtensions from './defaultExtensions.js'
import { mapGetters } from 'vuex'
import { Editor, EditorContent } from 'tiptap'
import { History } from 'tiptap-extensions'
import linkify from 'linkify-it'
import stringHash from 'string-hash'
import Fuse from 'fuse.js'
import tippy from 'tippy.js'
import { Editor, EditorContent, EditorFloatingMenu, EditorMenuBubble } from 'tiptap'
import * as key from '../../constants/keycodes'
import { HASHTAG, MENTION } from '../../constants/editor'
import defaultExtensions from './defaultExtensions.js'
import EventHandler from './plugins/eventHandler.js'
import { History } from 'tiptap-extensions'
import Hashtag from './nodes/Hashtag.js'
import Mention from './nodes/Mention.js'
import { mapGetters } from 'vuex'
import MenuBar from './MenuBar'
import ContextMenu from './ContextMenu'
import SuggestionList from './SuggestionList'
import LinkInput from './LinkInput'
let throttleInputEvent
export default {
components: {
ContextMenu,
EditorContent,
EditorFloatingMenu,
EditorMenuBubble,
LinkInput,
MenuBar,
SuggestionList,
},
props: {
users: { type: Array, default: () => null }, // If 'null', than the Mention extention is not assigned.
@ -206,189 +55,11 @@ export default {
doc: { type: Object, default: () => {} },
},
data() {
// Set array of optional extensions by analysing the props.
let optionalExtensions = []
// Don't change the following line. The functionallity is in danger!
if (this.users) {
optionalExtensions.push(
new Mention({
// a list of all suggested items
items: () => {
return this.users
},
// is called when a suggestion starts
onEnter: ({ items, query, range, command, virtualNode }) => {
this.suggestionType = this.mentionSuggestionType
this.query = query
this.filteredItems = items
this.suggestionRange = range
this.renderPopup(virtualNode)
// we save the command for inserting a selected mention
// this allows us to call it inside of our custom popup
// via keyboard navigation and on click
this.insertMentionOrHashtag = command
},
// is called when a suggestion has changed
onChange: ({ items, query, range, virtualNode }) => {
this.query = query
this.filteredItems = items
this.suggestionRange = range
this.navigatedItemIndex = 0
this.renderPopup(virtualNode)
},
// is called when a suggestion is cancelled
onExit: () => {
this.suggestionType = this.nullSuggestionType
// reset all saved values
this.query = null
this.filteredItems = []
this.suggestionRange = null
this.navigatedItemIndex = 0
this.destroyPopup()
},
// is called on every keyDown event while a suggestion is active
onKeyDown: ({ event }) => {
// pressing up arrow
if (event.keyCode === 38) {
this.upHandler()
return true
}
// pressing down arrow
if (event.keyCode === 40) {
this.downHandler()
return true
}
// pressing enter
if (event.keyCode === 13) {
this.enterHandler()
return true
}
return false
},
// is called when a suggestion has changed
// this function is optional because there is basic filtering built-in
// you can overwrite it if you prefer your own filtering
// in this example we use fuse.js with support for fuzzy search
onFilter: (items, query) => {
if (!query) {
return items
}
const fuse = new Fuse(items, {
threshold: 0.2,
keys: ['slug'],
})
return fuse.search(query)
},
}),
)
}
// Don't change the following line. The functionallity is in danger!
if (this.hashtags) {
optionalExtensions.push(
new Hashtag({
// a list of all suggested items
items: () => {
return this.hashtags
},
// is called when a suggestion starts
onEnter: ({ items, query, range, command, virtualNode }) => {
this.suggestionType = this.hashtagSuggestionType
this.query = this.sanitizedQuery(query)
this.filteredItems = items
this.suggestionRange = range
this.renderPopup(virtualNode)
// we save the command for inserting a selected mention
// this allows us to call it inside of our custom popup
// via keyboard navigation and on click
this.insertMentionOrHashtag = command
},
// is called when a suggestion has changed
onChange: ({ items, query, range, virtualNode }) => {
this.query = this.sanitizedQuery(query)
this.filteredItems = items
this.suggestionRange = range
this.navigatedItemIndex = 0
this.renderPopup(virtualNode)
},
// is called when a suggestion is cancelled
onExit: () => {
this.suggestionType = this.nullSuggestionType
// reset all saved values
this.query = null
this.filteredItems = []
this.suggestionRange = null
this.navigatedItemIndex = 0
this.destroyPopup()
},
// is called on every keyDown event while a suggestion is active
onKeyDown: ({ event }) => {
// pressing up arrow
if (event.keyCode === 38) {
this.upHandler()
return true
}
// pressing down arrow
if (event.keyCode === 40) {
this.downHandler()
return true
}
// pressing enter
if (event.keyCode === 13) {
this.enterHandler()
return true
}
// pressing space
if (event.keyCode === 32) {
this.spaceHandler()
return true
}
return false
},
// is called when a suggestion has changed
// this function is optional because there is basic filtering built-in
// you can overwrite it if you prefer your own filtering
// in this example we use fuse.js with support for fuzzy search
onFilter: (items, query) => {
query = this.sanitizedQuery(query)
if (!query) {
return items
}
return items.filter(item =>
JSON.stringify(item)
.toLowerCase()
.includes(query.toLowerCase()),
)
},
}),
)
}
return {
lastValueHash: null,
editor: new Editor({
content: this.value || '',
doc: this.doc,
extensions: [
...defaultExtensions(this),
new EventHandler(),
new History(),
...optionalExtensions,
],
onUpdate: e => {
clearTimeout(throttleInputEvent)
throttleInputEvent = setTimeout(() => this.onUpdate(e), 300)
},
}),
linkUrl: null,
linkMenuIsActive: false,
nullSuggestionType: '',
mentionSuggestionType: 'mention',
hashtagSuggestionType: 'hashtag',
suggestionType: this.nullSuggestionType,
editor: null,
isLinkInputActive: false,
suggestionType: '',
query: null,
suggestionRange: null,
filteredItems: [],
@ -399,17 +70,39 @@ export default {
},
computed: {
...mapGetters({ placeholder: 'editor/placeholder' }),
hasResults() {
return this.filteredItems.length
},
showSuggestions() {
return this.query || this.hasResults
},
isMention() {
return this.suggestionType === this.mentionSuggestionType
},
isHashtag() {
return this.suggestionType === this.hashtagSuggestionType
optionalExtensions() {
const extensions = []
// Don't change the following line. The functionallity is in danger!
if (this.users) {
extensions.push(
new Mention({
items: () => {
return this.users
},
onEnter: props => this.openSuggestionList(props, MENTION),
onChange: this.updateSuggestionList,
onExit: this.closeSuggestionList,
onKeyDown: this.navigateSuggestionList,
onFilter: this.filterSuggestionList,
}),
)
}
// Don't change the following line. The functionallity is in danger!
if (this.hashtags) {
extensions.push(
new Hashtag({
items: () => {
return this.hashtags
},
onEnter: props => this.openSuggestionList(props, HASHTAG),
onChange: this.updateSuggestionList,
onExit: this.closeSuggestionList,
onKeyDown: this.navigateSuggestionList,
onFilter: this.filterSuggestionList,
}),
)
}
return extensions
},
},
watch: {
@ -421,52 +114,110 @@ export default {
return
}
this.lastValueHash = contentHash
this.editor.setContent(content)
this.$nextTick(() => this.editor.setContent(content))
},
},
placeholder: {
immediate: true,
handler: function(val) {
if (!val) {
if (!val || !this.editor) {
return
}
this.editor.extensions.options.placeholder.emptyNodeText = val
},
},
},
created() {
this.editor = new Editor({
content: this.value || '',
doc: this.doc,
extensions: [
...defaultExtensions(this),
new EventHandler(),
new History(),
...this.optionalExtensions,
],
onUpdate: e => {
clearTimeout(throttleInputEvent)
throttleInputEvent = setTimeout(() => this.onUpdate(e), 300)
},
})
},
beforeDestroy() {
this.editor.destroy()
},
methods: {
sanitizedQuery(query) {
// remove all not allowed chars
query = query.replace(/[^a-zA-Z0-9]/gm, '')
// if the query is only made of digits, make it empty
return query.replace(/[0-9]/gm, '') === '' ? '' : query
openSuggestionList({ items, query, range, command, virtualNode }, suggestionType) {
this.suggestionType = suggestionType
this.query = this.sanitizeQuery(query)
this.filteredItems = items
this.suggestionRange = range
this.$refs.contextMenu.displayContextMenu(virtualNode, this.$refs.suggestions.$el)
this.insertMentionOrHashtag = command
},
// navigate to the previous item
// if it's the first item, navigate to the last one
upHandler() {
this.navigatedItemIndex =
(this.navigatedItemIndex + this.filteredItems.length - 1) % this.filteredItems.length
updateSuggestionList({ items, query, range, virtualNode }) {
this.query = this.sanitizeQuery(query)
this.filteredItems = items
this.suggestionRange = range
this.navigatedItemIndex = 0
this.$refs.contextMenu.displayContextMenu(virtualNode, this.$refs.suggestions.$el)
},
// navigate to the next item
// if it's the last item, navigate to the first one
downHandler() {
this.navigatedItemIndex = (this.navigatedItemIndex + 1) % this.filteredItems.length
closeSuggestionList() {
this.suggestionType = ''
this.query = null
this.filteredItems = []
this.suggestionRange = null
this.navigatedItemIndex = 0
this.$refs.contextMenu.hideContextMenu()
},
// Handles pressing of enter.
enterHandler() {
navigateSuggestionList({ event }) {
const item = this.filteredItems[this.navigatedItemIndex]
if (item) {
this.selectItem(item)
switch (event.keyCode) {
case key.ARROW_UP:
this.navigatedItemIndex =
(this.navigatedItemIndex + this.filteredItems.length - 1) % this.filteredItems.length
return true
case key.ARROW_DOWN:
this.navigatedItemIndex = (this.navigatedItemIndex + 1) % this.filteredItems.length
return true
case key.RETURN:
if (item) {
this.selectItem(item)
}
return true
case key.SPACE:
if (this.suggestionType === HASHTAG && this.query !== '') {
this.selectItem({ id: this.query })
}
return true
default:
return false
}
},
// For hashtags handles pressing of space.
spaceHandler() {
if (this.suggestionType === this.hashtagSuggestionType && this.query !== '') {
this.selectItem({ id: this.query })
filterSuggestionList(items, query) {
query = this.sanitizeQuery(query)
if (!query) {
return items
}
return items.filter(item => {
const itemString = item.slug || item.id
return itemString.toLowerCase().includes(query.toLowerCase())
})
},
sanitizeQuery(query) {
if (this.suggestionType === HASHTAG) {
// remove all not allowed chars
query = query.replace(/[^a-zA-Z0-9]/gm, '')
// if the query is only made of digits, make it empty
return query.replace(/[0-9]/gm, '') === '' ? '' : query
}
return query
},
// we have to replace our suggestion text with a mention
// so it's important to pass also the position of your suggestion text
@ -487,45 +238,6 @@ export default {
})
this.editor.focus()
},
// renders a popup with suggestions
// tiptap provides a virtualNode object for using popper.js (or tippy.js) for popups
renderPopup(node) {
if (this.popup) {
return
}
this.popup = tippy(node, {
content: this.$refs.suggestions,
trigger: 'mouseenter',
interactive: true,
theme: 'dark',
placement: 'top-start',
inertia: true,
duration: [400, 200],
showOnInit: true,
arrow: true,
arrowType: 'round',
})
// we have to update tippy whenever the DOM is updated
if (MutationObserver) {
this.observer = new MutationObserver(() => {
this.popup.popperInstance.scheduleUpdate()
})
this.observer.observe(this.$refs.suggestions, {
childList: true,
subtree: true,
characterData: true,
})
}
},
destroyPopup() {
if (this.popup) {
this.popup.destroy()
this.popup = null
}
if (this.observer) {
this.observer.disconnect()
}
},
onUpdate(e) {
const content = e.getHTML()
const contentHash = stringHash(content)
@ -534,36 +246,28 @@ export default {
this.$emit('input', content)
}
},
showLinkMenu(attrs) {
this.linkUrl = attrs.href
this.linkMenuIsActive = true
this.$nextTick(() => {
try {
const $el = this.$refs.linkInput.$el.getElementsByTagName('input')[0]
$el.focus()
$el.select()
} catch (err) {}
})
toggleLinkInput(attrs, element) {
if (!this.isLinkInputActive && attrs && element) {
this.$refs.linkInput.linkUrl = attrs.href
this.isLinkInputActive = true
this.$refs.contextMenu.displayContextMenu(element, this.$refs.linkInput.$el, 'link')
} else {
this.$refs.contextMenu.hideContextMenu()
this.isLinkInputActive = false
this.editor.focus()
}
},
hideLinkMenu() {
this.linkUrl = null
this.linkMenuIsActive = false
this.editor.focus()
},
hideMenu(isActive) {
isActive = false
this.hideLinkMenu()
},
setLinkUrl(command, url) {
const links = linkify().match(url)
if (links) {
setLinkUrl(url) {
const normalizedLinks = url ? linkify().match(url) : null
const command = this.editor.commands.link
if (normalizedLinks) {
// add valid link
command({
href: links.pop().url,
href: normalizedLinks.pop().url,
})
this.hideLinkMenu()
this.toggleLinkInput()
this.editor.focus()
} else if (!url) {
} else {
// remove link
command({ href: null })
}
@ -576,70 +280,6 @@ export default {
</script>
<style lang="scss">
.suggestion-list {
padding: 0.2rem;
border: 2px solid rgba($color-neutral-0, 0.1);
font-size: 0.8rem;
font-weight: bold;
&__no-results {
padding: 0.2rem 0.5rem;
}
&__item {
border-radius: 5px;
padding: 0.2rem 0.5rem;
margin-bottom: 0.2rem;
cursor: pointer;
&:last-child {
margin-bottom: 0;
}
&.is-selected,
&:hover {
background-color: rgba($color-neutral-100, 0.2);
}
&.is-empty {
opacity: 0.5;
}
}
}
.tippy-tooltip.dark-theme {
background-color: $color-neutral-0;
padding: 0;
font-size: 1rem;
text-align: inherit;
color: $color-neutral-100;
border-radius: 5px;
.tippy-backdrop {
display: none;
}
.tippy-roundarrow {
fill: $color-neutral-0;
}
.tippy-popper[x-placement^='top'] & .tippy-arrow {
border-top-color: $color-neutral-0;
}
.tippy-popper[x-placement^='bottom'] & .tippy-arrow {
border-bottom-color: $color-neutral-0;
}
.tippy-popper[x-placement^='left'] & .tippy-arrow {
border-left-color: $color-neutral-0;
}
.tippy-popper[x-placement^='right'] & .tippy-arrow {
border-right-color: $color-neutral-0;
}
}
.ProseMirror {
padding: $space-base;
margin: -$space-base;
min-height: $space-large;
}
.ProseMirror:focus {
outline: none;
}
.editor p.is-empty:first-child::before {
content: attr(data-empty-text);
float: left;
@ -659,74 +299,40 @@ li > p {
}
.editor {
.mention-suggestion {
color: $color-primary;
}
display: flex;
flex-direction: column;
.hashtag {
color: $color-primary;
}
.hashtag-suggestion {
color: $color-primary;
}
&__floating-menu {
position: absolute;
margin-top: -0.25rem;
margin-left: $space-xx-small;
visibility: hidden;
opacity: 0;
transition: opacity 0.2s, visibility 0.2s;
background-color: #fff;
&.is-active {
opacity: 1;
visibility: visible;
}
.mention-suggestion {
color: $color-primary;
}
.menububble {
position: absolute;
// margin-top: -0.5rem;
visibility: hidden;
opacity: 0;
transition: opacity 200ms, visibility 200ms;
// transition-delay: 50ms;
transform: translate(-50%, -10%);
}
background-color: $background-color-inverse-soft;
// color: $text-color-inverse;
border-radius: $border-radius-base;
padding: $space-xx-small;
box-shadow: $box-shadow-large;
.editor-content {
flex-grow: 1;
margin-top: $space-small;
height: auto;
.ds-button {
color: $text-color-inverse;
&:focus-within {
border-color: $color-primary;
background-color: $color-neutral-100;
}
}
&.ds-button-hover,
&:hover {
color: $text-color-base;
}
}
.ProseMirror {
min-height: 100px;
&.is-active {
opacity: 1;
visibility: visible;
}
&:focus {
outline: none;
}
.tooltip-arrow {
left: calc(50% - 10px);
}
input,
button {
border: none;
border-radius: 2px;
}
.ds-input {
height: auto;
}
input {
padding: $space-xx-small $space-x-small;
}
p {
margin: 0 0 $space-x-small;
}
}
</style>

View File

@ -0,0 +1,33 @@
<template>
<div>
<ds-input
id="linkInputId"
v-model="linkUrl"
class="editor-menu-link-input"
placeholder="https://"
@blur.native.capture="toggleLinkInput()"
@keydown.native.esc.prevent="toggleLinkInput()"
@keydown.native.enter.prevent="enterLink()"
/>
</div>
</template>
<script>
export default {
props: {
toggleLinkInput: Function,
setLinkUrl: Function,
},
data() {
return {
linkUrl: null,
}
},
methods: {
enterLink() {
this.setLinkUrl(this.linkUrl)
this.linkUrl = null
},
},
}
</script>

View File

@ -0,0 +1,74 @@
<template>
<editor-menu-bar :editor="editor" v-slot="{ commands, isActive, getMarkAttrs }">
<div>
<menu-bar-button :isActive="isActive.bold()" :onClick="commands.bold" icon="bold" />
<menu-bar-button :isActive="isActive.italic()" :onClick="commands.italic" icon="italic" />
<menu-bar-button
ref="linkButton"
:isActive="isActive.link()"
:onClick="event => toggleLinkInput(getMarkAttrs('link'), event.currentTarget)"
icon="link"
/>
<menu-bar-button
:isActive="isActive.paragraph()"
:onClick="commands.paragraph"
icon="paragraph"
/>
<menu-bar-button
:isActive="isActive.heading({ level: 3 })"
:onClick="() => commands.heading({ level: 3 })"
label="H3"
/>
<menu-bar-button
:isActive="isActive.heading({ level: 4 })"
:onClick="() => commands.heading({ level: 4 })"
label="H4"
/>
<menu-bar-button
:isActive="isActive.bullet_list()"
:onClick="commands.bullet_list"
icon="list-ul"
/>
<menu-bar-button
:isActive="isActive.ordered_list()"
:onClick="commands.ordered_list"
icon="list-ol"
/>
<menu-bar-button
:isActive="isActive.blockquote()"
:onClick="commands.blockquote"
icon="quote-right"
/>
<menu-bar-button
:isActive="isActive.horizontal_rule()"
:onClick="commands.horizontal_rule"
icon="minus"
/>
</div>
</editor-menu-bar>
</template>
<script>
import { EditorMenuBar } from 'tiptap'
import MenuBarButton from './MenuBarButton'
export default {
components: {
EditorMenuBar,
MenuBarButton,
},
props: {
editor: Object,
toggleLinkInput: Function,
},
}
</script>

View File

@ -0,0 +1,16 @@
<template>
<ds-button size="small" :ghost="!isActive" @click.prevent="onClick" :icon="icon">
<span v-if="label">{{ label }}</span>
</ds-button>
</template>
<script>
export default {
props: {
isActive: Boolean,
icon: String,
label: String,
onClick: Function,
},
}
</script>

View File

@ -0,0 +1,96 @@
<template>
<ul v-show="showSuggestions" class="suggestion-list">
<li
v-for="(item, index) in filteredItems"
:key="item.id"
class="suggestion-list__item"
:class="{ 'is-selected': navigatedItemIndex === index }"
@click="selectItem(item)"
>
{{ createItemLabel(item) }}
</li>
<template v-if="isHashtag">
<li v-if="!query" class="suggestion-list__item hint">
{{ $t('editor.hashtag.addLetter') }}
</li>
<template v-else-if="!filteredItems.find(el => el.id === query)">
<li class="suggestion-list__item hint">{{ $t('editor.hashtag.addHashtag') }}</li>
<li class="suggestion-list__item" @click="selectItem({ id: query })">#{{ query }}</li>
</template>
</template>
<template v-else-if="isMention">
<li v-if="!hasResults" class="suggestion-list__item hint">
{{ $t('editor.mention.noUsersFound') }}
</li>
</template>
</ul>
</template>
<script>
import { HASHTAG, MENTION } from '../../constants/editor'
export default {
props: {
suggestionType: String,
filteredItems: Array,
query: String,
navigatedItemIndex: Number,
selectItem: Function,
},
computed: {
hasResults() {
return this.filteredItems.length > 0
},
isMention() {
return this.suggestionType === MENTION
},
isHashtag() {
return this.suggestionType === HASHTAG
},
showSuggestions() {
return this.query || this.hasResults
},
},
methods: {
createItemLabel(item) {
if (this.isMention) {
return `@${item.slug}`
} else {
return `#${item.id}`
}
},
},
}
</script>
<style lang="scss">
.suggestion-list {
list-style-type: none;
padding: 0.2rem;
border-radius: 5px;
border: 2px solid $color-primary;
font-size: 0.8rem;
font-weight: bold;
}
.suggestion-list__item {
border-radius: 5px;
padding: 0.2rem 0.5rem;
margin-bottom: 0.2rem;
cursor: pointer;
&:last-child {
margin-bottom: 0;
}
&.is-selected,
&:hover {
background-color: rgba($color-neutral-100, 0.3);
}
&.hint {
opacity: 0.7;
pointer-events: none;
}
}
</style>

View File

@ -0,0 +1,2 @@
export const HASHTAG = 'hashtag'
export const MENTION = 'mention'

View File

@ -0,0 +1,4 @@
export const ARROW_UP = 38
export const ARROW_DOWN = 40
export const RETURN = 13
export const SPACE = 32

View File

@ -51,5 +51,12 @@ export default i18n => {
}
}
`,
DeleteComment: gql`
mutation($id: ID!) {
DeleteComment(id: $id) {
id
}
}
`,
}
}

View File

@ -68,8 +68,8 @@
"jsonwebtoken": "~8.5.1",
"linkify-it": "~2.2.0",
"node-fetch": "^2.6.0",
"nuxt": "~2.9.1",
"nuxt-dropzone": "^1.0.3",
"nuxt": "~2.9.2",
"nuxt-dropzone": "^1.0.4",
"nuxt-env": "~0.1.0",
"stack-utils": "^1.0.2",
"string-hash": "^1.1.3",

View File

@ -1144,10 +1144,10 @@
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
"@nuxt/babel-preset-app@2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@nuxt/babel-preset-app/-/babel-preset-app-2.9.1.tgz#8394702e2829f9a576acc366b1335b02eaf5d1a1"
integrity sha512-lCY9lCXgiDEtnihxjDggzv4VE4+gHrxMxrnDmA66Fiks1KFLDVGN87PVc+Wo+hugi3rKHCTY0enP9h5Fkc0nFw==
"@nuxt/babel-preset-app@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@nuxt/babel-preset-app/-/babel-preset-app-2.9.2.tgz#e8d2ac841db845ef88ca2687093a95a480106e5d"
integrity sha512-s4423c5Pvl3aCmD8KoDdit1XZuZig0sCwop5KV3kn0/KfEru+jFWbQ3pTssCV8XTR9Am2BV0UIQ0hoCMdnvdfw==
dependencies:
"@babel/core" "^7.5.5"
"@babel/plugin-proposal-class-properties" "^7.5.5"
@ -1158,14 +1158,14 @@
"@vue/babel-preset-jsx" "^1.1.0"
core-js "^2.6.5"
"@nuxt/builder@2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@nuxt/builder/-/builder-2.9.1.tgz#e2196fcbd084122d04fc2e8cdd08d02efebd3a31"
integrity sha512-99jch8WVqYcWDEO+uKDvCjvoiRVLc8ZI+Qbnm/cBJvZ0bB6hsD0a2H/kzyQpRYG7mhSP5TxnKPOSHVykQanXOQ==
"@nuxt/builder@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@nuxt/builder/-/builder-2.9.2.tgz#57c515efc446c02e4062ebdb6cd735ea456df4dd"
integrity sha512-egDjm2AnaKjeAlZ0yNAooP+Xd/fKIvhK66qNyd+ekvzutSkbSkKtB/udNxyHcBnjg8GOB4KayIXvBX0K1TS/vg==
dependencies:
"@nuxt/devalue" "^1.2.4"
"@nuxt/utils" "2.9.1"
"@nuxt/vue-app" "2.9.1"
"@nuxt/utils" "2.9.2"
"@nuxt/vue-app" "2.9.2"
chokidar "^3.0.2"
consola "^2.10.1"
fs-extra "^8.1.0"
@ -1175,16 +1175,16 @@
lodash "^4.17.15"
pify "^4.0.1"
semver "^6.3.0"
serialize-javascript "^1.7.0"
serialize-javascript "^1.8.0"
upath "^1.1.2"
"@nuxt/cli@2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@nuxt/cli/-/cli-2.9.1.tgz#d9e0c18a566948f7d4d62132f38ef1648a0c253f"
integrity sha512-EunBJdOfPRt3slurQZ/CfgHF1p+SR0MIUdWgH3pzbpZO5OxuhFI8Kcse5AWgH3ONneyNG9pwh+7bVz9eubaJcg==
"@nuxt/cli@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@nuxt/cli/-/cli-2.9.2.tgz#d56540f95b58afa7c7073c166d6f624b78024fca"
integrity sha512-9Pxavn/w/K4uUItXPNmKyT1aBoGlJPqTdpr3nlXRX00JSU1OKd2fTNL3RlaN+xXtlYh2XoZo2roGHAFX1CyKrw==
dependencies:
"@nuxt/config" "2.9.1"
"@nuxt/utils" "2.9.1"
"@nuxt/config" "2.9.2"
"@nuxt/utils" "2.9.2"
boxen "^4.1.0"
chalk "^2.4.2"
consola "^2.10.1"
@ -1192,35 +1192,37 @@
execa "^2.0.4"
exit "^0.1.2"
fs-extra "^8.1.0"
hable "^2.2.1"
minimist "^1.2.0"
opener "1.5.1"
pretty-bytes "^5.3.0"
std-env "^2.2.1"
wrap-ansi "^6.0.0"
"@nuxt/config@2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@nuxt/config/-/config-2.9.1.tgz#02d6484460a3ed0bd46e8e731490e4a20194d1f7"
integrity sha512-Zwtym2dmDDky4hqhRk3BVDfcZ+qicRbivlgJO00dOaVxIhn9KoYGj2+3gtva28gIit7F3qDx24S/yKX6jOQCfg==
"@nuxt/config@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@nuxt/config/-/config-2.9.2.tgz#8976da395cc9f9971f48890ecaff9991d011578a"
integrity sha512-FjBPZNE2vUh7UsJ4GdiEYcgr3umvAxSKU2xvbBQpBGk8mItPyt8k/1LmrRSvImkno4j1IBKp4VehSBZYEczJdQ==
dependencies:
"@nuxt/utils" "2.9.1"
"@nuxt/utils" "2.9.2"
consola "^2.10.1"
std-env "^2.2.1"
"@nuxt/core@2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@nuxt/core/-/core-2.9.1.tgz#42611ee8984358810b061403cf8300daa46a3446"
integrity sha512-5nv1nk87SkrXMzchofVRsv6MSVhcf4QCk/rfn+meIB91pwJ/RqrMORGwR4vk+3JpZPnLMqrzi+CwnhhJodv3bw==
"@nuxt/core@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@nuxt/core/-/core-2.9.2.tgz#1ab1d5c1928c37100a680241f23fe6ebe230d9f9"
integrity sha512-OtjLLutaMsYP6/EYXD96i/J79GSrjHlxfHbBaqHjIxnHdDnzZlsvA13EjULJ9mhumw3fvOPi12AEqqNpBHXqUg==
dependencies:
"@nuxt/config" "2.9.1"
"@nuxt/config" "2.9.2"
"@nuxt/devalue" "^1.2.4"
"@nuxt/server" "2.9.1"
"@nuxt/utils" "2.9.1"
"@nuxt/vue-renderer" "2.9.1"
"@nuxt/server" "2.9.2"
"@nuxt/utils" "2.9.2"
"@nuxt/vue-renderer" "2.9.2"
consola "^2.10.1"
debug "^4.1.1"
esm "^3.2.25"
fs-extra "^8.1.0"
hable "^2.2.1"
hash-sum "^2.0.0"
std-env "^2.2.1"
@ -1241,12 +1243,12 @@
error-stack-parser "^2.0.0"
string-width "^2.0.0"
"@nuxt/generator@2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@nuxt/generator/-/generator-2.9.1.tgz#a46e95855e4c68fb890c01148676c6c91704c07c"
integrity sha512-GRosDDdwhSnd58bBoUjcewyUfEPolVLECqh1fmqTih5i2EPZm7aV4k6wGkoVZAu/4GQYjlZPo7sc2uZy14uJ8A==
"@nuxt/generator@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@nuxt/generator/-/generator-2.9.2.tgz#5fd8e1af5217b3c7049ef89af4a8568b3d34a437"
integrity sha512-54bp94eel5vAxUQPKP8YU3uxPmaqSb0EwXXY+712LS2kZ2HELR/YpuATOH2wS3IUfpc0x9Zu6O/nPkjYo+635Q==
dependencies:
"@nuxt/utils" "2.9.1"
"@nuxt/utils" "2.9.2"
chalk "^2.4.2"
consola "^2.10.1"
fs-extra "^8.1.0"
@ -1262,22 +1264,22 @@
node-res "^5.0.1"
serve-static "^1.14.1"
"@nuxt/opencollective@^0.2.2":
version "0.2.2"
resolved "https://registry.yarnpkg.com/@nuxt/opencollective/-/opencollective-0.2.2.tgz#17adc7d380457379cd14cbb64a435ea196cc4a6e"
integrity sha512-ie50SpS47L+0gLsW4yP23zI/PtjsDRglyozX2G09jeiUazC1AJlGPZo0JUs9iuCDUoIgsDEf66y7/bSfig0BpA==
"@nuxt/opencollective@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@nuxt/opencollective/-/opencollective-0.3.0.tgz#11d8944dcf2d526e31660bb69570be03f8fb72b7"
integrity sha512-Vf09BxCdj1iT2IRqVwX5snaY2WCTkvM0O4cWWSO1ThCFuc4if0Q/nNwAgCxRU0FeYHJ7DdyMUNSdswCLKlVqeg==
dependencies:
chalk "^2.4.1"
consola "^2.3.0"
node-fetch "^2.3.0"
chalk "^2.4.2"
consola "^2.10.1"
node-fetch "^2.6.0"
"@nuxt/server@2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@nuxt/server/-/server-2.9.1.tgz#dc6ea866bc36d1466e30f0b91e404e7c75961b5e"
integrity sha512-kIyZR/SlIjNIslReLDyGy4o+8NDNxFlFQM5zGbnOTSxOAIMEcyoUxoGeOc2wFr+QN5LFfpl+vruglUjRWGXhNQ==
"@nuxt/server@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@nuxt/server/-/server-2.9.2.tgz#ef6f45b57b2f873c48ddb3cb1c593f56052dc186"
integrity sha512-If9Yu1pCah3d9l1AmyZ6hyfJ4+3RTekAdB9lMyHskIFGR4DCoTx2cd8oJ0VOv9CgQz90j/1Wi/SdeHy22Hy9Fg==
dependencies:
"@nuxt/config" "2.9.1"
"@nuxt/utils" "2.9.1"
"@nuxt/config" "2.9.2"
"@nuxt/utils" "2.9.2"
"@nuxtjs/youch" "^4.2.3"
chalk "^2.4.2"
compression "^1.7.4"
@ -1294,24 +1296,24 @@
serve-static "^1.14.1"
server-destroy "^1.0.1"
"@nuxt/utils@2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@nuxt/utils/-/utils-2.9.1.tgz#5b2e0cdb9957971b6e20787c7582060c9ec1ba5c"
integrity sha512-7PWq0YM55+DRkwa2hLuFVKPkMhrFoWvehYtQhvhQWc0LvA+Hmv7hm6cABZsas1qsMunO4t3j5OK2xPxO0yLhDg==
"@nuxt/utils@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@nuxt/utils/-/utils-2.9.2.tgz#b6ced2abe8ada3f8d5ec03dd1a5e8053c9b4a66c"
integrity sha512-qmXbRNNJtdT4cr1t66ayaUFx9rQ9aOiLPHM/J69/uw/TKiy/j3WgX1YHE6TRAfIpg0eb68nDzHGM40T3XJ+jsg==
dependencies:
consola "^2.10.1"
fs-extra "^8.1.0"
hash-sum "^2.0.0"
proper-lockfile "^4.1.1"
semver "^6.3.0"
serialize-javascript "^1.7.0"
serialize-javascript "^1.8.0"
signal-exit "^3.0.2"
ua-parser-js "^0.7.20"
"@nuxt/vue-app@2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@nuxt/vue-app/-/vue-app-2.9.1.tgz#52433b20f9027949610981c4853604106ed80374"
integrity sha512-YiPii6wmf6R/LYOv+7Y5QGBBVwvwKVUDwR3AQ0HCh2FNJ/sz5vG2C+q2ADRZ8nMyqUMKhjLPgn9PTXFioySQ6w==
"@nuxt/vue-app@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@nuxt/vue-app/-/vue-app-2.9.2.tgz#725b1f6c4ac955b990ce3db68f9ae19a8d578c5b"
integrity sha512-zLoCvA3+UVfdikfol7plPukP0GddU1LdgkV+1EDeVUm22PNgt/OdYN3z5kJIZEfZoLpfMbtF8NsBVWrehPuoFQ==
dependencies:
node-fetch "^2.6.0"
unfetch "^4.1.0"
@ -1323,13 +1325,13 @@
vue-template-compiler "^2.6.10"
vuex "^3.1.1"
"@nuxt/vue-renderer@2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@nuxt/vue-renderer/-/vue-renderer-2.9.1.tgz#29e5334a3245f3cdab7cba29b2748c0e4cd75e6f"
integrity sha512-/V1LnjXEfLMaYFjzF1FtpHc2hjE66ppVnHnljBh56NEIwxBu9EGEGG1d3oydurnOtmikbpKgR5qnnHcKOQXnoA==
"@nuxt/vue-renderer@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@nuxt/vue-renderer/-/vue-renderer-2.9.2.tgz#5118ba5caa894d94b272ad4665f88837ab2359ef"
integrity sha512-bLUnYEj2PHs07K7EAH+a3Nhg9ZK4WRsbG9q5eYNF3CD0O10CzNOR6/8qqqbFYj8hFrP76EOf0P/5CAJcWvRtPg==
dependencies:
"@nuxt/devalue" "^1.2.4"
"@nuxt/utils" "2.9.1"
"@nuxt/utils" "2.9.2"
consola "^2.10.1"
fs-extra "^8.1.0"
lru-cache "^5.1.1"
@ -1337,15 +1339,15 @@
vue-meta "^2.2.1"
vue-server-renderer "^2.6.10"
"@nuxt/webpack@2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@nuxt/webpack/-/webpack-2.9.1.tgz#21a090a99b1cb6d644f72ee90143a1ad0e3c0d91"
integrity sha512-ib3UHu+1/CVkHIQPZbcZ+LFWNWuiNuJtGjpIkaPgY563yutqAqI1Xwinr9bzmrk1yaBoT9YEg00U2cviVzAc4A==
"@nuxt/webpack@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@nuxt/webpack/-/webpack-2.9.2.tgz#4db33ddcb6805d5fed06a67515e542ca54ffa75d"
integrity sha512-M+j3Ceo6BcBSz4eIXqMP+Owcp2f78Dco+KGHJuUuCxWRNJjVdJAo1RHa2sMVDezdQgiDJQzgChwORU2mjN6rEw==
dependencies:
"@babel/core" "^7.5.5"
"@nuxt/babel-preset-app" "2.9.1"
"@nuxt/babel-preset-app" "2.9.2"
"@nuxt/friendly-errors-webpack-plugin" "^2.5.0"
"@nuxt/utils" "2.9.1"
"@nuxt/utils" "2.9.2"
babel-loader "^8.0.6"
cache-loader "^4.1.0"
caniuse-lite "^1.0.30000989"
@ -1376,7 +1378,7 @@
time-fix-plugin "^2.0.6"
url-loader "^2.1.0"
vue-loader "^15.7.1"
webpack "^4.39.2"
webpack "^4.39.3"
webpack-bundle-analyzer "^3.4.1"
webpack-dev-middleware "^3.7.0"
webpack-hot-middleware "^2.25.0"
@ -5114,7 +5116,7 @@ connect@^3.7.0:
parseurl "~1.3.3"
utils-merge "1.0.1"
consola@^2.10.0, consola@^2.10.1, consola@^2.3.0, consola@^2.4.0, consola@^2.5.6, consola@^2.6.0, consola@^2.6.1, consola@^2.9.0:
consola@^2.10.0, consola@^2.10.1, consola@^2.4.0, consola@^2.5.6, consola@^2.6.0, consola@^2.6.1, consola@^2.9.0:
version "2.10.1"
resolved "https://registry.yarnpkg.com/consola/-/consola-2.10.1.tgz#4693edba714677c878d520e4c7e4f69306b4b927"
integrity sha512-4sxpH6SGFYLADfUip4vuY65f/gEogrzJoniVhNUYkJHtng0l8ZjnDCqxxrSVRHOHwKxsy8Vm5ONZh1wOR3/l/w==
@ -7658,6 +7660,11 @@ gzip-size@^5.0.0:
duplexer "^0.1.1"
pify "^4.0.1"
hable@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/hable/-/hable-2.2.1.tgz#714ef141a7eda5bd8530d6e4e3b37c6807716290"
integrity sha512-CuGRGMNnCp8RJ70zeoTX37sX4ctoT8BpmkStI2TYQwBBtWzQQFXQ/jsBUCqd34grt3IJQ+hkUXAU84/IuErVLQ==
handlebars@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67"
@ -10382,7 +10389,7 @@ node-fetch@^1.0.1:
encoding "^0.1.11"
is-stream "^1.0.1"
node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@^2.3.0:
node-fetch@^2.1.2, node-fetch@^2.2.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.5.0.tgz#8028c49fc1191bba56a07adc6e2a954644a48501"
integrity sha512-YuZKluhWGJwCcUu4RlZstdAxr8bFfOVHakc1mplwHkk8J+tqM1Y5yraYvIUpeX8aY7+crCwiELJq7Vl0o0LWXw==
@ -10712,10 +10719,10 @@ number-is-nan@^1.0.0:
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
nuxt-dropzone@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/nuxt-dropzone/-/nuxt-dropzone-1.0.3.tgz#f808ad3bc30809d34d6cbbcb24cece6e73341107"
integrity sha512-lElULoEkPJ1bJ7JzOyvg98/SSEAdvYHjdQ4V1k/XPe1Q/vmzMtOn2DxKwtzFKVWA5RqnB1P+EAjUMYan4mn0aw==
nuxt-dropzone@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/nuxt-dropzone/-/nuxt-dropzone-1.0.4.tgz#ef10af35938f95bfe6a9ba3eb7b7de17db7cbb14"
integrity sha512-1QuthM3bDGBN2ugXE5HfcvBmekNy4YUYfMurTeuBrwIGId0JSF9HasspwndxsSNL42eGET83eezRcH4ekLGqeA==
dependencies:
vue2-dropzone "3.6.0"
@ -10724,18 +10731,18 @@ nuxt-env@~0.1.0:
resolved "https://registry.yarnpkg.com/nuxt-env/-/nuxt-env-0.1.0.tgz#8ac50b9ff45391ad3044ea932cbd05f06a585f87"
integrity sha512-7mTao3qG0zfN0hahk3O6SuDy0KEwYmNojammWQsMwhqMn3aUjX4nMYnWDa0pua+2/rwAY9oG53jQtLgJdG7f9w==
nuxt@~2.9.1:
version "2.9.1"
resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-2.9.1.tgz#6a9ce48d03b9e6f82919d4e66051b3d49b7aee36"
integrity sha512-riZ9ZUXCtUnRWcixJj3Mja6t5ujGlD/9/E71VDwW47AvyxhlYrSzitSUSs9sBwsC+6zzwP8cCM2k1fO/2oWyrg==
nuxt@~2.9.2:
version "2.9.2"
resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-2.9.2.tgz#3c190fe79dcb00550029d065bb9505caffd02bbb"
integrity sha512-PQjHQfh567g9J+SdbiZPWUZ9FXKWDONE9kB6/H9O9reWcac+jwD/uwWzZrgt+W6AiphHmbfwyGGLwCLv5hrQBg==
dependencies:
"@nuxt/builder" "2.9.1"
"@nuxt/cli" "2.9.1"
"@nuxt/core" "2.9.1"
"@nuxt/generator" "2.9.1"
"@nuxt/builder" "2.9.2"
"@nuxt/cli" "2.9.2"
"@nuxt/core" "2.9.2"
"@nuxt/generator" "2.9.2"
"@nuxt/loading-screen" "^1.0.1"
"@nuxt/opencollective" "^0.2.2"
"@nuxt/webpack" "2.9.1"
"@nuxt/opencollective" "^0.3.0"
"@nuxt/webpack" "2.9.2"
nwsapi@^2.0.7:
version "2.1.4"
@ -13458,6 +13465,11 @@ serialize-javascript@^1.3.0, serialize-javascript@^1.4.0, serialize-javascript@^
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65"
integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==
serialize-javascript@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.8.0.tgz#9515fc687232e2321aea1ca7a529476eb34bb480"
integrity sha512-3tHgtF4OzDmeKYj6V9nSyceRS0UJ3C7VqyD2Yj28vC/z2j6jG5FmFGahOKMD9CrglxTm3tETr87jEypaYV8DUg==
serve-favicon@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0"
@ -15473,10 +15485,10 @@ webpack@^4.38.0:
watchpack "^1.6.0"
webpack-sources "^1.4.1"
webpack@^4.39.2:
version "4.39.2"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.39.2.tgz#c9aa5c1776d7c309d1b3911764f0288c8c2816aa"
integrity sha512-AKgTfz3xPSsEibH00JfZ9sHXGUwIQ6eZ9tLN8+VLzachk1Cw2LVmy+4R7ZiwTa9cZZ15tzySjeMui/UnSCAZhA==
webpack@^4.39.3:
version "4.39.3"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.39.3.tgz#a02179d1032156b713b6ec2da7e0df9d037def50"
integrity sha512-BXSI9M211JyCVc3JxHWDpze85CvjC842EvpRsVTc/d15YJGlox7GIDd38kJgWrb3ZluyvIjgenbLDMBQPDcxYQ==
dependencies:
"@webassemblyjs/ast" "1.8.5"
"@webassemblyjs/helper-module-context" "1.8.5"

View File

@ -1847,10 +1847,10 @@ cucumber@^4.2.1:
util-arity "^1.0.2"
verror "^1.9.0"
cypress-cucumber-preprocessor@^1.15.0:
version "1.15.0"
resolved "https://registry.yarnpkg.com/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-1.15.0.tgz#bc2bbad5799dcc07798a0f8f1d374b99e0d3bbab"
integrity sha512-6exZ4cPruFcx55INZtxGnUwoGuzcAq+8T1k7NaCC2g36mdweltGjtjIGuHy4lk+VQaW6zmLV6zDtuxrEQsFC/w==
cypress-cucumber-preprocessor@^1.15.1:
version "1.15.1"
resolved "https://registry.yarnpkg.com/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-1.15.1.tgz#9a53d4931e9fcc502f0fd89c8373a4869f9a0e79"
integrity sha512-rZeZskdOXljFKSiSiSUg0oQ4+3/kY8g1y5mNS8POrFM8Ch3rldw6ZJy4soMfqHKitNyilaUl/pRsgjH6cFI95w==
dependencies:
"@cypress/browserify-preprocessor" "^1.1.2"
chai "^4.1.2"