diff --git a/.codecov.yml b/.codecov.yml
deleted file mode 100644
index 82b50aba3..000000000
--- a/.codecov.yml
+++ /dev/null
@@ -1,157 +0,0 @@
-codecov:
- #token: uuid # Your private repository token
- #url: "http" # for Codecov Enterprise customers
- #slug: "owner/repo" # for Codecov Enterprise customers
- #branch: master # override the default branch
- #bot: username # set user whom will be the consumer of oauth requests
- #ci: # Custom CI domains if Codecov does not identify them automatically
- # - ci.domain.com
- # - !provider # ignore these providers when checking if CI passed
- # # ex. You may test on Travis, Circle, and AppVeyor, but only need
- # # to check if Travis passes. Therefore add: !circle and !appveyor
- notify:
- #after_n_builds: null # number of expected builds to recieve before sending notifications
- # # after: check ci status unless disabled via require_ci_to_pass
- require_ci_to_pass: yes # yes: will delay sending notifications until all ci is finished
- # no: will send notifications without checking ci status and wait till "after_n_builds" are uploaded
- #countdown: null # number of seconds to wait before first ci build check
- #delay: null # number of seconds to wait between ci build checks
-
-coverage:
- precision: 2 # 2 = xx.xx%, 0 = xx%
- round: nearest # down|up|nearest - default down
- # range: 50...60 # default 70...90. red...green
-
- #notify:
- # irc:
- # default:
- # server: "chat.freenode.net"|encrypted
- # branches: null # all branches by default
- # threshold: 1%
- # message: "Coverage {{changed}} for {{owner}}/{{repo}}" # customize the message
- # flags: null
- # paths: null
- #
- # slack:
- # default:
- # url: "http"|encrypted
- # threshold: 1%
- # branches: null # all branches by default
- # message: "Coverage {{changed}} for {{owner}}/{{repo}}" # customize the message
- # attachments: "sunburst, diff"
- # only_pulls: false
- # flags: null
- # paths: null
- #
- # email:
- # default:
- # to:
- # - example@domain.com
- # - &author
- # threshold: 1%
- # only_pulls: false
- # layout: header, diff, trends
- # flags: null
- # paths: null
- #
- # hipchat:
- # default:
- # url: "http"|encrypted
- # room: name|id
- # threshold: 1%
- # token: encrypted
- # branches: null # all branches by default
- # notify: false # if the hipchat message is silent or loud (default false)
- # message: "Coverage {{changed}} for {{owner}}/{{repo}}" # customize the message
- # flags: null
- # paths: null
- #
- # gitter:
- # url: "http"|encrypted
- # threshold: 1%
- # branches: null # all branches by default
- # message: "Coverage {{changed}} for {{owner}}/{{repo}}" # customize the message
- #
- # webhooks:
- # _name_:
- # url: "http"|encrypted
- # threshold: 1%
- # branches: null # all branches by default
-
- status:
- project:
- default: false # disable the default status that measures entire project
- backend: # declare a new status context "backend"
- against: parent
- target: auto
- threshold: null
- #threshold: 1%
- base: auto
- if_no_uploads: error
- if_not_found: success
- if_ci_failed: error
- only_pulls: false
- #branches:
- # - master
- #flags:
- # - integration
- paths:
- - backend/ # only include coverage in "backend/" folder
- webapp: # declare a new status context "frontend"
- against: parent
- target: auto
- threshold: null
- #threshold: 1%
- base: auto
- if_no_uploads: error
- if_not_found: success
- if_ci_failed: error
- only_pulls: false
- #branches:
- # - master
- #flags:
- # - integration
- paths:
- - webapp/ # only include coverage in "webapp/" folder
-
- patch:
- default: false
- # against: parent
- # target: 80%
- # branches: null
- # if_no_uploads: success
- # if_not_found: success
- # if_ci_failed: error
- # only_pulls: false
- # flags:
- # - integration
- # paths:
- # - folder
-
- #changes:
- # default:
- # against: parent
- # branches: null
- # if_no_uploads: error
- # if_not_found: success
- # if_ci_failed: error
- # only_pulls: false
- # flags:
- # - integration
- # paths:
- # - folder
-
- #flags:
- # integration:
- # branches:
- # - master
- # ignore:
- # - app/ui
-
- #ignore: # files and folders for processing
- # - tests/*
-
- #fixes:
- # - "old_path::new_path"
-
-comment: off
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 3cd77a905..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,84 +0,0 @@
-dist: xenial
-language: node_js
-node_js: lts/*
-cache:
- yarn: false
- npm: false
-
-addons:
- apt:
- packages:
- - libgconf-2-4
- snaps:
- - docker
- firefox: "latest-esr"
-
-install:
- - yarn global add wait-on
- # Install Codecov
- - yarn install --frozen-lockfile
- - cp backend/.env.template backend/.env
-
-before_script:
- - docker-compose -f docker-compose.yml build --parallel
- - docker-compose -f docker-compose.yml -f docker-compose.build-and-test.yml build # just tagging, just be quite fast
- - docker-compose -f docker-compose.yml -f docker-compose.build-and-test.yml up -d
- - wait-on http://localhost:7474
- - docker-compose -f docker-compose.yml -f docker-compose.build-and-test.yml exec backend yarn run db:migrate init
-
-script:
- - export CYPRESS_RETRIES=1
- - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
- - echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH"
- # Miscellaneous
- - ./scripts/translations/sort.sh
- - ./scripts/translations/missing-keys.sh
- # Backend
- - docker-compose exec backend yarn run lint
- - docker-compose exec backend yarn run test --ci --verbose=false --coverage
- - docker-compose exec backend yarn run db:seed
- - docker-compose exec backend yarn run db:reset
- # Frontend
- - docker-compose exec webapp yarn run lint
- - docker-compose exec webapp yarn run test --ci --verbose=false --coverage
- # Fullstack
- - docker-compose down
- - docker-compose -f docker-compose.yml up -d
- - wait-on http://localhost:7474
- # disable for last deploy, because of flakiness!
- # - yarn run cypress:run --record
- # - yarn run cucumber
- # Coverage
- # disable this uneffective thing for last deploy, because of easyness!
- # - yarn run codecov
-
-after_success:
- - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh
- - chmod +x send.sh
- - ./send.sh success $WEBHOOK_URL
- - if [ $TRAVIS_BRANCH == "master" ] && [ $TRAVIS_EVENT_TYPE == "push" ]; then
- wget https://raw.githubusercontent.com/Human-Connection/Discord-Bot/develop/tester.sh &&
- chmod +x tester.sh &&
- ./tester.sh staging $WEBHOOK_URL;
- fi
-
-after_failure:
- - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh
- - chmod +x send.sh
- - ./send.sh failure $WEBHOOK_URL
-
-before_deploy:
- - go get -u github.com/tcnksm/ghr
- # stop deployment to kubernetes until we have set it up
- # - ./scripts/setup_kubernetes.sh
-
-deploy:
- - provider: script
- script: bash scripts/docker_push.sh
- on:
- branch: master
- # stop deployment to kubernetes until we have set it up
- # - provider: script
- # script: bash scripts/deploy.sh
- # on:
- # branch: master
diff --git a/backend/.env.template b/backend/.env.template
index dd46846a9..c1742ef93 100644
--- a/backend/.env.template
+++ b/backend/.env.template
@@ -1,3 +1,5 @@
+DEBUG=true
+
NEO4J_URI=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=letmein
diff --git a/backend/package.json b/backend/package.json
index 0c380d660..7d27fb6f8 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -29,7 +29,6 @@
"@babel/plugin-proposal-throw-expressions": "^7.8.3",
"@babel/preset-env": "~7.9.5",
"@babel/register": "^7.9.0",
- "@hapi/joi": "^17.1.1",
"@sentry/node": "^5.15.4",
"apollo-cache-inmemory": "~1.6.5",
"apollo-client": "~2.6.8",
@@ -46,13 +45,10 @@
"cheerio": "~1.0.0-rc.3",
"cors": "~2.8.5",
"cross-env": "~7.0.3",
- "date-fns": "2.22.1",
"debug": "~4.1.1",
"dotenv": "~8.2.0",
"express": "^4.17.1",
"graphql": "^14.6.0",
- "graphql-custom-directives": "~0.2.14",
- "graphql-iso-date": "~3.6.1",
"graphql-middleware": "~4.0.2",
"graphql-middleware-sentry": "^3.2.1",
"graphql-redis-subscriptions": "^2.2.1",
@@ -68,7 +64,6 @@
"metascraper": "^5.33.5",
"metascraper-audio": "^5.34.4",
"metascraper-author": "^5.33.5",
- "metascraper-clearbit-logo": "^5.3.0",
"metascraper-date": "^5.33.5",
"metascraper-description": "^5.33.5",
"metascraper-image": "^5.33.5",
@@ -91,7 +86,6 @@
"node-fetch": "~2.6.1",
"nodemailer": "^6.4.4",
"nodemailer-html-to-text": "^3.2.0",
- "npm-run-all": "~4.1.5",
"request": "~2.88.2",
"sanitize-html": "~1.22.0",
"slug": "~6.0.0",
@@ -99,11 +93,10 @@
"trunc-html": "~1.1.2",
"uuid": "~8.3.2",
"validator": "^13.9.0",
- "wait-on": "~4.0.1",
"xregexp": "^4.3.0"
},
"devDependencies": {
- "@faker-js/faker": "5.1.0",
+ "@faker-js/faker": "7.6.0",
"apollo-server-testing": "~2.11.0",
"chai": "~4.2.0",
"cucumber": "~6.0.5",
@@ -119,8 +112,7 @@
"jest": "29.4",
"nodemon": "~2.0.2",
"prettier": "~2.3.2",
- "rosie": "^2.0.1",
- "supertest": "~4.0.2"
+ "rosie": "^2.0.1"
},
"resolutions": {
"**/**/fs-capacitor": "^6.2.0",
diff --git a/backend/src/db/factories.js b/backend/src/db/factories.js
index 44af5bbea..3f38b5b9c 100644
--- a/backend/src/db/factories.js
+++ b/backend/src/db/factories.js
@@ -2,7 +2,7 @@ import { v4 as uuid } from 'uuid'
import slugify from 'slug'
import { hashSync } from 'bcryptjs'
import { Factory } from 'rosie'
-import faker from '@faker-js/faker'
+import { faker } from '@faker-js/faker'
import { getDriver, getNeode } from './neo4j'
import CONFIG from '../config/index.js'
import generateInviteCode from '../schema/resolvers/helpers/generateInviteCode.js'
@@ -63,7 +63,7 @@ Factory.define('basicUser')
.option('password', '1234')
.attrs({
id: uuid,
- name: faker.name.findName,
+ name: faker.name.fullName,
password: '1234',
role: 'user',
termsAndConditionsAgreedVersion: '0.0.1',
diff --git a/backend/src/db/migrations/20230329150329-article-label-for-posts.js b/backend/src/db/migrations/20230329150329-article-label-for-posts.js
new file mode 100644
index 000000000..3cf435203
--- /dev/null
+++ b/backend/src/db/migrations/20230329150329-article-label-for-posts.js
@@ -0,0 +1,53 @@
+import { getDriver } from '../../db/neo4j'
+
+export const description = 'Add to all existing posts the Article label'
+
+export async function up(next) {
+ const driver = getDriver()
+ const session = driver.session()
+ const transaction = session.beginTransaction()
+
+ try {
+ await transaction.run(`
+ MATCH (post:Post)
+ SET post:Article
+ RETURN post
+ `)
+ await transaction.commit()
+ next()
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.log(error)
+ await transaction.rollback()
+ // eslint-disable-next-line no-console
+ console.log('rolled back')
+ throw new Error(error)
+ } finally {
+ session.close()
+ }
+}
+
+export async function down(next) {
+ const driver = getDriver()
+ const session = driver.session()
+ const transaction = session.beginTransaction()
+
+ try {
+ await transaction.run(`
+ MATCH (post:Post)
+ REMOVE post:Article
+ RETURN post
+ `)
+ await transaction.commit()
+ next()
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.log(error)
+ await transaction.rollback()
+ // eslint-disable-next-line no-console
+ console.log('rolled back')
+ throw new Error(error)
+ } finally {
+ session.close()
+ }
+}
diff --git a/backend/src/db/seed.js b/backend/src/db/seed.js
index 8339e48a8..a8f8b9c68 100644
--- a/backend/src/db/seed.js
+++ b/backend/src/db/seed.js
@@ -2,7 +2,7 @@ import sample from 'lodash/sample'
import { createTestClient } from 'apollo-server-testing'
import CONFIG from '../config'
import createServer from '../server'
-import faker from '@faker-js/faker'
+import { faker } from '@faker-js/faker'
import Factory from '../db/factories'
import { getNeode, getDriver } from '../db/neo4j'
import {
@@ -173,6 +173,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
},
{
email: 'moderator@example.org',
+ avatar: null,
},
),
Factory.build(
@@ -209,6 +210,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
},
{
email: 'dewey@example.org',
+ avatar: null,
},
),
Factory.build(
diff --git a/backend/src/graphql/GraphQL-Playground.md b/backend/src/graphql/GraphQL-Playground.md
index af248f112..33e371eb5 100644
--- a/backend/src/graphql/GraphQL-Playground.md
+++ b/backend/src/graphql/GraphQL-Playground.md
@@ -1,5 +1,7 @@
# GraphQL Playground
+***Attention:** For using the GraphQL Playground set `DEBUG=true` in your backend `.env`, see `.env.template`!*
+
To use GraphQL Playground, we need to know some basics:
## How To Login?
diff --git a/backend/src/graphql/posts.js b/backend/src/graphql/posts.js
index 2669d6f24..d1dc3ee45 100644
--- a/backend/src/graphql/posts.js
+++ b/backend/src/graphql/posts.js
@@ -11,6 +11,8 @@ export const createPostMutation = () => {
$content: String!
$categoryIds: [ID]
$groupId: ID
+ $postType: PostType
+ $eventInput: _EventInput
) {
CreatePost(
id: $id
@@ -19,11 +21,31 @@ export const createPostMutation = () => {
content: $content
categoryIds: $categoryIds
groupId: $groupId
+ postType: $postType
+ eventInput: $eventInput
) {
id
slug
title
content
+ disabled
+ deleted
+ postType
+ author {
+ name
+ }
+ categories {
+ id
+ }
+ eventStart
+ eventEnd
+ eventLocationName
+ eventVenue
+ eventIsOnline
+ eventLocation {
+ lng
+ lat
+ }
}
}
`
@@ -50,6 +72,7 @@ export const filterPosts = () => {
id
title
content
+ eventStart
}
}
`
diff --git a/backend/src/schema/resolvers/embeds/scraper.js b/backend/src/schema/resolvers/embeds/scraper.js
index df37611f3..bcaa6e462 100644
--- a/backend/src/schema/resolvers/embeds/scraper.js
+++ b/backend/src/schema/resolvers/embeds/scraper.js
@@ -17,7 +17,6 @@ const metascraper = Metascraper([
require('metascraper-lang')(),
require('metascraper-lang-detector')(),
require('metascraper-logo')(),
- // require('metascraper-clearbit-logo')(),
require('metascraper-publisher')(),
require('metascraper-title')(),
require('metascraper-url')(),
diff --git a/backend/src/schema/resolvers/filter-posts.spec.js b/backend/src/schema/resolvers/filter-posts.spec.js
new file mode 100644
index 000000000..0b96e001f
--- /dev/null
+++ b/backend/src/schema/resolvers/filter-posts.spec.js
@@ -0,0 +1,230 @@
+import { createTestClient } from 'apollo-server-testing'
+import Factory, { cleanDatabase } from '../../db/factories'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import CONFIG from '../../config'
+import { filterPosts, createPostMutation } from '../../graphql/posts'
+
+CONFIG.CATEGORIES_ACTIVE = false
+
+const driver = getDriver()
+const neode = getNeode()
+
+let query
+let mutate
+let authenticatedUser
+let user
+
+beforeAll(async () => {
+ await cleanDatabase()
+
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+ mutate = createTestClient(server).mutate
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+ driver.close()
+})
+
+describe('Filter Posts', () => {
+ const now = new Date()
+
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'user',
+ name: 'User',
+ about: 'I am a user.',
+ })
+ authenticatedUser = await user.toJson()
+ await mutate({
+ mutation: createPostMutation(),
+ variables: {
+ id: 'a1',
+ title: 'I am an article',
+ content: 'I am an article written by user.',
+ },
+ })
+ await mutate({
+ mutation: createPostMutation(),
+ variables: {
+ id: 'a2',
+ title: 'I am anonther article',
+ content: 'I am another article written by user.',
+ },
+ })
+ await mutate({
+ mutation: createPostMutation(),
+ variables: {
+ id: 'e1',
+ title: 'Illegaler Kindergeburtstag',
+ content: 'Elli wird fünf. Wir feiern ihren Geburtstag.',
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventVenue: 'Garten der Familie Maier',
+ },
+ },
+ })
+ await mutate({
+ mutation: createPostMutation(),
+ variables: {
+ id: 'e2',
+ title: 'Räuber-Treffen',
+ content: 'Planung der nächsten Räuberereien',
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1).toISOString(),
+ eventVenue: 'Wirtshaus im Spessart',
+ },
+ },
+ })
+ })
+
+ describe('no filters set', () => {
+ it('finds all posts', async () => {
+ const {
+ data: { Post: result },
+ } = await query({ query: filterPosts() })
+ expect(result).toHaveLength(4)
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({ id: 'a1' }),
+ expect.objectContaining({ id: 'a2' }),
+ expect.objectContaining({ id: 'e1' }),
+ expect.objectContaining({ id: 'e2' }),
+ ]),
+ )
+ })
+ })
+
+ describe('post type filter set to ["Article"]', () => {
+ it('finds the articles', async () => {
+ const {
+ data: { Post: result },
+ } = await query({ query: filterPosts(), variables: { filter: { postType_in: ['Article'] } } })
+ expect(result).toHaveLength(2)
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({ id: 'a1' }),
+ expect.objectContaining({ id: 'a2' }),
+ ]),
+ )
+ })
+ })
+
+ describe('post type filter set to ["Event"]', () => {
+ it('finds the articles', async () => {
+ const {
+ data: { Post: result },
+ } = await query({ query: filterPosts(), variables: { filter: { postType_in: ['Event'] } } })
+ expect(result).toHaveLength(2)
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({ id: 'e1' }),
+ expect.objectContaining({ id: 'e2' }),
+ ]),
+ )
+ })
+ })
+
+ describe('post type filter set to ["Article", "Event"]', () => {
+ it('finds all posts', async () => {
+ const {
+ data: { Post: result },
+ } = await query({
+ query: filterPosts(),
+ variables: { filter: { postType_in: ['Article', 'Event'] } },
+ })
+ expect(result).toHaveLength(4)
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({ id: 'a1' }),
+ expect.objectContaining({ id: 'a2' }),
+ expect.objectContaining({ id: 'e1' }),
+ expect.objectContaining({ id: 'e2' }),
+ ]),
+ )
+ })
+ })
+
+ describe('order events by event start descending', () => {
+ it('finds the events orderd accordingly', async () => {
+ const {
+ data: { Post: result },
+ } = await query({
+ query: filterPosts(),
+ variables: { filter: { postType_in: ['Event'] }, orderBy: ['eventStart_desc'] },
+ })
+ expect(result).toHaveLength(2)
+ expect(result).toEqual([
+ expect.objectContaining({
+ id: 'e1',
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ }),
+ expect.objectContaining({
+ id: 'e2',
+ eventStart: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1).toISOString(),
+ }),
+ ])
+ })
+ })
+
+ describe('order events by event start ascending', () => {
+ it('finds the events orderd accordingly', async () => {
+ const {
+ data: { Post: result },
+ } = await query({
+ query: filterPosts(),
+ variables: { filter: { postType_in: ['Event'] }, orderBy: ['eventStart_asc'] },
+ })
+ expect(result).toHaveLength(2)
+ expect(result).toEqual([
+ expect.objectContaining({
+ id: 'e2',
+ eventStart: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1).toISOString(),
+ }),
+ expect.objectContaining({
+ id: 'e1',
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ }),
+ ])
+ })
+ })
+
+ describe('filter events by event start date', () => {
+ it('finds only events after given date', async () => {
+ const {
+ data: { Post: result },
+ } = await query({
+ query: filterPosts(),
+ variables: {
+ filter: {
+ postType_in: ['Event'],
+ eventStart_gte: new Date(
+ now.getFullYear(),
+ now.getMonth(),
+ now.getDate() + 2,
+ ).toISOString(),
+ },
+ },
+ })
+ expect(result).toHaveLength(1)
+ expect(result).toEqual([
+ expect.objectContaining({
+ id: 'e1',
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ }),
+ ])
+ })
+ })
+})
diff --git a/backend/src/schema/resolvers/helpers/events.js b/backend/src/schema/resolvers/helpers/events.js
new file mode 100644
index 000000000..84e64299d
--- /dev/null
+++ b/backend/src/schema/resolvers/helpers/events.js
@@ -0,0 +1,47 @@
+import { UserInputError } from 'apollo-server'
+
+export const validateEventParams = (params) => {
+ if (params.postType && params.postType === 'Event') {
+ const { eventInput } = params
+ validateEventDate(eventInput.eventStart)
+ params.eventStart = eventInput.eventStart
+ if (eventInput.eventEnd) {
+ validateEventEnd(eventInput.eventStart, eventInput.eventEnd)
+ params.eventEnd = eventInput.eventEnd
+ }
+ if (eventInput.eventLocationName && !eventInput.eventVenue) {
+ throw new UserInputError('Event venue must be present if event location is given!')
+ }
+ params.eventVenue = eventInput.eventVenue
+ params.eventLocationName = eventInput.eventLocationName
+ params.eventIsOnline = !!eventInput.eventIsOnline
+ }
+ delete params.eventInput
+ let locationName
+ if (params.eventLocationName) {
+ locationName = params.eventLocationName
+ } else {
+ params.eventLocationName = null
+ locationName = null
+ }
+ return locationName
+}
+
+const validateEventDate = (dateString) => {
+ const date = new Date(dateString)
+ if (date.toString() === 'Invalid Date')
+ throw new UserInputError('Event start date must be a valid date!')
+ const now = new Date()
+ if (date.getTime() < now.getTime()) {
+ throw new UserInputError('Event start date must be in the future!')
+ }
+}
+
+const validateEventEnd = (start, end) => {
+ const endDate = new Date(end)
+ if (endDate.toString() === 'Invalid Date')
+ throw new UserInputError('Event end date must be a valid date!')
+ const startDate = new Date(start)
+ if (endDate < startDate)
+ throw new UserInputError('Event end date must be a after event start date!')
+}
diff --git a/backend/src/schema/resolvers/notifications.js b/backend/src/schema/resolvers/notifications.js
index 117b9b530..c3b882146 100644
--- a/backend/src/schema/resolvers/notifications.js
+++ b/backend/src/schema/resolvers/notifications.js
@@ -51,7 +51,7 @@ export default {
OPTIONAL MATCH (resource)<-[membership:MEMBER_OF]-(relatedUser)
WITH user, notification, resource, membership, relatedUser,
[(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors,
- [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author)} ] AS posts
+ [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author), postType: filter(l IN labels(post) WHERE NOT l = "Post")} ] AS posts
WITH resource, user, notification, authors, posts, relatedUser, membership,
resource {.*,
__typename: labels(resource)[0],
@@ -90,7 +90,7 @@ export default {
SET notification.read = TRUE
WITH user, notification, resource,
[(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors,
- [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] AS posts
+ [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: filter(l IN labels(post) WHERE NOT l = "Post")} ] AS posts
OPTIONAL MATCH (resource)<-[membership:MEMBER_OF]-(user)
WITH resource, user, notification, authors, posts, membership,
resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0], myRole: membership.role } AS finalResource
@@ -120,7 +120,7 @@ export default {
SET notification.read = TRUE
WITH user, notification, resource,
[(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors,
- [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] AS posts
+ [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: filter(l IN labels(post) WHERE NOT l = "Post")} ] AS posts
OPTIONAL MATCH (resource)<-[membership:MEMBER_OF]-(user)
WITH resource, user, notification, authors, posts, membership,
resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0], myRole: membership.role} AS finalResource
diff --git a/backend/src/schema/resolvers/posts.js b/backend/src/schema/resolvers/posts.js
index 063b2210d..c7d2eebdb 100644
--- a/backend/src/schema/resolvers/posts.js
+++ b/backend/src/schema/resolvers/posts.js
@@ -7,6 +7,8 @@ import Resolver from './helpers/Resolver'
import { filterForMutedUsers } from './helpers/filterForMutedUsers'
import { filterInvisiblePosts } from './helpers/filterInvisiblePosts'
import { filterPostsOfMyGroups } from './helpers/filterPostsOfMyGroups'
+import { validateEventParams } from './helpers/events'
+import { createOrUpdateLocations } from './users/location'
import CONFIG from '../../config'
const maintainPinnedPosts = (params) => {
@@ -81,6 +83,9 @@ export default {
CreatePost: async (_parent, params, context, _resolveInfo) => {
const { categoryIds, groupId } = params
const { image: imageInput } = params
+
+ const locationName = validateEventParams(params)
+
delete params.categoryIds
delete params.image
delete params.groupId
@@ -125,12 +130,13 @@ export default {
SET post.updatedAt = toString(datetime())
SET post.clickedCount = 0
SET post.viewedTeaserCount = 0
+ SET post:${params.postType}
WITH post
MATCH (author:User {id: $userId})
MERGE (post)<-[:WROTE]-(author)
${categoriesCypher}
${groupCypher}
- RETURN post {.*}
+ RETURN post {.*, postType: filter(l IN labels(post) WHERE NOT l = "Post") }
`,
{ userId: context.user.id, categoryIds, groupId, params },
)
@@ -142,6 +148,9 @@ export default {
})
try {
const post = await writeTxResultPromise
+ if (locationName) {
+ await createOrUpdateLocations('Post', post.id, locationName, session)
+ }
return post
} catch (e) {
if (e.code === 'Neo.ClientError.Schema.ConstraintValidationFailed')
@@ -154,6 +163,9 @@ export default {
UpdatePost: async (_parent, params, context, _resolveInfo) => {
const { categoryIds } = params
const { image: imageInput } = params
+
+ const locationName = validateEventParams(params)
+
delete params.categoryIds
delete params.image
const session = context.driver.session()
@@ -183,7 +195,16 @@ export default {
`
}
- updatePostCypher += `RETURN post {.*}`
+ if (params.postType) {
+ updatePostCypher += `
+ REMOVE post:Article
+ REMOVE post:Event
+ SET post:${params.postType}
+ WITH post
+ `
+ }
+
+ updatePostCypher += `RETURN post {.*, postType: filter(l IN labels(post) WHERE NOT l = "Post")}`
const updatePostVariables = { categoryIds, params }
try {
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
@@ -196,6 +217,9 @@ export default {
return post
})
const post = await writeTxResultPromise
+ if (locationName) {
+ await createOrUpdateLocations('Post', post.id, locationName, session)
+ }
return post
} finally {
session.close()
@@ -385,7 +409,19 @@ export default {
},
Post: {
...Resolver('Post', {
- undefinedToNull: ['activityId', 'objectId', 'language', 'pinnedAt', 'pinned'],
+ undefinedToNull: [
+ 'activityId',
+ 'objectId',
+ 'language',
+ 'pinnedAt',
+ 'pinned',
+ 'eventVenue',
+ 'eventLocation',
+ 'eventLocationName',
+ 'eventStart',
+ 'eventEnd',
+ 'eventIsOnline',
+ ],
hasMany: {
tags: '-[:TAGGED]->(related:Tag)',
categories: '-[:CATEGORIZED]->(related:Category)',
@@ -398,6 +434,7 @@ export default {
pinnedBy: '<-[:PINNED]-(related:User)',
image: '-[:HERO_IMAGE]->(related:Image)',
group: '-[:IN]->(related:Group)',
+ eventLocation: '-[:IS_IN]->(related:Location)',
},
count: {
commentsCount:
diff --git a/backend/src/schema/resolvers/posts.spec.js b/backend/src/schema/resolvers/posts.spec.js
index 9335c1313..87d09e262 100644
--- a/backend/src/schema/resolvers/posts.spec.js
+++ b/backend/src/schema/resolvers/posts.spec.js
@@ -3,6 +3,10 @@ import Factory, { cleanDatabase } from '../../db/factories'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
+import { createPostMutation } from '../../graphql/posts'
+import CONFIG from '../../config'
+
+CONFIG.CATEGORIES_ACTIVE = true
const driver = getDriver()
const neode = getNeode()
@@ -15,29 +19,6 @@ let user
const categoryIds = ['cat9', 'cat4', 'cat15']
let variables
-const createPostMutation = gql`
- mutation ($id: ID, $title: String!, $content: String!, $language: String, $categoryIds: [ID]) {
- CreatePost(
- id: $id
- title: $title
- content: $content
- language: $language
- categoryIds: $categoryIds
- ) {
- id
- title
- content
- slug
- disabled
- deleted
- language
- author {
- name
- }
- }
- }
-`
-
beforeAll(async () => {
await cleanDatabase()
@@ -281,7 +262,7 @@ describe('CreatePost', () => {
describe('unauthenticated', () => {
it('throws authorization error', async () => {
- const { errors } = await mutate({ mutation: createPostMutation, variables })
+ const { errors } = await mutate({ mutation: createPostMutation(), variables })
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
})
})
@@ -296,7 +277,7 @@ describe('CreatePost', () => {
data: { CreatePost: { title: 'I am a title', content: 'Some content' } },
errors: undefined,
}
- await expect(mutate({ mutation: createPostMutation, variables })).resolves.toMatchObject(
+ await expect(mutate({ mutation: createPostMutation(), variables })).resolves.toMatchObject(
expected,
)
})
@@ -313,25 +294,327 @@ describe('CreatePost', () => {
},
errors: undefined,
}
- await expect(mutate({ mutation: createPostMutation, variables })).resolves.toMatchObject(
+ await expect(mutate({ mutation: createPostMutation(), variables })).resolves.toMatchObject(
expected,
)
})
it('`disabled` and `deleted` default to `false`', async () => {
const expected = { data: { CreatePost: { disabled: false, deleted: false } } }
- await expect(mutate({ mutation: createPostMutation, variables })).resolves.toMatchObject(
+ await expect(mutate({ mutation: createPostMutation(), variables })).resolves.toMatchObject(
expected,
)
})
+
+ it('has label "Article" as default', async () => {
+ await expect(mutate({ mutation: createPostMutation(), variables })).resolves.toMatchObject({
+ data: { CreatePost: { postType: ['Article'] } },
+ })
+ })
+
+ describe('with invalid post type', () => {
+ it('throws an error', async () => {
+ await expect(
+ mutate({
+ mutation: createPostMutation(),
+ variables: { ...variables, postType: 'not-valid' },
+ }),
+ ).resolves.toMatchObject({
+ errors: [
+ {
+ message:
+ 'Variable "$postType" got invalid value "not-valid"; Expected type PostType.',
+ },
+ ],
+ })
+ })
+ })
+
+ describe('with post type "Event"', () => {
+ describe('without event start date', () => {
+ it('throws an error', async () => {
+ await expect(
+ mutate({
+ mutation: createPostMutation(),
+ variables: {
+ ...variables,
+ postType: 'Event',
+ },
+ }),
+ ).resolves.toMatchObject({
+ errors: [
+ {
+ message: "Cannot read properties of undefined (reading 'eventStart')",
+ },
+ ],
+ })
+ })
+ })
+
+ describe('with invalid event start date', () => {
+ it('throws an error', async () => {
+ await expect(
+ mutate({
+ mutation: createPostMutation(),
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: 'no date',
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ errors: [
+ {
+ message: 'Event start date must be a valid date!',
+ },
+ ],
+ })
+ })
+ })
+
+ describe('with event start date in the past', () => {
+ it('throws an error', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: createPostMutation(),
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() - 1).toISOString(),
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ errors: [
+ {
+ message: 'Event start date must be in the future!',
+ },
+ ],
+ })
+ })
+ })
+
+ describe('with valid start date and invalid end date', () => {
+ it('throws an error', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: createPostMutation(),
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventEnd: 'not-valid',
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ errors: [
+ {
+ message: 'Event end date must be a valid date!',
+ },
+ ],
+ })
+ })
+ })
+
+ describe('with valid start date and end date before start date', () => {
+ it('throws an error', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: createPostMutation(),
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 2).toISOString(),
+ eventEnd: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ errors: [
+ {
+ message: 'Event end date must be a after event start date!',
+ },
+ ],
+ })
+ })
+ })
+
+ describe('with valid start date and valid end date', () => {
+ it('creates the event', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: createPostMutation(),
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventEnd: new Date(now.getFullYear(), now.getMonth() + 2).toISOString(),
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ CreatePost: {
+ postType: ['Event'],
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventEnd: new Date(now.getFullYear(), now.getMonth() + 2).toISOString(),
+ eventIsOnline: false,
+ },
+ },
+ errors: undefined,
+ })
+ })
+ })
+
+ describe('with valid start date and event is online', () => {
+ it('creates the event', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: createPostMutation(),
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventIsOnline: true,
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ CreatePost: {
+ postType: ['Event'],
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventIsOnline: true,
+ },
+ },
+ errors: undefined,
+ })
+ })
+ })
+
+ describe('event location name is given but event venue is missing', () => {
+ it('throws an error', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: createPostMutation(),
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventLocationName: 'Berlin',
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ errors: [
+ {
+ message: 'Event venue must be present if event location is given!',
+ },
+ ],
+ })
+ })
+ })
+
+ describe('valid event input without location', () => {
+ it('has label "Event" set', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: createPostMutation(),
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ CreatePost: {
+ postType: ['Event'],
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventIsOnline: false,
+ },
+ },
+ errors: undefined,
+ })
+ })
+ })
+
+ describe('valid event input with location name', () => {
+ it('has label "Event" set', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: createPostMutation(),
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventLocationName: 'Leipzig',
+ eventVenue: 'Connewitzer Kreuz',
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ CreatePost: {
+ postType: ['Event'],
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventLocationName: 'Leipzig',
+ eventVenue: 'Connewitzer Kreuz',
+ eventLocation: {
+ lng: 12.374733,
+ lat: 51.340632,
+ },
+ },
+ },
+ errors: undefined,
+ })
+ })
+ })
+ })
})
})
describe('UpdatePost', () => {
let author, newlyCreatedPost
const updatePostMutation = gql`
- mutation ($id: ID!, $title: String!, $content: String!, $image: ImageInput) {
- UpdatePost(id: $id, title: $title, content: $content, image: $image) {
+ mutation (
+ $id: ID!
+ $title: String!
+ $content: String!
+ $image: ImageInput
+ $categoryIds: [ID]
+ $postType: PostType
+ $eventInput: _EventInput
+ ) {
+ UpdatePost(
+ id: $id
+ title: $title
+ content: $content
+ image: $image
+ categoryIds: $categoryIds
+ postType: $postType
+ eventInput: $eventInput
+ ) {
id
title
content
@@ -341,26 +624,34 @@ describe('UpdatePost', () => {
}
createdAt
updatedAt
+ categories {
+ id
+ }
+ postType
+ eventStart
+ eventLocationName
+ eventVenue
+ eventLocation {
+ lng
+ lat
+ }
}
}
`
beforeEach(async () => {
author = await Factory.build('user', { slug: 'the-author' })
- newlyCreatedPost = await Factory.build(
- 'post',
- {
- id: 'p9876',
+ authenticatedUser = await author.toJson()
+ const { data } = await mutate({
+ mutation: createPostMutation(),
+ variables: {
title: 'Old title',
content: 'Old content',
- },
- {
- author,
categoryIds,
},
- )
-
+ })
+ newlyCreatedPost = data.CreatePost
variables = {
- id: 'p9876',
+ id: newlyCreatedPost.id,
title: 'New title',
content: 'New content',
}
@@ -394,7 +685,7 @@ describe('UpdatePost', () => {
it('updates a post', async () => {
const expected = {
- data: { UpdatePost: { id: 'p9876', content: 'New content' } },
+ data: { UpdatePost: { id: newlyCreatedPost.id, content: 'New content' } },
errors: undefined,
}
await expect(mutate({ mutation: updatePostMutation, variables })).resolves.toMatchObject(
@@ -405,7 +696,11 @@ describe('UpdatePost', () => {
it('updates a post, but maintains non-updated attributes', async () => {
const expected = {
data: {
- UpdatePost: { id: 'p9876', content: 'New content', createdAt: expect.any(String) },
+ UpdatePost: {
+ id: newlyCreatedPost.id,
+ content: 'New content',
+ createdAt: expect.any(String),
+ },
},
errors: undefined,
}
@@ -415,23 +710,20 @@ describe('UpdatePost', () => {
})
it('updates the updatedAt attribute', async () => {
- newlyCreatedPost = await newlyCreatedPost.toJson()
const {
data: { UpdatePost },
} = await mutate({ mutation: updatePostMutation, variables })
- expect(newlyCreatedPost.updatedAt).toBeTruthy()
- expect(Date.parse(newlyCreatedPost.updatedAt)).toEqual(expect.any(Number))
expect(UpdatePost.updatedAt).toBeTruthy()
expect(Date.parse(UpdatePost.updatedAt)).toEqual(expect.any(Number))
expect(newlyCreatedPost.updatedAt).not.toEqual(UpdatePost.updatedAt)
})
- /* describe('no new category ids provided for update', () => {
+ describe('no new category ids provided for update', () => {
it('resolves and keeps current categories', async () => {
const expected = {
data: {
UpdatePost: {
- id: 'p9876',
+ id: newlyCreatedPost.id,
categories: expect.arrayContaining([{ id: 'cat9' }, { id: 'cat4' }, { id: 'cat15' }]),
},
},
@@ -441,9 +733,9 @@ describe('UpdatePost', () => {
expected,
)
})
- }) */
+ })
- /* describe('given category ids', () => {
+ describe('given category ids', () => {
beforeEach(() => {
variables = { ...variables, categoryIds: ['cat27'] }
})
@@ -452,7 +744,7 @@ describe('UpdatePost', () => {
const expected = {
data: {
UpdatePost: {
- id: 'p9876',
+ id: newlyCreatedPost.id,
categories: expect.arrayContaining([{ id: 'cat27' }]),
},
},
@@ -462,9 +754,160 @@ describe('UpdatePost', () => {
expected,
)
})
- }) */
+ })
- describe('params.image', () => {
+ describe('change post type to event', () => {
+ describe('with missing event start date', () => {
+ it('throws an error', async () => {
+ await expect(
+ mutate({
+ mutation: updatePostMutation,
+ variables: { ...variables, postType: 'Event' },
+ }),
+ ).resolves.toMatchObject({
+ errors: [
+ {
+ message: "Cannot read properties of undefined (reading 'eventStart')",
+ },
+ ],
+ })
+ })
+ })
+
+ describe('with invalid event start date', () => {
+ it('throws an error', async () => {
+ await expect(
+ mutate({
+ mutation: updatePostMutation,
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: 'no-date',
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ errors: [
+ {
+ message: 'Event start date must be a valid date!',
+ },
+ ],
+ })
+ })
+ })
+
+ describe('with event start date in the past', () => {
+ it('throws an error', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: updatePostMutation,
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() - 1).toISOString(),
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ errors: [
+ {
+ message: 'Event start date must be in the future!',
+ },
+ ],
+ })
+ })
+ })
+
+ describe('event location name is given but event venue is missing', () => {
+ it('throws an error', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: updatePostMutation,
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventLocationName: 'Berlin',
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ errors: [
+ {
+ message: 'Event venue must be present if event location is given!',
+ },
+ ],
+ })
+ })
+ })
+
+ describe('valid event input without location name', () => {
+ it('has label "Event" set', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: updatePostMutation,
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ UpdatePost: {
+ postType: ['Event'],
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ },
+ },
+ errors: undefined,
+ })
+ })
+ })
+
+ describe('valid event input with location name', () => {
+ it('has label "Event" set', async () => {
+ const now = new Date()
+ await expect(
+ mutate({
+ mutation: updatePostMutation,
+ variables: {
+ ...variables,
+ postType: 'Event',
+ eventInput: {
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventLocationName: 'Leipzig',
+ eventVenue: 'Connewitzer Kreuz',
+ },
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ UpdatePost: {
+ postType: ['Event'],
+ eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
+ eventLocationName: 'Leipzig',
+ eventVenue: 'Connewitzer Kreuz',
+ eventLocation: {
+ lng: 12.374733,
+ lat: 51.340632,
+ },
+ },
+ },
+ errors: undefined,
+ })
+ })
+ })
+ })
+
+ describe.skip('params.image', () => {
describe('is object', () => {
beforeEach(() => {
variables = { ...variables, image: { sensitive: true } }
diff --git a/backend/src/schema/resolvers/postsInGroups.spec.js b/backend/src/schema/resolvers/postsInGroups.spec.js
index 86a278207..ba9041090 100644
--- a/backend/src/schema/resolvers/postsInGroups.spec.js
+++ b/backend/src/schema/resolvers/postsInGroups.spec.js
@@ -818,11 +818,13 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
]),
},
@@ -846,11 +848,13 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
]),
},
@@ -874,11 +878,13 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
]),
},
@@ -902,11 +908,13 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
]),
},
@@ -930,21 +938,25 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
{
id: 'post-to-closed-group',
title: 'A post to a closed group',
content: 'I am posting into a closed group as a member of the group',
+ eventStart: null,
},
{
id: 'post-to-hidden-group',
title: 'A post to a hidden group',
content: 'I am posting into a hidden group as a member of the group',
+ eventStart: null,
},
]),
},
@@ -1319,16 +1331,19 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
{
id: 'post-to-closed-group',
title: 'A post to a closed group',
content: 'I am posting into a closed group as a member of the group',
+ eventStart: null,
},
]),
},
@@ -1361,21 +1376,25 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
{
id: 'post-to-closed-group',
title: 'A post to a closed group',
content: 'I am posting into a closed group as a member of the group',
+ eventStart: null,
},
{
id: 'post-to-hidden-group',
title: 'A post to a hidden group',
content: 'I am posting into a hidden group as a member of the group',
+ eventStart: null,
},
]),
},
@@ -1410,16 +1429,19 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
{
id: 'post-to-hidden-group',
title: 'A post to a hidden group',
content: 'I am posting into a hidden group as a member of the group',
+ eventStart: null,
},
]),
},
@@ -1452,11 +1474,13 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
]),
},
@@ -1489,21 +1513,25 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
{
id: 'post-to-closed-group',
title: 'A post to a closed group',
content: 'I am posting into a closed group as a member of the group',
+ eventStart: null,
},
{
id: 'post-to-hidden-group',
title: 'A post to a hidden group',
content: 'I am posting into a hidden group as a member of the group',
+ eventStart: null,
},
]),
},
@@ -1534,21 +1562,25 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
{
id: 'post-to-closed-group',
title: 'A post to a closed group',
content: 'I am posting into a closed group as a member of the group',
+ eventStart: null,
},
{
id: 'post-to-hidden-group',
title: 'A post to a hidden group',
content: 'I am posting into a hidden group as a member of the group',
+ eventStart: null,
},
]),
},
@@ -1579,21 +1611,25 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
{
id: 'post-to-closed-group',
title: 'A post to a closed group',
content: 'I am posting into a closed group as a member of the group',
+ eventStart: null,
},
{
id: 'post-to-hidden-group',
title: 'A post to a hidden group',
content: 'I am posting into a hidden group as a member of the group',
+ eventStart: null,
},
]),
},
@@ -1628,21 +1664,25 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
{
id: 'post-to-closed-group',
title: 'A post to a closed group',
content: 'I am posting into a closed group as a member of the group',
+ eventStart: null,
},
{
id: 'post-to-hidden-group',
title: 'A post to a hidden group',
content: 'I am posting into a hidden group as a member of the group',
+ eventStart: null,
},
]),
},
@@ -1675,21 +1715,25 @@ describe('Posts in Groups', () => {
id: 'post-to-public-group',
title: 'A post to a public group',
content: 'I am posting into a public group as a member of the group',
+ eventStart: null,
},
{
id: 'post-without-group',
title: 'A post without a group',
content: 'I am a user who does not belong to a group yet.',
+ eventStart: null,
},
{
id: 'post-to-closed-group',
title: 'A post to a closed group',
content: 'I am posting into a closed group as a member of the group',
+ eventStart: null,
},
{
id: 'post-to-hidden-group',
title: 'A post to a hidden group',
content: 'I am posting into a hidden group as a member of the group',
+ eventStart: null,
},
]),
},
@@ -1739,11 +1783,13 @@ describe('Posts in Groups', () => {
id: 'post-to-closed-group',
title: 'A post to a closed group',
content: 'I am posting into a closed group as a member of the group',
+ eventStart: null,
},
{
id: 'post-to-hidden-group',
title: 'A post to a hidden group',
content: 'I am posting into a hidden group as a member of the group',
+ eventStart: null,
},
]),
},
diff --git a/backend/src/schema/resolvers/users/location.js b/backend/src/schema/resolvers/users/location.js
index 9d8a11f89..54d73560b 100644
--- a/backend/src/schema/resolvers/users/location.js
+++ b/backend/src/schema/resolvers/users/location.js
@@ -22,7 +22,7 @@ const locales = ['en', 'de', 'fr', 'nl', 'it', 'es', 'pt', 'pl', 'ru']
const createLocation = async (session, mapboxData) => {
const data = {
- id: mapboxData.id,
+ id: mapboxData.id + (mapboxData.address ? `-${mapboxData.address}` : ''),
nameEN: mapboxData.text_en,
nameDE: mapboxData.text_de,
nameFR: mapboxData.text_fr,
@@ -33,6 +33,7 @@ const createLocation = async (session, mapboxData) => {
namePL: mapboxData.text_pl,
nameRU: mapboxData.text_ru,
type: mapboxData.id.split('.')[0].toLowerCase(),
+ address: mapboxData.address,
lng: mapboxData.center && mapboxData.center.length ? mapboxData.center[0] : null,
lat: mapboxData.center && mapboxData.center.length ? mapboxData.center[1] : null,
}
@@ -54,6 +55,10 @@ const createLocation = async (session, mapboxData) => {
if (data.lat && data.lng) {
mutation += ', l.lat = $lat, l.lng = $lng'
}
+ if (data.address) {
+ mutation += ', l.address = $address'
+ }
+
mutation += ' RETURN l.id'
await session.writeTransaction((transaction) => {
@@ -72,7 +77,7 @@ export const createOrUpdateLocations = async (nodeLabel, nodeId, locationName, s
locationName,
)}.json?access_token=${
CONFIG.MAPBOX_TOKEN
- }&types=region,place,country&language=${locales.join(',')}`,
+ }&types=region,place,country,address&language=${locales.join(',')}`,
)
debug(res)
@@ -103,6 +108,10 @@ export const createOrUpdateLocations = async (nodeLabel, nodeId, locationName, s
let parent = data
+ if (parent.address) {
+ parent.id += `-${parent.address}`
+ }
+
if (data.context) {
await asyncForEach(data.context, async (ctx) => {
await createLocation(session, ctx)
diff --git a/backend/src/schema/types/enum/PostType.gql b/backend/src/schema/types/enum/PostType.gql
new file mode 100644
index 000000000..eef80d6ba
--- /dev/null
+++ b/backend/src/schema/types/enum/PostType.gql
@@ -0,0 +1,4 @@
+enum PostType {
+ Article
+ Event
+}
diff --git a/backend/src/schema/types/type/Post.gql b/backend/src/schema/types/type/Post.gql
index 6fc7a3215..5a5d57b9a 100644
--- a/backend/src/schema/types/type/Post.gql
+++ b/backend/src/schema/types/type/Post.gql
@@ -83,6 +83,8 @@ input _PostFilter {
emotions_every: _PostEMOTEDFilter
group: _GroupFilter
postsInMyGroups: Boolean
+ postType_in: [PostType]
+ eventStart_gte: String
}
enum _PostOrdering {
@@ -104,6 +106,8 @@ enum _PostOrdering {
language_desc
pinned_asc
pinned_desc
+ eventStart_asc
+ eventStart_desc
}
@@ -171,12 +175,30 @@ type Post {
@cypher(statement: "MATCH (this)<-[emoted:EMOTED]-(:User) RETURN COUNT(DISTINCT emoted)")
group: Group @relation(name: "IN", direction: "OUT")
+
+ postType: [PostType]
+ @cypher(statement: "RETURN filter(l IN labels(this) WHERE NOT l = 'Post')")
+
+ eventLocationName: String
+ eventLocation: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l")
+ eventVenue: String
+ eventStart: String
+ eventEnd: String
+ eventIsOnline: Boolean
}
input _PostInput {
id: ID!
}
+input _EventInput {
+ eventStart: String!
+ eventEnd: String
+ eventVenue: String
+ eventLocationName: String
+ eventIsOnline: Boolean
+}
+
type Mutation {
CreatePost(
id: ID
@@ -189,6 +211,8 @@ type Mutation {
categoryIds: [ID]
contentExcerpt: String
groupId: ID
+ postType: PostType = Article
+ eventInput: _EventInput
): Post
UpdatePost(
id: ID!
@@ -200,6 +224,8 @@ type Mutation {
visibility: Visibility
language: String
categoryIds: [ID]
+ postType: PostType
+ eventInput: _EventInput
): Post
DeletePost(id: ID!): Post
AddPostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
diff --git a/backend/yarn.lock b/backend/yarn.lock
index fbb356cf2..d576416fc 100644
--- a/backend/yarn.lock
+++ b/backend/yarn.lock
@@ -1088,10 +1088,10 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
-"@faker-js/faker@5.1.0":
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-5.1.0.tgz#cee1d77ada0d0dbbe77201d18b1ebabf432d9c0f"
- integrity sha512-0VonSKh7fBCqvY+V2FLN2ZW4pR4ZtWJalWmwSaiaB7yK7y4qp8vDfuaq9QdLjf/cdZGx3M7Wc4Q+x4fZHxI21Q==
+"@faker-js/faker@7.6.0":
+ version "7.6.0"
+ resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-7.6.0.tgz#9ea331766084288634a9247fcd8b84f16ff4ba07"
+ integrity sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==
"@gar/promisify@^1.1.3":
version "1.1.3"
@@ -1131,33 +1131,16 @@
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==
-"@hapi/address@^4.0.1":
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/@hapi/address/-/address-4.0.1.tgz#267301ddf7bc453718377a6fb3832a2f04a721dd"
- integrity sha512-0oEP5UiyV4f3d6cBL8F3Z5S7iWSX39Knnl0lY8i+6gfmmIBj44JCBNtcMgwyS+5v7j3VYavNay0NFHDS+UGQcw==
- dependencies:
- "@hapi/hoek" "^9.0.0"
-
"@hapi/bourne@1.x.x":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a"
integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==
-"@hapi/formula@^2.0.0":
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/@hapi/formula/-/formula-2.0.0.tgz#edade0619ed58c8e4f164f233cda70211e787128"
- integrity sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==
-
"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0":
version "8.5.1"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06"
integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==
-"@hapi/hoek@^9.0.0":
- version "9.0.0"
- resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.0.0.tgz#ba83436edfac1d1ffd0e94797d43419c20ad49b8"
- integrity sha512-XxD4A5YMIH70ddjG7BJBUz7RWVQAwIP/36Eoyh0DsaWp92OAeXkrbtSEaYkynBPTsN9Uv2mZq9QWZYILl2Svrw==
-
"@hapi/joi@^15.1.1":
version "15.1.1"
resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7"
@@ -1168,22 +1151,6 @@
"@hapi/hoek" "8.x.x"
"@hapi/topo" "3.x.x"
-"@hapi/joi@^17.1.0", "@hapi/joi@^17.1.1":
- version "17.1.1"
- resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-17.1.1.tgz#9cc8d7e2c2213d1e46708c6260184b447c661350"
- integrity sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==
- dependencies:
- "@hapi/address" "^4.0.1"
- "@hapi/formula" "^2.0.0"
- "@hapi/hoek" "^9.0.0"
- "@hapi/pinpoint" "^2.0.0"
- "@hapi/topo" "^5.0.0"
-
-"@hapi/pinpoint@^2.0.0":
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/@hapi/pinpoint/-/pinpoint-2.0.0.tgz#805b40d4dbec04fc116a73089494e00f073de8df"
- integrity sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==
-
"@hapi/topo@3.x.x":
version "3.1.6"
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29"
@@ -1191,13 +1158,6 @@
dependencies:
"@hapi/hoek" "^8.3.0"
-"@hapi/topo@^5.0.0":
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7"
- integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==
- dependencies:
- "@hapi/hoek" "^9.0.0"
-
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
@@ -1733,11 +1693,6 @@
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.21.tgz#763b05a4b472c93a8db29b2c3e359d55b29ce272"
integrity sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==
-"@sindresorhus/is@^0.14.0":
- version "0.14.0"
- resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
- integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
-
"@sindresorhus/is@^4.0.0":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5"
@@ -1757,13 +1712,6 @@
dependencies:
"@sinonjs/commons" "^2.0.0"
-"@szmarczak/http-timer@^1.1.2":
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
- integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
- dependencies:
- defer-to-connect "^1.0.1"
-
"@szmarczak/http-timer@^4.0.5":
version "4.0.6"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807"
@@ -3181,19 +3129,6 @@ cacheable-lookup@^5.0.3:
resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
-cacheable-request@^6.0.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
- integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
- dependencies:
- clone-response "^1.0.2"
- get-stream "^5.1.0"
- http-cache-semantics "^4.0.0"
- keyv "^3.0.0"
- lowercase-keys "^2.0.0"
- normalize-url "^4.1.0"
- responselike "^1.0.2"
-
cacheable-request@^7.0.2:
version "7.0.2"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27"
@@ -3610,7 +3545,7 @@ commondir@^1.0.1:
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
-component-emitter@^1.2.0, component-emitter@^1.2.1:
+component-emitter@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
@@ -3696,11 +3631,6 @@ cookie@^0.3.1:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
-cookiejar@^2.1.0:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c"
- integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==
-
copy-descriptor@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
@@ -3917,11 +3847,6 @@ data-urls@^4.0.0:
whatwg-mimetype "^3.0.0"
whatwg-url "^12.0.0"
-date-fns@2.22.1:
- version "2.22.1"
- resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.22.1.tgz#1e5af959831ebb1d82992bf67b765052d8f0efc4"
- integrity sha512-yUFPQjrxEmIsMqlHhAhmxkuH769baF21Kk+nZwZGyrMoyLA+LugaQtC0+Tqf9CBUUULWwUJt6Q5ySI3LJDDCGg==
-
dateformat@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
@@ -3946,7 +3871,7 @@ debug@4, debug@^4.0.1, debug@~4.1.1:
dependencies:
ms "^2.1.1"
-debug@^3.1.0, debug@^3.2.6:
+debug@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
@@ -3970,13 +3895,6 @@ decode-uri-component@^0.2.0:
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
-decompress-response@^3.3.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
- integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
- dependencies:
- mimic-response "^1.0.0"
-
decompress-response@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
@@ -4016,11 +3934,6 @@ deepmerge@^4.2.2:
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.0.tgz#65491893ec47756d44719ae520e0e2609233b59b"
integrity sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==
-defer-to-connect@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.0.2.tgz#4bae758a314b034ae33902b5aac25a8dd6a8633e"
- integrity sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw==
-
defer-to-connect@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
@@ -4417,7 +4330,7 @@ error-stack-parser@^2.0.1:
dependencies:
stackframe "^1.0.4"
-es-abstract@^1.12.0, es-abstract@^1.4.3, es-abstract@^1.5.1, es-abstract@^1.7.0:
+es-abstract@^1.12.0, es-abstract@^1.5.1, es-abstract@^1.7.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9"
integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==
@@ -4883,7 +4796,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
assign-symbols "^1.0.0"
is-extendable "^1.0.1"
-extend@^3.0.0, extend@~3.0.2:
+extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
@@ -5090,15 +5003,6 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
-form-data@^2.3.1:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.0.tgz#094ec359dc4b55e7d62e0db4acd76e89fe874d37"
- integrity sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA==
- dependencies:
- asynckit "^0.4.0"
- combined-stream "^1.0.6"
- mime-types "^2.1.12"
-
form-data@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
@@ -5126,11 +5030,6 @@ form-data@~2.3.2:
combined-stream "^1.0.6"
mime-types "^2.1.12"
-formidable@^1.2.0:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.1.tgz#70fb7ca0290ee6ff961090415f4b3df3d2082659"
- integrity sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==
-
forwarded@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
@@ -5202,7 +5101,7 @@ fsevents@~2.1.1:
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805"
integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==
-function-bind@^1.0.2, function-bind@^1.1.1:
+function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
@@ -5270,7 +5169,7 @@ get-stream@^3.0.0:
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
-get-stream@^4.0.0, get-stream@^4.1.0:
+get-stream@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
@@ -5426,23 +5325,6 @@ got@~11.8.0, got@~11.8.5, got@~11.8.6:
p-cancelable "^2.0.0"
responselike "^2.0.0"
-got@~9.6.0:
- version "9.6.0"
- resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
- integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
- dependencies:
- "@sindresorhus/is" "^0.14.0"
- "@szmarczak/http-timer" "^1.1.2"
- cacheable-request "^6.0.0"
- decompress-response "^3.3.0"
- duplexer3 "^0.1.4"
- get-stream "^4.1.0"
- lowercase-keys "^1.0.1"
- mimic-response "^1.0.1"
- p-cancelable "^1.0.0"
- to-readable-stream "^1.0.0"
- url-parse-lax "^3.0.0"
-
graceful-fs@^4.1.11, graceful-fs@^4.1.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
@@ -5467,16 +5349,6 @@ graphql-auth-directives@^2.1.0:
graphql-tools "^4.0.4"
jsonwebtoken "^8.3.0"
-graphql-custom-directives@~0.2.14:
- version "0.2.14"
- resolved "https://registry.yarnpkg.com/graphql-custom-directives/-/graphql-custom-directives-0.2.14.tgz#88611b8cb074477020ad85af47bfe168c4c23992"
- integrity sha512-c3+r+st7dbBNGOLumkWrnv4nwAHJr1sZnkYc72AIMtzjuQ4+Slk1ZsFVYt1kwXJpfxXgf6g2g0jYc9+Lmz4ENg==
- dependencies:
- libphonenumber-js "^1.6.4"
- lodash "^4.17.5"
- moment "^2.22.2"
- numeral "^2.0.6"
-
graphql-extensions@^0.12.6:
version "0.12.6"
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.12.6.tgz#c66be43035662a8cfb0b8efe9df96595338bd13c"
@@ -5486,11 +5358,6 @@ graphql-extensions@^0.12.6:
apollo-server-env "^2.4.5"
apollo-server-types "^0.6.1"
-graphql-iso-date@~3.6.1:
- version "3.6.1"
- resolved "https://registry.yarnpkg.com/graphql-iso-date/-/graphql-iso-date-3.6.1.tgz#bd2d0dc886e0f954cbbbc496bbf1d480b57ffa96"
- integrity sha512-AwFGIuYMJQXOEAgRlJlFL4H1ncFM8n8XmoVDTNypNOZyQ8LFDG2ppMFlsS862BSTCDcSUfHp8PD3/uJhv7t59Q==
-
graphql-middleware-sentry@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/graphql-middleware-sentry/-/graphql-middleware-sentry-3.2.1.tgz#b5653d78903d655cf4212a602cfa6e26689cda07"
@@ -6919,21 +6786,11 @@ jsesc@~0.5.0:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
-json-buffer@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
- integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
-
json-buffer@3.0.1, json-buffer@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
-json-parse-better-errors@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
- integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
-
json-parse-even-better-errors@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
@@ -7007,13 +6864,6 @@ jws@^3.2.2:
jwa "^1.4.1"
safe-buffer "^5.0.1"
-keyv@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
- integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
- dependencies:
- json-buffer "3.0.0"
-
keyv@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254"
@@ -7089,14 +6939,6 @@ levn@^0.3.0, levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
-libphonenumber-js@^1.6.4:
- version "1.7.22"
- resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.7.22.tgz#e206e3c227ec47ff306f7405ac52c331911e1b35"
- integrity sha512-KCK4874gp640B+d1zjNi2ZiZ3ubEUPH/0B9AwcuhHDVAL6NdthxC8obbdhGlo7FcEpjFVwEMDoHRfi+lI8NM/g==
- dependencies:
- minimist "^1.2.0"
- xml2js "^0.4.17"
-
lines-and-columns@^1.1.6:
version "1.2.4"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
@@ -7121,16 +6963,6 @@ load-json-file@^2.0.0:
pify "^2.0.0"
strip-bom "^3.0.0"
-load-json-file@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
- integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs=
- dependencies:
- graceful-fs "^4.1.2"
- parse-json "^4.0.0"
- pify "^3.0.0"
- strip-bom "^3.0.0"
-
locate-path@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
@@ -7234,7 +7066,7 @@ lodash@4.17.15:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
-lodash@^4.15.0, lodash@^4.17.14, lodash@^4.17.5, lodash@~4.17.11, lodash@~4.17.14:
+lodash@^4.15.0, lodash@^4.17.14, lodash@~4.17.11, lodash@~4.17.14:
version "4.17.20"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
@@ -7273,7 +7105,7 @@ lower-case@^2.0.1:
dependencies:
tslib "^1.10.0"
-lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
+lowercase-keys@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
@@ -7388,11 +7220,6 @@ memoize-one@~6.0.0:
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
-memorystream@^0.3.1:
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
- integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI=
-
merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
@@ -7434,13 +7261,6 @@ metascraper-author@^5.33.5:
dependencies:
"@metascraper/helpers" "^5.33.5"
-metascraper-clearbit-logo@^5.3.0:
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/metascraper-clearbit-logo/-/metascraper-clearbit-logo-5.3.0.tgz#e4596dbaf35503635d585a705f4119c7eddc6773"
- integrity sha512-Vg9m8cj2yEIUDrRjvCORvf8vgq2HLsWLVqNnIactNUPJ+Lcly5Xcxh5TcmHYp5Qx5DtNUCoKlakomYHn8mOjqg==
- dependencies:
- got "~9.6.0"
-
metascraper-date@^5.33.5:
version "5.33.5"
resolved "https://registry.yarnpkg.com/metascraper-date/-/metascraper-date-5.33.5.tgz#fccd8f7b685e0f3bb152c86aa93ed03a96c3c834"
@@ -7545,7 +7365,7 @@ metascraper@^5.33.5:
lodash "~4.17.21"
whoops "~4.1.2"
-methods@^1.1.1, methods@^1.1.2, methods@~1.1.2:
+methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
@@ -7620,7 +7440,7 @@ mime-types@^2.1.26, mime-types@~2.1.22, mime-types@~2.1.24:
dependencies:
mime-db "1.43.0"
-mime@1.6.0, mime@^1.4.1:
+mime@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
@@ -7645,7 +7465,7 @@ mimic-fn@~3.1.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74"
integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==
-mimic-response@^1.0.0, mimic-response@^1.0.1:
+mimic-response@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
@@ -7794,11 +7614,6 @@ moment@2.21.0:
resolved "https://registry.yarnpkg.com/moment/-/moment-2.21.0.tgz#2a114b51d2a6ec9e6d83cf803f838a878d8a023a"
integrity sha512-TCZ36BjURTeFTM/CwRcViQlfkMvL1/vFISuNLO5GkcVm1+QHfbSiNqZuWeMFjj1/3+uAjXswgRk30j1kkLYJBQ==
-moment@^2.22.2:
- version "2.24.0"
- resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
- integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
-
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -8098,11 +7913,6 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
-normalize-url@^4.1.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.3.0.tgz#9c49e10fc1876aeb76dba88bf1b2b5d9fa57b2ee"
- integrity sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ==
-
normalize-url@^6.0.1, normalize-url@~6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
@@ -8126,21 +7936,6 @@ npm-packlist@^1.1.6:
ignore-walk "^3.0.1"
npm-bundled "^1.0.1"
-npm-run-all@~4.1.5:
- version "4.1.5"
- resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba"
- integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==
- dependencies:
- ansi-styles "^3.2.1"
- chalk "^2.4.1"
- cross-spawn "^6.0.5"
- memorystream "^0.3.1"
- minimatch "^3.0.4"
- pidtree "^0.3.0"
- read-pkg "^3.0.0"
- shell-quote "^1.6.1"
- string.prototype.padend "^3.0.0"
-
npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
@@ -8194,11 +7989,6 @@ 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=
-numeral@^2.0.6:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506"
- integrity sha1-StCAk21EPCVhrtnyGX7//iX05QY=
-
nwsapi@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.4.tgz#fd59d5e904e8e1f03c25a7d5a15cfa16c714a1e5"
@@ -8351,11 +8141,6 @@ osenv@^0.1.4:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
-p-cancelable@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
- integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
-
p-cancelable@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e"
@@ -8475,14 +8260,6 @@ parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"
-parse-json@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
- integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=
- dependencies:
- error-ex "^1.3.1"
- json-parse-better-errors "^1.0.1"
-
parse-json@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
@@ -8600,13 +8377,6 @@ path-type@^2.0.0:
dependencies:
pify "^2.0.0"
-path-type@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
- integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==
- dependencies:
- pify "^3.0.0"
-
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
@@ -8632,11 +8402,6 @@ picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
-pidtree@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.0.tgz#f6fada10fccc9f99bf50e90d0b23d72c9ebc2e6b"
- integrity sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg==
-
pify@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -8709,11 +8474,6 @@ prepend-http@^1.0.1:
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
-prepend-http@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
- integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
-
prettier-linter-helpers@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b"
@@ -8841,11 +8601,6 @@ qs@6.7.0:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
-qs@^6.5.1:
- version "6.8.0"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.8.0.tgz#87b763f0d37ca54200334cd57bb2ef8f68a1d081"
- integrity sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w==
-
qs@~6.5.2:
version "6.5.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
@@ -8954,16 +8709,7 @@ read-pkg@^2.0.0:
normalize-package-data "^2.3.2"
path-type "^2.0.0"
-read-pkg@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
- integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=
- dependencies:
- load-json-file "^4.0.0"
- normalize-package-data "^2.3.2"
- path-type "^3.0.0"
-
-readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.3.5:
+readable-stream@^2.0.2, readable-stream@^2.0.6:
version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
@@ -9165,23 +8911,7 @@ repeat-string@^1.5.2, repeat-string@^1.6.1:
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
-request-promise-core@1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9"
- integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==
- dependencies:
- lodash "^4.17.15"
-
-request-promise-native@^1.0.8:
- version "1.0.8"
- resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36"
- integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==
- dependencies:
- request-promise-core "1.1.3"
- stealthy-require "^1.1.1"
- tough-cookie "^2.3.3"
-
-request@^2.88.0, request@~2.88.2:
+request@~2.88.2:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
@@ -9265,13 +8995,6 @@ resolve@^1.20.0, resolve@^1.3.2:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
-responselike@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
- integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
- dependencies:
- lowercase-keys "^1.0.0"
-
responselike@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723"
@@ -9350,7 +9073,7 @@ run-parallel@^1.1.9:
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679"
integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==
-rxjs@^6.4.0, rxjs@^6.5.4:
+rxjs@^6.4.0:
version "6.5.4"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c"
integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==
@@ -9569,11 +9292,6 @@ shebang-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
-shell-quote@^1.6.1:
- version "1.7.1"
- resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.1.tgz#3161d969886fb14f9140c65245a5dd19b6f0b06b"
- integrity sha512-2kUqeAGnMAu6YrTPX4E3LfxacH9gKljzVjlkUeSqY0soGwK4KLl7TURXCem712tkhBCeeaFP9QK4dKn88s3Icg==
-
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7:
version "3.0.7"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
@@ -9848,11 +9566,6 @@ static-extend@^0.1.1:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
-stealthy-require@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
- integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==
-
streamsearch@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
@@ -9906,15 +9619,6 @@ string-width@^3.0.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
-string.prototype.padend@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0"
- integrity sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=
- dependencies:
- define-properties "^1.1.2"
- es-abstract "^1.4.3"
- function-bind "^1.0.2"
-
string.prototype.trimend@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913"
@@ -10035,30 +9739,6 @@ subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.16, subscrip
symbol-observable "^1.0.4"
ws "^5.2.0 || ^6.0.0 || ^7.0.0"
-superagent@^3.8.3:
- version "3.8.3"
- resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.3.tgz#460ea0dbdb7d5b11bc4f78deba565f86a178e128"
- integrity sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==
- dependencies:
- component-emitter "^1.2.0"
- cookiejar "^2.1.0"
- debug "^3.1.0"
- extend "^3.0.0"
- form-data "^2.3.1"
- formidable "^1.2.0"
- methods "^1.1.1"
- mime "^1.4.1"
- qs "^6.5.1"
- readable-stream "^2.3.5"
-
-supertest@~4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/supertest/-/supertest-4.0.2.tgz#c2234dbdd6dc79b6f15b99c8d6577b90e4ce3f36"
- integrity sha512-1BAbvrOZsGA3YTCWqbmh14L0YEq0EGICX/nBnfkfVJn7SrxQV1I3pMYjSzG9y/7ZU2V9dWqyqk2POwxlb09duQ==
- dependencies:
- methods "^1.1.2"
- superagent "^3.8.3"
-
supports-color@^4.0.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
@@ -10263,11 +9943,6 @@ to-object-path@^0.3.0:
dependencies:
kind-of "^3.0.2"
-to-readable-stream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
- integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
-
to-regex-range@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38"
@@ -10310,14 +9985,6 @@ touch@^3.1.0:
dependencies:
nopt "~1.0.10"
-tough-cookie@^2.3.3, tough-cookie@~2.5.0:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
- integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
- dependencies:
- psl "^1.1.28"
- punycode "^2.1.1"
-
tough-cookie@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874"
@@ -10328,6 +9995,14 @@ tough-cookie@^4.1.2:
universalify "^0.2.0"
url-parse "^1.5.3"
+tough-cookie@~2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
+ integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
+ dependencies:
+ psl "^1.1.28"
+ punycode "^2.1.1"
+
tr46@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-4.1.1.tgz#281a758dcc82aeb4fe38c7dfe4d11a395aac8469"
@@ -10598,13 +10273,6 @@ url-parse-lax@^1.0.0:
dependencies:
prepend-http "^1.0.1"
-url-parse-lax@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
- integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
- dependencies:
- prepend-http "^2.0.0"
-
url-parse@^1.5.3:
version "1.5.10"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
@@ -10759,18 +10427,6 @@ w3c-xmlserializer@^4.0.0:
dependencies:
xml-name-validator "^4.0.0"
-wait-on@~4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-4.0.1.tgz#c49ca18b1ea60580404feed9df76ab3af2425a56"
- integrity sha512-x83fmTH2X0KL7vXoGt9aV5x4SMCvO8A/NbwWpaYYh4NJ16d3KSgbHwBy9dVdHj0B30cEhOFRvDob4fnpUmZxvA==
- dependencies:
- "@hapi/joi" "^17.1.0"
- lodash "^4.17.15"
- minimist "^1.2.0"
- request "^2.88.0"
- request-promise-native "^1.0.8"
- rxjs "^6.5.4"
-
walker@^1.0.7, walker@^1.0.8, walker@~1.0.5:
version "1.0.8"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f"
@@ -10926,7 +10582,7 @@ xml-name-validator@^4.0.0:
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835"
integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==
-xml2js@0.4.19, xml2js@^0.4.17:
+xml2js@0.4.19:
version "0.4.19"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==
diff --git a/package.json b/package.json
index a1a6336df..bc2cdfd62 100644
--- a/package.json
+++ b/package.json
@@ -25,10 +25,9 @@
"@babel/core": "^7.21.8",
"@babel/preset-env": "^7.21.5",
"@babel/register": "^7.12.10",
- "@faker-js/faker": "5.1.0",
+ "@faker-js/faker": "7.6.0",
"auto-changelog": "^2.3.0",
"bcryptjs": "^2.4.3",
- "codecov": "^3.8.2",
"cross-env": "^7.0.3",
"cucumber": "^6.0.5",
"cypress": "^7.0.1",
@@ -43,13 +42,12 @@
"mock-socket": "^9.0.3",
"neo4j-driver": "^4.3.4",
"neode": "^0.4.8",
- "npm-run-all": "^4.1.5",
"rosie": "^2.1.0",
- "slug": "^6.0.0"
+ "slug": "^6.0.0",
+ "wait-on": "^7.0.1"
},
"resolutions": {
"set-value": "^2.0.1",
"nan": "2.17.0"
- },
- "dependencies": {}
+ }
}
diff --git a/webapp/.eslintignore b/webapp/.eslintignore
index be90fc8e3..a90a66efa 100644
--- a/webapp/.eslintignore
+++ b/webapp/.eslintignore
@@ -1,5 +1,5 @@
node_modules
-build
+dist
.nuxt
styleguide/
**/*.min.js
diff --git a/webapp/assets/_new/icons/svgs/book.svg b/webapp/assets/_new/icons/svgs/book.svg
new file mode 100644
index 000000000..305e367ac
--- /dev/null
+++ b/webapp/assets/_new/icons/svgs/book.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/webapp/assets/_new/icons/svgs/calendar.svg b/webapp/assets/_new/icons/svgs/calendar.svg
new file mode 100644
index 000000000..5a67a8299
--- /dev/null
+++ b/webapp/assets/_new/icons/svgs/calendar.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/webapp/components/ContributionForm/ContributionForm.spec.js b/webapp/components/ContributionForm/ContributionForm.spec.js
index ef3b47c37..6b9db448b 100644
--- a/webapp/components/ContributionForm/ContributionForm.spec.js
+++ b/webapp/components/ContributionForm/ContributionForm.spec.js
@@ -15,6 +15,7 @@ const stubs = {
'client-only': true,
'nuxt-link': true,
'v-popover': true,
+ 'date-picker': true,
}
describe('ContributionForm.vue', () => {
@@ -45,6 +46,7 @@ describe('ContributionForm.vue', () => {
slug: 'this-is-a-title-for-a-post',
content: postContent,
contentExcerpt: postContent,
+ postType: ['Article'],
},
},
}),
@@ -142,6 +144,7 @@ describe('ContributionForm.vue', () => {
id: null,
image: null,
groupId: null,
+ postType: 'Article',
},
}
postTitleInput = wrapper.find('.ds-input')
@@ -268,6 +271,7 @@ describe('ContributionForm.vue', () => {
image: {
sensitive: false,
},
+ postType: 'Article',
},
}
})
diff --git a/webapp/components/ContributionForm/ContributionForm.vue b/webapp/components/ContributionForm/ContributionForm.vue
index f740e1f05..997a25341 100644
--- a/webapp/components/ContributionForm/ContributionForm.vue
+++ b/webapp/components/ContributionForm/ContributionForm.vue
@@ -30,6 +30,7 @@