From 5fcceda30f12af2b585d61edc7dc7902d8ca3487 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 5 Oct 2018 13:31:45 +0200 Subject: [PATCH 001/554] initial commit --- .babelrc | 1 + .env | 6 + .gitignore | 1 + .graphqlconfig | 3 + README.md | 93 + package.json | 32 + src/graphql-schema.js | 17 + src/index.js | 64 + src/schema.graphql | 107 ++ src/seed/seed-db.js | 21 + src/seed/seed-mutations.js | 321 ++++ yarn.lock | 3366 ++++++++++++++++++++++++++++++++++++ 12 files changed, 4032 insertions(+) create mode 100644 .babelrc create mode 100644 .env create mode 100644 .gitignore create mode 100644 .graphqlconfig create mode 100644 README.md create mode 100644 package.json create mode 100644 src/graphql-schema.js create mode 100644 src/index.js create mode 100644 src/schema.graphql create mode 100644 src/seed/seed-db.js create mode 100644 src/seed/seed-mutations.js create mode 100644 yarn.lock diff --git a/.babelrc b/.babelrc new file mode 100644 index 000000000..684fff677 --- /dev/null +++ b/.babelrc @@ -0,0 +1 @@ +{ "presets": ["env"] } diff --git a/.env b/.env new file mode 100644 index 000000000..4d849a121 --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +NEO4J_URI=bolt://localhost:7687 +NEO4J_USER=neo4j +NEO4J_PASSWORD=letmein +GRAPHQL_LISTEN_PORT=4000 +GRAPHQL_URI=http://localhost:4000 +MOCK=false diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..c2658d7d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/.graphqlconfig b/.graphqlconfig new file mode 100644 index 000000000..ca328bc83 --- /dev/null +++ b/.graphqlconfig @@ -0,0 +1,3 @@ +{ + "schemaPath": "./src/schema.graphql" +} diff --git a/README.md b/README.md new file mode 100644 index 000000000..7ab257aeb --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# Human-Connection - GraphQL API - Prototype + +> This Prototype tries to resolve the biggest hurdle of connecting +> our services together. This is not possible in a sane way using +> our current approach. +> +> With this Prototype we can explore using the combination of +> GraphQL and the Neo4j Graph Database for achieving the connected +> nature of a social graph with better development experience as we +> do not need to connect data by our own any more through weird table +> structures etc. + +> +> #### Advantages: +> - easer data structure +> - better connected data +> - easy to achieve "recommendations" based on actions (relations) +> - more performant and better to understand API +> - better API client that uses caching +> +> We still need to evaluate the drawbacks and estimate the development +> cost of such an approach + +## Quick Start + +Install dependencies: + +```bash +yarn install +# -or- +npm install +``` + +Start the GraphQL service: + +```bash +yarn start +# -or- +npm start +``` + +This will start the GraphQL service (by default on localhost:4000) +where you can issue GraphQL requests or access GraphQL Playground in the browser: + +![GraphQL Playground](img/graphql-playground.png) + +## Configure + +Set your Neo4j connection string and credentials in `.env`. +For example: + +_.env_ + +```yaml +NEO4J_URI=bolt://localhost:7687 +NEO4J_USER=neo4j +NEO4J_PASSWORD=letmein +``` + +Note that grand-stack-starter does not currently bundle a distribution +of Neo4j. You can download [Neo4j Desktop](https://neo4j.com/download/) +and run locally for development, spin up a [hosted Neo4j Sandbox instance](https://neo4j.com/download/), +run Neo4j in one of the [many cloud options](https://neo4j.com/developer/guide-cloud-deployment/), +or [spin up Neo4j in a Docker container](https://neo4j.com/developer/docker/). +Just be sure to update the Neo4j connection string and credentials accordingly in `.env`. + +## Deployment + +You can deploy to any service that hosts Node.js apps, but [Zeit Now](https://zeit.co/now) +is a great easy to use service for hosting your app that has an easy to use free plan for small projects. + +To deploy your GraphQL service on Zeit Now, first install [Now Desktop](https://zeit.co/download) - +you'll need to provide an email address. Then run + +``` +now +``` + +to deploy your GraphQL service on Zeit Now. Once deployed you'll be given +a fresh URL that represents the current state of your application where you +can access your GraphQL endpoint and GraphQL Playgound. +For example: https://hc-graph-api-prototype-sdga96ad7.now.sh/ + +## Seeding The Database + +Optionally you can seed the GraphQL service by executing mutations that +will write sample data to the database: + +```bash +yarn seedDb +# -or- +npm run seedDb +``` diff --git a/package.json b/package.json new file mode 100644 index 000000000..75707f466 --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name": "hc-graph-api-prototype", + "version": "0.0.1", + "description": "Graph API Protype for Human Connection", + "main": "src/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", + "seedDb": "./node_modules/.bin/babel-node src/seed/seed-db.js" + }, + "author": "Grzegorz Leoniec", + "license": "MIT", + "dependencies": { + "apollo-boost": "^0.1.10", + "apollo-cache-inmemory": "^1.2.5", + "apollo-client": "^2.3.2", + "apollo-link-http": "^1.5.4", + "apollo-server": "^2.0.4", + "dotenv": "^6.0.0", + "faker": "^4.1.0", + "graphql-custom-directives": "^0.2.13", + "graphql-tag": "^2.9.2", + "neo4j-driver": "^1.6.1", + "neo4j-graphql-js": "^1.0.2", + "node-fetch": "^2.1.2" + }, + "devDependencies": { + "babel-cli": "^6.26.0", + "babel-preset-env": "^1.7.0", + "nodemon": "^1.17.5" + } +} diff --git a/src/graphql-schema.js b/src/graphql-schema.js new file mode 100644 index 000000000..3a0c954cb --- /dev/null +++ b/src/graphql-schema.js @@ -0,0 +1,17 @@ +// import { neo4jgraphql } from "neo4j-graphql-js" +import fs from 'fs' +import path from 'path' + +export const typeDefs = + fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, "schema.graphql")) + .toString('utf-8') + +export const resolvers = { + // Query: { + // usersBySubstring: neo4jgraphql + // } +} + +export const mutations = { + +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 000000000..7242b6661 --- /dev/null +++ b/src/index.js @@ -0,0 +1,64 @@ +// import { GraphQLServer } from 'graphql-yoga' +import { ApolloServer, makeExecutableSchema } from 'apollo-server' +import { augmentSchema } from 'neo4j-graphql-js' +import { typeDefs, resolvers } from './graphql-schema' +import { v1 as neo4j } from 'neo4j-driver' +import dotenv from 'dotenv' +import { + GraphQLLowerCaseDirective, + GraphQLTrimDirective, + GraphQLDefaultToDirective +} from 'graphql-custom-directives'; +import faker from 'faker' + +dotenv.config() + +const schema = makeExecutableSchema({ + typeDefs, + resolvers +}) + +// augmentSchema will add auto generated mutations based on types in schema +const augmentedSchema = augmentSchema(schema) + +// add custom directives +const directives = [ + GraphQLLowerCaseDirective, + GraphQLTrimDirective, + GraphQLDefaultToDirective +] +augmentedSchema._directives.push.apply(augmentedSchema._directives, directives) + +const driver = neo4j.driver( + process.env.NEO4J_URI || 'bolt://localhost:7687', + neo4j.auth.basic( + process.env.NEO4J_USER || 'neo4j', + process.env.NEO4J_PASSWORD || 'neo4j' + ) +) + +const MOCK = (process.env.MOCK === 'true') +console.log('MOCK:', MOCK) + +const server = new ApolloServer({ + context: { + driver + }, + tracing: true, + schema: augmentedSchema, + mocks: MOCK ? { + User: () => ({ + name: () => `${faker.name.firstName()} ${faker.name.lastName()}`, + email: () => `${faker.internet.email()}` + }), + Post: () => ({ + title: () => faker.lorem.lines(1), + slug: () => faker.lorem.slug(3), + content: () => faker.lorem.paragraphs(5), + contentExcerpt: () => faker.lorem.paragraphs(1) + }) + } : false +}) +server.listen().then(({ url }) => { + console.log(`Server ready at ${url} 🚀`); +}) diff --git a/src/schema.graphql b/src/schema.graphql new file mode 100644 index 000000000..da9436512 --- /dev/null +++ b/src/schema.graphql @@ -0,0 +1,107 @@ +enum VisibilityEnum { + Public + Friends + Private +} + +enum UserGroupEnum { + Admin + Moderator + User +} + +type WrittenPost @relation(name: "WROTE") { + from: User + to: Post + timestamp: Int +} +type WrittenComment @relation(name: "WROTE") { + from: User + to: Comment + timestamp: Int +} + +type User { + id: ID! + name: String! + email: String + disabled: Boolean @default(to: false) + role: UserGroupEnum + + friends: [User]! @relation(name: "FRIENDS", direction: "BOTH") + friendsCount: Int! @cypher(statement: "MATCH (this)<-[:FRIENDS]->(r:User) RETURN COUNT(r)") + + following: [User]! @relation(name: "FOLLOWING", direction: "OUT") + followingCount: Int! @cypher(statement: "MATCH (this)-[:FOLLOWING]->(r:User) RETURN COUNT(r)") + + followedBy: [User]! @relation(name: "FOLLOWING", direction: "IN") + followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWING]-(r:User) RETURN COUNT(r)") + + contributions: [WrittenPost]! + contributionsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Post) RETURN COUNT(r)") + + comments: [WrittenComment]! + commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) RETURN COUNT(r)") + + shouted: [Post]! @relation(name: "SHOUTED", direction: "OUT") + + organizationsCreated: [Organization] @relation(name: "CREATED_ORGA", direction: "OUT") + organizationsOwned: [Organization] @relation(name: "OWNING_ORGA", direction: "OUT") +} + +type Post { + id: ID! + author: WrittenPost + title: String! + slug: String! + content: String! + contentExcerpt: String! + visibility: VisibilityEnum + disabled: Boolean @default(to: false) + + tags: [Tag]! @relation(name: "TAGGED", direction: "OUT") + categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT") + + comments: [Comment]! @relation(name: "COMMENT", direction: "IN") + commentsCount: Int! @cypher(statement: "MATCH (this)<-[:COMMENT]-(r:Comment) RETURN COUNT(r)") + + shoutedBy: [User]! @relation(name: "SHOUTED", direction: "IN") + shoutedCount: Int! @cypher(statement: "MATCH (this)<-[:SHOUTED]-(r:User) RETURN COUNT(r)") +} + +type Comment { + id: ID! + author: WrittenComment + content: String! + contentExcerpt: String! + post: Post @relation(name: "COMMENT", direction: "OUT") + disabled: Boolean @default(to: false) +} + +type Category { + id: ID! + name: String! + slug: String! + icon: String! +} + +type Organization { + id: ID! + createdBy: User @relation(name: "CREATED_ORGA", direction: "IN") + ownedBy: [User] @relation(name: "OWNING_ORGA", direction: "IN") + name: String! + slug: String! + disabled: Boolean @default(to: false) + + tags: [Tag]! @relation(name: "TAGGED", direction: "OUT") + categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT") +} + +type Tag { + id: ID! + name: String! + taggedPosts: [Post]! @relation(name: "TAGGED", direction: "IN") + taggedOrganizations: [Organization]! @relation(name: "TAGGED", direction: "IN") + taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(r) RETURN COUNT(r)") + disabled: Boolean @default(to: false) +} diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js new file mode 100644 index 000000000..1fa478fd1 --- /dev/null +++ b/src/seed/seed-db.js @@ -0,0 +1,21 @@ +import ApolloClient from "apollo-client"; +import dotenv from "dotenv"; +import gql from 'graphql-tag' +import seedMutations from "./seed-mutations"; +import fetch from "node-fetch"; +import { HttpLink } from "apollo-link-http"; +import { InMemoryCache } from "apollo-cache-inmemory"; + +dotenv.config(); + +const client = new ApolloClient({ + link: new HttpLink({ uri: process.env.GRAPHQL_URI, fetch }), + cache: new InMemoryCache() +}); + +client + .mutate({ + mutation: gql(seedMutations) + }) + .then(data => console.log(data)) + .catch(error => console.error(error)); diff --git a/src/seed/seed-mutations.js b/src/seed/seed-mutations.js new file mode 100644 index 000000000..e7d9d1695 --- /dev/null +++ b/src/seed/seed-mutations.js @@ -0,0 +1,321 @@ +export default ` + mutation { + u1: CreateUser(id: "u1", name: "Will Blast", email: "Will-Blast@Yahoo.com", role: Admin) { + id + name + email + role + } + u2: CreateUser(id: "u2", name: "Bob der Bausmeister", email: "Bob-der-Bausmeister@yahoo.com", role: Moderator) { + id + name + email + role + } + u3: CreateUser(id: "u3", name: "Jenny Rostock", email: "JennyRostock@yahoo.com", role: Admin) { + id + name + email + role + } + u4: CreateUser(id: "u4", name: "Angie Banjie", email: "Angie_Banjie@yahoo.com", role: User) { + id + name + email + role + } + + cat1: CreateCategory( id: "cat1", name: "Just For Fun", slug: "justforfun", icon: "categories-justforfun" ) { name } + cat2: CreateCategory( id: "cat2", name: "Happyness & Values", slug: "happyness-values", icon: "categories-luck" ) { name } + cat3: CreateCategory( id: "cat3", name: "Health & Wellbeing", slug: "health-wellbeing", icon: "categories-health" ) { name } + cat4: CreateCategory( id: "cat4", name: "Environment & Nature", slug: "environment-nature", icon: "categories-environment" ) { name } + cat5: CreateCategory( id: "cat5", name: "Animal Protection", slug: "animalprotection", icon: "categories-animal-justice" ) { name } + cat6: CreateCategory( id: "cat6", name: "Humanrights Justice", slug: "humanrights-justice", icon: "categories-human-rights" ) { name } + cat7: CreateCategory( id: "cat7", name: "Education & Sciences", slug: "education-sciences", icon: "categories-education" ) { name } + cat8: CreateCategory( id: "cat8", name: "Cooperation & Development", slug: "cooperation-development", icon: "categories-cooperation" ) { name } + cat9: CreateCategory( id: "cat9", name: "Democracy & Politics", slug: "democracy-politics", icon: "categories-politics" ) { name } + cat10: CreateCategory( id: "cat10", name: "Economy & Finances", slug: "economy-finances", icon: "categories-economy" ) { name } + cat11: CreateCategory( id: "cat11", name: "Energy & Technology", slug: "energy-technology", icon: "categories-technology" ) { name } + cat12: CreateCategory( id: "cat12", name: "IT, Internet & Data Privacy", slug: "it-internet-dataprivacy", icon: "categories-internet" ) { name } + cat13: CreateCategory( id: "cat13", name: "Art, Curlure & Sport", slug: "art-culture-sport", icon: "categories-art" ) { name } + cat14: CreateCategory( id: "cat14", name: "Freedom of Speech", slug: "freedomofspeech", icon: "categories-freedom-of-speech" ) { name } + cat15: CreateCategory( id: "cat15", name: "Consumption & Sustainability", slug: "consumption-sustainability", icon: "categories-sustainability" ) { name } + cat16: CreateCategory( id: "cat16", name: "Global Peace & Nonviolence", slug: "globalpeace-nonviolence", icon: "categories-peace" ) { name } + + p1: CreatePost( + id: "p1", + title: "Gedanken eines Polizisten zum Einsatz im Hambacher Forst", + slug: "gedanken-eines-polizisten-zum-einsatz-im-hambacher-forst", + content: "# 1 This is my content 1", + contentExcerpt: "# 1 This is my content 1", + visibility: Public + ) { title } + p1_cat1: AddPostCategories(from: {id: "p1"}, to: {id: "cat1"}) { from { id } } + p1_cat2: AddPostCategories(from: {id: "p1"}, to: {id: "cat2"}) { from { id } } + + p2: CreatePost( + id: "p2", + title: "Julian Assange", + slug: "julian-assange", + content: "#2 This is my content 2", + contentExcerpt: "#2 This is my content 2", + visibility: Public + ) { title } + p2_cat1: AddPostCategories(from: {id: "p2"}, to: {id: "cat1"}) { from { id } } + p2_cat16: AddPostCategories(from: {id: "p2"}, to: {id: "cat16"}) { from { id } } + + p3: CreatePost( + id: "p3", + title: "Hacker, Freaks und Funktionäre...Der CCC", + slug: "hacker-freaks-und-funktionäre-der-ccc", + content: "#3 This is my content 3", + contentExcerpt: "#3 This is my content 3", + visibility: Public + ) { title } + p3_cat1: AddPostCategories(from: {id: "p3"}, to: {id: "cat1"}) { from { id } } + p3_cat3: AddPostCategories(from: {id: "p3"}, to: {id: "cat3"}) { from { id } } + p3_cat14: AddPostCategories(from: {id: "p3"}, to: {id: "cat14"}) { from { id } } + + p4: CreatePost( + id: "p4", + title: "Lebensmittel (?)", + slug: "lebensmittel", + content: "#4 This is my content 4", + contentExcerpt: "#4 This is my content 4", + visibility: Public + ) { title } + p4_cat1: AddPostCategories(from: {id: "p4"}, to: {id: "cat1"}) { from { id } } + p4_cat9: AddPostCategories(from: {id: "p4"}, to: {id: "cat9"}) { from { id } } + p4_cat4: AddPostCategories(from: {id: "p4"}, to: {id: "cat4"}) { from { id } } + + c1: CreateComment( + id: "c1", + content: "# 1 This is my comment 1", + contentExcerpt: "# 1 This is my..." + ) { id } + c2: CreateComment( + id: "c2", + content: "# 2 This is my comment 2", + contentExcerpt: "# 2 This is my..." + ) { id } + c3: CreateComment( + id: "c3", + content: "# 3 This is my comment 3", + contentExcerpt: "# 3 This is my..." + ) { id } + c4: CreateComment( + id: "c4", + content: "# 4 This is my comment 4", + contentExcerpt: "# 4 This is my..." + ) { id } + c5: CreateComment( + id: "c5", + content: "# 5 This is my comment 5", + contentExcerpt: "# 5 This is my..." + ) { id } + + c1_u1: AddCommentAuthor( + from: { id: "u1" }, + to: { id: "c1" }, + data: { timestamp: 1538655020 } + ) { from { id } } + c2_u1: AddCommentAuthor( + from: { id: "u1" }, + to: { id: "c2" }, + data: { timestamp: 1538655020 } + ) { from { id } } + c3_u2: AddCommentAuthor( + from: { id: "u2" }, + to: { id: "c3" }, + data: { timestamp: 1538655020 } + ) { from { id } } + c4_u3: AddCommentAuthor( + from: { id: "u3" }, + to: { id: "c4" }, + data: { timestamp: 1538655020 } + ) { from { id } } + c5_u4: AddCommentAuthor( + from: { id: "u4" }, + to: { id: "c5" }, + data: { timestamp: 1538655020 } + ) { from { id } } + + c1_p1: AddCommentPost( + from: { id: "c1" }, + to: { id: "p1" } + ) { from { id } } + c2_p1: AddCommentPost( + from: { id: "c2" }, + to: { id: "p1" } + ) { from { id } } + c3_p2: AddCommentPost( + from: { id: "c3" }, + to: { id: "p2" } + ) { from { id } } + c4_p3: AddCommentPost( + from: { id: "c4" }, + to: { id: "p3" } + ) { from { id } } + c5_p4: AddCommentPost( + from: { id: "c5" }, + to: { id: "p4" } + ) { from { id } } + + t1: CreateTag( + id: "t1", + name: "Umwelt" + ) { name } + t2: CreateTag( + id: "t2", + name: "Naturschutz" + ) { name } + t3: CreateTag( + id: "t3", + name: "Demokratie" + ) { name } + t4: CreateTag( + id: "t4", + name: "Freiheit" + ) { name } + + p1_t1: AddPostTags( + from: { id: "p1" } + to: { id: "t1" } + ) { from { id } } + p1_t2: AddPostTags( + from: { id: "p1" } + to: { id: "t2" } + ) { from { id } } + p1_t3: AddPostTags( + from: { id: "p1" } + to: { id: "t3" } + ) { from { id } } + p2_t4: AddPostTags( + from: { id: "p2" } + to: { id: "t4" } + ) { from { id } } + p3_t2: AddPostTags( + from: { id: "p3" } + to: { id: "t2" } + ) { from { id } } + p3_t4: AddPostTags( + from: { id: "p3" } + to: { id: "t4" } + ) { from { id } } + + o1: CreateOrganization( + id: "o1", + name: "Democracy Deutschland", + slug: "democracy-deutschland" + ) { name } + o2: CreateOrganization( + id: "o2", + name: "Human-Connection", + slug: "human-connection" + ) { name } + o3: CreateOrganization( + id: "o3", + name: "Pro Veg", + slug: "pro-veg" + ) { name } + o4: CreateOrganization( + id: "o4", + name: "Greenpeace", + slug: "greenpeace" + ) { name } + + u1_c_o1: AddOrganizationCreatedBy( + from: { id: "u1" }, + to: { id: "o1" } + ) { from { id } } + u1_c_o2: AddOrganizationCreatedBy( + from: { id: "u1" }, + to: { id: "o2" } + ) { from { id } } + + u2_o_o1: AddOrganizationOwnedBy( + from: { id: "u2" }, + to: { id: "o2" } + ) { from { id } } + u2_c_o3: AddOrganizationOwnedBy( + from: { id: "u2" }, + to: { id: "o3" } + ) { from { id } } + + u1_friends_u2: AddUserFriends( + from: { id: "u1" }, + to: { id: "u2" } + ) { from { id } } + u1_friends_u3: AddUserFriends( + from: { id: "u1" }, + to: { id: "u3" } + ) { from { id } } + + u1_follow_u2: AddUserFollowing( + from: { id: "u1" }, + to: { id: "u2" } + ) { from { id } } + u2_follow_u1: AddUserFollowing( + from: { id: "u2" }, + to: { id: "u1" } + ) { from { id } } + u2_follow_u3: AddUserFollowing( + from: { id: "u2" }, + to: { id: "u3" } + ) { from { id } } + u2_follow_u4: AddUserFollowing( + from: { id: "u2" }, + to: { id: "u4" } + ) { from { id } } + u4_follow_u2: AddUserFollowing( + from: { id: "u4" }, + to: { id: "u2" } + ) { from { id } } + + ur1: AddUserContributions( + from: { id: "u1" }, + to: { id: "p1" }, + data: { timestamp: 1538655020 } + ) { from { id } } + ur2: AddUserContributions( + from: { id: "u2" }, + to: { id: "p2" }, + data: { timestamp: 1538655120 } + ) { from { id } } + ur3: AddUserContributions( + from: { id: "u3" }, + to: { id: "p3" }, + data: { timestamp: 1538653120 } + ) { from { id } } + ur4: AddUserContributions( + from: { id: "u4" }, + to: { id: "p4" }, + data: { timestamp: 1538615120 } + ) { from { id } } + + u1s2: AddUserShouted( + from: { id: "u1" }, + to: { id: "p2" } + ) { from { id } } + u1s3: AddUserShouted( + from: { id: "u1" }, + to: { id: "p3" } + ) { from { id } } + u2s1: AddUserShouted( + from: { id: "u2" }, + to: { id: "p1" } + ) { from { id } } + u3s1: AddUserShouted( + from: { id: "u3" }, + to: { id: "p1" } + ) { from { id } } + u3s4: AddUserShouted( + from: { id: "u3" }, + to: { id: "p4" } + ) { from { id } } + u4s1: AddUserShouted( + from: { id: "u4" }, + to: { id: "p1" } + ) { from { id } } + } +` diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..5c38ee36e --- /dev/null +++ b/yarn.lock @@ -0,0 +1,3366 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@apollographql/apollo-upload-server@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" + dependencies: + "@babel/runtime-corejs2" "^7.0.0-rc.1" + busboy "^0.2.14" + object-path "^0.11.4" + +"@apollographql/graphql-playground-html@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz#15e1a042b97d6834e6d70b17cc73e1514fde9027" + +"@babel/runtime-corejs2@^7.0.0-rc.1": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.1.2.tgz#8695811a3fd8091f54f274b9320334e5e8c62200" + dependencies: + core-js "^2.5.7" + regenerator-runtime "^0.12.0" + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + +"@types/accepts@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" + dependencies: + "@types/node" "*" + +"@types/async@2.0.49": + version "2.0.49" + resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0" + +"@types/body-parser@*", "@types/body-parser@1.17.0": + version "1.17.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.32" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" + dependencies: + "@types/node" "*" + +"@types/cors@^2.8.4": + version "2.8.4" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.4.tgz#50991a759a29c0b89492751008c6af7a7c8267b0" + dependencies: + "@types/express" "*" + +"@types/events@*": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" + +"@types/express-serve-static-core@*": + version "4.16.0" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz#fdfe777594ddc1fe8eb8eccce52e261b496e43e7" + dependencies: + "@types/events" "*" + "@types/node" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@4.16.0": + version "4.16.0" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.0.tgz#6d8bc42ccaa6f35cf29a2b7c3333cb47b5a32a19" + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/serve-static" "*" + +"@types/long@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" + +"@types/mime@*": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" + +"@types/node@*", "@types/node@^10.1.0": + version "10.11.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.4.tgz#e8bd933c3f78795d580ae41d86590bfc1f4f389d" + +"@types/range-parser@*": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.2.tgz#fa8e1ad1d474688a757140c91de6dace6f4abc8d" + +"@types/serve-static@*": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48" + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + +"@types/ws@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-5.1.2.tgz#f02d3b1cd46db7686734f3ce83bdf46c49decd64" + dependencies: + "@types/events" "*" + "@types/node" "*" + +"@types/zen-observable@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +accepts@^1.3.5, accepts@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + dependencies: + string-width "^2.0.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +apollo-boost@^0.1.10: + version "0.1.16" + resolved "https://registry.yarnpkg.com/apollo-boost/-/apollo-boost-0.1.16.tgz#77f73a30c49ab6d749ddc3e5683a7e322c15f07d" + dependencies: + apollo-cache "^1.1.17" + apollo-cache-inmemory "^1.2.10" + apollo-client "^2.4.2" + apollo-link "^1.0.6" + apollo-link-error "^1.0.3" + apollo-link-http "^1.3.1" + apollo-link-state "^0.4.0" + graphql-tag "^2.4.2" + +apollo-cache-control@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.2.5.tgz#0831ad796754a7beec858668f99e7517fe744a1e" + dependencies: + apollo-server-env "^2.0.3" + graphql-extensions "^0.2.1" + +apollo-cache-inmemory@^1.2.10, apollo-cache-inmemory@^1.2.5: + version "1.2.10" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.2.10.tgz#362d6c36cfd815a309b966f71e5d2b6c770c7989" + dependencies: + apollo-cache "^1.1.17" + apollo-utilities "^1.0.21" + graphql-anywhere "^4.1.19" + +apollo-cache@1.1.17, apollo-cache@^1.1.17: + version "1.1.17" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.17.tgz#1fcca8423125223723b97fd72808be91a1a76490" + dependencies: + apollo-utilities "^1.0.21" + +apollo-client@^2.3.2, apollo-client@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.2.tgz#d2f044d8740723bf98a6d8d8b9684ee8c36150e6" + dependencies: + "@types/zen-observable" "^0.8.0" + apollo-cache "1.1.17" + apollo-link "^1.0.0" + apollo-link-dedup "^1.0.0" + apollo-utilities "1.0.21" + symbol-observable "^1.0.2" + zen-observable "^0.8.0" + optionalDependencies: + "@types/async" "2.0.49" + +apollo-datasource@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.1.3.tgz#e7ae9d20f29a8a35f239b02f0c47169cfd78d70b" + dependencies: + apollo-server-caching "0.1.2" + apollo-server-env "2.0.3" + +apollo-engine-reporting-protobuf@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz#cd394f0f769c6f97d8621c4a7839095c84efcdb0" + dependencies: + protobufjs "^6.8.6" + +apollo-engine-reporting@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.0.6.tgz#c1a74dffce782525f8a3230e4e5228fbd05bbd59" + dependencies: + apollo-engine-reporting-protobuf "^0.0.1" + apollo-server-env "^2.0.3" + async-retry "^1.2.1" + graphql-extensions "^0.2.1" + lodash "^4.17.10" + +apollo-link-dedup@^1.0.0: + version "1.0.10" + resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.10.tgz#7b94589fe7f969777efd18a129043c78430800ae" + dependencies: + apollo-link "^1.2.3" + +apollo-link-error@^1.0.3: + version "1.1.1" + resolved "https://registry.yarnpkg.com/apollo-link-error/-/apollo-link-error-1.1.1.tgz#69d7124d4dc11ce60f505c940f05d4f1aa0945fb" + dependencies: + apollo-link "^1.2.3" + +apollo-link-http-common@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.5.tgz#d094beb7971523203359bf830bfbfa7b4e7c30ed" + dependencies: + apollo-link "^1.2.3" + +apollo-link-http@^1.3.1, apollo-link-http@^1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.5.tgz#7dbe851821771ad67fa29e3900c57f38cbd80da8" + dependencies: + apollo-link "^1.2.3" + apollo-link-http-common "^0.2.5" + +apollo-link-state@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/apollo-link-state/-/apollo-link-state-0.4.2.tgz#ac00e9be9b0ca89eae0be6ba31fe904b80bbe2e8" + dependencies: + apollo-utilities "^1.0.8" + graphql-anywhere "^4.1.0-alpha.0" + +apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.2, apollo-link@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.3.tgz#9bd8d5fe1d88d31dc91dae9ecc22474d451fb70d" + dependencies: + apollo-utilities "^1.0.0" + zen-observable-ts "^0.8.10" + +apollo-server-caching@0.1.2, apollo-server-caching@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.1.2.tgz#f5b85701945110a5fca1956450e8553576635936" + dependencies: + lru-cache "^4.1.3" + +apollo-server-core@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.1.0.tgz#b56f9f1ddb948b257e738eb25c5fdfd2f2fb2e07" + dependencies: + "@apollographql/apollo-upload-server" "^5.0.3" + "@types/ws" "^5.1.2" + apollo-cache-control "^0.2.5" + apollo-datasource "^0.1.3" + apollo-engine-reporting "^0.0.6" + apollo-server-caching "^0.1.2" + apollo-server-env "^2.0.3" + apollo-server-errors "^2.0.2" + apollo-tracing "^0.2.5" + graphql-extensions "^0.2.1" + graphql-subscriptions "^0.5.8" + graphql-tag "^2.9.2" + graphql-tools "^3.0.4" + hash.js "^1.1.3" + lodash "^4.17.10" + subscriptions-transport-ws "^0.9.11" + ws "^5.2.0" + +apollo-server-env@2.0.3, apollo-server-env@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.0.3.tgz#3c13552cd33f400160076cf8e1c9b24be4d27e13" + dependencies: + node-fetch "^2.1.2" + util.promisify "^1.0.0" + +apollo-server-errors@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz#e9cbb1b74d2cd78aed23cd886ca2d0c186323b2b" + +apollo-server-express@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.1.0.tgz#b2d423c2c934df5c4e0a1b0d5f0088a9461f3c86" + dependencies: + "@apollographql/apollo-upload-server" "^5.0.3" + "@apollographql/graphql-playground-html" "^1.6.0" + "@types/accepts" "^1.3.5" + "@types/body-parser" "1.17.0" + "@types/cors" "^2.8.4" + "@types/express" "4.16.0" + accepts "^1.3.5" + apollo-server-core "^2.1.0" + body-parser "^1.18.3" + cors "^2.8.4" + graphql-subscriptions "^0.5.8" + graphql-tools "^3.0.4" + type-is "^1.6.16" + +apollo-server@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.1.0.tgz#abec7853647c59f386087352cc7f06a4f1f8afe2" + dependencies: + apollo-server-core "^2.1.0" + apollo-server-express "^2.1.0" + express "^4.0.0" + graphql-subscriptions "^0.5.8" + graphql-tools "^3.0.4" + +apollo-tracing@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.2.5.tgz#15bb8d6f37efe8c1bb6351e8e21521dd4f14c5f2" + dependencies: + apollo-server-env "^2.0.3" + graphql-extensions "^0.2.1" + +apollo-utilities@1.0.21, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.21, apollo-utilities@^1.0.8: + version "1.0.21" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.21.tgz#cb8b5779fe275850b16046ff8373f4af2de90765" + dependencies: + fast-json-stable-stringify "^2.0.0" + fclone "^1.0.11" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + +async-retry@^1.2.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.2.3.tgz#a6521f338358d322b1a0012b79030c6f411d1ce0" + dependencies: + retry "0.12.0" + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + +babel-cli@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" + dependencies: + babel-core "^6.26.0" + babel-polyfill "^6.26.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + commander "^2.11.0" + convert-source-map "^1.5.0" + fs-readdir-recursive "^1.0.0" + glob "^7.1.2" + lodash "^4.17.4" + output-file-sync "^1.1.2" + path-is-absolute "^1.0.1" + slash "^1.0.0" + source-map "^0.5.6" + v8flags "^2.1.1" + optionalDependencies: + chokidar "^1.6.1" + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +babel-preset-env@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + +backo2@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +binary-extensions@^1.0.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" + +body-parser@1.18.2: + version "1.18.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.1" + http-errors "~1.6.2" + iconv-lite "0.4.19" + on-finished "~2.3.0" + qs "6.5.1" + raw-body "2.3.2" + type-is "~1.6.15" + +body-parser@^1.18.3: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" + on-finished "~2.3.0" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" + +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.0, braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + +busboy@^0.2.14: + version "0.2.14" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" + dependencies: + dicer "0.2.5" + readable-stream "1.1.x" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +camelcase@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +caniuse-lite@^1.0.30000844: + version "1.0.30000889" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000889.tgz#53e266c83e725ad3bd2e4a3ea76d5031a8aa4c3e" + +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + +chalk@^1.1.3: + version "1.1.3" + resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chokidar@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +chokidar@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + +chownr@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +commander@^2.11.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +configstore@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + +convert-source-map@^1.5.0, convert-source-map@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + +core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.7: + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cors@^2.8.4: + version "2.8.4" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.4.tgz#2bd381f2eb201020105cd50ea59da63090694686" + dependencies: + object-assign "^4" + vary "^1" + +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.2.5" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.5.tgz#c2418fbfd7a29f4d4f70ff4cea604d4b64c46407" + dependencies: + ms "^2.1.1" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +depd@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" + +depd@~1.1.1, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + +deprecated-decorator@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + +dicer@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" + dependencies: + readable-stream "1.1.x" + streamsearch "0.1.2" + +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + dependencies: + is-obj "^1.0.0" + +dotenv@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.0.0.tgz#24e37c041741c5f4b25324958ebbc34bca965935" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + +duplexer@^0.1.1, duplexer@~0.1.1: + version "0.1.1" + resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +electron-to-chromium@^1.3.47: + version "1.3.73" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.73.tgz#aa67787067d58cc3920089368b3b8d6fe0fc12f6" + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + +es-abstract@^1.5.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + +event-stream@~3.3.0: + version "3.3.6" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.6.tgz#cac1230890e07e73ec9cacd038f60a5b66173eef" + dependencies: + duplexer "^0.1.1" + flatmap-stream "^0.1.0" + from "^0.1.7" + map-stream "0.0.7" + pause-stream "^0.0.11" + split "^1.0.1" + stream-combiner "^0.2.2" + through "^2.3.8" + +eventemitter3@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +express@^4.0.0: + version "4.16.3" + resolved "http://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" + dependencies: + accepts "~1.3.5" + array-flatten "1.1.1" + body-parser "1.18.2" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.1" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.3" + qs "6.5.1" + range-parser "~1.2.0" + safe-buffer "5.1.1" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +faker@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +fclone@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.1.1: + version "1.1.1" + resolved "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + +flatmap-stream@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.0.tgz#ed54e01422cd29281800914fcb968d58b685d5f1" + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + +from@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + dependencies: + minipass "^2.2.1" + +fs-readdir-recursive@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0, fsevents@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-stream@^3.0.0: + version "3.0.0" + resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob@^7.0.5, glob@^7.1.2: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + dependencies: + ini "^1.3.4" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +got@^6.7.1: + version "6.7.1" + resolved "http://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +graphql-anywhere@^4.1.0-alpha.0, graphql-anywhere@^4.1.19: + version "4.1.19" + resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.19.tgz#5f6ca3b58218e5449f4798e3c6d942fcd2fef082" + dependencies: + apollo-utilities "^1.0.21" + +graphql-custom-directives@^0.2.13: + version "0.2.13" + resolved "https://registry.yarnpkg.com/graphql-custom-directives/-/graphql-custom-directives-0.2.13.tgz#5e175069f5ff404f751d232e302007bc25488ea8" + dependencies: + lodash "^4.17.5" + moment "^2.22.2" + numeral "^2.0.6" + +graphql-extensions@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.2.1.tgz#7697e0fcea2e622afe9e24dd31fc84f533e84c70" + dependencies: + apollo-server-env "^2.0.3" + +graphql-subscriptions@^0.5.8: + version "0.5.8" + resolved "http://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7" + dependencies: + iterall "^1.2.1" + +graphql-tag@^2.4.2, graphql-tag@^2.9.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" + +graphql-tools@^3.0.4: + version "3.1.1" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-3.1.1.tgz#d593358f01e7c8b1671a17b70ddb034dea9dbc50" + dependencies: + apollo-link "^1.2.2" + apollo-utilities "^1.0.1" + deprecated-decorator "^0.1.6" + iterall "^1.1.3" + uuid "^3.1.0" + +graphql@^0.13.2: + version "0.13.2" + resolved "http://registry.npmjs.org/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" + dependencies: + iterall "^1.2.1" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + dependencies: + function-bind "^1.1.1" + +hash.js@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +http-errors@1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" + dependencies: + depd "1.1.1" + inherits "2.0.3" + setprototypeof "1.0.3" + statuses ">= 1.3.1 < 2" + +http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: + version "1.6.3" + resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +iconv-lite@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +iconv-lite@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + dependencies: + minimatch "^3.0.4" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + dependencies: + loose-envify "^1.0.0" + +ipaddr.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + dependencies: + kind-of "^6.0.0" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-callable@^1.1.3, is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + dependencies: + ci-info "^1.5.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + +is-obj@^1.0.0: + version "1.0.1" + resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + dependencies: + path-is-inside "^1.0.1" + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + dependencies: + has-symbols "^1.0.0" + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + +iterall@^1.1.3, iterall@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json5@^0.5.1: + version "0.5.1" + resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + dependencies: + package-json "^4.0.0" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + +lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + +lru-cache@^4.0.1, lru-cache@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + dependencies: + pify "^3.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + +map-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" + +math-random@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + +micromatch@^2.1.5: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +mime-db@~1.36.0: + version "1.36.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" + +mime-types@~2.1.18: + version "2.1.20" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" + dependencies: + mime-db "~1.36.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + +minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.2.0: + version "1.2.0" + resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minipass@^2.2.1, minipass@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" + dependencies: + minipass "^2.2.1" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.1" + resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +moment@^2.22.2: + version "2.22.2" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + +nan@^2.9.2: + version "2.11.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +needle@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + +neo4j-driver@^1.6.1: + version "1.6.3" + resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.6.3.tgz#b7a51bac401bd341082dff7766e8643d61752eb7" + dependencies: + babel-runtime "^6.18.0" + uri-js "^4.2.1" + +neo4j-graphql-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.2.tgz#e4dd66b85e817347efb13beaa8340f8eda9df24f" + dependencies: + graphql "^0.13.2" + lodash "^4.17.10" + neo4j-driver "^1.6.1" + +node-fetch@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5" + +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +nodemon@^1.17.5: + version "1.18.4" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.4.tgz#873f65fdb53220eb166180cf106b1354ac5d714d" + dependencies: + chokidar "^2.0.2" + debug "^3.1.0" + ignore-by-default "^1.0.1" + minimatch "^3.0.4" + pstree.remy "^1.1.0" + semver "^5.5.0" + supports-color "^5.2.0" + touch "^3.1.0" + undefsafe "^2.0.2" + update-notifier "^2.3.0" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + dependencies: + abbrev "1" + +normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-bundled@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + +npm-packlist@^1.1.6: + version "1.1.11" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +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" + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +numeral@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" + +object-assign@^4, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + +object-path@^0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + dependencies: + isobject "^3.0.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +output-file-sync@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" + dependencies: + graceful-fs "^4.1.4" + mkdirp "^0.5.1" + object-assign "^4.1.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + +pause-stream@^0.0.11: + version "0.0.11" + resolved "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + dependencies: + through "~2.3" + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +protobufjs@^6.8.6: + version "6.8.8" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.0" + "@types/node" "^10.1.0" + long "^4.0.0" + +proxy-addr@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.8.0" + +ps-tree@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" + dependencies: + event-stream "~3.3.0" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +pstree.remy@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.0.tgz#f2af27265bd3e5b32bbfcc10e80bac55ba78688b" + dependencies: + ps-tree "^1.1.0" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + +qs@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + +qs@6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + +randomatic@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.0.tgz#36f2ca708e9e567f5ed2ec01949026d50aa10116" + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +raw-body@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" + dependencies: + bytes "3.0.0" + http-errors "1.6.2" + iconv-lite "0.4.19" + unpipe "1.0.0" + +raw-body@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + +rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +readable-stream@1.1.x: + version "1.1.14" + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.2, readable-stream@^2.0.6: + version "2.3.6" + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +regenerate@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regenerator-runtime@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +registry-auth-token@^3.0.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + dependencies: + rc "^1.0.1" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + +retry@0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + +rimraf@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +safe-buffer@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + dependencies: + semver "^5.0.3" + +semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: + version "5.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setprototypeof@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + +source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + dependencies: + extend-shallow "^3.0.0" + +split@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + dependencies: + through "2" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.3.1 < 2", "statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + +stream-combiner@^0.2.2: + version "0.2.2" + resolved "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" + dependencies: + duplexer "~0.1.1" + through "~2.3.4" + +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +subscriptions-transport-ws@^0.9.11: + version "0.9.15" + resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz#68a8b7ba0037d8c489fb2f5a102d1494db297d0d" + dependencies: + backo2 "^1.0.2" + eventemitter3 "^3.1.0" + iterall "^1.2.1" + symbol-observable "^1.0.4" + ws "^5.2.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^5.2.0, supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + dependencies: + has-flag "^3.0.0" + +symbol-observable@^1.0.2, symbol-observable@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + +tar@^4: + version "4.4.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" + dependencies: + chownr "^1.0.1" + fs-minipass "^1.2.5" + minipass "^2.3.3" + minizlib "^1.1.0" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + dependencies: + execa "^0.7.0" + +through@2, through@^2.3.8, through@~2.3, through@~2.3.4: + version "2.3.8" + resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + dependencies: + kind-of "^3.0.2" + +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" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + dependencies: + nopt "~1.0.10" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +type-is@^1.6.16, type-is@~1.6.15, type-is@~1.6.16: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +undefsafe@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76" + dependencies: + debug "^2.2.0" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + dependencies: + crypto-random-string "^1.0.0" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + +update-notifier@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +uri-js@^4.2.1: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + +uuid@^3.1.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + +v8flags@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" + dependencies: + user-home "^1.1.1" + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + dependencies: + string-width "^1.0.2 || 2" + +widest-line@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.0.tgz#0142a4e8a243f8882c0233aa0e0281aa76152273" + dependencies: + string-width "^2.1.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + dependencies: + async-limiter "~1.0.0" + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + +zen-observable-ts@^0.8.10: + version "0.8.10" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz#18e2ce1c89fe026e9621fd83cc05168228fce829" + dependencies: + zen-observable "^0.8.0" + +zen-observable@^0.8.0: + version "0.8.9" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.9.tgz#0475c760ff0eda046bbdfa4dc3f95d392807ac53" From a5ca646b7112f3c0c60f1b1266fac8b4f8ba84a3 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 5 Oct 2018 14:04:33 +0200 Subject: [PATCH 002/554] added badges --- src/schema.graphql | 22 ++++++++++++++++++++++ src/seed/seed-mutations.js | 21 +++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/schema.graphql b/src/schema.graphql index da9436512..e5ce16e65 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -47,6 +47,9 @@ type User { organizationsCreated: [Organization] @relation(name: "CREATED_ORGA", direction: "OUT") organizationsOwned: [Organization] @relation(name: "OWNING_ORGA", direction: "OUT") + + badges: [Badge]! @relation(name: "REWARDED", direction: "IN") + badgesCount: Int! @cypher(statement: "MATCH (this)<-[:REWARDED]-(r:Badge) RETURN COUNT(r)") } type Post { @@ -85,6 +88,25 @@ type Category { icon: String! } +type Badge { + id: ID! + key: String! + type: BadgeTypeEnum! + status: BadgeStatusEnum! + icon: String! + + rewarded: [User]! @relation(name: "REWARDED", direction: "OUT") +} + +enum BadgeTypeEnum { + Role + Crowdfunding +} +enum BadgeStatusEnum { + Permanent + Temorary +} + type Organization { id: ID! createdBy: User @relation(name: "CREATED_ORGA", direction: "IN") diff --git a/src/seed/seed-mutations.js b/src/seed/seed-mutations.js index e7d9d1695..03a7847ea 100644 --- a/src/seed/seed-mutations.js +++ b/src/seed/seed-mutations.js @@ -1,5 +1,7 @@ export default ` mutation { + + # Users u1: CreateUser(id: "u1", name: "Will Blast", email: "Will-Blast@Yahoo.com", role: Admin) { id name @@ -25,6 +27,22 @@ export default ` role } + # Badges + b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_racoon") { id } + b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_rabbit") { id } + b3: CreateBadge(id: "b3", key: "indiegogo_en_wolf", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_wolf") { id } + b4: CreateBadge(id: "b4", key: "indiegogo_en_bear", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_bear") { id } + b5: CreateBadge(id: "b5", key: "indiegogo_en_turtle", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_turtle") { id } + b6: CreateBadge(id: "b6", key: "indiegogo_en_rhino", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_rhino") { id } + + b1_u1: AddUserBadges(from: {id: "b1"}, to: {id: "u1"}) { from { id } } + b2_u1: AddUserBadges(from: {id: "b2"}, to: {id: "u1"}) { from { id } } + b3_u1: AddUserBadges(from: {id: "b3"}, to: {id: "u1"}) { from { id } } + b6_u2: AddUserBadges(from: {id: "b6"}, to: {id: "u2"}) { from { id } } + b3_u3: AddUserBadges(from: {id: "b3"}, to: {id: "u3"}) { from { id } } + b5_u4: AddUserBadges(from: {id: "b5"}, to: {id: "u4"}) { from { id } } + + # categories cat1: CreateCategory( id: "cat1", name: "Just For Fun", slug: "justforfun", icon: "categories-justforfun" ) { name } cat2: CreateCategory( id: "cat2", name: "Happyness & Values", slug: "happyness-values", icon: "categories-luck" ) { name } cat3: CreateCategory( id: "cat3", name: "Health & Wellbeing", slug: "health-wellbeing", icon: "categories-health" ) { name } @@ -42,6 +60,7 @@ export default ` cat15: CreateCategory( id: "cat15", name: "Consumption & Sustainability", slug: "consumption-sustainability", icon: "categories-sustainability" ) { name } cat16: CreateCategory( id: "cat16", name: "Global Peace & Nonviolence", slug: "globalpeace-nonviolence", icon: "categories-peace" ) { name } + # Posts p1: CreatePost( id: "p1", title: "Gedanken eines Polizisten zum Einsatz im Hambacher Forst", @@ -88,6 +107,7 @@ export default ` p4_cat9: AddPostCategories(from: {id: "p4"}, to: {id: "cat9"}) { from { id } } p4_cat4: AddPostCategories(from: {id: "p4"}, to: {id: "cat4"}) { from { id } } + # Comments c1: CreateComment( id: "c1", content: "# 1 This is my comment 1", @@ -161,6 +181,7 @@ export default ` to: { id: "p4" } ) { from { id } } + # Tags t1: CreateTag( id: "t1", name: "Umwelt" From 6c87ba2ada03e303a8f334367fc7fbf78de64ee6 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 5 Oct 2018 14:09:31 +0200 Subject: [PATCH 003/554] added blacklist relation --- src/schema.graphql | 2 ++ src/seed/seed-mutations.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/schema.graphql b/src/schema.graphql index e5ce16e65..0e4e2652b 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -48,6 +48,8 @@ type User { organizationsCreated: [Organization] @relation(name: "CREATED_ORGA", direction: "OUT") organizationsOwned: [Organization] @relation(name: "OWNING_ORGA", direction: "OUT") + blacklisted: [User]! @relation(name: "BLACKLISTED", direction: "OUT") + badges: [Badge]! @relation(name: "REWARDED", direction: "IN") badgesCount: Int! @cypher(statement: "MATCH (this)<-[:REWARDED]-(r:Badge) RETURN COUNT(r)") } diff --git a/src/seed/seed-mutations.js b/src/seed/seed-mutations.js index 03a7847ea..66ccfad1f 100644 --- a/src/seed/seed-mutations.js +++ b/src/seed/seed-mutations.js @@ -27,6 +27,8 @@ export default ` role } + u1_blacklist_u4: AddUserBlacklisted(from: { id: "u1" }, to: { id: "u4" }) { from { id } } + # Badges b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_racoon") { id } b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_rabbit") { id } From af8dba7f165c6cf562f25da31cbe3a962c36ba20 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 5 Oct 2018 14:53:11 +0200 Subject: [PATCH 004/554] updated readme --- README.md | 18 ++++++++++++++++++ src/schema.graphql | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7ab257aeb..eb0bc561d 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,13 @@ run Neo4j in one of the [many cloud options](https://neo4j.com/developer/guide-c or [spin up Neo4j in a Docker container](https://neo4j.com/developer/docker/). Just be sure to update the Neo4j connection string and credentials accordingly in `.env`. +## Mocking API Results + +Alternatively you can just mock all responses from the api which let +you build a frontend application without running a neo4j instance. + +Just set `MOCK=true` inside `.env` or pass it on application start. + ## Deployment You can deploy to any service that hosts Node.js apps, but [Zeit Now](https://zeit.co/now) @@ -91,3 +98,14 @@ yarn seedDb # -or- npm run seedDb ``` + +## Todo`s + +- [ ] add jwt authentication +- [ ] get directives working correctly (@toLower, @auth, @role, etc.) +- [ ] check if search is working +- [ ] check if sorting is working +- [ ] check if pagination is working +- [ ] check if upload is working (using graphql-yoga?) +- [ ] evaluate middleware +- [ ] ignore Posts and Comments by blacklisted Users diff --git a/src/schema.graphql b/src/schema.graphql index 0e4e2652b..497d1e4aa 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -13,12 +13,12 @@ enum UserGroupEnum { type WrittenPost @relation(name: "WROTE") { from: User to: Post - timestamp: Int + timestamp: Int # TODO: change that to custom Date Type } type WrittenComment @relation(name: "WROTE") { from: User to: Comment - timestamp: Int + timestamp: Int # TODO: change that to custom Date Type } type User { From 0ad05e1a443bae7c4497b3ec4a4d5352c01e998a Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 9 Oct 2018 15:06:33 +0200 Subject: [PATCH 005/554] added middleware, new nodes and migrations --- package.json | 5 +- src/index.js | 36 +++++- src/middleware/excerptMiddleware.js | 21 ++++ src/middleware/passwordMiddleware.js | 17 +++ src/middleware/sluggifyMiddleware.js | 40 ++++++ src/schema.graphql | 19 ++- src/seed/seed-mutations.js | 174 ++++++++++++++------------- yarn.lock | 57 +++++++++ 8 files changed, 280 insertions(+), 89 deletions(-) create mode 100644 src/middleware/excerptMiddleware.js create mode 100644 src/middleware/passwordMiddleware.js create mode 100644 src/middleware/sluggifyMiddleware.js diff --git a/package.json b/package.json index 75707f466..14324b60f 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,13 @@ "dotenv": "^6.0.0", "faker": "^4.1.0", "graphql-custom-directives": "^0.2.13", + "graphql-middleware": "^1.7.6", "graphql-tag": "^2.9.2", "neo4j-driver": "^1.6.1", "neo4j-graphql-js": "^1.0.2", - "node-fetch": "^2.1.2" + "node-fetch": "^2.1.2", + "slug": "^0.9.1", + "trunc-html": "^1.1.2" }, "devDependencies": { "babel-cli": "^6.26.0", diff --git a/src/index.js b/src/index.js index 7242b6661..66494bb49 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,12 @@ // import { GraphQLServer } from 'graphql-yoga' +import { applyMiddleware } from 'graphql-middleware' import { ApolloServer, makeExecutableSchema } from 'apollo-server' import { augmentSchema } from 'neo4j-graphql-js' import { typeDefs, resolvers } from './graphql-schema' import { v1 as neo4j } from 'neo4j-driver' +import passwordMiddleware from './middleware/passwordMiddleware' +import sluggifyMiddleware from './middleware/sluggifyMiddleware' +import excerptMiddleware from './middleware/excerptMiddleware' import dotenv from 'dotenv' import { GraphQLLowerCaseDirective, @@ -40,12 +44,42 @@ const driver = neo4j.driver( const MOCK = (process.env.MOCK === 'true') console.log('MOCK:', MOCK) +/* const logInput = async (resolve, root, args, context, info) => { + console.log(args) + if (args.email) { + args.email = args.email.toLowerCase() + } + console.log(`1. logInput: ${JSON.stringify(args)}`) + const result = await resolve(root, args, context, info) + console.log(`5. logInput`) + return result +} + +const logResult = async (resolve, root, args, context, info) => { + console.log(`2. logResult`) + let result = await resolve(root, args, context, info) + console.log('RESULT:', result) + if (Array.isArray(result)) { + result.forEach(res => { + if (res.email) { + res.email = '******' + // res.email = res.email.toLowerCase() + } + }) + } else if (typeof result === 'string' && info.fieldName === 'email') { + result = '******' + // result = result.toLowerCase() + } + console.log(`4. logResult: ${JSON.stringify(result)}`) + return result +} */ + const server = new ApolloServer({ context: { driver }, tracing: true, - schema: augmentedSchema, + schema: applyMiddleware(augmentedSchema, passwordMiddleware, sluggifyMiddleware, excerptMiddleware), mocks: MOCK ? { User: () => ({ name: () => `${faker.name.firstName()} ${faker.name.lastName()}`, diff --git a/src/middleware/excerptMiddleware.js b/src/middleware/excerptMiddleware.js new file mode 100644 index 000000000..4b54c5341 --- /dev/null +++ b/src/middleware/excerptMiddleware.js @@ -0,0 +1,21 @@ +import trunc from 'trunc-html' + +export default { + Mutation: { + CreatePost: async (resolve, root, args, context, info) => { + args.contentExcerpt = trunc(args.content, 120).html + const result = await resolve(root, args, context, info) + return result + }, + CreateComment: async (resolve, root, args, context, info) => { + args.contentExcerpt = trunc(args.content, 180).html + const result = await resolve(root, args, context, info) + return result + }, + CreateOrganization: async (resolve, root, args, context, info) => { + args.descriptionExcerpt = trunc(args.description, 120).html + const result = await resolve(root, args, context, info) + return result + } + } +} diff --git a/src/middleware/passwordMiddleware.js b/src/middleware/passwordMiddleware.js new file mode 100644 index 000000000..1153d4588 --- /dev/null +++ b/src/middleware/passwordMiddleware.js @@ -0,0 +1,17 @@ +export default { + Mutation: { + CreateUser: async (resolve, root, args, context, info) => { + args.password = 'TRY TO ENCRYPT IT' + const result = await resolve(root, args, context, info) + result.password = '*****' + return result + } + }, + Query: async (resolve, root, args, context, info) => { + const result = await resolve(root, args, context, info) + if (result.password) { + result.password = '*****' + } + return result + } +} diff --git a/src/middleware/sluggifyMiddleware.js b/src/middleware/sluggifyMiddleware.js new file mode 100644 index 000000000..f059cb680 --- /dev/null +++ b/src/middleware/sluggifyMiddleware.js @@ -0,0 +1,40 @@ +import slug from 'slug' + +export default { + Mutation: { + CreatePost: async (resolve, root, args, context, info) => { + args.slug = slug(args.title, { + lower: true + }) + const result = await resolve(root, args, context, info) + return result + }, + CreateUser: async (resolve, root, args, context, info) => { + if (!args.slug) { + args.slug = slug(args.name, { + lower: true + }) + } + const result = await resolve(root, args, context, info) + return result + }, + CreateOrganization: async (resolve, root, args, context, info) => { + if (!args.slug) { + args.slug = slug(args.name, { + lower: true + }) + } + const result = await resolve(root, args, context, info) + return result + }, + CreateCategory: async (resolve, root, args, context, info) => { + if (!args.slug) { + args.slug = slug(args.name, { + lower: true + }) + } + const result = await resolve(root, args, context, info) + return result + } + } +} diff --git a/src/schema.graphql b/src/schema.graphql index 497d1e4aa..d835c2d24 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -25,6 +25,9 @@ type User { id: ID! name: String! email: String + slug: String + password: String! + avatar: String disabled: Boolean @default(to: false) role: UserGroupEnum @@ -58,12 +61,16 @@ type Post { id: ID! author: WrittenPost title: String! - slug: String! + slug: String content: String! - contentExcerpt: String! + contentExcerpt: String + image: String visibility: VisibilityEnum disabled: Boolean @default(to: false) + # relatedContributions: [Post]! @cypher(statement: "MATCH (this)-[:TAGGED]->(t:Tag)<-[:TAGGED]-(p1:Post) MATCH (this)-[:CATEGORIZED]->(t:Category)<-[:CATEGORIZED]-(p2:Post) RETURN collect(distinct p2) + p1") + relatedContributions: [Post]! @cypher(statement: "MATCH (this)-[:TAGGED]->(t:Tag)<-[:TAGGED]-(p:Post) return p") + tags: [Tag]! @relation(name: "TAGGED", direction: "OUT") categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT") @@ -78,7 +85,7 @@ type Comment { id: ID! author: WrittenComment content: String! - contentExcerpt: String! + contentExcerpt: String post: Post @relation(name: "COMMENT", direction: "OUT") disabled: Boolean @default(to: false) } @@ -86,7 +93,7 @@ type Comment { type Category { id: ID! name: String! - slug: String! + slug: String icon: String! } @@ -114,7 +121,9 @@ type Organization { createdBy: User @relation(name: "CREATED_ORGA", direction: "IN") ownedBy: [User] @relation(name: "OWNING_ORGA", direction: "IN") name: String! - slug: String! + slug: String + description: String! + descriptionExcerpt: String disabled: Boolean @default(to: false) tags: [Tag]! @relation(name: "TAGGED", direction: "OUT") diff --git a/src/seed/seed-mutations.js b/src/seed/seed-mutations.js index 66ccfad1f..ec9a1317c 100644 --- a/src/seed/seed-mutations.js +++ b/src/seed/seed-mutations.js @@ -1,29 +1,35 @@ +import faker from 'faker' + export default ` mutation { # Users - u1: CreateUser(id: "u1", name: "Will Blast", email: "Will-Blast@Yahoo.com", role: Admin) { + u1: CreateUser(id: "u1", name: "Peter Lustig", password: "1234", email: "admin@test.de", avatar: "${faker.internet.avatar()}", role: Admin) { id name email + avatar role } - u2: CreateUser(id: "u2", name: "Bob der Bausmeister", email: "Bob-der-Bausmeister@yahoo.com", role: Moderator) { + u2: CreateUser(id: "u2", name: "Bob der Bausmeister", password: "1234", email: "moderator@test.de", avatar: "${faker.internet.avatar()}", role: Moderator) { id name email + avatar role } - u3: CreateUser(id: "u3", name: "Jenny Rostock", email: "JennyRostock@yahoo.com", role: Admin) { + u3: CreateUser(id: "u3", name: "Jenny Rostock", password: "1234", email: "user@test.de", avatar: "${faker.internet.avatar()}", role: Admin) { id name email + avatar role } - u4: CreateUser(id: "u4", name: "Angie Banjie", email: "Angie_Banjie@yahoo.com", role: User) { + u4: CreateUser(id: "u4", name: "Angie Banjie", password: "1234", email: "Angie_Banjie@yahoo.com", avatar: "${faker.internet.avatar()}", role: User) { id name email + avatar role } @@ -66,101 +72,114 @@ export default ` p1: CreatePost( id: "p1", title: "Gedanken eines Polizisten zum Einsatz im Hambacher Forst", - slug: "gedanken-eines-polizisten-zum-einsatz-im-hambacher-forst", - content: "# 1 This is my content 1", - contentExcerpt: "# 1 This is my content 1", + content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", + image: "https://picsum.photos/1280/1024?image=352", visibility: Public ) { title } p1_cat1: AddPostCategories(from: {id: "p1"}, to: {id: "cat1"}) { from { id } } p1_cat2: AddPostCategories(from: {id: "p1"}, to: {id: "cat2"}) { from { id } } + ur1: AddUserContributions(from: { id: "u1" }, to: { id: "p1" }, data: { timestamp: 1538655020 }) { from { id } } p2: CreatePost( id: "p2", title: "Julian Assange", - slug: "julian-assange", - content: "#2 This is my content 2", - contentExcerpt: "#2 This is my content 2", + content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", + image: "https://picsum.photos/1280/1024?image=72", visibility: Public ) { title } p2_cat1: AddPostCategories(from: {id: "p2"}, to: {id: "cat1"}) { from { id } } p2_cat16: AddPostCategories(from: {id: "p2"}, to: {id: "cat16"}) { from { id } } + ur2: AddUserContributions(from: { id: "u2" }, to: { id: "p2" }, data: { timestamp: 1538655120 }) { from { id } } p3: CreatePost( id: "p3", title: "Hacker, Freaks und Funktionäre...Der CCC", - slug: "hacker-freaks-und-funktionäre-der-ccc", - content: "#3 This is my content 3", - contentExcerpt: "#3 This is my content 3", + content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", + image: "https://picsum.photos/1280/1024?image=121", visibility: Public ) { title } p3_cat1: AddPostCategories(from: {id: "p3"}, to: {id: "cat1"}) { from { id } } p3_cat3: AddPostCategories(from: {id: "p3"}, to: {id: "cat3"}) { from { id } } p3_cat14: AddPostCategories(from: {id: "p3"}, to: {id: "cat14"}) { from { id } } + ur3: AddUserContributions(from: { id: "u3" }, to: { id: "p3" }, data: { timestamp: 1538653120 }) { from { id } } p4: CreatePost( id: "p4", title: "Lebensmittel (?)", - slug: "lebensmittel", - content: "#4 This is my content 4", - contentExcerpt: "#4 This is my content 4", + content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", + image: "https://picsum.photos/1280/1024?image=142", visibility: Public ) { title } p4_cat1: AddPostCategories(from: {id: "p4"}, to: {id: "cat1"}) { from { id } } p4_cat9: AddPostCategories(from: {id: "p4"}, to: {id: "cat9"}) { from { id } } p4_cat4: AddPostCategories(from: {id: "p4"}, to: {id: "cat4"}) { from { id } } + ur4: AddUserContributions(from: { id: "u4" }, to: { id: "p4" }, data: { timestamp: 1538615120 }) { from { id } } + + p5: CreatePost( + id: "p5", + title: "${faker.lorem.sentence()}", + content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", + image: "https://picsum.photos/1280/1024?image=231", + visibility: Public + ) { title } + p5_cat8: AddPostCategories(from: {id: "p5"}, to: {id: "cat8"}) { from { id } } + p5_cat12: AddPostCategories(from: {id: "p5"}, to: {id: "cat12"}) { from { id } } + ur5: AddUserContributions(from: { id: "u2" }, to: { id: "p5" }, data: { timestamp: 1538615120 }) { from { id } } + + p6: CreatePost( + id: "p6", + title: "${faker.lorem.sentence()}", + content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", + image: "https://picsum.photos/1280/1024?image=424", + visibility: Public + ) { title } + p6_cat1: AddPostCategories(from: {id: "p6"}, to: {id: "cat1"}) { from { id } } + p6_cat2: AddPostCategories(from: {id: "p6"}, to: {id: "cat2"}) { from { id } } + p6_cat5: AddPostCategories(from: {id: "p6"}, to: {id: "cat5"}) { from { id } } + ur6: AddUserContributions(from: { id: "u4" }, to: { id: "p6" }, data: { timestamp: 1538615120 }) { from { id } } # Comments c1: CreateComment( id: "c1", - content: "# 1 This is my comment 1", - contentExcerpt: "# 1 This is my..." + content: "

da stimm ich dir zu. Mir ging das auch nie in den kopf, und hatte jesus nie als gott gesehen.

", ) { id } + c1_u1: AddCommentAuthor(from: { id: "u3" }, to: { id: "c1" }, data: { timestamp: 1538655020 }) { from { id } } + c2: CreateComment( id: "c2", - content: "# 2 This is my comment 2", - contentExcerpt: "# 2 This is my..." + content: "

Schön das es dich gibt ❤️❤️❤️❤️❤️❤️❤️❤️❤️

", ) { id } + c2_u1: AddCommentAuthor(from: { id: "u1" }, to: { id: "c2" }, data: { timestamp: 1538655020 }) { from { id } } + c3: CreateComment( id: "c3", - content: "# 3 This is my comment 3", - contentExcerpt: "# 3 This is my..." + content: "

Hi Dieter,

danke fĂźr Deine Info. Hast Du mal ein Foto von Deinem Cabrio mit dem Logo drauf?

", ) { id } + c3_u2: AddCommentAuthor(from: { id: "u1" }, to: { id: "c3" }, data: { timestamp: 1538655020 }) { from { id } } + c4: CreateComment( id: "c4", - content: "# 4 This is my comment 4", - contentExcerpt: "# 4 This is my..." + content: "

Das ZusammenfĂźhren aller Gruppen, die mit uns am gleichen Strang in die gleiche Richtung ziehen, in eine gemeinsame Adressenstruktur sehe ich auch als Haupt - Aufgabe fĂźr unsere neue Netzwerkbildung an.

", ) { id } + c4_u3: AddCommentAuthor(from: { id: "u4" }, to: { id: "c4" }, data: { timestamp: 1538655020 }) { from { id } } + c5: CreateComment( id: "c5", - content: "# 5 This is my comment 5", - contentExcerpt: "# 5 This is my..." + content: "${faker.lorem.paragraph()}", ) { id } + c5_u4: AddCommentAuthor(from: { id: "u4" }, to: { id: "c5" }, data: { timestamp: 1538655020 }) { from { id } } - c1_u1: AddCommentAuthor( - from: { id: "u1" }, - to: { id: "c1" }, - data: { timestamp: 1538655020 } - ) { from { id } } - c2_u1: AddCommentAuthor( - from: { id: "u1" }, - to: { id: "c2" }, - data: { timestamp: 1538655020 } - ) { from { id } } - c3_u2: AddCommentAuthor( - from: { id: "u2" }, - to: { id: "c3" }, - data: { timestamp: 1538655020 } - ) { from { id } } - c4_u3: AddCommentAuthor( - from: { id: "u3" }, - to: { id: "c4" }, - data: { timestamp: 1538655020 } - ) { from { id } } - c5_u4: AddCommentAuthor( - from: { id: "u4" }, - to: { id: "c5" }, - data: { timestamp: 1538655020 } - ) { from { id } } + c6: CreateComment( + id: "c6", + content: "${faker.lorem.paragraph()}", + ) { id } + c6_u3: AddCommentAuthor(from: { id: "u3" }, to: { id: "c6" }, data: { timestamp: 1538655020 }) { from { id } } + + c7: CreateComment( + id: "c7", + content: "${faker.lorem.paragraph()}", + ) { id } + c7_u2: AddCommentAuthor(from: { id: "u2" }, to: { id: "c7" }, data: { timestamp: 1538655020 }) { from { id } } c1_p1: AddCommentPost( from: { id: "c1" }, @@ -170,18 +189,30 @@ export default ` from: { id: "c2" }, to: { id: "p1" } ) { from { id } } - c3_p2: AddCommentPost( + c3_p3: AddCommentPost( from: { id: "c3" }, - to: { id: "p2" } - ) { from { id } } - c4_p3: AddCommentPost( - from: { id: "c4" }, to: { id: "p3" } ) { from { id } } - c5_p4: AddCommentPost( + c4_p2: AddCommentPost( + from: { id: "c4" }, + to: { id: "p2" } + ) { from { id } } + c5_p3: AddCommentPost( from: { id: "c5" }, + to: { id: "p3" } + ) { from { id } } + c6_p4: AddCommentPost( + from: { id: "c6" }, to: { id: "p4" } ) { from { id } } + c6_p1: AddCommentPost( + from: { id: "c6" }, + to: { id: "p1" } + ) { from { id } } + c7_p2: AddCommentPost( + from: { id: "c7" }, + to: { id: "p2" } + ) { from { id } } # Tags t1: CreateTag( @@ -229,22 +260,22 @@ export default ` o1: CreateOrganization( id: "o1", name: "Democracy Deutschland", - slug: "democracy-deutschland" + description: "Description for democracy-deutschland." ) { name } o2: CreateOrganization( id: "o2", name: "Human-Connection", - slug: "human-connection" + description: "Description for human-connection." ) { name } o3: CreateOrganization( id: "o3", name: "Pro Veg", - slug: "pro-veg" + description: "Description for pro-veg." ) { name } o4: CreateOrganization( id: "o4", name: "Greenpeace", - slug: "greenpeace" + description: "Description for greenpeace." ) { name } u1_c_o1: AddOrganizationCreatedBy( @@ -295,27 +326,6 @@ export default ` to: { id: "u2" } ) { from { id } } - ur1: AddUserContributions( - from: { id: "u1" }, - to: { id: "p1" }, - data: { timestamp: 1538655020 } - ) { from { id } } - ur2: AddUserContributions( - from: { id: "u2" }, - to: { id: "p2" }, - data: { timestamp: 1538655120 } - ) { from { id } } - ur3: AddUserContributions( - from: { id: "u3" }, - to: { id: "p3" }, - data: { timestamp: 1538653120 } - ) { from { id } } - ur4: AddUserContributions( - from: { id: "u4" }, - to: { id: "p4" }, - data: { timestamp: 1538615120 } - ) { from { id } } - u1s2: AddUserShouted( from: { id: "u1" }, to: { id: "p2" } diff --git a/yarn.lock b/yarn.lock index 5c38ee36e..e897cb8e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -432,6 +432,14 @@ assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" +assignment@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.0.0.tgz#ffd17b21bf5d6b22e777b989681a815456a3dd3e" + +assignment@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.2.0.tgz#f5b5bc2d160d69986e8700cd38f567c0aabe101e" + async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" @@ -1729,6 +1737,12 @@ graphql-extensions@^0.2.1: dependencies: apollo-server-env "^2.0.3" +graphql-middleware@^1.7.6: + version "1.7.6" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.6.tgz#f226bf6671f3d82a9378f8b335804c8e44d21733" + dependencies: + graphql-tools "^4.0.0" + graphql-subscriptions@^0.5.8: version "0.5.8" resolved "http://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7" @@ -1749,6 +1763,16 @@ graphql-tools@^3.0.4: iterall "^1.1.3" uuid "^3.1.0" +graphql-tools@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.0.tgz#6ea01937c6f947212f83567ba687e97c22fdd2a6" + dependencies: + apollo-link "^1.2.3" + apollo-utilities "^1.0.1" + deprecated-decorator "^0.1.6" + iterall "^1.1.3" + uuid "^3.1.0" + graphql@^0.13.2: version "0.13.2" resolved "http://registry.npmjs.org/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" @@ -1813,6 +1837,10 @@ hash.js@^1.1.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +he@0.5.0: + version "0.5.0" + resolved "http://registry.npmjs.org/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" + home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -1887,6 +1915,13 @@ ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" +insane@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/insane/-/insane-2.6.1.tgz#c7dcae7b51c20346883b71078fad6ce0483c198f" + dependencies: + assignment "2.0.0" + he "0.5.0" + invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -2972,6 +3007,12 @@ slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" +slug@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.1.tgz#af08f608a7c11516b61778aa800dce84c518cfda" + dependencies: + unicode ">= 0.3.1" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -3192,6 +3233,18 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" +trunc-html@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/trunc-html/-/trunc-html-1.1.2.tgz#1e97d51f67d470b67662b1a670e6d0ea7a8edafe" + dependencies: + assignment "2.2.0" + insane "2.6.1" + trunc-text "1.0.1" + +trunc-text@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" + type-is@^1.6.16, type-is@~1.6.15, type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" @@ -3205,6 +3258,10 @@ undefsafe@^2.0.2: dependencies: debug "^2.2.0" +"unicode@>= 0.3.1": + version "11.0.1" + resolved "https://registry.yarnpkg.com/unicode/-/unicode-11.0.1.tgz#735bd422ec75cf28d396eb224d535d168d5f1db6" + union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" From 33bfe3881ff57aaa09d6929d8fb352c714e9b331 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 9 Oct 2018 15:07:30 +0200 Subject: [PATCH 006/554] updated package json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 14324b60f..227824f28 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "hc-graph-api-prototype", + "name": "hc-prototype-api-", "version": "0.0.1", "description": "Graph API Protype for Human Connection", "main": "src/index.js", @@ -17,7 +17,6 @@ "apollo-link-http": "^1.5.4", "apollo-server": "^2.0.4", "dotenv": "^6.0.0", - "faker": "^4.1.0", "graphql-custom-directives": "^0.2.13", "graphql-middleware": "^1.7.6", "graphql-tag": "^2.9.2", @@ -28,6 +27,7 @@ "trunc-html": "^1.1.2" }, "devDependencies": { + "faker": "^4.1.0", "babel-cli": "^6.26.0", "babel-preset-env": "^1.7.0", "nodemon": "^1.17.5" From 5faf3ec6ee40816dd80bacb77c8fa1b3bc3a049a Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 9 Oct 2018 15:09:56 +0200 Subject: [PATCH 007/554] updated readme --- README.md | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index eb0bc561d..a15da7112 100644 --- a/README.md +++ b/README.md @@ -71,23 +71,6 @@ you build a frontend application without running a neo4j instance. Just set `MOCK=true` inside `.env` or pass it on application start. -## Deployment - -You can deploy to any service that hosts Node.js apps, but [Zeit Now](https://zeit.co/now) -is a great easy to use service for hosting your app that has an easy to use free plan for small projects. - -To deploy your GraphQL service on Zeit Now, first install [Now Desktop](https://zeit.co/download) - -you'll need to provide an email address. Then run - -``` -now -``` - -to deploy your GraphQL service on Zeit Now. Once deployed you'll be given -a fresh URL that represents the current state of your application where you -can access your GraphQL endpoint and GraphQL Playgound. -For example: https://hc-graph-api-prototype-sdga96ad7.now.sh/ - ## Seeding The Database Optionally you can seed the GraphQL service by executing mutations that @@ -105,7 +88,7 @@ npm run seedDb - [ ] get directives working correctly (@toLower, @auth, @role, etc.) - [ ] check if search is working - [ ] check if sorting is working -- [ ] check if pagination is working +- [x] check if pagination is working - [ ] check if upload is working (using graphql-yoga?) -- [ ] evaluate middleware +- [x] evaluate middleware - [ ] ignore Posts and Comments by blacklisted Users From 6dee6f676a1dbe3b9ce98b82952d5777da530cb7 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 9 Oct 2018 15:13:32 +0200 Subject: [PATCH 008/554] updated readme --- README.md | 2 +- graphql-playground.png | Bin 0 -> 318421 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 graphql-playground.png diff --git a/README.md b/README.md index a15da7112..cbec5394e 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ npm start This will start the GraphQL service (by default on localhost:4000) where you can issue GraphQL requests or access GraphQL Playground in the browser: -![GraphQL Playground](img/graphql-playground.png) +![GraphQL Playground](graphql-playground.png) ## Configure diff --git a/graphql-playground.png b/graphql-playground.png new file mode 100644 index 0000000000000000000000000000000000000000..87f04d242265f84ca99dddf21c8337e19bd310d0 GIT binary patch literal 318421 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%0Da0rc+? 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�ksg{J%oZtXc^soyB(qE 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

Z{l%nn|4pFwrJ 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 hJF@nQZz2<(p4>3d{S|>j_yqV Date: Tue, 9 Oct 2018 15:25:05 +0200 Subject: [PATCH 010/554] added important point about the APOC in neo4j --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index cbec5394e..f1805a90c 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ NEO4J_USER=neo4j NEO4J_PASSWORD=letmein ``` +> You need to install APOC as a plugin for the graph you create in the neo4j desktop app! + Note that grand-stack-starter does not currently bundle a distribution of Neo4j. You can download [Neo4j Desktop](https://neo4j.com/download/) and run locally for development, spin up a [hosted Neo4j Sandbox instance](https://neo4j.com/download/), From 2105b4d4aaa58a723595c78c09af7fb7bffc8c40 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 16 Oct 2018 09:45:50 +0200 Subject: [PATCH 011/554] added softdelete and image fix middleware --- src/index.js | 34 +++--------------------- src/middleware/fixImageUrlsMiddleware.js | 24 +++++++++++++++++ src/middleware/softDeleteMiddleware.js | 26 ++++++++++++++++++ 3 files changed, 53 insertions(+), 31 deletions(-) create mode 100644 src/middleware/fixImageUrlsMiddleware.js create mode 100644 src/middleware/softDeleteMiddleware.js diff --git a/src/index.js b/src/index.js index 66494bb49..4f39b5f0a 100644 --- a/src/index.js +++ b/src/index.js @@ -5,7 +5,9 @@ import { augmentSchema } from 'neo4j-graphql-js' import { typeDefs, resolvers } from './graphql-schema' import { v1 as neo4j } from 'neo4j-driver' import passwordMiddleware from './middleware/passwordMiddleware' +import softDeleteMiddleware from './middleware/softDeleteMiddleware' import sluggifyMiddleware from './middleware/sluggifyMiddleware' +import fixImageUrlsMiddleware from './middleware/fixImageUrlsMiddleware' import excerptMiddleware from './middleware/excerptMiddleware' import dotenv from 'dotenv' import { @@ -44,42 +46,12 @@ const driver = neo4j.driver( const MOCK = (process.env.MOCK === 'true') console.log('MOCK:', MOCK) -/* const logInput = async (resolve, root, args, context, info) => { - console.log(args) - if (args.email) { - args.email = args.email.toLowerCase() - } - console.log(`1. logInput: ${JSON.stringify(args)}`) - const result = await resolve(root, args, context, info) - console.log(`5. logInput`) - return result -} - -const logResult = async (resolve, root, args, context, info) => { - console.log(`2. logResult`) - let result = await resolve(root, args, context, info) - console.log('RESULT:', result) - if (Array.isArray(result)) { - result.forEach(res => { - if (res.email) { - res.email = '******' - // res.email = res.email.toLowerCase() - } - }) - } else if (typeof result === 'string' && info.fieldName === 'email') { - result = '******' - // result = result.toLowerCase() - } - console.log(`4. logResult: ${JSON.stringify(result)}`) - return result -} */ - const server = new ApolloServer({ context: { driver }, tracing: true, - schema: applyMiddleware(augmentedSchema, passwordMiddleware, sluggifyMiddleware, excerptMiddleware), + schema: applyMiddleware(augmentedSchema, passwordMiddleware, sluggifyMiddleware, excerptMiddleware, fixImageUrlsMiddleware, softDeleteMiddleware), mocks: MOCK ? { User: () => ({ name: () => `${faker.name.firstName()} ${faker.name.lastName()}`, diff --git a/src/middleware/fixImageUrlsMiddleware.js b/src/middleware/fixImageUrlsMiddleware.js new file mode 100644 index 000000000..218f3c2ea --- /dev/null +++ b/src/middleware/fixImageUrlsMiddleware.js @@ -0,0 +1,24 @@ + +const replaceURL = (url) => { + return url.replace('https://api-alpha.human-connection.org/uploads', 'http://localhost:3000/uploads') +} +const fixImageURLs = (result, resolve, root, args, context, info) => { + + if (result && typeof result === 'string' && result.indexOf('https://api-alpha.human-connection.org/uploads') === 0) { + result = replaceURL(result) + } else if (result && typeof result === 'object') { + Object.keys(result).forEach(key => { + result[key] = fixImageURLs(result[key]) + }) + } + + return result +} + +export default { + Query: async (resolve, root, args, context, info) => { + let result = await resolve(root, args, context, info) + + return fixImageURLs(result, resolve, root, args, context, info) + } +} diff --git a/src/middleware/softDeleteMiddleware.js b/src/middleware/softDeleteMiddleware.js new file mode 100644 index 000000000..c40cdf116 --- /dev/null +++ b/src/middleware/softDeleteMiddleware.js @@ -0,0 +1,26 @@ +export default { + Query: { + Post: async (resolve, root, args, context, info) => { + if (typeof args.deleted !== 'boolean') { + args.deleted = false + } + const result = await resolve(root, args, context, info) + return result + }, + Comment: async (resolve, root, args, context, info) => { + if (typeof args.deleted !== 'boolean') { + args.deleted = false + } + const result = await resolve(root, args, context, info) + return result + }, + User: async (resolve, root, args, context, info) => { + // console.log('ROOT', root) + // console.log('ARGS', args) + // console.log('CONTEXT', context) + // console.log('info', info.fieldNodes[0].arguments) + const result = await resolve(root, args, context, info) + return result + } + } +} From 81216f52c6b93e9270211c1e75fda305ed27a107 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 16 Oct 2018 09:46:21 +0200 Subject: [PATCH 012/554] improved schema --- src/schema.graphql | 48 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index d835c2d24..e7e936bab 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -15,6 +15,10 @@ type WrittenPost @relation(name: "WROTE") { to: Post timestamp: Int # TODO: change that to custom Date Type } +# type WrittenPost2 { +# Post: Post! +# timestamp: Int # TODO: change that to custom Date Type +# } type WrittenComment @relation(name: "WROTE") { from: User to: Comment @@ -23,30 +27,41 @@ type WrittenComment @relation(name: "WROTE") { type User { id: ID! - name: String! + name: String @default(to: "Anonymus") email: String slug: String password: String! avatar: String + deleted: Boolean @default(to: false) disabled: Boolean @default(to: false) role: UserGroupEnum friends: [User]! @relation(name: "FRIENDS", direction: "BOTH") friendsCount: Int! @cypher(statement: "MATCH (this)<-[:FRIENDS]->(r:User) RETURN COUNT(r)") - following: [User]! @relation(name: "FOLLOWING", direction: "OUT") - followingCount: Int! @cypher(statement: "MATCH (this)-[:FOLLOWING]->(r:User) RETURN COUNT(r)") + following: [User]! @relation(name: "FOLLOWS", direction: "OUT") + followingCount: Int! @cypher(statement: "MATCH (this)-[:FOLLOWS]->(r:User) RETURN COUNT(r)") - followedBy: [User]! @relation(name: "FOLLOWING", direction: "IN") - followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWING]-(r:User) RETURN COUNT(r)") + followedBy: [User]! @relation(name: "FOLLOWS", direction: "IN") + followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(r)") contributions: [WrittenPost]! - contributionsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Post) RETURN COUNT(r)") + #contributions2(first: Int = 10, offset: Int = 0): [WrittenPost2]! + # @cypher( + # statement: "MATCH (this)-[w:WROTE]->(p:Post) RETURN p as Post, w.timestamp as timestamp" + # ) + contributionsCount: Int! @cypher(statement: """ + MATCH (this)-[:WROTE]->(r:Post) + WHERE (NOT exists(r.deleted) OR r.deleted = false) + AND (NOT exists(r.disabled) OR r.disabled = false) + RETURN COUNT(r)""" + ) comments: [WrittenComment]! commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) RETURN COUNT(r)") shouted: [Post]! @relation(name: "SHOUTED", direction: "OUT") + shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) RETURN COUNT(r)") organizationsCreated: [Organization] @relation(name: "CREATED_ORGA", direction: "OUT") organizationsOwned: [Organization] @relation(name: "OWNING_ORGA", direction: "OUT") @@ -66,16 +81,19 @@ type Post { contentExcerpt: String image: String visibility: VisibilityEnum - disabled: Boolean @default(to: false) + deleted: Boolean @default(to: false) - # relatedContributions: [Post]! @cypher(statement: "MATCH (this)-[:TAGGED]->(t:Tag)<-[:TAGGED]-(p1:Post) MATCH (this)-[:CATEGORIZED]->(t:Category)<-[:CATEGORIZED]-(p2:Post) RETURN collect(distinct p2) + p1") - relatedContributions: [Post]! @cypher(statement: "MATCH (this)-[:TAGGED]->(t:Tag)<-[:TAGGED]-(p:Post) return p") + relatedContributions: [Post]! @cypher(statement: """ + MATCH (this)-[:TAGGED|CATEGORIZED]->(categoryOrTag)<-[:TAGGED|CATEGORIZED]-(post:Post) + RETURN DISTINCT post + LIMIT 10 + """) tags: [Tag]! @relation(name: "TAGGED", direction: "OUT") categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT") - comments: [Comment]! @relation(name: "COMMENT", direction: "IN") - commentsCount: Int! @cypher(statement: "MATCH (this)<-[:COMMENT]-(r:Comment) RETURN COUNT(r)") + comments: [Comment]! @relation(name: "COMMENTS", direction: "IN") + commentsCount: Int! @cypher(statement: "MATCH (this)<-[:COMMENTS]-(r:Comment) RETURN COUNT(r)") shoutedBy: [User]! @relation(name: "SHOUTED", direction: "IN") shoutedCount: Int! @cypher(statement: "MATCH (this)<-[:SHOUTED]-(r:User) RETURN COUNT(r)") @@ -87,7 +105,7 @@ type Comment { content: String! contentExcerpt: String post: Post @relation(name: "COMMENT", direction: "OUT") - disabled: Boolean @default(to: false) + deleted: Boolean @default(to: false) } type Category { @@ -95,6 +113,8 @@ type Category { name: String! slug: String icon: String! + posts: [Post]! @relation(name: "CATEGORIZED", direction: "IN") + postCount: Int! @cypher(statement: "MATCH (this)<-[:CATEGORIZED]-(r:Post) RETURN COUNT(r)") } type Badge { @@ -124,7 +144,7 @@ type Organization { slug: String description: String! descriptionExcerpt: String - disabled: Boolean @default(to: false) + deleted: Boolean @default(to: false) tags: [Tag]! @relation(name: "TAGGED", direction: "OUT") categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT") @@ -136,5 +156,5 @@ type Tag { taggedPosts: [Post]! @relation(name: "TAGGED", direction: "IN") taggedOrganizations: [Organization]! @relation(name: "TAGGED", direction: "IN") taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(r) RETURN COUNT(r)") - disabled: Boolean @default(to: false) + deleted: Boolean @default(to: false) } From e7a59d303a491db649f11d8648a7f0d190988790 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 16 Oct 2018 14:36:42 +0200 Subject: [PATCH 013/554] added disabled and deleted keys to the seeder and schema --- src/schema.graphql | 3 +++ src/seed/seed-mutations.js | 54 +++++++++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index e7e936bab..f67b53bf2 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -82,6 +82,7 @@ type Post { image: String visibility: VisibilityEnum deleted: Boolean @default(to: false) + disabled: Boolean @default(to: false) relatedContributions: [Post]! @cypher(statement: """ MATCH (this)-[:TAGGED|CATEGORIZED]->(categoryOrTag)<-[:TAGGED|CATEGORIZED]-(post:Post) @@ -106,6 +107,7 @@ type Comment { contentExcerpt: String post: Post @relation(name: "COMMENT", direction: "OUT") deleted: Boolean @default(to: false) + disabled: Boolean @default(to: false) } type Category { @@ -145,6 +147,7 @@ type Organization { description: String! descriptionExcerpt: String deleted: Boolean @default(to: false) + disabled: Boolean @default(to: false) tags: [Tag]! @relation(name: "TAGGED", direction: "OUT") categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT") diff --git a/src/seed/seed-mutations.js b/src/seed/seed-mutations.js index ec9a1317c..9b85ec0d6 100644 --- a/src/seed/seed-mutations.js +++ b/src/seed/seed-mutations.js @@ -74,7 +74,9 @@ export default ` title: "Gedanken eines Polizisten zum Einsatz im Hambacher Forst", content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", image: "https://picsum.photos/1280/1024?image=352", - visibility: Public + visibility: Public, + disabled: false, + deleted: false ) { title } p1_cat1: AddPostCategories(from: {id: "p1"}, to: {id: "cat1"}) { from { id } } p1_cat2: AddPostCategories(from: {id: "p1"}, to: {id: "cat2"}) { from { id } } @@ -85,7 +87,9 @@ export default ` title: "Julian Assange", content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", image: "https://picsum.photos/1280/1024?image=72", - visibility: Public + visibility: Public, + disabled: false, + deleted: false ) { title } p2_cat1: AddPostCategories(from: {id: "p2"}, to: {id: "cat1"}) { from { id } } p2_cat16: AddPostCategories(from: {id: "p2"}, to: {id: "cat16"}) { from { id } } @@ -96,7 +100,9 @@ export default ` title: "Hacker, Freaks und Funktionäre...Der CCC", content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", image: "https://picsum.photos/1280/1024?image=121", - visibility: Public + visibility: Public, + disabled: false, + deleted: false ) { title } p3_cat1: AddPostCategories(from: {id: "p3"}, to: {id: "cat1"}) { from { id } } p3_cat3: AddPostCategories(from: {id: "p3"}, to: {id: "cat3"}) { from { id } } @@ -108,7 +114,9 @@ export default ` title: "Lebensmittel (?)", content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", image: "https://picsum.photos/1280/1024?image=142", - visibility: Public + visibility: Public, + disabled: false, + deleted: false ) { title } p4_cat1: AddPostCategories(from: {id: "p4"}, to: {id: "cat1"}) { from { id } } p4_cat9: AddPostCategories(from: {id: "p4"}, to: {id: "cat9"}) { from { id } } @@ -120,7 +128,9 @@ export default ` title: "${faker.lorem.sentence()}", content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", image: "https://picsum.photos/1280/1024?image=231", - visibility: Public + visibility: Public, + disabled: false, + deleted: false ) { title } p5_cat8: AddPostCategories(from: {id: "p5"}, to: {id: "cat8"}) { from { id } } p5_cat12: AddPostCategories(from: {id: "p5"}, to: {id: "cat12"}) { from { id } } @@ -131,7 +141,9 @@ export default ` title: "${faker.lorem.sentence()}", content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", image: "https://picsum.photos/1280/1024?image=424", - visibility: Public + visibility: Public, + disabled: false, + deleted: false ) { title } p6_cat1: AddPostCategories(from: {id: "p6"}, to: {id: "cat1"}) { from { id } } p6_cat2: AddPostCategories(from: {id: "p6"}, to: {id: "cat2"}) { from { id } } @@ -142,42 +154,56 @@ export default ` c1: CreateComment( id: "c1", content: "

da stimm ich dir zu. Mir ging das auch nie in den kopf, und hatte jesus nie als gott gesehen.

", + disabled: false, + deleted: false ) { id } c1_u1: AddCommentAuthor(from: { id: "u3" }, to: { id: "c1" }, data: { timestamp: 1538655020 }) { from { id } } c2: CreateComment( id: "c2", content: "

Schön das es dich gibt ❤️❤️❤️❤️❤️❤️❤️❤️❤️

", + disabled: false, + deleted: false ) { id } c2_u1: AddCommentAuthor(from: { id: "u1" }, to: { id: "c2" }, data: { timestamp: 1538655020 }) { from { id } } c3: CreateComment( id: "c3", content: "

Hi Dieter,

danke fĂźr Deine Info. Hast Du mal ein Foto von Deinem Cabrio mit dem Logo drauf?

", + disabled: false, + deleted: false ) { id } c3_u2: AddCommentAuthor(from: { id: "u1" }, to: { id: "c3" }, data: { timestamp: 1538655020 }) { from { id } } c4: CreateComment( id: "c4", content: "

Das ZusammenfĂźhren aller Gruppen, die mit uns am gleichen Strang in die gleiche Richtung ziehen, in eine gemeinsame Adressenstruktur sehe ich auch als Haupt - Aufgabe fĂźr unsere neue Netzwerkbildung an.

", + disabled: false, + deleted: false ) { id } c4_u3: AddCommentAuthor(from: { id: "u4" }, to: { id: "c4" }, data: { timestamp: 1538655020 }) { from { id } } c5: CreateComment( id: "c5", content: "${faker.lorem.paragraph()}", + disabled: false, + deleted: false ) { id } c5_u4: AddCommentAuthor(from: { id: "u4" }, to: { id: "c5" }, data: { timestamp: 1538655020 }) { from { id } } c6: CreateComment( id: "c6", content: "${faker.lorem.paragraph()}", + disabled: false, + deleted: false ) { id } c6_u3: AddCommentAuthor(from: { id: "u3" }, to: { id: "c6" }, data: { timestamp: 1538655020 }) { from { id } } c7: CreateComment( id: "c7", content: "${faker.lorem.paragraph()}", + disabled: false, + deleted: false ) { id } c7_u2: AddCommentAuthor(from: { id: "u2" }, to: { id: "c7" }, data: { timestamp: 1538655020 }) { from { id } } @@ -260,22 +286,30 @@ export default ` o1: CreateOrganization( id: "o1", name: "Democracy Deutschland", - description: "Description for democracy-deutschland." + description: "Description for democracy-deutschland.", + disabled: false, + deleted: false ) { name } o2: CreateOrganization( id: "o2", name: "Human-Connection", - description: "Description for human-connection." + description: "Description for human-connection.", + disabled: false, + deleted: false ) { name } o3: CreateOrganization( id: "o3", name: "Pro Veg", - description: "Description for pro-veg." + description: "Description for pro-veg.", + disabled: false, + deleted: false ) { name } o4: CreateOrganization( id: "o4", name: "Greenpeace", - description: "Description for greenpeace." + description: "Description for greenpeace.", + disabled: false, + deleted: false ) { name } u1_c_o1: AddOrganizationCreatedBy( From 43707a4fcbcd01ba57c689b5a6cf48e165b67b81 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 17 Oct 2018 20:07:58 +0200 Subject: [PATCH 014/554] using graphql-yoga and implemented jwt login --- .env | 4 + .gitignore | 1 + package.json | 11 +- src/graphql-schema.js | 55 ++- src/index.js | 104 ++-- src/jwt/generateToken.js | 18 + src/jwt/strategy.js | 30 ++ src/middleware/fixImageUrlsMiddleware.js | 9 +- src/middleware/index.js | 13 + src/mocks/index.js | 15 + src/schema.graphql | 17 + yarn.lock | 580 ++++++++++++++++++----- 12 files changed, 695 insertions(+), 162 deletions(-) create mode 100644 src/jwt/generateToken.js create mode 100644 src/jwt/strategy.js create mode 100644 src/middleware/index.js create mode 100644 src/mocks/index.js diff --git a/.env b/.env index 4d849a121..dcb5cdb41 100644 --- a/.env +++ b/.env @@ -1,6 +1,10 @@ NEO4J_URI=bolt://localhost:7687 NEO4J_USER=neo4j NEO4J_PASSWORD=letmein + GRAPHQL_LISTEN_PORT=4000 GRAPHQL_URI=http://localhost:4000 +CLIENT_URI=http://localhost:3000 +JWT_SECRET=b/&&7b78BF&fv/Vd + MOCK=false diff --git a/.gitignore b/.gitignore index c2658d7d1..c8fcd1649 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules/ +.vscode diff --git a/package.json b/package.json index 227824f28..1612d5211 100644 --- a/package.json +++ b/package.json @@ -16,20 +16,27 @@ "apollo-client": "^2.3.2", "apollo-link-http": "^1.5.4", "apollo-server": "^2.0.4", + "bcryptjs": "^2.4.3", "dotenv": "^6.0.0", "graphql-custom-directives": "^0.2.13", "graphql-middleware": "^1.7.6", "graphql-tag": "^2.9.2", + "graphql-yoga": "^1.16.2", + "jsonwebtoken": "^8.3.0", + "lodash": "^4.17.11", + "ms": "^2.1.1", "neo4j-driver": "^1.6.1", "neo4j-graphql-js": "^1.0.2", "node-fetch": "^2.1.2", + "passport": "^0.4.0", + "passport-jwt": "^4.0.0", "slug": "^0.9.1", "trunc-html": "^1.1.2" }, "devDependencies": { - "faker": "^4.1.0", "babel-cli": "^6.26.0", "babel-preset-env": "^1.7.0", - "nodemon": "^1.17.5" + "faker": "^4.1.0", + "nodemon": "^1.18.4" } } diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 3a0c954cb..9f7699c77 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -1,17 +1,62 @@ // import { neo4jgraphql } from "neo4j-graphql-js" import fs from 'fs' import path from 'path' +import bcrypt from 'bcryptjs' +import zipObject from 'lodash/zipObject' +import generateJwt from './jwt/generateToken' +import { fixUrl } from './middleware/fixImageUrlsMiddleware' export const typeDefs = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, "schema.graphql")) .toString('utf-8') export const resolvers = { - // Query: { - // usersBySubstring: neo4jgraphql - // } -} + Query: { + isLoggedIn: (parent, args, { user }) => { + console.log(user) + return Boolean(user && user.id) + } + // usersBySubstring: neo4jgraphql + }, + Mutation: { + signup: async (parent, { email, password }, { req }) => { + // if (data[email]) { + // throw new Error('Another User with same email exists.') + // } + // data[email] = { + // password: await bcrypt.hashSync(password, 10), + // } -export const mutations = { + return true + }, + login: async (parent, { email, password }, { driver, req, user }) => { + // if (user && user.id) { + // throw new Error('Already logged in.') + // } + const session = driver.session() + const res = await session.run('MATCH (u:User {email: "' + email + '"}) RETURN u.id, u.slug, u.name, u.avatar, u.email, u.password, u.role LIMIT 1') + let u = res.records[0]._fields ? zipObject([ + 'id', + 'slug', + 'name', + 'avatar', + 'email', + 'password', + 'role' + ], res.records[0]._fields) : null + if (u) { + if (await bcrypt.compareSync(password, u.password)) { + delete u.password + u.avatar = fixUrl(u.avatar) + return Object.assign(u, { + token: generateJwt(u) + }) + } + throw new Error('Incorrect password.') + } + + throw new Error('No Such User exists.') + } + } } diff --git a/src/index.js b/src/index.js index 4f39b5f0a..8cae4d4f6 100644 --- a/src/index.js +++ b/src/index.js @@ -1,21 +1,21 @@ -// import { GraphQLServer } from 'graphql-yoga' -import { applyMiddleware } from 'graphql-middleware' -import { ApolloServer, makeExecutableSchema } from 'apollo-server' +import { GraphQLServer } from 'graphql-yoga' +import { makeExecutableSchema } from 'apollo-server' import { augmentSchema } from 'neo4j-graphql-js' import { typeDefs, resolvers } from './graphql-schema' import { v1 as neo4j } from 'neo4j-driver' -import passwordMiddleware from './middleware/passwordMiddleware' -import softDeleteMiddleware from './middleware/softDeleteMiddleware' -import sluggifyMiddleware from './middleware/sluggifyMiddleware' -import fixImageUrlsMiddleware from './middleware/fixImageUrlsMiddleware' -import excerptMiddleware from './middleware/excerptMiddleware' import dotenv from 'dotenv' -import { - GraphQLLowerCaseDirective, - GraphQLTrimDirective, - GraphQLDefaultToDirective -} from 'graphql-custom-directives'; -import faker from 'faker' +import mocks from './mocks' +import middleware from './middleware' + +import passport from 'passport' +import jwtStrategy from './jwt/strategy' +import jwt from 'jsonwebtoken' + +// import { +// GraphQLLowerCaseDirective, +// GraphQLTrimDirective, +// GraphQLDefaultToDirective +// } from 'graphql-custom-directives'; dotenv.config() @@ -25,15 +25,15 @@ const schema = makeExecutableSchema({ }) // augmentSchema will add auto generated mutations based on types in schema -const augmentedSchema = augmentSchema(schema) +// const augmentedSchema = augmentSchema(schema) // add custom directives -const directives = [ - GraphQLLowerCaseDirective, - GraphQLTrimDirective, - GraphQLDefaultToDirective -] -augmentedSchema._directives.push.apply(augmentedSchema._directives, directives) +// const directives = [ +// GraphQLLowerCaseDirective, +// GraphQLTrimDirective, +// GraphQLDefaultToDirective +// ] +// augmentedSchema._directives.push.apply(augmentedSchema._directives, directives) const driver = neo4j.driver( process.env.NEO4J_URI || 'bolt://localhost:7687', @@ -46,25 +46,51 @@ const driver = neo4j.driver( const MOCK = (process.env.MOCK === 'true') console.log('MOCK:', MOCK) -const server = new ApolloServer({ - context: { - driver +const server = new GraphQLServer({ + context: async (req) => { + const payload = { + driver, + user: null, + req: req.request + } + try { + const token = payload.req.headers.authorization.replace('Bearer ', '') + payload.user = await jwt.verify(token, process.env.JWT_SECRET) + } catch (err) {} + + return payload }, + schema: augmentSchema(schema), tracing: true, - schema: applyMiddleware(augmentedSchema, passwordMiddleware, sluggifyMiddleware, excerptMiddleware, fixImageUrlsMiddleware, softDeleteMiddleware), - mocks: MOCK ? { - User: () => ({ - name: () => `${faker.name.firstName()} ${faker.name.lastName()}`, - email: () => `${faker.internet.email()}` - }), - Post: () => ({ - title: () => faker.lorem.lines(1), - slug: () => faker.lorem.slug(3), - content: () => faker.lorem.paragraphs(5), - contentExcerpt: () => faker.lorem.paragraphs(1) - }) - } : false + middlewares: middleware, + mocks: MOCK ? mocks : false }) -server.listen().then(({ url }) => { - console.log(`Server ready at ${url} 🚀`); + +passport.use('jwt', jwtStrategy()) +server.express.use(passport.initialize()) + +server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) + +// session middleware +// server.express.use(session({ +// name: 'qid', +// secret: process.env.JWT_SECRET, +// resave: true, +// saveUninitialized: true, +// cookie: { +// secure: process.env.NODE_ENV === 'production', +// maxAge: ms('1d') +// } +// })) + +const serverConfig = { + port: 4000 + // cors: { + // credentials: true, + // origin: [process.env.CLIENT_URI] // your frontend url. + // } +} + +server.start(serverConfig, options => { + console.log(`Server ready at ${process.env.GRAPHQL_URI} 🚀`); }) diff --git a/src/jwt/generateToken.js b/src/jwt/generateToken.js new file mode 100644 index 000000000..f02ea7c8f --- /dev/null +++ b/src/jwt/generateToken.js @@ -0,0 +1,18 @@ + +import jwt from 'jsonwebtoken' +import ms from 'ms' + +// Generate an Access Token for the given User ID +export default function generateJwt(user) { + console.log('generateJwt', user) + const token = jwt.sign(user, process.env.JWT_SECRET, { + expiresIn: ms('1d'), + issuer: process.env.GRAPHQL_URI, + audience: process.env.CLIENT_URI, + subject: user.id.toString() + }) + jwt.verify(token, process.env.JWT_SECRET, (err, data) => { + console.log('token verification:', err, data) + }) + return token +} diff --git a/src/jwt/strategy.js b/src/jwt/strategy.js new file mode 100644 index 000000000..97593ae82 --- /dev/null +++ b/src/jwt/strategy.js @@ -0,0 +1,30 @@ +import { Strategy } from 'passport-jwt' + +const cookieExtractor = (req) => { + var token = null + if (req && req.cookies) { + token = req.cookies['jwt'] + } + return token +} + +export default () => { + const options = { + jwtFromRequest: cookieExtractor, + secretOrKey: process.env.JWT_SECRET, + issuer: process.env.GRAPHQL_URI, + audience: process.env.CLIENT_URI + } + + return new Strategy(options, + (JWTPayload, next) => { + console.log('JWT Payload Received:', JWTPayload) + // usually this would be a database call: + // var user = users[_.findIndex(users, {id: JWTPayload.id})] + if (true) { + next(null, {}) + } else { + next(null, false) + } + }) +} diff --git a/src/middleware/fixImageUrlsMiddleware.js b/src/middleware/fixImageUrlsMiddleware.js index 218f3c2ea..04c08c303 100644 --- a/src/middleware/fixImageUrlsMiddleware.js +++ b/src/middleware/fixImageUrlsMiddleware.js @@ -1,21 +1,24 @@ -const replaceURL = (url) => { +export const fixUrl = (url) => { return url.replace('https://api-alpha.human-connection.org/uploads', 'http://localhost:3000/uploads') } const fixImageURLs = (result, resolve, root, args, context, info) => { if (result && typeof result === 'string' && result.indexOf('https://api-alpha.human-connection.org/uploads') === 0) { - result = replaceURL(result) + result = fixUrl(result) } else if (result && typeof result === 'object') { Object.keys(result).forEach(key => { result[key] = fixImageURLs(result[key]) }) } - return result } export default { + Mutation: async (resolve, root, args, context, info) => { + const result = await resolve(root, args, context, info) + return fixImageURLs(result, resolve, root, args, context, info) + }, Query: async (resolve, root, args, context, info) => { let result = await resolve(root, args, context, info) diff --git a/src/middleware/index.js b/src/middleware/index.js new file mode 100644 index 000000000..9a32862c3 --- /dev/null +++ b/src/middleware/index.js @@ -0,0 +1,13 @@ +import passwordMiddleware from './passwordMiddleware' +import softDeleteMiddleware from './softDeleteMiddleware' +import sluggifyMiddleware from './sluggifyMiddleware' +import fixImageUrlsMiddleware from './fixImageUrlsMiddleware' +import excerptMiddleware from './excerptMiddleware' + +export default [ + passwordMiddleware, + sluggifyMiddleware, + excerptMiddleware, + fixImageUrlsMiddleware, + softDeleteMiddleware +] diff --git a/src/mocks/index.js b/src/mocks/index.js new file mode 100644 index 000000000..a87ccfbbc --- /dev/null +++ b/src/mocks/index.js @@ -0,0 +1,15 @@ + +import faker from 'faker' + +export default { + User: () => ({ + name: () => `${faker.name.firstName()} ${faker.name.lastName()}`, + email: () => `${faker.internet.email()}` + }), + Post: () => ({ + title: () => faker.lorem.lines(1), + slug: () => faker.lorem.slug(3), + content: () => faker.lorem.paragraphs(5), + contentExcerpt: () => faker.lorem.paragraphs(1) + }) +} diff --git a/src/schema.graphql b/src/schema.graphql index f67b53bf2..0334b4124 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -1,3 +1,20 @@ +type Query { + isLoggedIn: Boolean! +} +type Mutation { + login(email: String!, password: String!): LoggedInUser + signup(email: String!, password: String!): Boolean! +} +type LoggedInUser { + id: ID! + slug: String! + name: String! + avatar:String! + email: String! + role: String!, + token: String! +} + enum VisibilityEnum { Public Friends diff --git a/yarn.lock b/yarn.lock index e897cb8e2..ab036af96 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21,6 +21,12 @@ core-js "^2.5.7" regenerator-runtime "^0.12.0" +"@babel/runtime@^7.0.0-beta.40": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.2.tgz#81c89935f4647706fc54541145e6b4ecfef4b8e3" + dependencies: + regenerator-runtime "^0.12.0" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -66,13 +72,13 @@ "@types/accepts@^1.3.5": version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" + resolved "http://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" dependencies: "@types/node" "*" "@types/async@2.0.49": version "2.0.49" - resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0" + resolved "http://registry.npmjs.org/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0" "@types/body-parser@*", "@types/body-parser@1.17.0": version "1.17.0" @@ -95,7 +101,7 @@ "@types/events@*": version "1.2.0" - resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" + resolved "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" "@types/express-serve-static-core@*": version "4.16.0" @@ -105,7 +111,7 @@ "@types/node" "*" "@types/range-parser" "*" -"@types/express@*", "@types/express@4.16.0": +"@types/express@*", "@types/express@4.16.0", "@types/express@^4.11.1": version "4.16.0" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.0.tgz#6d8bc42ccaa6f35cf29a2b7c3333cb47b5a32a19" dependencies: @@ -113,6 +119,14 @@ "@types/express-serve-static-core" "*" "@types/serve-static" "*" +"@types/graphql-deduplicator@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/graphql-deduplicator/-/graphql-deduplicator-2.0.0.tgz#9e577b8f3feb3d067b0ca756f4a1fb356d533922" + +"@types/graphql@^0.13.0": + version "0.13.4" + resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.13.4.tgz#55ae9c29f0fd6b85ee536f5c72b4769d5c5e06b1" + "@types/long@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" @@ -122,8 +136,8 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" "@types/node@*", "@types/node@^10.1.0": - version "10.11.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.4.tgz#e8bd933c3f78795d580ae41d86590bfc1f4f389d" + version "10.12.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.0.tgz#ea6dcbddbc5b584c83f06c60e82736d8fbb0c235" "@types/range-parser@*": version "1.2.2" @@ -143,6 +157,10 @@ "@types/events" "*" "@types/node" "*" +"@types/zen-observable@^0.5.3": + version "0.5.4" + resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.4.tgz#b863a4191e525206819e008097ebf0fb2e3a1cdc" + "@types/zen-observable@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" @@ -209,6 +227,12 @@ apollo-boost@^0.1.10: apollo-link-state "^0.4.0" graphql-tag "^2.4.2" +apollo-cache-control@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz#173d14ceb3eb9e7cb53de7eb8b61bee6159d4171" + dependencies: + graphql-extensions "^0.0.x" + apollo-cache-control@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.2.5.tgz#0831ad796754a7beec858668f99e7517fe744a1e" @@ -217,12 +241,12 @@ apollo-cache-control@^0.2.5: graphql-extensions "^0.2.1" apollo-cache-inmemory@^1.2.10, apollo-cache-inmemory@^1.2.5: - version "1.2.10" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.2.10.tgz#362d6c36cfd815a309b966f71e5d2b6c770c7989" + version "1.3.5" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.5.tgz#7628ee598271cfffa611e15a7ce67652a84b07b0" dependencies: apollo-cache "^1.1.17" apollo-utilities "^1.0.21" - graphql-anywhere "^4.1.19" + optimism "^0.6.6" apollo-cache@1.1.17, apollo-cache@^1.1.17: version "1.1.17" @@ -312,6 +336,14 @@ apollo-server-caching@0.1.2, apollo-server-caching@^0.1.2: dependencies: lru-cache "^4.1.3" +apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592" + dependencies: + apollo-cache-control "^0.1.0" + apollo-tracing "^0.1.0" + graphql-extensions "^0.0.x" + apollo-server-core@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.1.0.tgz#b56f9f1ddb948b257e738eb25c5fdfd2f2fb2e07" @@ -345,6 +377,13 @@ apollo-server-errors@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz#e9cbb1b74d2cd78aed23cd886ca2d0c186323b2b" +apollo-server-express@^1.3.6: + version "1.4.0" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.4.0.tgz#7d7c58d6d6f9892b83fe575669093bb66738b125" + dependencies: + apollo-server-core "^1.4.0" + apollo-server-module-graphiql "^1.4.0" + apollo-server-express@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.1.0.tgz#b2d423c2c934df5c4e0a1b0d5f0088a9461f3c86" @@ -363,6 +402,17 @@ apollo-server-express@^2.1.0: graphql-tools "^3.0.4" type-is "^1.6.16" +apollo-server-lambda@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/apollo-server-lambda/-/apollo-server-lambda-1.3.6.tgz#bdaac37f143c6798e40b8ae75580ba673cea260e" + dependencies: + apollo-server-core "^1.3.6" + apollo-server-module-graphiql "^1.3.4" + +apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" + apollo-server@^2.0.4: version "2.1.0" resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.1.0.tgz#abec7853647c59f386087352cc7f06a4f1f8afe2" @@ -373,6 +423,12 @@ apollo-server@^2.0.4: graphql-subscriptions "^0.5.8" graphql-tools "^3.0.4" +apollo-tracing@^0.1.0: + version "0.1.4" + resolved "http://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" + dependencies: + graphql-extensions "~0.0.9" + apollo-tracing@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.2.5.tgz#15bb8d6f37efe8c1bb6351e8e21521dd4f14c5f2" @@ -380,6 +436,14 @@ apollo-tracing@^0.2.5: apollo-server-env "^2.0.3" graphql-extensions "^0.2.1" +apollo-upload-server@^5.0.0: + version "5.0.0" + resolved "http://registry.npmjs.org/apollo-upload-server/-/apollo-upload-server-5.0.0.tgz#c953b523608313966e0c8444637f4ae8ef77d5bc" + dependencies: + "@babel/runtime" "^7.0.0-beta.40" + busboy "^0.2.14" + object-path "^0.11.4" + apollo-utilities@1.0.21, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.21, apollo-utilities@^1.0.8: version "1.0.21" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.21.tgz#cb8b5779fe275850b16046ff8373f4af2de90765" @@ -398,6 +462,12 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + dependencies: + sprintf-js "~1.0.2" + arr-diff@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" @@ -458,6 +528,28 @@ atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" +aws-lambda@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/aws-lambda/-/aws-lambda-0.1.2.tgz#19b1585075df31679597b976a5f1def61f12ccee" + dependencies: + aws-sdk "^*" + commander "^2.5.0" + dotenv "^0.4.0" + +aws-sdk@^*: + version "2.336.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.336.0.tgz#b15371aff3e30ba77b74968c086375594be897c9" + dependencies: + buffer "4.9.1" + events "1.1.1" + ieee754 "1.1.8" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.1.0" + xml2js "0.4.19" + babel-cli@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" @@ -953,6 +1045,10 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" @@ -965,26 +1061,21 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +bcryptjs@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + binary-extensions@^1.0.0: version "1.12.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" -body-parser@1.18.2: - version "1.18.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" +body-parser-graphql@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/body-parser-graphql/-/body-parser-graphql-1.1.0.tgz#80a80353c7cb623562fd375750dfe018d75f0f7c" dependencies: - bytes "3.0.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.1" - http-errors "~1.6.2" - iconv-lite "0.4.19" - on-finished "~2.3.0" - qs "6.5.1" - raw-body "2.3.2" - type-is "~1.6.15" + body-parser "^1.18.2" -body-parser@^1.18.3: +body-parser@1.18.3, body-parser@^1.18.2, body-parser@^1.18.3: version "1.18.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" dependencies: @@ -1048,6 +1139,22 @@ browserslist@^3.2.6: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + +buffer@4.9.1: + version "4.9.1" + resolved "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + busboy@^0.2.14: version "0.2.14" resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" @@ -1078,8 +1185,8 @@ camelcase@^4.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" caniuse-lite@^1.0.30000844: - version "1.0.30000889" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000889.tgz#53e266c83e725ad3bd2e4a3ea76d5031a8aa4c3e" + version "1.0.30000892" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000892.tgz#344d2b51ee3ff5977537da4aa449c90eec40b759" capture-stack-trace@^1.0.0: version "1.0.1" @@ -1179,9 +1286,9 @@ color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" -commander@^2.11.0: - version "2.18.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" +commander@^2.11.0, commander@^2.5.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" component-emitter@^1.2.1: version "1.2.1" @@ -1232,7 +1339,7 @@ copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" -core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.7: +core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.3, core-js@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -1253,6 +1360,13 @@ create-error-class@^3.0.0: dependencies: capture-stack-trace "^1.0.0" +cross-fetch@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.2.tgz#a47ff4f7fc712daba8f6a695a11c948440d45723" + dependencies: + node-fetch "2.1.2" + whatwg-fetch "2.0.4" + cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -1272,8 +1386,8 @@ debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6. ms "2.0.0" debug@^3.1.0: - version "3.2.5" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.5.tgz#c2418fbfd7a29f4d4f70ff4cea604d4b64c46407" + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" dependencies: ms "^2.1.1" @@ -1314,11 +1428,7 @@ delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" -depd@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" - -depd@~1.1.1, depd@~1.1.2: +depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -1353,9 +1463,13 @@ dot-prop@^4.1.0: dependencies: is-obj "^1.0.0" +dotenv@^0.4.0: + version "0.4.0" + resolved "http://registry.npmjs.org/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" + dotenv@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.0.0.tgz#24e37c041741c5f4b25324958ebbc34bca965935" + version "6.1.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.1.0.tgz#9853b6ca98292acb7dec67a95018fa40bccff42c" duplexer3@^0.1.4: version "0.1.4" @@ -1365,13 +1479,19 @@ duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.1" resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" +ecdsa-sig-formatter@1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz#1c595000f04a8897dfb85000892a0f4c33af86c3" + dependencies: + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" electron-to-chromium@^1.3.47: - version "1.3.73" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.73.tgz#aa67787067d58cc3920089368b3b8d6fe0fc12f6" + version "1.3.79" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.79.tgz#774718f06284a4bf8f578ac67e74508fe659f13a" encodeurl@~1.0.2: version "1.0.2" @@ -1403,6 +1523,10 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -1428,6 +1552,10 @@ eventemitter3@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" +events@1.1.1: + version "1.1.1" + resolved "http://registry.npmjs.org/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -1464,13 +1592,13 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -express@^4.0.0: - version "4.16.3" - resolved "http://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" +express@^4.0.0, express@^4.16.3: + version "4.16.4" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" dependencies: accepts "~1.3.5" array-flatten "1.1.1" - body-parser "1.18.2" + body-parser "1.18.3" content-disposition "0.5.2" content-type "~1.0.4" cookie "0.3.1" @@ -1487,10 +1615,10 @@ express@^4.0.0: on-finished "~2.3.0" parseurl "~1.3.2" path-to-regexp "0.1.7" - proxy-addr "~2.0.3" - qs "6.5.1" + proxy-addr "~2.0.4" + qs "6.5.2" range-parser "~1.2.0" - safe-buffer "5.1.1" + safe-buffer "5.1.2" send "0.16.2" serve-static "1.13.2" setprototypeof "1.1.0" @@ -1579,8 +1707,8 @@ finalhandler@1.1.1: unpipe "~1.0.0" flatmap-stream@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.0.tgz#ed54e01422cd29281800914fcb968d58b685d5f1" + version "0.1.1" + resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.1.tgz#d34f39ef3b9aa5a2fc225016bd3adf28ac5ae6ea" for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" @@ -1717,12 +1845,22 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" -graphql-anywhere@^4.1.0-alpha.0, graphql-anywhere@^4.1.19: +graphql-anywhere@^4.1.0-alpha.0: version "4.1.19" resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.19.tgz#5f6ca3b58218e5449f4798e3c6d942fcd2fef082" dependencies: apollo-utilities "^1.0.21" +graphql-config@2.0.0: + version "2.0.0" + resolved "http://registry.npmjs.org/graphql-config/-/graphql-config-2.0.0.tgz#daf69091055c6f675d63893a2d14c48f3fec3327" + dependencies: + graphql-import "^0.4.0" + graphql-request "^1.4.0" + js-yaml "^3.10.0" + lodash "^4.17.4" + minimatch "^3.0.4" + graphql-custom-directives@^0.2.13: version "0.2.13" resolved "https://registry.yarnpkg.com/graphql-custom-directives/-/graphql-custom-directives-0.2.13.tgz#5e175069f5ff404f751d232e302007bc25488ea8" @@ -1731,17 +1869,76 @@ graphql-custom-directives@^0.2.13: moment "^2.22.2" numeral "^2.0.6" +graphql-deduplicator@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.1.tgz#20c6b39e3a6f096b46dfc8491432818739c0ee37" + +graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: + version "0.0.10" + resolved "http://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" + dependencies: + core-js "^2.5.3" + source-map-support "^0.5.1" + graphql-extensions@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.2.1.tgz#7697e0fcea2e622afe9e24dd31fc84f533e84c70" dependencies: apollo-server-env "^2.0.3" -graphql-middleware@^1.7.6: - version "1.7.6" - resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.6.tgz#f226bf6671f3d82a9378f8b335804c8e44d21733" +graphql-import@^0.4.0: + version "0.4.5" + resolved "http://registry.npmjs.org/graphql-import/-/graphql-import-0.4.5.tgz#e2f18c28d335733f46df8e0733d8deb1c6e2a645" dependencies: - graphql-tools "^4.0.0" + lodash "^4.17.4" + +graphql-import@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.6.0.tgz#c00cb8a269ceea263e062922c8c81a2272d1ffcb" + dependencies: + lodash "^4.17.4" + +graphql-middleware@1.6.6: + version "1.6.6" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.6.6.tgz#f40f4e836ced479df718dbc1869ea4cd3b64027b" + dependencies: + graphql-tools "^3.0.5" + +graphql-middleware@^1.7.6: + version "1.7.7" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.7.tgz#0a7a7193a873c4769401df2aef4ffb9c6ca97f43" + dependencies: + graphql-tools "^4.0.1" + +graphql-playground-html@1.5.5: + version "1.5.5" + resolved "http://registry.npmjs.org/graphql-playground-html/-/graphql-playground-html-1.5.5.tgz#e2aca543eb66b435ead495b45244b2604d6b2d48" + dependencies: + graphql-config "2.0.0" + +graphql-playground-html@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz#6ec4d54325ab2e5352506fdb89eb37c3fc718bf8" + dependencies: + graphql-config "2.0.0" + +graphql-playground-middleware-express@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.2.tgz#5f7bf3683494fe17893d1b54bbecee5e222c2e78" + dependencies: + graphql-playground-html "1.6.0" + +graphql-playground-middleware-lambda@1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/graphql-playground-middleware-lambda/-/graphql-playground-middleware-lambda-1.6.1.tgz#e0f1944558136dd3975570c92c702d6009cc779c" + dependencies: + graphql-playground-html "1.5.5" + +graphql-request@^1.4.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" + dependencies: + cross-fetch "2.2.2" graphql-subscriptions@^0.5.8: version "0.5.8" @@ -1753,7 +1950,7 @@ graphql-tag@^2.4.2, graphql-tag@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" -graphql-tools@^3.0.4: +graphql-tools@^3.0.0, graphql-tools@^3.0.4, graphql-tools@^3.0.5: version "3.1.1" resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-3.1.1.tgz#d593358f01e7c8b1671a17b70ddb034dea9dbc50" dependencies: @@ -1763,9 +1960,9 @@ graphql-tools@^3.0.4: iterall "^1.1.3" uuid "^3.1.0" -graphql-tools@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.0.tgz#6ea01937c6f947212f83567ba687e97c22fdd2a6" +graphql-tools@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.1.tgz#c995a4e25c2967d108c975e508322d12969c8c0e" dependencies: apollo-link "^1.2.3" apollo-utilities "^1.0.1" @@ -1773,7 +1970,33 @@ graphql-tools@^4.0.0: iterall "^1.1.3" uuid "^3.1.0" -graphql@^0.13.2: +graphql-yoga@^1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.16.2.tgz#083293a9cecab6283e883c5a482c5c920fa66585" + dependencies: + "@types/cors" "^2.8.4" + "@types/express" "^4.11.1" + "@types/graphql" "^0.13.0" + "@types/graphql-deduplicator" "^2.0.0" + "@types/zen-observable" "^0.5.3" + apollo-server-express "^1.3.6" + apollo-server-lambda "1.3.6" + apollo-upload-server "^5.0.0" + aws-lambda "^0.1.2" + body-parser-graphql "1.1.0" + cors "^2.8.4" + express "^4.16.3" + graphql "^0.11.0 || ^0.12.0 || ^0.13.0" + graphql-deduplicator "^2.0.1" + graphql-import "^0.6.0" + graphql-middleware "1.6.6" + graphql-playground-middleware-express "1.7.2" + graphql-playground-middleware-lambda "1.6.1" + graphql-subscriptions "^0.5.8" + graphql-tools "^3.0.0" + subscriptions-transport-ws "^0.9.8" + +"graphql@^0.11.0 || ^0.12.0 || ^0.13.0", graphql@^0.13.2: version "0.13.2" resolved "http://registry.npmjs.org/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" dependencies: @@ -1848,15 +2071,6 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" -http-errors@1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" - dependencies: - depd "1.1.1" - inherits "2.0.3" - setprototypeof "1.0.3" - statuses ">= 1.3.1 < 2" - http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: version "1.6.3" resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" @@ -1866,10 +2080,6 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -iconv-lite@0.4.19: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" - iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" @@ -1882,6 +2092,14 @@ iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +ieee754@^1.1.4: + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" @@ -1892,6 +2110,10 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" +immutable-tuple@^0.4.4: + version "0.4.8" + resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.8.tgz#f60b65b863d34be39d307d1bbf4a450e1ac3048a" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -2141,7 +2363,7 @@ isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" -isarray@1.0.0, isarray@~1.0.0: +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -2163,6 +2385,10 @@ iterall@^1.1.3, iterall@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" +jmespath@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + "js-tokens@^3.0.0 || ^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -2171,6 +2397,13 @@ js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" +js-yaml@^3.10.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -2183,6 +2416,35 @@ json5@^0.5.1: version "0.5.1" resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" +jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz#056c90eee9a65ed6e6c72ddb0a1d325109aaf643" + dependencies: + jws "^3.1.5" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + +jwa@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.6.tgz#87240e76c9808dbde18783cf2264ef4929ee50e6" + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.10" + safe-buffer "^5.0.1" + +jws@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.5.tgz#80d12d05b293d1e841e7cb8b4e69e561adcf834f" + dependencies: + jwa "^1.1.5" + safe-buffer "^5.0.1" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -2213,7 +2475,35 @@ lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" -lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5: +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + +lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -2350,8 +2640,8 @@ minipass@^2.2.1, minipass@^2.3.3: yallist "^3.0.0" minizlib@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" + version "1.1.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" dependencies: minipass "^2.2.1" @@ -2420,13 +2710,17 @@ neo4j-driver@^1.6.1: uri-js "^4.2.1" neo4j-graphql-js@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.2.tgz#e4dd66b85e817347efb13beaa8340f8eda9df24f" + version "1.0.4" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.4.tgz#250bd44024f1505c726d2fc4ab27a35a1fc5330b" dependencies: graphql "^0.13.2" lodash "^4.17.10" neo4j-driver "^1.6.1" +node-fetch@2.1.2: + version "2.1.2" + resolved "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + node-fetch@^2.1.2: version "2.2.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5" @@ -2446,7 +2740,7 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -nodemon@^1.17.5: +nodemon@^1.18.4: version "1.18.4" resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.4.tgz#873f65fdb53220eb166180cf106b1354ac5d714d" dependencies: @@ -2485,8 +2779,8 @@ npm-bundled@^1.0.1: resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" npm-packlist@^1.1.6: - version "1.1.11" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" + version "1.1.12" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -2572,6 +2866,12 @@ once@^1.3.0: dependencies: wrappy "1" +optimism@^0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.6.tgz#5415b2d6a2f8b3745aedb9f97fdf4e52467ecd84" + dependencies: + immutable-tuple "^0.4.4" + os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -2625,6 +2925,24 @@ pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" +passport-jwt@^4.0.0: + version "4.0.0" + resolved "http://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" + dependencies: + jsonwebtoken "^8.2.0" + passport-strategy "^1.0.0" + +passport-strategy@1.x.x, passport-strategy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + +passport@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" @@ -2651,6 +2969,10 @@ pause-stream@^0.0.11: dependencies: through "~2.3" +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" @@ -2693,7 +3015,7 @@ protobufjs@^6.8.6: "@types/node" "^10.1.0" long "^4.0.0" -proxy-addr@~2.0.3: +proxy-addr@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" dependencies: @@ -2716,18 +3038,22 @@ pstree.remy@^1.1.0: dependencies: ps-tree "^1.1.0" +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" -qs@6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" - qs@6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + randomatic@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.0.tgz#36f2ca708e9e567f5ed2ec01949026d50aa10116" @@ -2740,15 +3066,6 @@ range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" -raw-body@2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" - dependencies: - bytes "3.0.0" - http-errors "1.6.2" - iconv-lite "0.4.19" - unpipe "1.0.0" - raw-body@2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" @@ -2900,11 +3217,7 @@ rimraf@^2.6.1: dependencies: glob "^7.0.5" -safe-buffer@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -2918,7 +3231,11 @@ safe-regex@^1.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" -sax@^1.2.4: +sax@1.2.1: + version "1.2.1" + resolved "http://registry.npmjs.org/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + +sax@>=0.6.0, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -2929,8 +3246,8 @@ semver-diff@^2.0.0: semver "^5.0.3" semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: - version "5.5.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" send@0.16.2: version "0.16.2" @@ -2981,10 +3298,6 @@ set-value@^2.0.0: is-plain-object "^2.0.3" split-string "^3.0.1" -setprototypeof@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" - setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" @@ -3009,7 +3322,7 @@ slash@^1.0.0: slug@^0.9.1: version "0.9.1" - resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.1.tgz#af08f608a7c11516b61778aa800dce84c518cfda" + resolved "http://registry.npmjs.org/slug/-/slug-0.9.1.tgz#af08f608a7c11516b61778aa800dce84c518cfda" dependencies: unicode ">= 0.3.1" @@ -3056,6 +3369,13 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" +source-map-support@^0.5.1: + version "0.5.9" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" @@ -3064,6 +3384,10 @@ source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -3076,6 +3400,10 @@ split@^1.0.1: dependencies: through "2" +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -3083,7 +3411,7 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.3.1 < 2", "statuses@>= 1.4.0 < 2": +"statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" @@ -3147,7 +3475,7 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -subscriptions-transport-ws@^0.9.11: +subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: version "0.9.15" resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz#68a8b7ba0037d8c489fb2f5a102d1494db297d0d" dependencies: @@ -3245,7 +3573,7 @@ trunc-text@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" -type-is@^1.6.16, type-is@~1.6.15, type-is@~1.6.16: +type-is@^1.6.16, type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" dependencies: @@ -3327,6 +3655,13 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" +url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -3350,6 +3685,10 @@ utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" +uuid@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + uuid@^3.1.0: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" @@ -3364,6 +3703,10 @@ vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" +whatwg-fetch@2.0.4: + version "2.0.4" + resolved "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -3377,8 +3720,8 @@ wide-align@^1.1.0: string-width "^1.0.2 || 2" widest-line@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.0.tgz#0142a4e8a243f8882c0233aa0e0281aa76152273" + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" dependencies: string-width "^2.1.1" @@ -3404,6 +3747,17 @@ xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" +xml2js@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + +xmlbuilder@~9.0.1: + version "9.0.7" + resolved "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" From 81430b0bad9896f26f444175d71f28dd3a48c99c Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 18 Oct 2018 12:54:01 +0200 Subject: [PATCH 015/554] fixed install example --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f1805a90c..0965e4967 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,10 @@ Install dependencies: ```bash -yarn install +# NOTE: currently we need the --ignore-engines parameter as one package is an idiot and dont like new node versions +yarn install --ignore-engines # -or- -npm install +npm install --ignore-engines ``` Start the GraphQL service: From 98d90140a2afaaef5fcd47e174c6fe6e0c16c68c Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 18 Oct 2018 13:53:25 +0200 Subject: [PATCH 016/554] updated jwt status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0965e4967..c11d02c70 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ npm run seedDb ## Todo`s -- [ ] add jwt authentication +- [x] add jwt authentication - [ ] get directives working correctly (@toLower, @auth, @role, etc.) - [ ] check if search is working - [ ] check if sorting is working From 31f4db460a1565657cf8c78ac0cf00a5514d0872 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 18 Oct 2018 14:32:45 +0200 Subject: [PATCH 017/554] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c11d02c70..b75488607 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,9 @@ Install dependencies: ```bash -# NOTE: currently we need the --ignore-engines parameter as one package is an idiot and dont like new node versions -yarn install --ignore-engines +yarn install # -or- -npm install --ignore-engines +npm install ``` Start the GraphQL service: From 8d0cc971bbd871cb0210341d5ce2f91ba769183e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 18 Oct 2018 14:48:32 +0200 Subject: [PATCH 018/554] Add README instructions to configure .env --- .env.template | 6 ++++++ .gitignore | 1 + README.md | 6 ++++++ 3 files changed, 13 insertions(+) create mode 100644 .env.template diff --git a/.env.template b/.env.template new file mode 100644 index 000000000..4d849a121 --- /dev/null +++ b/.env.template @@ -0,0 +1,6 @@ +NEO4J_URI=bolt://localhost:7687 +NEO4J_USER=neo4j +NEO4J_PASSWORD=letmein +GRAPHQL_LISTEN_PORT=4000 +GRAPHQL_URI=http://localhost:4000 +MOCK=false diff --git a/.gitignore b/.gitignore index c2658d7d1..713d5006d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules/ +.env diff --git a/README.md b/README.md index f1805a90c..670fefcae 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,12 @@ yarn install npm install ``` +Copy: +``` +cp .env.template .env +``` +Configure the file `.env` according to your needs and your local setup. + Start the GraphQL service: ```bash From e91acd5eb479abdae35cf78ccde388052448db59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 18 Oct 2018 15:35:32 +0200 Subject: [PATCH 019/554] Replace fake email domain with example.org Test.de is the website of Stiftung Warentest. We should do everything right from the beginning, use example.org as the mailserver of choice for our seed data and never spam test.de by accident. --- src/seed/seed-mutations.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/seed/seed-mutations.js b/src/seed/seed-mutations.js index 9b85ec0d6..766ddfe57 100644 --- a/src/seed/seed-mutations.js +++ b/src/seed/seed-mutations.js @@ -4,21 +4,21 @@ export default ` mutation { # Users - u1: CreateUser(id: "u1", name: "Peter Lustig", password: "1234", email: "admin@test.de", avatar: "${faker.internet.avatar()}", role: Admin) { + u1: CreateUser(id: "u1", name: "Peter Lustig", password: "1234", email: "admin@example.org", avatar: "${faker.internet.avatar()}", role: Admin) { id name email avatar role } - u2: CreateUser(id: "u2", name: "Bob der Bausmeister", password: "1234", email: "moderator@test.de", avatar: "${faker.internet.avatar()}", role: Moderator) { + u2: CreateUser(id: "u2", name: "Bob der Bausmeister", password: "1234", email: "moderator@example.org", avatar: "${faker.internet.avatar()}", role: Moderator) { id name email avatar role } - u3: CreateUser(id: "u3", name: "Jenny Rostock", password: "1234", email: "user@test.de", avatar: "${faker.internet.avatar()}", role: Admin) { + u3: CreateUser(id: "u3", name: "Jenny Rostock", password: "1234", email: "user@example.org", avatar: "${faker.internet.avatar()}", role: Admin) { id name email From 77e744022ee3b895d6ab3ae0ced077e46c959bfc Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 19 Oct 2018 12:28:26 +0200 Subject: [PATCH 020/554] fixed password middleware --- src/middleware/passwordMiddleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/passwordMiddleware.js b/src/middleware/passwordMiddleware.js index 1153d4588..139fcffcf 100644 --- a/src/middleware/passwordMiddleware.js +++ b/src/middleware/passwordMiddleware.js @@ -9,7 +9,7 @@ export default { }, Query: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) - if (result.password) { + if (result && result.password) { result.password = '*****' } return result From 58dfc281f7b6e1fc57a0fe5d14af73c9075d3396 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 19 Oct 2018 12:29:27 +0200 Subject: [PATCH 021/554] added statistics type and query and hide deleted or disabled relations --- src/graphql-schema.js | 70 +++++++++++++++++++++++++++++++++++++++++-- src/schema.graphql | 41 ++++++++++++++++--------- 2 files changed, 95 insertions(+), 16 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 9f7699c77..b71c64ab7 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -4,17 +4,81 @@ import path from 'path' import bcrypt from 'bcryptjs' import zipObject from 'lodash/zipObject' import generateJwt from './jwt/generateToken' +import values from 'lodash/values' import { fixUrl } from './middleware/fixImageUrlsMiddleware' export const typeDefs = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, "schema.graphql")) .toString('utf-8') +const query = (cypher, session) => { + return new Promise((resolve, reject) => { + let data = [] + session + .run(cypher) + .subscribe({ + onNext: function (record) { + let item = {} + record.keys.forEach(key => { + item[key] = record.get(key) + }) + data.push(item) + }, + onCompleted: function () { + session.close() + resolve(data) + }, + onError: function (error) { + reject(error) + } + }) + }) +} +const queryOne = (cypher, session) => { + return new Promise((resolve, reject) => { + query(cypher, session) + .then(res => { + resolve(res.length ? res.pop() : {}) + }) + .catch(err => { + reject(err) + }) + }) +} + export const resolvers = { Query: { - isLoggedIn: (parent, args, { user }) => { - console.log(user) + isLoggedIn: (parent, args, { driver, user }) => { return Boolean(user && user.id) + }, + statistics: async (parent, args, { driver, user }) => { + return new Promise(async (resolve) => { + const session = driver.session() + const queries = { + countUsers: `MATCH (r:User) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countUsers`, + countPosts: `MATCH (r:Post) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countPosts`, + countComments: `MATCH (r:Comment) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countComments`, + countNotifications: `MATCH (r:Notification) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countNotifications`, + countOrganizations: `MATCH (r:Organization) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countOrganizations`, + countProjects: `MATCH (r:Project) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countProjects`, + countInvites: `MATCH (r:Invite) WHERE r.wasUsed <> true OR NOT exists(r.wasUsed) RETURN COUNT(r) AS countInvites`, + countFollows: `MATCH (:User)-[r:FOLLOWS]->(:User) RETURN COUNT(r) AS countFollows`, + countShouts: `MATCH (:User)-[r:SHOUTED]->(:Post) RETURN COUNT(r) AS countShouts` + } + let data = { + countUsers: (await queryOne(queries.countUsers, session)).countUsers, + countPosts: (await queryOne(queries.countPosts, session)).countPosts, + countComments: (await queryOne(queries.countComments, session)).countComments, + countNotifications: (await queryOne(queries.countNotifications, session)).countNotifications, + countOrganizations: (await queryOne(queries.countOrganizations, session)).countOrganizations, + countProjects: (await queryOne(queries.countProjects, session)).countProjects, + countInvites: (await queryOne(queries.countInvites, session)).countInvites, + countFollows: (await queryOne(queries.countFollows, session)).countFollows, + countShouts: (await queryOne(queries.countShouts, session)).countShouts + } + resolve(data) + }) + } // usersBySubstring: neo4jgraphql }, @@ -53,9 +117,11 @@ export const resolvers = { token: generateJwt(u) }) } + session.close() throw new Error('Incorrect password.') } + session.close() throw new Error('No Such User exists.') } } diff --git a/src/schema.graphql b/src/schema.graphql index 0334b4124..8ec8310ca 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -1,5 +1,6 @@ type Query { isLoggedIn: Boolean! + statistics: Statistics! } type Mutation { login(email: String!, password: String!): LoggedInUser @@ -11,10 +12,22 @@ type LoggedInUser { name: String! avatar:String! email: String! - role: String!, + role: String! token: String! } +type Statistics { + countUsers: Int! + countPosts: Int! + countComments: Int! + countNotifications: Int! + countOrganizations: Int! + countProjects: Int! + countInvites: Int! + countFollows: Int! + countShouts: Int! +} + enum VisibilityEnum { Public Friends @@ -44,13 +57,13 @@ type WrittenComment @relation(name: "WROTE") { type User { id: ID! - name: String @default(to: "Anonymus") + name: String email: String slug: String password: String! avatar: String - deleted: Boolean @default(to: false) - disabled: Boolean @default(to: false) + deleted: Boolean + disabled: Boolean role: UserGroupEnum friends: [User]! @relation(name: "FRIENDS", direction: "BOTH") @@ -75,10 +88,10 @@ type User { ) comments: [WrittenComment]! - commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) RETURN COUNT(r)") + commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)") shouted: [Post]! @relation(name: "SHOUTED", direction: "OUT") - shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) RETURN COUNT(r)") + shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)") organizationsCreated: [Organization] @relation(name: "CREATED_ORGA", direction: "OUT") organizationsOwned: [Organization] @relation(name: "OWNING_ORGA", direction: "OUT") @@ -98,8 +111,8 @@ type Post { contentExcerpt: String image: String visibility: VisibilityEnum - deleted: Boolean @default(to: false) - disabled: Boolean @default(to: false) + deleted: Boolean + disabled: Boolean relatedContributions: [Post]! @cypher(statement: """ MATCH (this)-[:TAGGED|CATEGORIZED]->(categoryOrTag)<-[:TAGGED|CATEGORIZED]-(post:Post) @@ -114,7 +127,7 @@ type Post { commentsCount: Int! @cypher(statement: "MATCH (this)<-[:COMMENTS]-(r:Comment) RETURN COUNT(r)") shoutedBy: [User]! @relation(name: "SHOUTED", direction: "IN") - shoutedCount: Int! @cypher(statement: "MATCH (this)<-[:SHOUTED]-(r:User) RETURN COUNT(r)") + shoutedCount: Int! @cypher(statement: "MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)") } type Comment { @@ -123,8 +136,8 @@ type Comment { content: String! contentExcerpt: String post: Post @relation(name: "COMMENT", direction: "OUT") - deleted: Boolean @default(to: false) - disabled: Boolean @default(to: false) + deleted: Boolean + disabled: Boolean } type Category { @@ -163,8 +176,8 @@ type Organization { slug: String description: String! descriptionExcerpt: String - deleted: Boolean @default(to: false) - disabled: Boolean @default(to: false) + deleted: Boolean + disabled: Boolean tags: [Tag]! @relation(name: "TAGGED", direction: "OUT") categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT") @@ -176,5 +189,5 @@ type Tag { taggedPosts: [Post]! @relation(name: "TAGGED", direction: "IN") taggedOrganizations: [Organization]! @relation(name: "TAGGED", direction: "IN") taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(r) RETURN COUNT(r)") - deleted: Boolean @default(to: false) + deleted: Boolean } From 513de69bf986128ac5f8cc8933d7cb00ce35530e Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 19 Oct 2018 12:29:52 +0200 Subject: [PATCH 022/554] some cleanup --- package.json | 7 +- src/jwt/generateToken.js | 7 +- src/jwt/strategy.js | 1 - src/middleware/softDeleteMiddleware.js | 26 +- src/seed/seed-mutations.js | 2 +- yarn-error.log | 3862 ++++++++++++++++++++++++ yarn.lock | 18 +- 7 files changed, 3898 insertions(+), 25 deletions(-) create mode 100644 yarn-error.log diff --git a/package.json b/package.json index 1612d5211..d753ed31c 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", + "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "seedDb": "./node_modules/.bin/babel-node src/seed/seed-db.js" }, "author": "Grzegorz Leoniec", @@ -19,14 +20,14 @@ "bcryptjs": "^2.4.3", "dotenv": "^6.0.0", "graphql-custom-directives": "^0.2.13", - "graphql-middleware": "^1.7.6", + "graphql-middleware": "1.7.6", "graphql-tag": "^2.9.2", - "graphql-yoga": "^1.16.2", + "graphql-yoga": "1.16.2", "jsonwebtoken": "^8.3.0", "lodash": "^4.17.11", "ms": "^2.1.1", "neo4j-driver": "^1.6.1", - "neo4j-graphql-js": "^1.0.2", + "neo4j-graphql-js": "1.0.4", "node-fetch": "^2.1.2", "passport": "^0.4.0", "passport-jwt": "^4.0.0", diff --git a/src/jwt/generateToken.js b/src/jwt/generateToken.js index f02ea7c8f..d1daeaf33 100644 --- a/src/jwt/generateToken.js +++ b/src/jwt/generateToken.js @@ -4,15 +4,14 @@ import ms from 'ms' // Generate an Access Token for the given User ID export default function generateJwt(user) { - console.log('generateJwt', user) const token = jwt.sign(user, process.env.JWT_SECRET, { expiresIn: ms('1d'), issuer: process.env.GRAPHQL_URI, audience: process.env.CLIENT_URI, subject: user.id.toString() }) - jwt.verify(token, process.env.JWT_SECRET, (err, data) => { - console.log('token verification:', err, data) - }) + // jwt.verify(token, process.env.JWT_SECRET, (err, data) => { + // console.log('token verification:', err, data) + // }) return token } diff --git a/src/jwt/strategy.js b/src/jwt/strategy.js index 97593ae82..80774b65b 100644 --- a/src/jwt/strategy.js +++ b/src/jwt/strategy.js @@ -18,7 +18,6 @@ export default () => { return new Strategy(options, (JWTPayload, next) => { - console.log('JWT Payload Received:', JWTPayload) // usually this would be a database call: // var user = users[_.findIndex(users, {id: JWTPayload.id})] if (true) { diff --git a/src/middleware/softDeleteMiddleware.js b/src/middleware/softDeleteMiddleware.js index c40cdf116..c413961bc 100644 --- a/src/middleware/softDeleteMiddleware.js +++ b/src/middleware/softDeleteMiddleware.js @@ -4,18 +4,30 @@ export default { if (typeof args.deleted !== 'boolean') { args.deleted = false } - const result = await resolve(root, args, context, info) - return result - }, - Comment: async (resolve, root, args, context, info) => { - if (typeof args.deleted !== 'boolean') { - args.deleted = false + if (typeof args.disabled !== 'boolean') { + args.disabled = false } const result = await resolve(root, args, context, info) return result }, + Comment: async (resolve, root, args, context, info) => { + // if (typeof args.deleted !== 'boolean') { + // args.deleted = false + // } + // if (typeof args.disabled !== 'boolean') { + // args.disabled = false + // } + const result = await resolve(root, args, context, info) + return result + }, User: async (resolve, root, args, context, info) => { - // console.log('ROOT', root) + if (typeof args.deleted !== 'boolean') { + args.deleted = false + } + if (typeof args.disabled !== 'boolean') { + args.disabled = false + } + // console.log('ROOT', root) // console.log('ARGS', args) // console.log('CONTEXT', context) // console.log('info', info.fieldNodes[0].arguments) diff --git a/src/seed/seed-mutations.js b/src/seed/seed-mutations.js index 9b85ec0d6..cf1cba49e 100644 --- a/src/seed/seed-mutations.js +++ b/src/seed/seed-mutations.js @@ -18,7 +18,7 @@ export default ` avatar role } - u3: CreateUser(id: "u3", name: "Jenny Rostock", password: "1234", email: "user@test.de", avatar: "${faker.internet.avatar()}", role: Admin) { + u3: CreateUser(id: "u3", name: "Jenny Rostock", password: "1234", email: "user@test.de", avatar: "${faker.internet.avatar()}", role: User) { id name email diff --git a/yarn-error.log b/yarn-error.log new file mode 100644 index 000000000..2277f3e46 --- /dev/null +++ b/yarn-error.log @@ -0,0 +1,3862 @@ +Arguments: + /usr/local/bin/node /usr/local/Cellar/yarn/1.9.4/libexec/bin/yarn.js add graph-middleware@1.7.6 graphql-yoga@1.16.2 + +PATH: + /usr/local/opt/mongodb@3.6/bin:/usr/local/opt/php@7.1/sbin:/usr/local/opt/php@7.1/bin:/usr/local/opt/libxml2/bin:/Users/Greg/.bin:/usr/local/sbin:/usr/local/opt/coreutils/libexec/gnubin:/Users/Greg/.composer/vendor/bin:/Users/Greg/.npm/bin:/usr/local/bin/npm:/usr/local/share/npm/bin:/usr/local/Cellar:/usr/local/sbin:/usr/local/bin:/Users/Greg/.yarn/bin:/Users/Greg/Projekte/HumanConnection/kube-vm/kubernetes/client/bin:/usr/local/opt/mysql@5.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/MacGPG2/bin:/usr/local/opt/mongodb@3.6/bin:/usr/local/opt/php@7.1/sbin:/usr/local/opt/php@7.1/bin:/usr/local/opt/libxml2/bin:/Users/Greg/.bin:/usr/local/sbin:/usr/local/opt/coreutils/libexec/gnubin:/Users/Greg/.composer/vendor/bin:/Users/Greg/.npm/bin:/usr/local/bin/npm:/usr/local/share/npm/bin:/usr/local/Cellar:/Users/Greg/.yarn/bin:/Users/Greg/Projekte/HumanConnection/kube-vm/kubernetes/client/bin:/usr/local/opt/mysql@5.7/bin:/Users/Greg/.composer/vendor/bin:/Users/Greg/.composer/vendor/bin + +Yarn version: + 1.9.4 + +Node version: + 10.11.0 + +Platform: + darwin x64 + +Trace: + Error: https://registry.yarnpkg.com/graph-middleware: Not found + at Request.params.callback [as _callback] (/usr/local/Cellar/yarn/1.9.4/libexec/lib/cli.js:64202:18) + at Request.self.callback (/usr/local/Cellar/yarn/1.9.4/libexec/lib/cli.js:137468:22) + at Request.emit (events.js:182:13) + at Request. (/usr/local/Cellar/yarn/1.9.4/libexec/lib/cli.js:138440:10) + at Request.emit (events.js:182:13) + at IncomingMessage. (/usr/local/Cellar/yarn/1.9.4/libexec/lib/cli.js:138362:12) + at Object.onceWrapper (events.js:273:13) + at IncomingMessage.emit (events.js:187:15) + at endReadableNT (_stream_readable.js:1092:12) + at process._tickCallback (internal/process/next_tick.js:63:19) + +npm manifest: + { + "name": "hc-prototype-api-", + "version": "0.0.1", + "description": "Graph API Protype for Human Connection", + "main": "src/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", + "seedDb": "./node_modules/.bin/babel-node src/seed/seed-db.js" + }, + "author": "Grzegorz Leoniec", + "license": "MIT", + "dependencies": { + "apollo-boost": "^0.1.10", + "apollo-cache-inmemory": "^1.2.5", + "apollo-client": "^2.3.2", + "apollo-link-http": "^1.5.4", + "apollo-server": "^2.0.4", + "bcryptjs": "^2.4.3", + "dotenv": "^6.0.0", + "graphql-custom-directives": "^0.2.13", + "graphql-middleware": "^1.7.8", + "graphql-tag": "^2.9.2", + "graphql-yoga": "^1.16.6", + "jsonwebtoken": "^8.3.0", + "lodash": "^4.17.11", + "ms": "^2.1.1", + "neo4j-driver": "^1.6.1", + "neo4j-graphql-js": "1.0.2", + "node-fetch": "^2.1.2", + "passport": "^0.4.0", + "passport-jwt": "^4.0.0", + "slug": "^0.9.1", + "trunc-html": "^1.1.2" + }, + "devDependencies": { + "babel-cli": "^6.26.0", + "babel-preset-env": "^1.7.0", + "faker": "^4.1.0", + "nodemon": "^1.18.4" + } + } + +yarn manifest: + No manifest + +Lockfile: + # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + # yarn lockfile v1 + + + "@apollographql/apollo-upload-server@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" + dependencies: + "@babel/runtime-corejs2" "^7.0.0-rc.1" + busboy "^0.2.14" + object-path "^0.11.4" + + "@apollographql/graphql-playground-html@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz#15e1a042b97d6834e6d70b17cc73e1514fde9027" + + "@babel/runtime-corejs2@^7.0.0-rc.1": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.1.2.tgz#8695811a3fd8091f54f274b9320334e5e8c62200" + dependencies: + core-js "^2.5.7" + regenerator-runtime "^0.12.0" + + "@babel/runtime@^7.0.0-beta.40": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.2.tgz#81c89935f4647706fc54541145e6b4ecfef4b8e3" + dependencies: + regenerator-runtime "^0.12.0" + + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + + "@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + + "@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + + "@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + + "@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + + "@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + + "@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + + "@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + + "@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + + "@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + + "@types/accepts@^1.3.5": + version "1.3.5" + resolved "http://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" + dependencies: + "@types/node" "*" + + "@types/async@2.0.49": + version "2.0.49" + resolved "http://registry.npmjs.org/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0" + + "@types/body-parser@*", "@types/body-parser@1.17.0": + version "1.17.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" + dependencies: + "@types/connect" "*" + "@types/node" "*" + + "@types/connect@*": + version "3.4.32" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" + dependencies: + "@types/node" "*" + + "@types/cors@^2.8.4": + version "2.8.4" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.4.tgz#50991a759a29c0b89492751008c6af7a7c8267b0" + dependencies: + "@types/express" "*" + + "@types/events@*": + version "1.2.0" + resolved "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" + + "@types/express-serve-static-core@*": + version "4.16.0" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz#fdfe777594ddc1fe8eb8eccce52e261b496e43e7" + dependencies: + "@types/events" "*" + "@types/node" "*" + "@types/range-parser" "*" + + "@types/express@*", "@types/express@4.16.0", "@types/express@^4.11.1": + version "4.16.0" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.0.tgz#6d8bc42ccaa6f35cf29a2b7c3333cb47b5a32a19" + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/serve-static" "*" + + "@types/graphql-deduplicator@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/graphql-deduplicator/-/graphql-deduplicator-2.0.0.tgz#9e577b8f3feb3d067b0ca756f4a1fb356d533922" + + "@types/graphql@^14.0.0": + version "14.0.3" + resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-14.0.3.tgz#389e2e5b83ecdb376d9f98fae2094297bc112c1c" + + "@types/long@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" + + "@types/mime@*": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" + + "@types/node@*", "@types/node@^10.1.0": + version "10.12.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.0.tgz#ea6dcbddbc5b584c83f06c60e82736d8fbb0c235" + + "@types/range-parser@*": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.2.tgz#fa8e1ad1d474688a757140c91de6dace6f4abc8d" + + "@types/serve-static@*": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48" + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + + "@types/ws@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-5.1.2.tgz#f02d3b1cd46db7686734f3ce83bdf46c49decd64" + dependencies: + "@types/events" "*" + "@types/node" "*" + + "@types/zen-observable@^0.5.3": + version "0.5.4" + resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.4.tgz#b863a4191e525206819e008097ebf0fb2e3a1cdc" + + "@types/zen-observable@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" + + abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + + accepts@^1.3.5, accepts@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + + ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + dependencies: + string-width "^2.0.0" + + ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + + ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + + ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + + ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + + anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + + anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + + apollo-boost@^0.1.10: + version "0.1.16" + resolved "https://registry.yarnpkg.com/apollo-boost/-/apollo-boost-0.1.16.tgz#77f73a30c49ab6d749ddc3e5683a7e322c15f07d" + dependencies: + apollo-cache "^1.1.17" + apollo-cache-inmemory "^1.2.10" + apollo-client "^2.4.2" + apollo-link "^1.0.6" + apollo-link-error "^1.0.3" + apollo-link-http "^1.3.1" + apollo-link-state "^0.4.0" + graphql-tag "^2.4.2" + + apollo-cache-control@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz#173d14ceb3eb9e7cb53de7eb8b61bee6159d4171" + dependencies: + graphql-extensions "^0.0.x" + + apollo-cache-control@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.2.5.tgz#0831ad796754a7beec858668f99e7517fe744a1e" + dependencies: + apollo-server-env "^2.0.3" + graphql-extensions "^0.2.1" + + apollo-cache-inmemory@^1.2.10, apollo-cache-inmemory@^1.2.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.5.tgz#7628ee598271cfffa611e15a7ce67652a84b07b0" + dependencies: + apollo-cache "^1.1.17" + apollo-utilities "^1.0.21" + optimism "^0.6.6" + + apollo-cache@1.1.17, apollo-cache@^1.1.17: + version "1.1.17" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.17.tgz#1fcca8423125223723b97fd72808be91a1a76490" + dependencies: + apollo-utilities "^1.0.21" + + apollo-client@^2.3.2, apollo-client@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.2.tgz#d2f044d8740723bf98a6d8d8b9684ee8c36150e6" + dependencies: + "@types/zen-observable" "^0.8.0" + apollo-cache "1.1.17" + apollo-link "^1.0.0" + apollo-link-dedup "^1.0.0" + apollo-utilities "1.0.21" + symbol-observable "^1.0.2" + zen-observable "^0.8.0" + optionalDependencies: + "@types/async" "2.0.49" + + apollo-datasource@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.1.3.tgz#e7ae9d20f29a8a35f239b02f0c47169cfd78d70b" + dependencies: + apollo-server-caching "0.1.2" + apollo-server-env "2.0.3" + + apollo-engine-reporting-protobuf@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz#cd394f0f769c6f97d8621c4a7839095c84efcdb0" + dependencies: + protobufjs "^6.8.6" + + apollo-engine-reporting@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.0.6.tgz#c1a74dffce782525f8a3230e4e5228fbd05bbd59" + dependencies: + apollo-engine-reporting-protobuf "^0.0.1" + apollo-server-env "^2.0.3" + async-retry "^1.2.1" + graphql-extensions "^0.2.1" + lodash "^4.17.10" + + apollo-link-dedup@^1.0.0: + version "1.0.10" + resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.10.tgz#7b94589fe7f969777efd18a129043c78430800ae" + dependencies: + apollo-link "^1.2.3" + + apollo-link-error@^1.0.3: + version "1.1.1" + resolved "https://registry.yarnpkg.com/apollo-link-error/-/apollo-link-error-1.1.1.tgz#69d7124d4dc11ce60f505c940f05d4f1aa0945fb" + dependencies: + apollo-link "^1.2.3" + + apollo-link-http-common@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.5.tgz#d094beb7971523203359bf830bfbfa7b4e7c30ed" + dependencies: + apollo-link "^1.2.3" + + apollo-link-http@^1.3.1, apollo-link-http@^1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.5.tgz#7dbe851821771ad67fa29e3900c57f38cbd80da8" + dependencies: + apollo-link "^1.2.3" + apollo-link-http-common "^0.2.5" + + apollo-link-state@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/apollo-link-state/-/apollo-link-state-0.4.2.tgz#ac00e9be9b0ca89eae0be6ba31fe904b80bbe2e8" + dependencies: + apollo-utilities "^1.0.8" + graphql-anywhere "^4.1.0-alpha.0" + + apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.2, apollo-link@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.3.tgz#9bd8d5fe1d88d31dc91dae9ecc22474d451fb70d" + dependencies: + apollo-utilities "^1.0.0" + zen-observable-ts "^0.8.10" + + apollo-server-caching@0.1.2, apollo-server-caching@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.1.2.tgz#f5b85701945110a5fca1956450e8553576635936" + dependencies: + lru-cache "^4.1.3" + + apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592" + dependencies: + apollo-cache-control "^0.1.0" + apollo-tracing "^0.1.0" + graphql-extensions "^0.0.x" + + apollo-server-core@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.1.0.tgz#b56f9f1ddb948b257e738eb25c5fdfd2f2fb2e07" + dependencies: + "@apollographql/apollo-upload-server" "^5.0.3" + "@types/ws" "^5.1.2" + apollo-cache-control "^0.2.5" + apollo-datasource "^0.1.3" + apollo-engine-reporting "^0.0.6" + apollo-server-caching "^0.1.2" + apollo-server-env "^2.0.3" + apollo-server-errors "^2.0.2" + apollo-tracing "^0.2.5" + graphql-extensions "^0.2.1" + graphql-subscriptions "^0.5.8" + graphql-tag "^2.9.2" + graphql-tools "^3.0.4" + hash.js "^1.1.3" + lodash "^4.17.10" + subscriptions-transport-ws "^0.9.11" + ws "^5.2.0" + + apollo-server-env@2.0.3, apollo-server-env@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.0.3.tgz#3c13552cd33f400160076cf8e1c9b24be4d27e13" + dependencies: + node-fetch "^2.1.2" + util.promisify "^1.0.0" + + apollo-server-errors@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz#e9cbb1b74d2cd78aed23cd886ca2d0c186323b2b" + + apollo-server-express@^1.3.6: + version "1.4.0" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.4.0.tgz#7d7c58d6d6f9892b83fe575669093bb66738b125" + dependencies: + apollo-server-core "^1.4.0" + apollo-server-module-graphiql "^1.4.0" + + apollo-server-express@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.1.0.tgz#b2d423c2c934df5c4e0a1b0d5f0088a9461f3c86" + dependencies: + "@apollographql/apollo-upload-server" "^5.0.3" + "@apollographql/graphql-playground-html" "^1.6.0" + "@types/accepts" "^1.3.5" + "@types/body-parser" "1.17.0" + "@types/cors" "^2.8.4" + "@types/express" "4.16.0" + accepts "^1.3.5" + apollo-server-core "^2.1.0" + body-parser "^1.18.3" + cors "^2.8.4" + graphql-subscriptions "^0.5.8" + graphql-tools "^3.0.4" + type-is "^1.6.16" + + apollo-server-lambda@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/apollo-server-lambda/-/apollo-server-lambda-1.3.6.tgz#bdaac37f143c6798e40b8ae75580ba673cea260e" + dependencies: + apollo-server-core "^1.3.6" + apollo-server-module-graphiql "^1.3.4" + + apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" + + apollo-server@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.1.0.tgz#abec7853647c59f386087352cc7f06a4f1f8afe2" + dependencies: + apollo-server-core "^2.1.0" + apollo-server-express "^2.1.0" + express "^4.0.0" + graphql-subscriptions "^0.5.8" + graphql-tools "^3.0.4" + + apollo-tracing@^0.1.0: + version "0.1.4" + resolved "http://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" + dependencies: + graphql-extensions "~0.0.9" + + apollo-tracing@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.2.5.tgz#15bb8d6f37efe8c1bb6351e8e21521dd4f14c5f2" + dependencies: + apollo-server-env "^2.0.3" + graphql-extensions "^0.2.1" + + apollo-upload-server@^5.0.0: + version "5.0.0" + resolved "http://registry.npmjs.org/apollo-upload-server/-/apollo-upload-server-5.0.0.tgz#c953b523608313966e0c8444637f4ae8ef77d5bc" + dependencies: + "@babel/runtime" "^7.0.0-beta.40" + busboy "^0.2.14" + object-path "^0.11.4" + + apollo-utilities@1.0.21, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.21, apollo-utilities@^1.0.8: + version "1.0.21" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.21.tgz#cb8b5779fe275850b16046ff8373f4af2de90765" + dependencies: + fast-json-stable-stringify "^2.0.0" + fclone "^1.0.11" + + aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + + are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + + argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + dependencies: + sprintf-js "~1.0.2" + + arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + + arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + + arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + + arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + + array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + + array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + + array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + + assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + + assignment@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.0.0.tgz#ffd17b21bf5d6b22e777b989681a815456a3dd3e" + + assignment@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.2.0.tgz#f5b5bc2d160d69986e8700cd38f567c0aabe101e" + + async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + + async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + + async-retry@^1.2.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.2.3.tgz#a6521f338358d322b1a0012b79030c6f411d1ce0" + dependencies: + retry "0.12.0" + + atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + + aws-lambda@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/aws-lambda/-/aws-lambda-0.1.2.tgz#19b1585075df31679597b976a5f1def61f12ccee" + dependencies: + aws-sdk "^*" + commander "^2.5.0" + dotenv "^0.4.0" + + aws-sdk@^*: + version "2.336.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.336.0.tgz#b15371aff3e30ba77b74968c086375594be897c9" + dependencies: + buffer "4.9.1" + events "1.1.1" + ieee754 "1.1.8" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.1.0" + xml2js "0.4.19" + + babel-cli@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" + dependencies: + babel-core "^6.26.0" + babel-polyfill "^6.26.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + commander "^2.11.0" + convert-source-map "^1.5.0" + fs-readdir-recursive "^1.0.0" + glob "^7.1.2" + lodash "^4.17.4" + output-file-sync "^1.1.2" + path-is-absolute "^1.0.1" + slash "^1.0.0" + source-map "^0.5.6" + v8flags "^2.1.1" + optionalDependencies: + chokidar "^1.6.1" + + babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + + babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + + babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + + babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + + babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + + babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + + babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + + babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + + babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + + babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + + babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + + babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + + babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + + babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + + babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + + babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + + babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + + babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + + babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + + babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + + babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + + babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + + babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + + babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + + babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + + babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + + babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + + babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + + babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + + babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + + babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + + babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + + babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + + babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + + babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + + babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + + babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + + babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + + babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + + babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + + babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + + babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + + babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + + babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + + babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + + babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + + babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + + babel-preset-env@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + + babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + + babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + + babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + + babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + + babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + + babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + + backo2@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + + balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + + base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + + base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + + bcryptjs@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + + binary-extensions@^1.0.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" + + body-parser-graphql@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/body-parser-graphql/-/body-parser-graphql-1.1.0.tgz#80a80353c7cb623562fd375750dfe018d75f0f7c" + dependencies: + body-parser "^1.18.2" + + body-parser@1.18.3, body-parser@^1.18.2, body-parser@^1.18.3: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" + on-finished "~2.3.0" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" + + boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + + brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + + braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + + braces@^2.3.0, braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + + browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + + buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + + buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + + buffer@4.9.1: + version "4.9.1" + resolved "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + + busboy@^0.2.14: + version "0.2.14" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" + dependencies: + dicer "0.2.5" + readable-stream "1.1.x" + + bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + + cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + + camelcase@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + + caniuse-lite@^1.0.30000844: + version "1.0.30000892" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000892.tgz#344d2b51ee3ff5977537da4aa449c90eec40b759" + + capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + + chalk@^1.1.3: + version "1.1.3" + resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + + chalk@^2.0.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + + chokidar@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + + chokidar@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + + chownr@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + + ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + + class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + + cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + + code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + + collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + + color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + dependencies: + color-name "1.1.3" + + color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + + commander@^2.11.0, commander@^2.5.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + + component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + + concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + + configstore@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + + console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + + content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + + content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + + convert-source-map@^1.5.0, convert-source-map@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + dependencies: + safe-buffer "~5.1.1" + + cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + + cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + + copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + + core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.3, core-js@^2.5.7: + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + + core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + + cors@^2.8.4: + version "2.8.4" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.4.tgz#2bd381f2eb201020105cd50ea59da63090694686" + dependencies: + object-assign "^4" + vary "^1" + + create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + + cross-fetch@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.2.tgz#a47ff4f7fc712daba8f6a695a11c948440d45723" + dependencies: + node-fetch "2.1.2" + whatwg-fetch "2.0.4" + + cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + + crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + + debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + + debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + dependencies: + ms "^2.1.1" + + decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + + deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + + define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + dependencies: + object-keys "^1.0.12" + + define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + + define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + + define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + + delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + + depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + + deprecated-decorator@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" + + destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + + detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + + detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + + dicer@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" + dependencies: + readable-stream "1.1.x" + streamsearch "0.1.2" + + dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + dependencies: + is-obj "^1.0.0" + + dotenv@^0.4.0: + version "0.4.0" + resolved "http://registry.npmjs.org/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" + + dotenv@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.1.0.tgz#9853b6ca98292acb7dec67a95018fa40bccff42c" + + duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + + duplexer@^0.1.1, duplexer@~0.1.1: + version "0.1.1" + resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + + ecdsa-sig-formatter@1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz#1c595000f04a8897dfb85000892a0f4c33af86c3" + dependencies: + safe-buffer "^5.0.1" + + ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + + electron-to-chromium@^1.3.47: + version "1.3.79" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.79.tgz#774718f06284a4bf8f578ac67e74508fe659f13a" + + encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + + es-abstract@^1.5.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + + es-to-primitive@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + + escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + + escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + + esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + + esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + + etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + + event-stream@~3.3.0: + version "3.3.6" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.6.tgz#cac1230890e07e73ec9cacd038f60a5b66173eef" + dependencies: + duplexer "^0.1.1" + flatmap-stream "^0.1.0" + from "^0.1.7" + map-stream "0.0.7" + pause-stream "^0.0.11" + split "^1.0.1" + stream-combiner "^0.2.2" + through "^2.3.8" + + eventemitter3@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" + + events@1.1.1: + version "1.1.1" + resolved "http://registry.npmjs.org/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + + execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + + expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + + expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + + express@^4.0.0, express@^4.16.3: + version "4.16.4" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" + dependencies: + accepts "~1.3.5" + array-flatten "1.1.1" + body-parser "1.18.3" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.1" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.4" + qs "6.5.2" + range-parser "~1.2.0" + safe-buffer "5.1.2" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + utils-merge "1.0.1" + vary "~1.1.2" + + extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + dependencies: + is-extendable "^0.1.0" + + extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + + extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + + extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + faker@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" + + fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + + fclone@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640" + + filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + + fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + + fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + + finalhandler@1.1.1: + version "1.1.1" + resolved "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + + flatmap-stream@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.1.tgz#d34f39ef3b9aa5a2fc225016bd3adf28ac5ae6ea" + + for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + + for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + + forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + + fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + dependencies: + map-cache "^0.2.2" + + fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + + from@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + + fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + dependencies: + minipass "^2.2.1" + + fs-readdir-recursive@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + + fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + + fsevents@^1.0.0, fsevents@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + + function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + + gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + + get-stream@^3.0.0: + version "3.0.0" + resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + + get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + + glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + + glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + + glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + + glob@^7.0.5, glob@^7.1.2: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + + global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + dependencies: + ini "^1.3.4" + + globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + + got@^6.7.1: + version "6.7.1" + resolved "http://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + + graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + + graphql-anywhere@^4.1.0-alpha.0: + version "4.1.19" + resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.19.tgz#5f6ca3b58218e5449f4798e3c6d942fcd2fef082" + dependencies: + apollo-utilities "^1.0.21" + + graphql-config@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-2.2.1.tgz#5fd0ec77ac7428ca5fb2026cf131be10151a0cb2" + dependencies: + graphql-import "^0.7.1" + graphql-request "^1.5.0" + js-yaml "^3.10.0" + lodash "^4.17.4" + minimatch "^3.0.4" + + graphql-custom-directives@^0.2.13: + version "0.2.13" + resolved "https://registry.yarnpkg.com/graphql-custom-directives/-/graphql-custom-directives-0.2.13.tgz#5e175069f5ff404f751d232e302007bc25488ea8" + dependencies: + lodash "^4.17.5" + moment "^2.22.2" + numeral "^2.0.6" + + graphql-deduplicator@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.1.tgz#20c6b39e3a6f096b46dfc8491432818739c0ee37" + + graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: + version "0.0.10" + resolved "http://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" + dependencies: + core-js "^2.5.3" + source-map-support "^0.5.1" + + graphql-extensions@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.2.1.tgz#7697e0fcea2e622afe9e24dd31fc84f533e84c70" + dependencies: + apollo-server-env "^2.0.3" + + graphql-import@^0.7.0, graphql-import@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.7.1.tgz#4add8d91a5f752d764b0a4a7a461fcd93136f223" + dependencies: + lodash "^4.17.4" + resolve-from "^4.0.0" + + graphql-middleware@1.7.7: + version "1.7.7" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.7.tgz#0a7a7193a873c4769401df2aef4ffb9c6ca97f43" + dependencies: + graphql-tools "^4.0.1" + + graphql-middleware@^1.7.8: + version "1.7.8" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.8.tgz#617940d3cd462e9553e582d2b6ce86cb0e95a3dd" + dependencies: + graphql-tools "^4.0.2" + + graphql-playground-html@1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.4.tgz#be7c5a6213d67aeedf03d90b7e7d55fec4d42212" + dependencies: + graphql-config "2.2.1" + + graphql-playground-middleware-express@1.7.6: + version "1.7.6" + resolved "https://registry.yarnpkg.com/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.6.tgz#aca38d2b8e5147914fc8fa613d151edd4ed0bc44" + dependencies: + graphql-playground-html "1.6.4" + + graphql-playground-middleware-lambda@1.7.6: + version "1.7.6" + resolved "https://registry.yarnpkg.com/graphql-playground-middleware-lambda/-/graphql-playground-middleware-lambda-1.7.6.tgz#03aa4e3592144f4eb390a216f09b39f6b29f12d2" + dependencies: + graphql-playground-html "1.6.4" + + graphql-request@^1.5.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" + dependencies: + cross-fetch "2.2.2" + + graphql-subscriptions@^0.5.8: + version "0.5.8" + resolved "http://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7" + dependencies: + iterall "^1.2.1" + + graphql-tag@^2.4.2, graphql-tag@^2.9.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" + + graphql-tools@^3.0.4: + version "3.1.1" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-3.1.1.tgz#d593358f01e7c8b1671a17b70ddb034dea9dbc50" + dependencies: + apollo-link "^1.2.2" + apollo-utilities "^1.0.1" + deprecated-decorator "^0.1.6" + iterall "^1.1.3" + uuid "^3.1.0" + + graphql-tools@^4.0.0, graphql-tools@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.2.tgz#9da22974cc6bf6524ed4f4af35556fd15aa6516d" + dependencies: + apollo-link "^1.2.3" + apollo-utilities "^1.0.1" + deprecated-decorator "^0.1.6" + iterall "^1.1.3" + uuid "^3.1.0" + + graphql-tools@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.1.tgz#c995a4e25c2967d108c975e508322d12969c8c0e" + dependencies: + apollo-link "^1.2.3" + apollo-utilities "^1.0.1" + deprecated-decorator "^0.1.6" + iterall "^1.1.3" + uuid "^3.1.0" + + graphql-yoga@^1.16.6: + version "1.16.6" + resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.16.6.tgz#fc0e75e0214b76afc57e0e7872479a65ff464412" + dependencies: + "@types/cors" "^2.8.4" + "@types/express" "^4.11.1" + "@types/graphql" "^14.0.0" + "@types/graphql-deduplicator" "^2.0.0" + "@types/zen-observable" "^0.5.3" + apollo-server-express "^1.3.6" + apollo-server-lambda "1.3.6" + apollo-upload-server "^5.0.0" + aws-lambda "^0.1.2" + body-parser-graphql "1.1.0" + cors "^2.8.4" + express "^4.16.3" + graphql "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0" + graphql-deduplicator "^2.0.1" + graphql-import "^0.7.0" + graphql-middleware "1.7.7" + graphql-playground-middleware-express "1.7.6" + graphql-playground-middleware-lambda "1.7.6" + graphql-subscriptions "^0.5.8" + graphql-tools "^4.0.0" + subscriptions-transport-ws "^0.9.8" + + "graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0": + version "14.0.2" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.0.2.tgz#7dded337a4c3fd2d075692323384034b357f5650" + dependencies: + iterall "^1.2.2" + + graphql@^0.13.2: + version "0.13.2" + resolved "http://registry.npmjs.org/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" + dependencies: + iterall "^1.2.1" + + has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + + has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + + has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + + has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + + has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + + has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + + has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + + has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + + has@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + dependencies: + function-bind "^1.1.1" + + hash.js@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + + he@0.5.0: + version "0.5.0" + resolved "http://registry.npmjs.org/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" + + home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + + http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: + version "1.6.3" + resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + + iconv-lite@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + dependencies: + safer-buffer ">= 2.1.2 < 3" + + iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + dependencies: + safer-buffer ">= 2.1.2 < 3" + + ieee754@1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + + ieee754@^1.1.4: + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + + ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + + ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + dependencies: + minimatch "^3.0.4" + + immutable-tuple@^0.4.4: + version "0.4.8" + resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.8.tgz#f60b65b863d34be39d307d1bbf4a450e1ac3048a" + + import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + + imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + + inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + + inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + + ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + + insane@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/insane/-/insane-2.6.1.tgz#c7dcae7b51c20346883b71078fad6ce0483c198f" + dependencies: + assignment "2.0.0" + he "0.5.0" + + invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + dependencies: + loose-envify "^1.0.0" + + ipaddr.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" + + is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + + is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + dependencies: + kind-of "^6.0.0" + + is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + + is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + + is-callable@^1.1.3, is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + + is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + dependencies: + ci-info "^1.5.0" + + is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + + is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + dependencies: + kind-of "^6.0.0" + + is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + + is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + + is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + + is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + + is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + + is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + + is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + dependencies: + is-plain-object "^2.0.4" + + is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + + is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + + is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + + is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + + is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + + is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + + is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + + is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + + is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + + is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + + is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + + is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + + is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + + is-obj@^1.0.0: + version "1.0.1" + resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + + is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + dependencies: + path-is-inside "^1.0.1" + + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + dependencies: + isobject "^3.0.1" + + is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + + is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + + is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + + is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + + is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + + is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + + is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + dependencies: + has-symbols "^1.0.0" + + is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + + isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + + isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + + isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + + isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + + iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" + + jmespath@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + + "js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + + js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + + js-yaml@^3.10.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + + jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + + jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + + json5@^0.5.1: + version "0.5.1" + resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + + jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz#056c90eee9a65ed6e6c72ddb0a1d325109aaf643" + dependencies: + jws "^3.1.5" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + + jwa@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.6.tgz#87240e76c9808dbde18783cf2264ef4929ee50e6" + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.10" + safe-buffer "^5.0.1" + + jws@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.5.tgz#80d12d05b293d1e841e7cb8b4e69e561adcf834f" + dependencies: + jwa "^1.1.5" + safe-buffer "^5.0.1" + + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + + kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + + kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + + kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + + latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + dependencies: + package-json "^4.0.0" + + lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + + lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + + lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + + lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + + lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + + lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + + lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + + lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + + lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + + long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + + loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + + lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + + lru-cache@^4.0.1, lru-cache@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + + make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + dependencies: + pify "^3.0.0" + + map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + + map-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" + + map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" + + math-random@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + + media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + + merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + + methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + + micromatch@^2.1.5: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + + micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + + mime-db@~1.36.0: + version "1.36.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" + + mime-types@~2.1.18: + version "2.1.20" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" + dependencies: + mime-db "~1.36.0" + + mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + + minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + + minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + + minimist@0.0.8: + version "0.0.8" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + + minimist@^1.2.0: + version "1.2.0" + resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + + minipass@^2.2.1, minipass@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + + minizlib@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" + dependencies: + minipass "^2.2.1" + + mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + + mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.1" + resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + + moment@^2.22.2: + version "2.22.2" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" + + ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + + ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + + nan@^2.9.2: + version "2.11.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" + + nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + needle@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + + negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + + neo4j-driver@^1.6.1: + version "1.6.3" + resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.6.3.tgz#b7a51bac401bd341082dff7766e8643d61752eb7" + dependencies: + babel-runtime "^6.18.0" + uri-js "^4.2.1" + + neo4j-graphql-js@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.2.tgz#e4dd66b85e817347efb13beaa8340f8eda9df24f" + dependencies: + graphql "^0.13.2" + lodash "^4.17.10" + neo4j-driver "^1.6.1" + + node-fetch@2.1.2: + version "2.1.2" + resolved "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + + node-fetch@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5" + + node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + + nodemon@^1.18.4: + version "1.18.4" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.4.tgz#873f65fdb53220eb166180cf106b1354ac5d714d" + dependencies: + chokidar "^2.0.2" + debug "^3.1.0" + ignore-by-default "^1.0.1" + minimatch "^3.0.4" + pstree.remy "^1.1.0" + semver "^5.5.0" + supports-color "^5.2.0" + touch "^3.1.0" + undefsafe "^2.0.2" + update-notifier "^2.3.0" + + nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + + nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + dependencies: + abbrev "1" + + normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + + npm-bundled@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + + npm-packlist@^1.1.6: + version "1.1.12" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + + 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" + dependencies: + path-key "^2.0.0" + + npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + + number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + + numeral@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" + + object-assign@^4, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + + object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + + object-keys@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + + object-path@^0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" + + object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + + object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + + object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + + object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + dependencies: + isobject "^3.0.1" + + on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + + once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + + optimism@^0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.6.tgz#5415b2d6a2f8b3745aedb9f97fdf4e52467ecd84" + dependencies: + immutable-tuple "^0.4.4" + + os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + + os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + + osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + + output-file-sync@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" + dependencies: + graceful-fs "^4.1.4" + mkdirp "^0.5.1" + object-assign "^4.1.0" + + p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + + package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + + parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + + parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + + pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + + passport-jwt@^4.0.0: + version "4.0.0" + resolved "http://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" + dependencies: + jsonwebtoken "^8.2.0" + passport-strategy "^1.0.0" + + passport-strategy@1.x.x, passport-strategy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + + passport@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + + path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + + path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + + path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + + path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + + path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + + pause-stream@^0.0.11: + version "0.0.11" + resolved "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + dependencies: + through "~2.3" + + pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + + pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + + posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + + prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + + preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + + private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + + process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + + protobufjs@^6.8.6: + version "6.8.8" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.0" + "@types/node" "^10.1.0" + long "^4.0.0" + + proxy-addr@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.8.0" + + ps-tree@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" + dependencies: + event-stream "~3.3.0" + + pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + + pstree.remy@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.0.tgz#f2af27265bd3e5b32bbfcc10e80bac55ba78688b" + dependencies: + ps-tree "^1.1.0" + + punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + + punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + + qs@6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + + querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + + randomatic@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.0.tgz#36f2ca708e9e567f5ed2ec01949026d50aa10116" + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + + range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + + raw-body@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + + rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + + readable-stream@1.1.x: + version "1.1.14" + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + + readable-stream@^2.0.2, readable-stream@^2.0.6: + version "2.3.6" + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + + readdirp@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + + regenerate@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + + regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + + regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + + regenerator-runtime@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" + + regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + + regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + + regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + + regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + + registry-auth-token@^3.0.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + + registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + dependencies: + rc "^1.0.1" + + regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + + regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + + remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + + repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + + repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + + repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + + resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + + resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + + ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + + retry@0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + + rimraf@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + + safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + + safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + + "safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + + sax@1.2.1: + version "1.2.1" + resolved "http://registry.npmjs.org/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + + sax@>=0.6.0, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + + semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + dependencies: + semver "^5.0.3" + + semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + + send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + + serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + + set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + + set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + + set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + + setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + + shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + + shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + + signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + + slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + + slug@^0.9.1: + version "0.9.1" + resolved "http://registry.npmjs.org/slug/-/slug-0.9.1.tgz#af08f608a7c11516b61778aa800dce84c518cfda" + dependencies: + unicode ">= 0.3.1" + + snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + + snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + + snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + + source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + + source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + + source-map-support@^0.5.1: + version "0.5.9" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + + source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + + source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + + source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + + split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + dependencies: + extend-shallow "^3.0.0" + + split@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + dependencies: + through "2" + + sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + + static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + + "statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + + statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + + stream-combiner@^0.2.2: + version "0.2.2" + resolved "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" + dependencies: + duplexer "~0.1.1" + through "~2.3.4" + + streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + + string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + + "string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + + string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + + string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + + strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + + strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + + strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + + strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + + subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: + version "0.9.15" + resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz#68a8b7ba0037d8c489fb2f5a102d1494db297d0d" + dependencies: + backo2 "^1.0.2" + eventemitter3 "^3.1.0" + iterall "^1.2.1" + symbol-observable "^1.0.4" + ws "^5.2.0" + + supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + + supports-color@^5.2.0, supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + dependencies: + has-flag "^3.0.0" + + symbol-observable@^1.0.2, symbol-observable@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + + tar@^4: + version "4.4.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" + dependencies: + chownr "^1.0.1" + fs-minipass "^1.2.5" + minipass "^2.3.3" + minizlib "^1.1.0" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + + term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + dependencies: + execa "^0.7.0" + + through@2, through@^2.3.8, through@~2.3, through@~2.3.4: + version "2.3.8" + resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + + timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + + to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + + to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + dependencies: + kind-of "^3.0.2" + + 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" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + + to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + + touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + dependencies: + nopt "~1.0.10" + + trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + + trunc-html@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/trunc-html/-/trunc-html-1.1.2.tgz#1e97d51f67d470b67662b1a670e6d0ea7a8edafe" + dependencies: + assignment "2.2.0" + insane "2.6.1" + trunc-text "1.0.1" + + trunc-text@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" + + type-is@^1.6.16, type-is@~1.6.16: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + + undefsafe@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76" + dependencies: + debug "^2.2.0" + + "unicode@>= 0.3.1": + version "11.0.1" + resolved "https://registry.yarnpkg.com/unicode/-/unicode-11.0.1.tgz#735bd422ec75cf28d396eb224d535d168d5f1db6" + + union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + + unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + dependencies: + crypto-random-string "^1.0.0" + + unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + + unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + + unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + + upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + + update-notifier@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + + uri-js@^4.2.1: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + dependencies: + punycode "^2.1.0" + + urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + + url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + + url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + + use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + + user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + + util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + + util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + + utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + + uuid@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + + uuid@^3.1.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + + v8flags@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" + dependencies: + user-home "^1.1.1" + + vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + + whatwg-fetch@2.0.4: + version "2.0.4" + resolved "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + + which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + dependencies: + isexe "^2.0.0" + + wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + dependencies: + string-width "^1.0.2 || 2" + + widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + dependencies: + string-width "^2.1.1" + + wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + + write-file-atomic@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + + ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + dependencies: + async-limiter "~1.0.0" + + xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + + xml2js@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + + xmlbuilder@~9.0.1: + version "9.0.7" + resolved "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + + yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + + yallist@^3.0.0, yallist@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + + zen-observable-ts@^0.8.10: + version "0.8.10" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz#18e2ce1c89fe026e9621fd83cc05168228fce829" + dependencies: + zen-observable "^0.8.0" + + zen-observable@^0.8.0: + version "0.8.9" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.9.tgz#0475c760ff0eda046bbdfa4dc3f95d392807ac53" diff --git a/yarn.lock b/yarn.lock index ab036af96..bcb870cb6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1904,11 +1904,11 @@ graphql-middleware@1.6.6: dependencies: graphql-tools "^3.0.5" -graphql-middleware@^1.7.6: - version "1.7.7" - resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.7.tgz#0a7a7193a873c4769401df2aef4ffb9c6ca97f43" +graphql-middleware@1.7.6: + version "1.7.6" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.6.tgz#f226bf6671f3d82a9378f8b335804c8e44d21733" dependencies: - graphql-tools "^4.0.1" + graphql-tools "^4.0.0" graphql-playground-html@1.5.5: version "1.5.5" @@ -1960,9 +1960,9 @@ graphql-tools@^3.0.0, graphql-tools@^3.0.4, graphql-tools@^3.0.5: iterall "^1.1.3" uuid "^3.1.0" -graphql-tools@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.1.tgz#c995a4e25c2967d108c975e508322d12969c8c0e" +graphql-tools@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.2.tgz#9da22974cc6bf6524ed4f4af35556fd15aa6516d" dependencies: apollo-link "^1.2.3" apollo-utilities "^1.0.1" @@ -1970,7 +1970,7 @@ graphql-tools@^4.0.1: iterall "^1.1.3" uuid "^3.1.0" -graphql-yoga@^1.16.2: +graphql-yoga@1.16.2: version "1.16.2" resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.16.2.tgz#083293a9cecab6283e883c5a482c5c920fa66585" dependencies: @@ -2709,7 +2709,7 @@ neo4j-driver@^1.6.1: babel-runtime "^6.18.0" uri-js "^4.2.1" -neo4j-graphql-js@^1.0.2: +neo4j-graphql-js@1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.4.tgz#250bd44024f1505c726d2fc4ab27a35a1fc5330b" dependencies: From cbf83273fb8b36d198818447eec45bcd50bcb1a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 19 Oct 2018 23:06:59 +0200 Subject: [PATCH 023/554] Provide installation with docker --- Dockerfile | 18 ++++++++++++++++++ docker-compose.yml | 29 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..36d94ffa5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM node:10-alpine +LABEL Description="Server part of the social network Human Connection" Vendor="Human-Connection gGmbH" Version="0.0.1" Maintainer="Human-Connection gGmbH (developer@human-connection.org)" + +# expose the app port +EXPOSE 4000 + +ARG WORKDIR=/HC-Server + +RUN mkdir -p $WORKDIR +WORKDIR $WORKDIR + +COPY package.json . +COPY yarn.lock . +RUN yarn install --production=false --frozen-lockfile --non-interactive + +COPY . . + +CMD ["yarn", "run", "start"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..013fad907 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,29 @@ +version: "3.7" + +services: + server: + build: . + networks: + - hc-network + depends_on: + - neo4j + ports: + - 4000:4000 + environment: + - NEO4J_URI=bolt://neo4j:7687 + - GRAPHQL_LISTEN_PORT=4000 + - GRAPHQL_URI=http://localhost:4000 + - CLIENT_URI=http://localhost:3000 + - JWT_SECRET=b/&&7b78BF&fv/Vd + - MOCK=false + + neo4j: + image: neo4j:3.4 + networks: + - hc-network + environment: + - NEO4J_AUTH=none + +networks: + hc-network: + name: hc-network From 91fb18f77dca7ea3c0d8478b902baa6d10c99df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 19 Oct 2018 23:18:22 +0200 Subject: [PATCH 024/554] DB volume (for cleaning) + Naming: server->backend --- docker-compose.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 013fad907..afb8037e7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.7" services: - server: + backend: build: . networks: - hc-network @@ -21,9 +21,14 @@ services: image: neo4j:3.4 networks: - hc-network + volumes: + - neo4j-data:/data environment: - NEO4J_AUTH=none networks: hc-network: name: hc-network + +volumes: + neo4j-data: From 67e330d10efd93af9543c60767cc9f3163ec6e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 19 Oct 2018 23:19:32 +0200 Subject: [PATCH 025/554] Add Documentation for Installation with Docker --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index b75488607..1a47ee398 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,26 @@ ## Quick Start +### Installation with Docker + +Run: +```sh +docker-compose up +# if you want seed data +# open another terminal and run +docker-compose exec backend yarn run seedDb +``` + +App is [running on port 4000](http://localhost:4000/) + +To wipe out your neo4j database run: +```sh +docker-compose down -v +``` + + +### Installation without Docker + Install dependencies: ```bash From 036e4a602be5c6da55c8d7c60329c7ab17294d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sat, 20 Oct 2018 01:25:53 +0200 Subject: [PATCH 026/554] Add .dockerignore --- .dockerignore | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..ccb6f6091 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +.vscode/ + +node_modules/ +npm-debug.log + +Dockerfile +docker-compose*.yml + +.env From 1e0e22013a2741b8cf912f4e20083b090f4e0483 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 23 Oct 2018 12:09:43 +0200 Subject: [PATCH 027/554] improved schema and middleware --- src/middleware/fixImageUrlsMiddleware.js | 18 ++++++++++-------- src/schema.graphql | 13 ++++++++----- src/seed/seed-mutations.js | 22 +++++++++++----------- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/middleware/fixImageUrlsMiddleware.js b/src/middleware/fixImageUrlsMiddleware.js index 04c08c303..864726a54 100644 --- a/src/middleware/fixImageUrlsMiddleware.js +++ b/src/middleware/fixImageUrlsMiddleware.js @@ -1,14 +1,17 @@ export const fixUrl = (url) => { - return url.replace('https://api-alpha.human-connection.org/uploads', 'http://localhost:3000/uploads') + return url.replace('https://api-alpha.human-connection.org', 'http://localhost:3000') } -const fixImageURLs = (result, resolve, root, args, context, info) => { - - if (result && typeof result === 'string' && result.indexOf('https://api-alpha.human-connection.org/uploads') === 0) { +const fixImageURLs = (result, recursive) => { + if (result && typeof result === 'string' && result.indexOf('https://api-alpha.human-connection.org') === 0) { result = fixUrl(result) + } else if (result && Array.isArray(result)) { + result.forEach((res, index) => { + result[index] = fixImageURLs(result[index], true) + }) } else if (result && typeof result === 'object') { Object.keys(result).forEach(key => { - result[key] = fixImageURLs(result[key]) + result[key] = fixImageURLs(result[key], true) }) } return result @@ -17,11 +20,10 @@ const fixImageURLs = (result, resolve, root, args, context, info) => { export default { Mutation: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) - return fixImageURLs(result, resolve, root, args, context, info) + return fixImageURLs(result) }, Query: async (resolve, root, args, context, info) => { let result = await resolve(root, args, context, info) - - return fixImageURLs(result, resolve, root, args, context, info) + return fixImageURLs(result) } } diff --git a/src/schema.graphql b/src/schema.graphql index 8ec8310ca..4640cebb5 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -75,11 +75,12 @@ type User { followedBy: [User]! @relation(name: "FOLLOWS", direction: "IN") followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(r)") - contributions: [WrittenPost]! + #contributions: [WrittenPost]! #contributions2(first: Int = 10, offset: Int = 0): [WrittenPost2]! # @cypher( # statement: "MATCH (this)-[w:WROTE]->(p:Post) RETURN p as Post, w.timestamp as timestamp" # ) + contributions: [Post]! @relation(name: "WROTE", direction: "OUT") contributionsCount: Int! @cypher(statement: """ MATCH (this)-[:WROTE]->(r:Post) WHERE (NOT exists(r.deleted) OR r.deleted = false) @@ -113,6 +114,8 @@ type Post { visibility: VisibilityEnum deleted: Boolean disabled: Boolean + createdAt: String + updatedAt: String relatedContributions: [Post]! @cypher(statement: """ MATCH (this)-[:TAGGED|CATEGORIZED]->(categoryOrTag)<-[:TAGGED|CATEGORIZED]-(post:Post) @@ -160,12 +163,12 @@ type Badge { } enum BadgeTypeEnum { - Role - Crowdfunding + role + crowdfunding } enum BadgeStatusEnum { - Permanent - Temorary + permanent + temorary } type Organization { diff --git a/src/seed/seed-mutations.js b/src/seed/seed-mutations.js index cf1cba49e..35aaff8eb 100644 --- a/src/seed/seed-mutations.js +++ b/src/seed/seed-mutations.js @@ -4,28 +4,28 @@ export default ` mutation { # Users - u1: CreateUser(id: "u1", name: "Peter Lustig", password: "1234", email: "admin@test.de", avatar: "${faker.internet.avatar()}", role: Admin) { + u1: CreateUser(id: "u1", name: "Peter Lustig", password: "1234", email: "admin@test.de", avatar: "${faker.internet.avatar()}", role: admin) { id name email avatar role } - u2: CreateUser(id: "u2", name: "Bob der Bausmeister", password: "1234", email: "moderator@test.de", avatar: "${faker.internet.avatar()}", role: Moderator) { + u2: CreateUser(id: "u2", name: "Bob der Bausmeister", password: "1234", email: "moderator@test.de", avatar: "${faker.internet.avatar()}", role: moderator) { id name email avatar role } - u3: CreateUser(id: "u3", name: "Jenny Rostock", password: "1234", email: "user@test.de", avatar: "${faker.internet.avatar()}", role: User) { + u3: CreateUser(id: "u3", name: "Jenny Rostock", password: "1234", email: "user@test.de", avatar: "${faker.internet.avatar()}", role: user) { id name email avatar role } - u4: CreateUser(id: "u4", name: "Angie Banjie", password: "1234", email: "Angie_Banjie@yahoo.com", avatar: "${faker.internet.avatar()}", role: User) { + u4: CreateUser(id: "u4", name: "Angie Banjie", password: "1234", email: "Angie_Banjie@yahoo.com", avatar: "${faker.internet.avatar()}", role: user) { id name email @@ -36,12 +36,12 @@ export default ` u1_blacklist_u4: AddUserBlacklisted(from: { id: "u1" }, to: { id: "u4" }) { from { id } } # Badges - b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_racoon") { id } - b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_rabbit") { id } - b3: CreateBadge(id: "b3", key: "indiegogo_en_wolf", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_wolf") { id } - b4: CreateBadge(id: "b4", key: "indiegogo_en_bear", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_bear") { id } - b5: CreateBadge(id: "b5", key: "indiegogo_en_turtle", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_turtle") { id } - b6: CreateBadge(id: "b6", key: "indiegogo_en_rhino", type: Crowdfunding, status: Permanent, icon: "indiegogo_en_rhino") { id } + b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: Crowdfunding, status: permanent, icon: "indiegogo_en_racoon") { id } + b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: Crowdfunding, status: permanent, icon: "indiegogo_en_rabbit") { id } + b3: CreateBadge(id: "b3", key: "indiegogo_en_wolf", type: Crowdfunding, status: permanent, icon: "indiegogo_en_wolf") { id } + b4: CreateBadge(id: "b4", key: "indiegogo_en_bear", type: Crowdfunding, status: permanent, icon: "indiegogo_en_bear") { id } + b5: CreateBadge(id: "b5", key: "indiegogo_en_turtle", type: Crowdfunding, status: permanent, icon: "indiegogo_en_turtle") { id } + b6: CreateBadge(id: "b6", key: "indiegogo_en_rhino", type: Crowdfunding, status: permanent, icon: "indiegogo_en_rhino") { id } b1_u1: AddUserBadges(from: {id: "b1"}, to: {id: "u1"}) { from { id } } b2_u1: AddUserBadges(from: {id: "b2"}, to: {id: "u1"}) { from { id } } @@ -72,7 +72,7 @@ export default ` p1: CreatePost( id: "p1", title: "Gedanken eines Polizisten zum Einsatz im Hambacher Forst", - content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", + content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", image: "https://picsum.photos/1280/1024?image=352", visibility: Public, disabled: false, From 8542105c8afd6c7e538f8a2c3871c4a775dbeac9 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 23 Oct 2018 12:40:11 +0200 Subject: [PATCH 028/554] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d71f1eb58..e00ac8306 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Human-Connection - GraphQL API - Prototype +# Human-Connection - NITRO API > This Prototype tries to resolve the biggest hurdle of connecting > our services together. This is not possible in a sane way using From 9b34376c1c06b01758c667545a2c7b607e9c3a2c Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 23 Oct 2018 21:23:08 +0200 Subject: [PATCH 029/554] fixed seeding and password hashing --- src/middleware/passwordMiddleware.js | 4 +- src/schema.graphql | 13 ++--- src/seed/seed-mutations.js | 78 ++++++++++++++++++++-------- 3 files changed, 65 insertions(+), 30 deletions(-) diff --git a/src/middleware/passwordMiddleware.js b/src/middleware/passwordMiddleware.js index 139fcffcf..b84680638 100644 --- a/src/middleware/passwordMiddleware.js +++ b/src/middleware/passwordMiddleware.js @@ -1,7 +1,9 @@ +import bcrypt from 'bcryptjs' + export default { Mutation: { CreateUser: async (resolve, root, args, context, info) => { - args.password = 'TRY TO ENCRYPT IT' + args.password = await bcrypt.hashSync(args.password, 10) const result = await resolve(root, args, context, info) result.password = '*****' return result diff --git a/src/schema.graphql b/src/schema.graphql index 4640cebb5..d4d184de0 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -29,15 +29,15 @@ type Statistics { } enum VisibilityEnum { - Public - Friends - Private + public + friends + private } enum UserGroupEnum { - Admin - Moderator - User + admin + moderator + user } type WrittenPost @relation(name: "WROTE") { @@ -193,4 +193,5 @@ type Tag { taggedOrganizations: [Organization]! @relation(name: "TAGGED", direction: "IN") taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(r) RETURN COUNT(r)") deleted: Boolean + disabled: Boolean } diff --git a/src/seed/seed-mutations.js b/src/seed/seed-mutations.js index 5a6e34227..8431e3c59 100644 --- a/src/seed/seed-mutations.js +++ b/src/seed/seed-mutations.js @@ -4,28 +4,60 @@ export default ` mutation { # Users - u1: CreateUser(id: "u1", name: "Peter Lustig", password: "1234", email: "admin@example.org", avatar: "${faker.internet.avatar()}", role: admin) { + u1: CreateUser( + id: "u1", + name: "Peter Lustig", + password: "1234", + email: "admin@example.org", + avatar: "${faker.internet.avatar()}", + role: admin, + disabled: false, + deleted: false) { id name email avatar role } - u2: CreateUser(id: "u2", name: "Bob der Bausmeister", password: "1234", email: "moderator@example.org", avatar: "${faker.internet.avatar()}", role: moderator) { + u2: CreateUser( + id: "u2", + name: "Bob der Bausmeister", + password: "1234", + email: "moderator@example.org", + avatar: "${faker.internet.avatar()}", + role: moderator, + disabled: false, + deleted: false) { id name email avatar role } - u3: CreateUser(id: "u3", name: "Jenny Rostock", password: "1234", email: "user@example.org", avatar: "${faker.internet.avatar()}", role: user) { + u3: CreateUser( + id: "u3", + name: "Jenny Rostock", + password: "1234", + email: "user@example.org", + avatar: "${faker.internet.avatar()}", + role: user, + disabled: false, + deleted: false) { id name email avatar role } - u4: CreateUser(id: "u4", name: "Angie Banjie", password: "1234", email: "angie@example.org", avatar: "${faker.internet.avatar()}", role: user) { + u4: CreateUser( + id: "u4", + name: "Angie Banjie", + password: "1234", + email: "angie@example.org", + avatar: "${faker.internet.avatar()}", + role: user, + disabled: false, + deleted: false) { id name email @@ -36,12 +68,12 @@ export default ` u1_blacklist_u4: AddUserBlacklisted(from: { id: "u1" }, to: { id: "u4" }) { from { id } } # Badges - b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: Crowdfunding, status: permanent, icon: "indiegogo_en_racoon") { id } - b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: Crowdfunding, status: permanent, icon: "indiegogo_en_rabbit") { id } - b3: CreateBadge(id: "b3", key: "indiegogo_en_wolf", type: Crowdfunding, status: permanent, icon: "indiegogo_en_wolf") { id } - b4: CreateBadge(id: "b4", key: "indiegogo_en_bear", type: Crowdfunding, status: permanent, icon: "indiegogo_en_bear") { id } - b5: CreateBadge(id: "b5", key: "indiegogo_en_turtle", type: Crowdfunding, status: permanent, icon: "indiegogo_en_turtle") { id } - b6: CreateBadge(id: "b6", key: "indiegogo_en_rhino", type: Crowdfunding, status: permanent, icon: "indiegogo_en_rhino") { id } + b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_racoon.svg") { id } + b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_rabbit.svg") { id } + b3: CreateBadge(id: "b3", key: "indiegogo_en_wolf", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_wolf.svg") { id } + b4: CreateBadge(id: "b4", key: "indiegogo_en_bear", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_bear.svg") { id } + b5: CreateBadge(id: "b5", key: "indiegogo_en_turtle", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_turtle.svg") { id } + b6: CreateBadge(id: "b6", key: "indiegogo_en_rhino", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_rhino.svg") { id } b1_u1: AddUserBadges(from: {id: "b1"}, to: {id: "u1"}) { from { id } } b2_u1: AddUserBadges(from: {id: "b2"}, to: {id: "u1"}) { from { id } } @@ -74,81 +106,81 @@ export default ` title: "Gedanken eines Polizisten zum Einsatz im Hambacher Forst", content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", image: "https://picsum.photos/1280/1024?image=352", - visibility: Public, + visibility: public, disabled: false, deleted: false ) { title } p1_cat1: AddPostCategories(from: {id: "p1"}, to: {id: "cat1"}) { from { id } } p1_cat2: AddPostCategories(from: {id: "p1"}, to: {id: "cat2"}) { from { id } } - ur1: AddUserContributions(from: { id: "u1" }, to: { id: "p1" }, data: { timestamp: 1538655020 }) { from { id } } + ur1: AddUserContributions(from: { id: "u1" }, to: { id: "p1" }) { from { id } } p2: CreatePost( id: "p2", title: "Julian Assange", - content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", + content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", image: "https://picsum.photos/1280/1024?image=72", - visibility: Public, + visibility: public, disabled: false, deleted: false ) { title } p2_cat1: AddPostCategories(from: {id: "p2"}, to: {id: "cat1"}) { from { id } } p2_cat16: AddPostCategories(from: {id: "p2"}, to: {id: "cat16"}) { from { id } } - ur2: AddUserContributions(from: { id: "u2" }, to: { id: "p2" }, data: { timestamp: 1538655120 }) { from { id } } + ur2: AddUserContributions(from: { id: "u2" }, to: { id: "p2" }) { from { id } } p3: CreatePost( id: "p3", title: "Hacker, Freaks und Funktionäre...Der CCC", content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", image: "https://picsum.photos/1280/1024?image=121", - visibility: Public, + visibility: public, disabled: false, deleted: false ) { title } p3_cat1: AddPostCategories(from: {id: "p3"}, to: {id: "cat1"}) { from { id } } p3_cat3: AddPostCategories(from: {id: "p3"}, to: {id: "cat3"}) { from { id } } p3_cat14: AddPostCategories(from: {id: "p3"}, to: {id: "cat14"}) { from { id } } - ur3: AddUserContributions(from: { id: "u3" }, to: { id: "p3" }, data: { timestamp: 1538653120 }) { from { id } } + ur3: AddUserContributions(from: { id: "u3" }, to: { id: "p3" }) { from { id } } p4: CreatePost( id: "p4", title: "Lebensmittel (?)", content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", image: "https://picsum.photos/1280/1024?image=142", - visibility: Public, + visibility: public, disabled: false, deleted: false ) { title } p4_cat1: AddPostCategories(from: {id: "p4"}, to: {id: "cat1"}) { from { id } } p4_cat9: AddPostCategories(from: {id: "p4"}, to: {id: "cat9"}) { from { id } } p4_cat4: AddPostCategories(from: {id: "p4"}, to: {id: "cat4"}) { from { id } } - ur4: AddUserContributions(from: { id: "u4" }, to: { id: "p4" }, data: { timestamp: 1538615120 }) { from { id } } + ur4: AddUserContributions(from: { id: "u4" }, to: { id: "p4" }) { from { id } } p5: CreatePost( id: "p5", title: "${faker.lorem.sentence()}", content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", image: "https://picsum.photos/1280/1024?image=231", - visibility: Public, + visibility: public, disabled: false, deleted: false ) { title } p5_cat8: AddPostCategories(from: {id: "p5"}, to: {id: "cat8"}) { from { id } } p5_cat12: AddPostCategories(from: {id: "p5"}, to: {id: "cat12"}) { from { id } } - ur5: AddUserContributions(from: { id: "u2" }, to: { id: "p5" }, data: { timestamp: 1538615120 }) { from { id } } + ur5: AddUserContributions(from: { id: "u2" }, to: { id: "p5" }) { from { id } } p6: CreatePost( id: "p6", title: "${faker.lorem.sentence()}", content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", image: "https://picsum.photos/1280/1024?image=424", - visibility: Public, + visibility: public, disabled: false, deleted: false ) { title } p6_cat1: AddPostCategories(from: {id: "p6"}, to: {id: "cat1"}) { from { id } } p6_cat2: AddPostCategories(from: {id: "p6"}, to: {id: "cat2"}) { from { id } } p6_cat5: AddPostCategories(from: {id: "p6"}, to: {id: "cat5"}) { from { id } } - ur6: AddUserContributions(from: { id: "u4" }, to: { id: "p6" }, data: { timestamp: 1538615120 }) { from { id } } + ur6: AddUserContributions(from: { id: "u4" }, to: { id: "p6" }) { from { id } } # Comments c1: CreateComment( From 5f102f7d986d773f5104a82304328a6ad7d8bd72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 23 Oct 2018 23:51:06 +0200 Subject: [PATCH 030/554] Custom Dockerfile to install apoc plugin in neo4j --- Dockerfile.neo4j | 3 +++ docker-compose.yml | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Dockerfile.neo4j diff --git a/Dockerfile.neo4j b/Dockerfile.neo4j new file mode 100644 index 000000000..3675669f6 --- /dev/null +++ b/Dockerfile.neo4j @@ -0,0 +1,3 @@ +FROM neo4j:3.4 +RUN mkdir /plugins && wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.4.0.3/apoc-3.4.0.3-all.jar -P /plugins + diff --git a/docker-compose.yml b/docker-compose.yml index afb8037e7..79ccc4b62 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,7 +18,9 @@ services: - MOCK=false neo4j: - image: neo4j:3.4 + build: + context: . + dockerfile: Dockerfile.neo4j networks: - hc-network volumes: From e40d19af5d226e6e4bae0efb77cf6d70e9276b52 Mon Sep 17 00:00:00 2001 From: Lala Sabathil Date: Fri, 26 Oct 2018 11:17:43 +0200 Subject: [PATCH 031/554] Update schema.graphql Fix #7 --- src/schema.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schema.graphql b/src/schema.graphql index d4d184de0..6577a1ef6 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -168,7 +168,7 @@ enum BadgeTypeEnum { } enum BadgeStatusEnum { permanent - temorary + temporary } type Organization { From ea33d55d0109fb483a747a0cb3275a8f911e9cd1 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 26 Oct 2018 14:24:00 +0200 Subject: [PATCH 032/554] fixed comment count in schema --- src/schema.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schema.graphql b/src/schema.graphql index d4d184de0..4d467cb41 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -89,7 +89,7 @@ type User { ) comments: [WrittenComment]! - commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)") + commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) WHERE NOT r.deleted = true RETURN COUNT(r)") shouted: [Post]! @relation(name: "SHOUTED", direction: "OUT") shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)") From 811dee372b4d1f6168e267d49131676cd8b07a1c Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 26 Oct 2018 15:16:10 +0200 Subject: [PATCH 033/554] output createdAt and updatedAt on comments --- src/schema.graphql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/schema.graphql b/src/schema.graphql index 4d467cb41..85ca019f2 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -139,6 +139,8 @@ type Comment { content: String! contentExcerpt: String post: Post @relation(name: "COMMENT", direction: "OUT") + createdAt: String, + updatedAt: String, deleted: Boolean disabled: Boolean } From 024ba81cd2dbeaae249460fa345cf2d8c5dc6fb1 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 26 Oct 2018 15:53:39 +0200 Subject: [PATCH 034/554] cleanup and some notes --- src/graphql-schema.js | 2 -- src/index.js | 9 +++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index b71c64ab7..44ec8116d 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -4,7 +4,6 @@ import path from 'path' import bcrypt from 'bcryptjs' import zipObject from 'lodash/zipObject' import generateJwt from './jwt/generateToken' -import values from 'lodash/values' import { fixUrl } from './middleware/fixImageUrlsMiddleware' export const typeDefs = @@ -78,7 +77,6 @@ export const resolvers = { } resolve(data) }) - } // usersBySubstring: neo4jgraphql }, diff --git a/src/index.js b/src/index.js index 8cae4d4f6..84787b154 100644 --- a/src/index.js +++ b/src/index.js @@ -61,6 +61,15 @@ const server = new GraphQLServer({ return payload }, schema: augmentSchema(schema), + // TODO: switch to the part below when neo4j-graphql-js 1.0.5 or higher is available + // schema: augmentSchema(schema, { + // query: { + // exclude: ['Statistics'] + // }, + // mutation: { + // exclude: ['Statistics'] + // } + // }), tracing: true, middlewares: middleware, mocks: MOCK ? mocks : false From 6449d2a99cb0851471dfadea449553ed69a21d25 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 28 Oct 2018 14:56:30 +0100 Subject: [PATCH 035/554] upgraded neo4j-graphql-js to 1.0.5 and removed blacklisted mutations for Statistics and LoggedInUser --- package.json | 2 +- src/index.js | 19 +++++++++---------- yarn.lock | 6 +++--- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index d753ed31c..bfddc0aa8 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "lodash": "^4.17.11", "ms": "^2.1.1", "neo4j-driver": "^1.6.1", - "neo4j-graphql-js": "1.0.4", + "neo4j-graphql-js": "1.0.5", "node-fetch": "^2.1.2", "passport": "^0.4.0", "passport-jwt": "^4.0.0", diff --git a/src/index.js b/src/index.js index 84787b154..e975ba57d 100644 --- a/src/index.js +++ b/src/index.js @@ -60,16 +60,15 @@ const server = new GraphQLServer({ return payload }, - schema: augmentSchema(schema), - // TODO: switch to the part below when neo4j-graphql-js 1.0.5 or higher is available - // schema: augmentSchema(schema, { - // query: { - // exclude: ['Statistics'] - // }, - // mutation: { - // exclude: ['Statistics'] - // } - // }), + // schema: augmentSchema(schema), + schema: augmentSchema(schema, { + query: { + exclude: ['Statistics', 'LoggedInUser'] + }, + mutation: { + exclude: ['Statistics', 'LoggedInUser'] + } + }), tracing: true, middlewares: middleware, mocks: MOCK ? mocks : false diff --git a/yarn.lock b/yarn.lock index bcb870cb6..42b231e58 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2709,9 +2709,9 @@ neo4j-driver@^1.6.1: babel-runtime "^6.18.0" uri-js "^4.2.1" -neo4j-graphql-js@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.4.tgz#250bd44024f1505c726d2fc4ab27a35a1fc5330b" +neo4j-graphql-js@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.5.tgz#ef5d59d2e7cf46971af49bceec2f4bcd2debc835" dependencies: graphql "^0.13.2" lodash "^4.17.10" From 00cc53e0458e378fda74c5c5e82acb99f2f62542 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 28 Oct 2018 18:47:24 +0100 Subject: [PATCH 036/554] added xss protection, automatic links and, date middleware --- package.json | 5 + src/bootstrap/directives.js | 16 ++ src/bootstrap/scalars.js | 13 ++ src/index.js | 50 ++---- src/middleware/dateTimeMiddleware.js | 54 +++++++ src/middleware/index.js | 4 + src/middleware/xssMiddleware.js | 124 +++++++++++++++ src/nodes/users/userMiddleware.js | 0 src/schema.graphql | 6 + yarn.lock | 228 +++++++++++++++++++++++++-- 10 files changed, 450 insertions(+), 50 deletions(-) create mode 100644 src/bootstrap/directives.js create mode 100644 src/bootstrap/scalars.js create mode 100644 src/middleware/dateTimeMiddleware.js create mode 100644 src/middleware/xssMiddleware.js create mode 100644 src/nodes/users/userMiddleware.js diff --git a/package.json b/package.json index bfddc0aa8..dcde920d2 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,16 @@ "apollo-link-http": "^1.5.4", "apollo-server": "^2.0.4", "bcryptjs": "^2.4.3", + "cheerio": "^1.0.0-rc.2", + "date-fns": "^2.0.0-alpha.24", "dotenv": "^6.0.0", "graphql-custom-directives": "^0.2.13", + "graphql-iso-date": "^3.6.1", "graphql-middleware": "1.7.6", "graphql-tag": "^2.9.2", "graphql-yoga": "1.16.2", "jsonwebtoken": "^8.3.0", + "linkifyjs": "^2.1.7", "lodash": "^4.17.11", "ms": "^2.1.1", "neo4j-driver": "^1.6.1", @@ -31,6 +35,7 @@ "node-fetch": "^2.1.2", "passport": "^0.4.0", "passport-jwt": "^4.0.0", + "sanitize-html": "^1.19.1", "slug": "^0.9.1", "trunc-html": "^1.1.2" }, diff --git a/src/bootstrap/directives.js b/src/bootstrap/directives.js new file mode 100644 index 000000000..280713721 --- /dev/null +++ b/src/bootstrap/directives.js @@ -0,0 +1,16 @@ +import { + GraphQLLowerCaseDirective, + GraphQLTrimDirective, + GraphQLDefaultToDirective +} from 'graphql-custom-directives' + +export default function applyDirectives(augmentedSchema) { + const directives = [ + GraphQLLowerCaseDirective, + GraphQLTrimDirective, + GraphQLDefaultToDirective + ] + augmentedSchema._directives.push.apply(augmentedSchema._directives, directives) + + return augmentedSchema +} diff --git a/src/bootstrap/scalars.js b/src/bootstrap/scalars.js new file mode 100644 index 000000000..2676f69ae --- /dev/null +++ b/src/bootstrap/scalars.js @@ -0,0 +1,13 @@ +import { + GraphQLDate, + GraphQLTime, + GraphQLDateTime +} from 'graphql-iso-date' + +export default function applyScalars(augmentedSchema) { + augmentedSchema._typeMap.Date = GraphQLDate + augmentedSchema._typeMap.Time = GraphQLTime + augmentedSchema._typeMap.DateTime = GraphQLDateTime + + return augmentedSchema +} diff --git a/src/index.js b/src/index.js index e975ba57d..7aaf8904d 100644 --- a/src/index.js +++ b/src/index.js @@ -6,17 +6,13 @@ import { v1 as neo4j } from 'neo4j-driver' import dotenv from 'dotenv' import mocks from './mocks' import middleware from './middleware' +import applyDirectives from './bootstrap/directives' +import applyScalars from './bootstrap/scalars' import passport from 'passport' import jwtStrategy from './jwt/strategy' import jwt from 'jsonwebtoken' -// import { -// GraphQLLowerCaseDirective, -// GraphQLTrimDirective, -// GraphQLDefaultToDirective -// } from 'graphql-custom-directives'; - dotenv.config() const schema = makeExecutableSchema({ @@ -24,17 +20,6 @@ const schema = makeExecutableSchema({ resolvers }) -// augmentSchema will add auto generated mutations based on types in schema -// const augmentedSchema = augmentSchema(schema) - -// add custom directives -// const directives = [ -// GraphQLLowerCaseDirective, -// GraphQLTrimDirective, -// GraphQLDefaultToDirective -// ] -// augmentedSchema._directives.push.apply(augmentedSchema._directives, directives) - const driver = neo4j.driver( process.env.NEO4J_URI || 'bolt://localhost:7687', neo4j.auth.basic( @@ -46,6 +31,15 @@ const driver = neo4j.driver( const MOCK = (process.env.MOCK === 'true') console.log('MOCK:', MOCK) +const augumentedSchema = augmentSchema(schema, { + query: { + exclude: ['Statistics', 'LoggedInUser'] + }, + mutation: { + exclude: ['Statistics', 'LoggedInUser'] + } +}) + const server = new GraphQLServer({ context: async (req) => { const payload = { @@ -60,15 +54,7 @@ const server = new GraphQLServer({ return payload }, - // schema: augmentSchema(schema), - schema: augmentSchema(schema, { - query: { - exclude: ['Statistics', 'LoggedInUser'] - }, - mutation: { - exclude: ['Statistics', 'LoggedInUser'] - } - }), + schema: applyScalars(applyDirectives(augumentedSchema)), tracing: true, middlewares: middleware, mocks: MOCK ? mocks : false @@ -79,18 +65,6 @@ server.express.use(passport.initialize()) server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) -// session middleware -// server.express.use(session({ -// name: 'qid', -// secret: process.env.JWT_SECRET, -// resave: true, -// saveUninitialized: true, -// cookie: { -// secure: process.env.NODE_ENV === 'production', -// maxAge: ms('1d') -// } -// })) - const serverConfig = { port: 4000 // cors: { diff --git a/src/middleware/dateTimeMiddleware.js b/src/middleware/dateTimeMiddleware.js new file mode 100644 index 000000000..8fd3c074b --- /dev/null +++ b/src/middleware/dateTimeMiddleware.js @@ -0,0 +1,54 @@ +import format from 'date-fns/format' + +export default { + Mutation: { + CreateUser: async (resolve, root, args, context, info) => { + args.createdAt = format(new Date()) + args.disabled = false + args.deleted = false + const result = await resolve(root, args, context, info) + return result + }, + CreatePost: async (resolve, root, args, context, info) => { + args.createdAt = format(new Date()) + args.disabled = false + args.deleted = false + const result = await resolve(root, args, context, info) + return result + }, + CreateComment: async (resolve, root, args, context, info) => { + args.createdAt = format(new Date()) + args.disabled = false + args.deleted = false + const result = await resolve(root, args, context, info) + return result + }, + CreateOrganization: async (resolve, root, args, context, info) => { + args.createdAt = format(new Date()) + args.disabled = false + args.deleted = false + const result = await resolve(root, args, context, info) + return result + }, + UpdateUser: async (resolve, root, args, context, info) => { + args.updatedAt = format(new Date()) + const result = await resolve(root, args, context, info) + return result + }, + UpdatePost: async (resolve, root, args, context, info) => { + args.updatedAt = format(new Date()) + const result = await resolve(root, args, context, info) + return result + }, + UpdateComment: async (resolve, root, args, context, info) => { + args.updatedAt = format(new Date()) + const result = await resolve(root, args, context, info) + return result + }, + UpdateOrganization: async (resolve, root, args, context, info) => { + args.updatedAt = format(new Date()) + const result = await resolve(root, args, context, info) + return result + } + } +} diff --git a/src/middleware/index.js b/src/middleware/index.js index 9a32862c3..4088c428b 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -3,8 +3,12 @@ import softDeleteMiddleware from './softDeleteMiddleware' import sluggifyMiddleware from './sluggifyMiddleware' import fixImageUrlsMiddleware from './fixImageUrlsMiddleware' import excerptMiddleware from './excerptMiddleware' +import dateTimeMiddleware from './dateTimeMiddleware'; +import xssMiddleware from './xssMiddleware'; export default [ + xssMiddleware, + dateTimeMiddleware, passwordMiddleware, sluggifyMiddleware, excerptMiddleware, diff --git a/src/middleware/xssMiddleware.js b/src/middleware/xssMiddleware.js new file mode 100644 index 000000000..240301cf7 --- /dev/null +++ b/src/middleware/xssMiddleware.js @@ -0,0 +1,124 @@ +import trunc from 'trunc-html' +// import { getByDot, setByDot, getItems, replaceItems } from 'feathers-hooks-common' +import sanitizeHtml from 'sanitize-html' +// import { isEmpty, intersection } from 'lodash' +import cheerio from 'cheerio' +import linkifyHtml from 'linkifyjs/html' + +const embedToAnchor = (content) => { + const $ = cheerio.load(content) + $('div[data-url-embed]').each((i, el) => { + let url = el.attribs['data-url-embed'] + let aTag = $(`
${url}`) + $(el).replaceWith(aTag) + }) + return $('body').html() +} + +function clean (dirty) { + if (!dirty) { + return dirty + } + + // Convert embeds to a-tags + dirty = embedToAnchor(dirty) + dirty = linkifyHtml(dirty) + dirty = sanitizeHtml(dirty, { + allowedTags: ['iframe', 'img', 'p', 'br', 'b', 'i', 'em', 'strong', 'a', 'pre', 'ul', 'li', 'ol', 's', 'strike', 'span', 'blockquote'], + allowedAttributes: { + a: ['href', 'class', 'target', 'data-*' , 'contenteditable'], + span: ['contenteditable', 'class', 'data-*'], + img: ['src'], + iframe: ['src', 'class', 'frameborder', 'allowfullscreen'] + }, + allowedIframeHostnames: ['www.youtube.com', 'player.vimeo.com'], + parser: { + lowerCaseTags: true + }, + transformTags: { + iframe: function (tagName, attribs) { + return { + tagName: 'a', + text: attribs.src, + attribs: { + href: attribs.src, + target: '_blank', + 'data-url-embed': '' + } + } + }, + i: 'em', + // a: function (tagName, attribs) { + // return { + // tagName: 'a', + // attribs: { + // href: attribs.href, + // target: '_blank', + // } + // } + // }, + b: 'strong', + s: 'strike', + img: function (tagName, attribs) { + let src = attribs.src + + // if (isEmpty(hook.result)) { + // const config = hook.app.get('thumbor') + // if (config && src.indexOf(config < 0)) { + // // download image + // // const ThumborUrlHelper = require('../helper/thumbor-helper') + // // const Thumbor = new ThumborUrlHelper(config.key || null, config.url || null) + // // src = Thumbor + // // .setImagePath(src) + // // .buildUrl('740x0') + // } + // } + return { + tagName: 'img', + attribs: { + src: `http://localhost:3050/images?url=${src}` + } + } + } + } + }) + + // remove empty html tags and duplicated returns + dirty = dirty + .replace(/<[a-z]>[\s]*<\/[a-z]>/igm, '') + .replace(/(]*)(>)[^>]*\/*>/igm, '') + .replace(/

[\s]*(
)+[\s]*<\/p>/igm, '
') + .replace(/(
){2,}/igm, '
') + .replace(/[\n]{3,}/igm, '\n\n') + .replace(/(\r\n|\n\r|\r|\n)/g, '
$1') + .replace(/


<\/p>/g, '') + return dirty +} + +// iterate through all fields and clean the values +function cleanAll (result, key, recursive, fields = ['content', 'contentExcerpt']) { + if (result && typeof result === 'string' && fields.includes(key)) { + result = clean(result) + } else if (result && Array.isArray(result)) { + result.forEach((res, index) => { + result[index] = cleanAll(result[index], index, true, fields) + }) + } else if (result && typeof result === 'object') { + Object.keys(result).forEach(key => { + result[key] = cleanAll(result[key], key, true, fields) + }) + } + return result +} + +export default { + Mutation: async (resolve, root, args, context, info) => { + args = cleanAll(args) + const result = await resolve(root, args, context, info) + return result + }, + Query: async (resolve, root, args, context, info) => { + const result = await resolve(root, args, context, info) + return cleanAll(result) + } +} diff --git a/src/nodes/users/userMiddleware.js b/src/nodes/users/userMiddleware.js new file mode 100644 index 000000000..e69de29bb diff --git a/src/schema.graphql b/src/schema.graphql index fb2279f9c..e6bb4f350 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -28,6 +28,10 @@ type Statistics { countShouts: Int! } +scalar Date +scalar Time +scalar DateTime + enum VisibilityEnum { public friends @@ -65,6 +69,8 @@ type User { deleted: Boolean disabled: Boolean role: UserGroupEnum + createdAt: String + updatedAt: String friends: [User]! @relation(name: "FRIENDS", direction: "BOTH") friendsCount: Int! @cypher(statement: "MATCH (this)<-[:FRIENDS]->(r:User) RETURN COUNT(r)") diff --git a/yarn.lock b/yarn.lock index 42b231e58..a855f8d7e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -490,6 +490,10 @@ array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" +array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" @@ -1090,6 +1094,10 @@ body-parser@1.18.3, body-parser@^1.18.2, body-parser@^1.18.3: raw-body "2.3.3" type-is "~1.6.16" +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + boxen@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" @@ -1202,7 +1210,7 @@ chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.1: +chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" dependencies: @@ -1210,6 +1218,17 @@ chalk@^2.0.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +cheerio@^1.0.0-rc.2: + version "1.0.0-rc.2" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash "^4.15.0" + parse5 "^3.0.1" + chokidar@^1.6.1: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" @@ -1379,6 +1398,23 @@ crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" +css-select@~1.2.0: + version "1.2.0" + resolved "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-what@2.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" + +date-fns@^2.0.0-alpha.24: + version "2.0.0-alpha.24" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.24.tgz#2988c137c72275af29d7d21cc53eb52b3a8c2586" + debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -1457,6 +1493,45 @@ dicer@0.2.5: readable-stream "1.1.x" streamsearch "0.1.2" +dom-serializer@0, dom-serializer@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" + dependencies: + domelementtype "~1.1.1" + entities "~1.1.1" + +domelementtype@1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.2.1.tgz#578558ef23befac043a1abb0db07635509393479" + +domelementtype@^1.3.0: + version "1.3.0" + resolved "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" + +domelementtype@~1.1.1: + version "1.1.3" + resolved "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + dependencies: + dom-serializer "0" + domelementtype "1" + dot-prop@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" @@ -1497,6 +1572,10 @@ encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" +entities@^1.1.1, entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + es-abstract@^1.5.1: version "1.12.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" @@ -1898,6 +1977,10 @@ graphql-import@^0.6.0: dependencies: lodash "^4.17.4" +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" + graphql-middleware@1.6.6: version "1.6.6" resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.6.6.tgz#f40f4e836ced479df718dbc1869ea4cd3b64027b" @@ -2071,6 +2154,17 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" +htmlparser2@^3.9.0, htmlparser2@^3.9.1: + version "3.10.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" + dependencies: + domelementtype "^1.3.0" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.0.6" + http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: version "1.6.3" resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" @@ -2389,6 +2483,10 @@ jmespath@0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" +jquery@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca" + "js-tokens@^3.0.0 || ^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -2471,10 +2569,26 @@ latest-version@^3.0.0: dependencies: package-json "^4.0.0" +linkifyjs@^2.1.7: + version "2.1.7" + resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-2.1.7.tgz#e5d68d2ae30b9c055e1d74cc40f9a31d3abb4012" + optionalDependencies: + jquery "^3.3.1" + react "^16.4.2" + react-dom "^16.4.2" + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" +lodash.escaperegexp@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" + lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" @@ -2499,11 +2613,15 @@ lodash.isstring@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" +lodash.mergewith@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" + lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5: +lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -2511,7 +2629,7 @@ long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" -loose-envify@^1.0.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" dependencies: @@ -2800,6 +2918,12 @@ npmlog@^4.0.2: gauge "~2.7.3" set-blocking "~2.0.0" +nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + dependencies: + boolbase "~1.0.0" + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" @@ -2808,7 +2932,7 @@ numeral@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" -object-assign@^4, object-assign@^4.1.0: +object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2917,6 +3041,12 @@ parse-glob@^3.0.4: is-extglob "^1.0.0" is-glob "^2.0.0" +parse5@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" + dependencies: + "@types/node" "*" + parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" @@ -2981,6 +3111,14 @@ posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" +postcss@^6.0.14: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" @@ -2997,6 +3135,13 @@ process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" +prop-types@^15.6.2: + version "15.6.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" + dependencies: + loose-envify "^1.3.1" + object-assign "^4.1.1" + protobufjs@^6.8.6: version "6.8.8" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" @@ -3084,6 +3229,24 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-dom@^16.4.2: + version "16.6.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.0.tgz#6375b8391e019a632a89a0988bce85f0cc87a92f" + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.10.0" + +react@^16.4.2: + version "16.6.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.6.0.tgz#b34761cfaf3e30f5508bc732fb4736730b7da246" + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.10.0" + readable-stream@1.1.x: version "1.1.14" resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" @@ -3105,6 +3268,14 @@ readable-stream@^2.0.2, readable-stream@^2.0.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.0.6.tgz#351302e4c68b5abd6a2ed55376a7f9a25be3057a" + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -3231,6 +3402,21 @@ safe-regex@^1.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" +sanitize-html@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.1.tgz#e8b33c69578054d6ee4f57ea152d6497f3f6fb7d" + dependencies: + chalk "^2.3.0" + htmlparser2 "^3.9.0" + lodash.clonedeep "^4.5.0" + lodash.escaperegexp "^4.1.2" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.mergewith "^4.6.0" + postcss "^6.0.14" + srcset "^1.0.0" + xtend "^4.0.0" + sax@1.2.1: version "1.2.1" resolved "http://registry.npmjs.org/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" @@ -3239,6 +3425,13 @@ sax@>=0.6.0, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" +scheduler@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.10.0.tgz#7988de90fe7edccc774ea175a783e69c40c521e1" + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -3384,7 +3577,7 @@ source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" -source-map@^0.6.0: +source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" @@ -3404,6 +3597,13 @@ sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" +srcset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/srcset/-/srcset-1.0.0.tgz#a5669de12b42f3b1d5e83ed03c71046fc48f41ef" + dependencies: + array-uniq "^1.0.2" + number-is-nan "^1.0.0" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -3445,16 +3645,16 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - -string_decoder@~1.1.1: +string_decoder@^1.1.1, string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" dependencies: safe-buffer "~5.1.0" +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -3489,7 +3689,7 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^5.2.0, supports-color@^5.3.0: +supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" dependencies: @@ -3670,7 +3870,7 @@ user-home@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -3758,6 +3958,10 @@ xmlbuilder@~9.0.1: version "9.0.7" resolved "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" +xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" From 4e153c9ce8a38b6fcc84c0eefbfc1adf694a4054 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 29 Oct 2018 13:54:12 +0100 Subject: [PATCH 037/554] commented xss middleware --- src/middleware/xssMiddleware.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/middleware/xssMiddleware.js b/src/middleware/xssMiddleware.js index 240301cf7..4a3d4aa08 100644 --- a/src/middleware/xssMiddleware.js +++ b/src/middleware/xssMiddleware.js @@ -76,6 +76,7 @@ function clean (dirty) { return { tagName: 'img', attribs: { + // TODO: use environment variables src: `http://localhost:3050/images?url=${src}` } } @@ -83,14 +84,20 @@ function clean (dirty) { } }) - // remove empty html tags and duplicated returns + // remove empty html tags and duplicated linebreaks and returns dirty = dirty + // remove all tags with "space only" .replace(/<[a-z]>[\s]*<\/[a-z]>/igm, '') + // remove all iframes .replace(/(]*)(>)[^>]*\/*>/igm, '') - .replace(/

[\s]*(
)+[\s]*<\/p>/igm, '
') - .replace(/(
){2,}/igm, '
') + // replace all p tags with line breaks (and spaces) only by single linebreaks + .replace(/

[\s]*(
)+[\s]*<\/p>/igm, '
') + // replace multiple linebreaks with single ones + // limit linebreaks to max 2 (equivalent to html "br" linebreak) + .replace(/(
){2,}/igm, '
') .replace(/[\n]{3,}/igm, '\n\n') .replace(/(\r\n|\n\r|\r|\n)/g, '
$1') + // remove additional linebreaks inside p tags .replace(/


<\/p>/g, '') return dirty } From 712ac1258034ea006b93422162af69e34b82e7bb Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 29 Oct 2018 14:39:37 +0100 Subject: [PATCH 038/554] removed whitespace --- src/middleware/xssMiddleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/xssMiddleware.js b/src/middleware/xssMiddleware.js index 4a3d4aa08..73212d1b8 100644 --- a/src/middleware/xssMiddleware.js +++ b/src/middleware/xssMiddleware.js @@ -26,7 +26,7 @@ function clean (dirty) { dirty = sanitizeHtml(dirty, { allowedTags: ['iframe', 'img', 'p', 'br', 'b', 'i', 'em', 'strong', 'a', 'pre', 'ul', 'li', 'ol', 's', 'strike', 'span', 'blockquote'], allowedAttributes: { - a: ['href', 'class', 'target', 'data-*' , 'contenteditable'], + a: ['href', 'class', 'target', 'data-*', 'contenteditable'], span: ['contenteditable', 'class', 'data-*'], img: ['src'], iframe: ['src', 'class', 'frameborder', 'allowfullscreen'] From 2ab1b0778cb3921f2633dcb454372ec2963c9b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 29 Oct 2018 23:39:49 +0100 Subject: [PATCH 039/554] Use xip.io trick for server/client side rendering --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 79ccc4b62..c995c672b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,6 +2,7 @@ version: "3.7" services: backend: + container_name: backend.127.0.0.1.xip.io build: . networks: - hc-network From dd89c52156a8965b76239ca7609656b33620bd8d Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 30 Oct 2018 13:03:05 +0100 Subject: [PATCH 040/554] added permissions middleware and introduced walkRecursive helper --- package.json | 1 + src/index.js | 9 +- src/middleware/helpers/walkRecursive.js | 28 ++++ src/middleware/index.js | 8 +- src/middleware/passwordMiddleware.js | 9 +- src/middleware/permissionsMiddleware.js | 34 +++++ src/middleware/xssMiddleware.js | 26 ++-- yarn.lock | 169 ++++++++++++++++++++++-- 8 files changed, 247 insertions(+), 37 deletions(-) create mode 100644 src/middleware/helpers/walkRecursive.js create mode 100644 src/middleware/permissionsMiddleware.js diff --git a/package.json b/package.json index dcde920d2..2e7d88f77 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "graphql-custom-directives": "^0.2.13", "graphql-iso-date": "^3.6.1", "graphql-middleware": "1.7.6", + "graphql-shield": "^4.0.1", "graphql-tag": "^2.9.2", "graphql-yoga": "1.16.2", "jsonwebtoken": "^8.3.0", diff --git a/src/index.js b/src/index.js index 7aaf8904d..5c3face1a 100644 --- a/src/index.js +++ b/src/index.js @@ -15,7 +15,7 @@ import jwt from 'jsonwebtoken' dotenv.config() -const schema = makeExecutableSchema({ +let schema = makeExecutableSchema({ typeDefs, resolvers }) @@ -31,7 +31,7 @@ const driver = neo4j.driver( const MOCK = (process.env.MOCK === 'true') console.log('MOCK:', MOCK) -const augumentedSchema = augmentSchema(schema, { +schema = augmentSchema(schema, { query: { exclude: ['Statistics', 'LoggedInUser'] }, @@ -39,6 +39,7 @@ const augumentedSchema = augmentSchema(schema, { exclude: ['Statistics', 'LoggedInUser'] } }) +schema = applyScalars(applyDirectives(schema)) const server = new GraphQLServer({ context: async (req) => { @@ -54,9 +55,9 @@ const server = new GraphQLServer({ return payload }, - schema: applyScalars(applyDirectives(augumentedSchema)), + schema: schema, tracing: true, - middlewares: middleware, + middlewares: middleware(schema), mocks: MOCK ? mocks : false }) diff --git a/src/middleware/helpers/walkRecursive.js b/src/middleware/helpers/walkRecursive.js new file mode 100644 index 000000000..2f60de2a4 --- /dev/null +++ b/src/middleware/helpers/walkRecursive.js @@ -0,0 +1,28 @@ +/** + * iterate through all fields and replace it with the callback result + * @property data Array + * @property fields Array + * @property callback Function + */ +function walkRecursive (data, fields, callback, _key) { + if (!Array.isArray(fields)) { + throw new Error('please provide an fields array for the walkRecursive helper') + } + if (data && typeof data === 'string' && fields.includes(_key)) { + // well we found what we searched for, lets replace the value with our callback result + data = callback(data, _key) + } else if (data && Array.isArray(data)) { + // go into the rabbit hole and dig through that array + data.forEach((res, index) => { + data[index] = walkRecursive(data[index], fields, callback, index) + }) + } else if (data && typeof data === 'object') { + // lets get some keys and stir them + Object.keys(data).forEach(k => { + data[k] = walkRecursive(data[k], fields, callback, k) + }) + } + return data +} + +export default walkRecursive diff --git a/src/middleware/index.js b/src/middleware/index.js index 4088c428b..f743ae74f 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -5,13 +5,15 @@ import fixImageUrlsMiddleware from './fixImageUrlsMiddleware' import excerptMiddleware from './excerptMiddleware' import dateTimeMiddleware from './dateTimeMiddleware'; import xssMiddleware from './xssMiddleware'; +import permissionsMiddleware from './permissionsMiddleware'; -export default [ - xssMiddleware, - dateTimeMiddleware, +export default schema => [ + permissionsMiddleware.generate(schema), passwordMiddleware, + dateTimeMiddleware, sluggifyMiddleware, excerptMiddleware, + xssMiddleware, fixImageUrlsMiddleware, softDeleteMiddleware ] diff --git a/src/middleware/passwordMiddleware.js b/src/middleware/passwordMiddleware.js index b84680638..4f551fe5d 100644 --- a/src/middleware/passwordMiddleware.js +++ b/src/middleware/passwordMiddleware.js @@ -1,4 +1,5 @@ import bcrypt from 'bcryptjs' +import walkRecursive from './helpers/walkRecursive' export default { Mutation: { @@ -11,9 +12,9 @@ export default { }, Query: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) - if (result && result.password) { - result.password = '*****' - } - return result + return walkRecursive(result, ['password'], () => { + // replace password with asterix + return '*****' + }) } } diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js new file mode 100644 index 000000000..98130239d --- /dev/null +++ b/src/middleware/permissionsMiddleware.js @@ -0,0 +1,34 @@ +import { rule, shield, and, or, not, allow } from 'graphql-shield' + +const isAuthenticated = rule()(async (parent, args, ctx, info) => { + return ctx.user !== null +}) +const isOwner = rule()(async (parent, args, ctx, info) => { + console.log('parent', parent) + return ctx.user.id === parent.id +}) +const isAdmin = rule()(async (parent, args, ctx, info) => { + return ctx.user.role === 'ADMIN' +}) +const isModerator = rule()(async (parent, args, ctx, info) => { + return ctx.user.role === 'MODERATOR' +}) + +// Permissions +const permissions = shield({ + Query: { + statistics: not(isAuthenticated) + // fruits: and(isAuthenticated, or(isAdmin, isModerator)), + // customers: and(isAuthenticated, isAdmin) + }, + Mutation: { + // addFruitToBasket: isAuthenticated + }, + User: { + email: isOwner, + password: isOwner + }, + Post: isAuthenticated +}) + +export default permissions diff --git a/src/middleware/xssMiddleware.js b/src/middleware/xssMiddleware.js index 73212d1b8..46d0c663d 100644 --- a/src/middleware/xssMiddleware.js +++ b/src/middleware/xssMiddleware.js @@ -1,3 +1,4 @@ +import walkRecursive from './helpers/walkRecursive' import trunc from 'trunc-html' // import { getByDot, setByDot, getItems, replaceItems } from 'feathers-hooks-common' import sanitizeHtml from 'sanitize-html' @@ -62,6 +63,11 @@ function clean (dirty) { img: function (tagName, attribs) { let src = attribs.src + if (!src) { + // remove broken images + return {} + } + // if (isEmpty(hook.result)) { // const config = hook.app.get('thumbor') // if (config && src.indexOf(config < 0)) { @@ -102,30 +108,16 @@ function clean (dirty) { return dirty } -// iterate through all fields and clean the values -function cleanAll (result, key, recursive, fields = ['content', 'contentExcerpt']) { - if (result && typeof result === 'string' && fields.includes(key)) { - result = clean(result) - } else if (result && Array.isArray(result)) { - result.forEach((res, index) => { - result[index] = cleanAll(result[index], index, true, fields) - }) - } else if (result && typeof result === 'object') { - Object.keys(result).forEach(key => { - result[key] = cleanAll(result[key], key, true, fields) - }) - } - return result -} +const fields = ['content', 'contentExcerpt'] export default { Mutation: async (resolve, root, args, context, info) => { - args = cleanAll(args) + args = walkRecursive(args, fields, clean) const result = await resolve(root, args, context, info) return result }, Query: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) - return cleanAll(result) + return walkRecursive(result, fields, clean) } } diff --git a/yarn.lock b/yarn.lock index a855f8d7e..c17a0c3c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -182,6 +182,10 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -942,6 +946,14 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-runtime "^6.22.0" babel-types "^6.24.1" +babel-polyfill@6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" + dependencies: + babel-runtime "^6.22.0" + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + babel-polyfill@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" @@ -1200,7 +1212,7 @@ capture-stack-trace@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" -chalk@^1.1.3: +chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -1218,6 +1230,10 @@ chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + cheerio@^1.0.0-rc.2: version "1.0.0-rc.2" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" @@ -1284,6 +1300,16 @@ cli-boxes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -1572,6 +1598,12 @@ encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + entities@^1.1.1, entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" @@ -1719,6 +1751,14 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" +external-editor@^2.0.1: + version "2.2.0" + resolved "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" @@ -1750,6 +1790,12 @@ fclone@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640" +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -2023,6 +2069,13 @@ graphql-request@^1.4.0: dependencies: cross-fetch "2.2.2" +graphql-shield@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.0.1.tgz#731fca9a69a540ff446edf9e5bec610da295f5cb" + dependencies: + object-hash "^1.3.0" + opencollective "1.0.3" + graphql-subscriptions@^0.5.8: version "0.5.8" resolved "http://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7" @@ -2180,7 +2233,7 @@ iconv-lite@0.4.23: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.4.4: +iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" dependencies: @@ -2231,6 +2284,24 @@ ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" +inquirer@3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" + dependencies: + ansi-escapes "^1.1.0" + chalk "^1.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.1" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx "^4.1.0" + string-width "^2.0.0" + strip-ansi "^3.0.0" + through "^2.3.6" + insane@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/insane/-/insane-2.6.1.tgz#c7dcae7b51c20346883b71078fad6ce0483c198f" @@ -2425,6 +2496,10 @@ is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" @@ -2439,7 +2514,7 @@ is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" -is-stream@^1.0.0, is-stream@^1.1.0: +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -2621,7 +2696,7 @@ lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" -lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5: +lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -2732,6 +2807,10 @@ mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -2746,7 +2825,7 @@ minimist@0.0.8: version "0.0.8" resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.2.0: +minimist@1.2.0, minimist@^1.2.0: version "1.2.0" resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" @@ -2788,6 +2867,10 @@ ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + nan@^2.9.2: version "2.11.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" @@ -2835,6 +2918,13 @@ neo4j-graphql-js@1.0.5: lodash "^4.17.10" neo4j-driver "^1.6.1" +node-fetch@1.6.3: + version "1.6.3" + resolved "http://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + node-fetch@2.1.2: version "2.1.2" resolved "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" @@ -2932,7 +3022,7 @@ numeral@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" -object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2944,6 +3034,10 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-hash@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.0.tgz#76d9ba6ff113cf8efc0d996102851fe6723963e2" + object-keys@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" @@ -2990,6 +3084,30 @@ once@^1.3.0: dependencies: wrappy "1" +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +opencollective@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/opencollective/-/opencollective-1.0.3.tgz#aee6372bc28144583690c3ca8daecfc120dd0ef1" + dependencies: + babel-polyfill "6.23.0" + chalk "1.1.3" + inquirer "3.0.6" + minimist "1.2.0" + node-fetch "1.6.3" + opn "4.0.2" + +opn@4.0.2: + version "4.0.2" + resolved "http://registry.npmjs.org/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + optimism@^0.6.6: version "0.6.6" resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.6.tgz#5415b2d6a2f8b3745aedb9f97fdf4e52467ecd84" @@ -3000,7 +3118,7 @@ os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -3107,6 +3225,16 @@ pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -3288,7 +3416,7 @@ regenerate@^1.2.1: version "1.4.0" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" -regenerator-runtime@^0.10.5: +regenerator-runtime@^0.10.0, regenerator-runtime@^0.10.5: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" @@ -3374,6 +3502,13 @@ resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -3388,6 +3523,16 @@ rimraf@^2.6.1: dependencies: glob "^7.0.5" +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +rx@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -3717,7 +3862,7 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" -through@2, through@^2.3.8, through@~2.3, through@~2.3.4: +through@2, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.4: version "2.3.8" resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -3725,6 +3870,12 @@ timed-out@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" From e7c6bf16561646dfbbd845289d3197693e3c6f38 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 30 Oct 2018 18:40:15 +0100 Subject: [PATCH 041/554] fixed permissions --- src/middleware/permissionsMiddleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 98130239d..11b4aabe4 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -17,7 +17,7 @@ const isModerator = rule()(async (parent, args, ctx, info) => { // Permissions const permissions = shield({ Query: { - statistics: not(isAuthenticated) + statistics: isAdmin // fruits: and(isAuthenticated, or(isAdmin, isModerator)), // customers: and(isAuthenticated, isAdmin) }, From 8aa3fea718f4e4d05acd8c3a3f4416b041c7a586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 31 Oct 2018 17:44:56 +0100 Subject: [PATCH 042/554] Expose neo4j-browser ports This helps developers to access the neo4j database from the browser. Visit http://localhost:7474/ to see it in action. --- docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index c995c672b..6110ceba4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,6 +19,9 @@ services: - MOCK=false neo4j: + ports: + - 7687:7687 + - 7474:7474 build: context: . dockerfile: Dockerfile.neo4j From f3c0678611a16ec262044296c6807e403d70c6be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 1 Nov 2018 14:10:06 +0100 Subject: [PATCH 043/554] Add volumes to use docker for development --- Dockerfile | 2 +- docker-compose.yml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 36d94ffa5..1c33f50b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ LABEL Description="Server part of the social network Human Connection" Vendor="H # expose the app port EXPOSE 4000 -ARG WORKDIR=/HC-Server +ARG WORKDIR=/Backend RUN mkdir -p $WORKDIR WORKDIR $WORKDIR diff --git a/docker-compose.yml b/docker-compose.yml index c995c672b..f018909d2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,6 +17,9 @@ services: - CLIENT_URI=http://localhost:3000 - JWT_SECRET=b/&&7b78BF&fv/Vd - MOCK=false + volumes: + - .:/Backend + - /Backend/node_modules neo4j: build: From 8c30959de84a1afca56c7c45381202840ae83bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 1 Nov 2018 14:59:05 +0100 Subject: [PATCH 044/554] Move kompose incompatible parts to .override Only version 3.7 is left, changing it would create a version mismatch. --- docker-compose.override.yml | 9 +++++++++ docker-compose.yml | 2 -- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 docker-compose.override.yml diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 000000000..707b45cee --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,9 @@ +version: "3.7" + +services: + backend: + container_name: backend.127.0.0.1.xip.io + +networks: + hc-network: + name: hc-network diff --git a/docker-compose.yml b/docker-compose.yml index a46a96f71..913a9a3e8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,6 @@ version: "3.7" services: backend: - container_name: backend.127.0.0.1.xip.io build: . networks: - hc-network @@ -37,7 +36,6 @@ services: networks: hc-network: - name: hc-network volumes: neo4j-data: From e1da9f1f906a01026ace6a9efb8ff4130478f22f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 1 Nov 2018 16:04:35 +0100 Subject: [PATCH 045/554] Run `kompose -f docker-compose.yml convert` Move files to folder kubernetes --- kubernetes/backend-deployment.yaml | 40 +++++++++++++++++++ kubernetes/backend-service.yaml | 19 +++++++++ .../neo4j-data-persistentvolumeclaim.yaml | 14 +++++++ kubernetes/neo4j-deployment.yaml | 39 ++++++++++++++++++ kubernetes/neo4j-service.yaml | 22 ++++++++++ 5 files changed, 134 insertions(+) create mode 100644 kubernetes/backend-deployment.yaml create mode 100644 kubernetes/backend-service.yaml create mode 100644 kubernetes/neo4j-data-persistentvolumeclaim.yaml create mode 100644 kubernetes/neo4j-deployment.yaml create mode 100644 kubernetes/neo4j-service.yaml diff --git a/kubernetes/backend-deployment.yaml b/kubernetes/backend-deployment.yaml new file mode 100644 index 000000000..5a6c3af1b --- /dev/null +++ b/kubernetes/backend-deployment.yaml @@ -0,0 +1,40 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + annotations: + kompose.cmd: kompose -f docker-compose.yml convert + kompose.version: 1.16.0 (0c01309) + creationTimestamp: null + labels: + io.kompose.service: backend + name: backend +spec: + replicas: 1 + strategy: {} + template: + metadata: + creationTimestamp: null + labels: + io.kompose.service: backend + spec: + containers: + - env: + - name: CLIENT_URI + value: http://localhost:3000 + - name: GRAPHQL_LISTEN_PORT + value: "4000" + - name: GRAPHQL_URI + value: http://localhost:4000 + - name: JWT_SECRET + value: b/&&7b78BF&fv/Vd + - name: MOCK + value: "false" + - name: NEO4J_URI + value: bolt://neo4j:7687 + image: backend + name: backend + ports: + - containerPort: 4000 + resources: {} + restartPolicy: Always +status: {} diff --git a/kubernetes/backend-service.yaml b/kubernetes/backend-service.yaml new file mode 100644 index 000000000..fb6db1191 --- /dev/null +++ b/kubernetes/backend-service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + kompose.cmd: kompose -f docker-compose.yml convert + kompose.version: 1.16.0 (0c01309) + creationTimestamp: null + labels: + io.kompose.service: backend + name: backend +spec: + ports: + - name: "4000" + port: 4000 + targetPort: 4000 + selector: + io.kompose.service: backend +status: + loadBalancer: {} diff --git a/kubernetes/neo4j-data-persistentvolumeclaim.yaml b/kubernetes/neo4j-data-persistentvolumeclaim.yaml new file mode 100644 index 000000000..de9c89e2f --- /dev/null +++ b/kubernetes/neo4j-data-persistentvolumeclaim.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + creationTimestamp: null + labels: + io.kompose.service: neo4j-data + name: neo4j-data +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi +status: {} diff --git a/kubernetes/neo4j-deployment.yaml b/kubernetes/neo4j-deployment.yaml new file mode 100644 index 000000000..9b08960c4 --- /dev/null +++ b/kubernetes/neo4j-deployment.yaml @@ -0,0 +1,39 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + annotations: + kompose.cmd: kompose -f docker-compose.yml convert + kompose.version: 1.16.0 (0c01309) + creationTimestamp: null + labels: + io.kompose.service: neo4j + name: neo4j +spec: + replicas: 1 + strategy: + type: Recreate + template: + metadata: + creationTimestamp: null + labels: + io.kompose.service: neo4j + spec: + containers: + - env: + - name: NEO4J_AUTH + value: none + image: neo4j + name: neo4j + ports: + - containerPort: 7687 + - containerPort: 7474 + resources: {} + volumeMounts: + - mountPath: /data + name: neo4j-data + restartPolicy: Always + volumes: + - name: neo4j-data + persistentVolumeClaim: + claimName: neo4j-data +status: {} diff --git a/kubernetes/neo4j-service.yaml b/kubernetes/neo4j-service.yaml new file mode 100644 index 000000000..b9af4fc19 --- /dev/null +++ b/kubernetes/neo4j-service.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + kompose.cmd: kompose -f docker-compose.yml convert + kompose.version: 1.16.0 (0c01309) + creationTimestamp: null + labels: + io.kompose.service: neo4j + name: neo4j +spec: + ports: + - name: "7687" + port: 7687 + targetPort: 7687 + - name: "7474" + port: 7474 + targetPort: 7474 + selector: + io.kompose.service: neo4j +status: + loadBalancer: {} From 3cbee31f01ea1def709e962237c29acaa5bd22b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 1 Nov 2018 16:05:29 +0100 Subject: [PATCH 046/554] Use commands that overwrite existing files For strange reasons, I could not `docker-compose up --build` because apoc plugin existed at the given location --- Dockerfile.neo4j | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.neo4j b/Dockerfile.neo4j index 3675669f6..880f0b117 100644 --- a/Dockerfile.neo4j +++ b/Dockerfile.neo4j @@ -1,3 +1,3 @@ FROM neo4j:3.4 -RUN mkdir /plugins && wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.4.0.3/apoc-3.4.0.3-all.jar -P /plugins - +RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.4.0.3/apoc-3.4.0.3-all.jar +RUN mkdir -p /plugins && mv apoc-3.4.0.3-all.jar plugins/ From 90c9e3843738140018b8202bbc033a57ca8e0c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 1 Nov 2018 21:12:56 +0100 Subject: [PATCH 047/554] Add image tag to kubernetes setup --- kubernetes/backend-deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/backend-deployment.yaml b/kubernetes/backend-deployment.yaml index 5a6c3af1b..c67d7297c 100644 --- a/kubernetes/backend-deployment.yaml +++ b/kubernetes/backend-deployment.yaml @@ -31,7 +31,7 @@ spec: value: "false" - name: NEO4J_URI value: bolt://neo4j:7687 - image: backend + image: humanconnection/backend:edge name: backend ports: - containerPort: 4000 From 5a844b4bfb4f3e9456200d17c382d33e9a2b5bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 1 Nov 2018 21:42:59 +0100 Subject: [PATCH 048/554] Add documentation --- kubernetes/README.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 kubernetes/README.md diff --git a/kubernetes/README.md b/kubernetes/README.md new file mode 100644 index 000000000..e6d7ba2aa --- /dev/null +++ b/kubernetes/README.md @@ -0,0 +1,38 @@ +# Usage with minikube + +First of all start minikube on your machine: +```sh +minikube start +``` + +Build your Docker image, using the Minikube Docker daemon: +```sh +eval $(minikube docker-env) +docker build -t humanconnection/backend:edge . +``` + +check that the image is in Minikube’s Docker registry: +```sh +minikube ssh docker images +``` + +Now change into directory kubernetes and create services and deployments: +```sh +cd kubernetes + +kubectl create -f backend-deployment.yaml neo4j-deployment.yaml neo4j-data-persistentvolumeclaim.yaml + +# expose the backend deployment +kubectl expose backend hello-node --type=LoadBalancer + +# and create the services +kubectl create -f backend-service.yaml neo4j-service.yaml +``` + +You can see the backend in action with +```sh +minikube service backend +``` + + + From 4e13c6abe8e3178415a96d375e04c1f0f3c96d9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 1 Nov 2018 22:02:42 +0100 Subject: [PATCH 049/554] Tag `edge` to `latest` for better understanding --- kubernetes/README.md | 2 +- kubernetes/backend-deployment.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index e6d7ba2aa..3cab40d63 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -8,7 +8,7 @@ minikube start Build your Docker image, using the Minikube Docker daemon: ```sh eval $(minikube docker-env) -docker build -t humanconnection/backend:edge . +docker build -t humanconnection/backend:latest . ``` check that the image is in Minikube’s Docker registry: diff --git a/kubernetes/backend-deployment.yaml b/kubernetes/backend-deployment.yaml index c67d7297c..c372a999d 100644 --- a/kubernetes/backend-deployment.yaml +++ b/kubernetes/backend-deployment.yaml @@ -31,7 +31,7 @@ spec: value: "false" - name: NEO4J_URI value: bolt://neo4j:7687 - image: humanconnection/backend:edge + image: humanconnection/backend:latest name: backend ports: - containerPort: 4000 From 0699b22137ea20209240587808349e6003faeb15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 2 Nov 2018 11:16:39 +0100 Subject: [PATCH 050/554] Move volume declaration for backend to .override + lowercase working directory + download plugins to correct location /var/lib/neo4j/plugins --- Dockerfile | 2 +- Dockerfile.neo4j | 3 +-- docker-compose.override.yml | 3 +++ docker-compose.yml | 3 --- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1c33f50b3..5e3f8c650 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ LABEL Description="Server part of the social network Human Connection" Vendor="H # expose the app port EXPOSE 4000 -ARG WORKDIR=/Backend +ARG WORKDIR=/backend RUN mkdir -p $WORKDIR WORKDIR $WORKDIR diff --git a/Dockerfile.neo4j b/Dockerfile.neo4j index 880f0b117..66f996e68 100644 --- a/Dockerfile.neo4j +++ b/Dockerfile.neo4j @@ -1,3 +1,2 @@ FROM neo4j:3.4 -RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.4.0.3/apoc-3.4.0.3-all.jar -RUN mkdir -p /plugins && mv apoc-3.4.0.3-all.jar plugins/ +RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.4.0.3/apoc-3.4.0.3-all.jar -P plugins/ diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 707b45cee..568376779 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -3,6 +3,9 @@ version: "3.7" services: backend: container_name: backend.127.0.0.1.xip.io + volumes: + - .:/backend + - /backend/node_modules networks: hc-network: diff --git a/docker-compose.yml b/docker-compose.yml index 913a9a3e8..8064d02bd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,9 +16,6 @@ services: - CLIENT_URI=http://localhost:3000 - JWT_SECRET=b/&&7b78BF&fv/Vd - MOCK=false - volumes: - - .:/Backend - - /Backend/node_modules neo4j: ports: From e81f2344c3a7b0398e6da2f48a914cbeb6c0e0e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 2 Nov 2018 11:33:08 +0100 Subject: [PATCH 051/554] Fix README --- docker-compose.override.yml | 4 ++++ docker-compose.yml | 5 ++--- kubernetes/README.md | 18 +++++++++++------- kubernetes/backend-deployment.yaml | 2 +- kubernetes/backend-service.yaml | 2 +- kubernetes/neo4j-deployment.yaml | 4 ++-- kubernetes/neo4j-service.yaml | 2 +- 7 files changed, 22 insertions(+), 15 deletions(-) diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 568376779..22e16da73 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -6,6 +6,10 @@ services: volumes: - .:/backend - /backend/node_modules + neo4j: + ports: + - 7687:7687 + - 7474:7474 networks: hc-network: diff --git a/docker-compose.yml b/docker-compose.yml index 8064d02bd..0a47bb3c0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,6 +2,7 @@ version: "3.7" services: backend: + image: humanconnection/backend:latest build: . networks: - hc-network @@ -18,9 +19,7 @@ services: - MOCK=false neo4j: - ports: - - 7687:7687 - - 7474:7474 + image: humanconnection/neo4j:latest build: context: . dockerfile: Dockerfile.neo4j diff --git a/kubernetes/README.md b/kubernetes/README.md index 3cab40d63..ed396a3a3 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -5,10 +5,11 @@ First of all start minikube on your machine: minikube start ``` -Build your Docker image, using the Minikube Docker daemon: +Build Docker images, using the Minikube Docker daemon: ```sh eval $(minikube docker-env) docker build -t humanconnection/backend:latest . +docker build -t humanconnection/neo4j:latest -f Dockerfile.neo4j . ``` check that the image is in Minikube’s Docker registry: @@ -20,19 +21,22 @@ Now change into directory kubernetes and create services and deployments: ```sh cd kubernetes -kubectl create -f backend-deployment.yaml neo4j-deployment.yaml neo4j-data-persistentvolumeclaim.yaml +kubectl create -f neo4j-deployment.yaml,neo4j-data-persistentvolumeclaim.yaml,backend-deployment.yaml,backend-service.yaml,neo4j-service.yaml # expose the backend deployment -kubectl expose backend hello-node --type=LoadBalancer - -# and create the services -kubectl create -f backend-service.yaml neo4j-service.yaml +kubectl expose deployment backend --type=LoadBalancer +# opionally expose the neo4j deployment +kubectl expose deployment neo4j --type=LoadBalancer ``` -You can see the backend in action with +You can see the backend in action with: ```sh minikube service backend ``` +Get an overview with your minikube dashboard: +```sh +minikube dashboard +``` diff --git a/kubernetes/backend-deployment.yaml b/kubernetes/backend-deployment.yaml index c372a999d..87a5080ea 100644 --- a/kubernetes/backend-deployment.yaml +++ b/kubernetes/backend-deployment.yaml @@ -2,7 +2,7 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: annotations: - kompose.cmd: kompose -f docker-compose.yml convert + kompose.cmd: kompose convert -f ../docker-compose.yml kompose.version: 1.16.0 (0c01309) creationTimestamp: null labels: diff --git a/kubernetes/backend-service.yaml b/kubernetes/backend-service.yaml index fb6db1191..223e8a42b 100644 --- a/kubernetes/backend-service.yaml +++ b/kubernetes/backend-service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: annotations: - kompose.cmd: kompose -f docker-compose.yml convert + kompose.cmd: kompose convert -f ../docker-compose.yml kompose.version: 1.16.0 (0c01309) creationTimestamp: null labels: diff --git a/kubernetes/neo4j-deployment.yaml b/kubernetes/neo4j-deployment.yaml index 9b08960c4..32a0cd303 100644 --- a/kubernetes/neo4j-deployment.yaml +++ b/kubernetes/neo4j-deployment.yaml @@ -2,7 +2,7 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: annotations: - kompose.cmd: kompose -f docker-compose.yml convert + kompose.cmd: kompose convert -f ../docker-compose.yml kompose.version: 1.16.0 (0c01309) creationTimestamp: null labels: @@ -22,7 +22,7 @@ spec: - env: - name: NEO4J_AUTH value: none - image: neo4j + image: humanconnection/neo4j:latest name: neo4j ports: - containerPort: 7687 diff --git a/kubernetes/neo4j-service.yaml b/kubernetes/neo4j-service.yaml index b9af4fc19..7ee0606c1 100644 --- a/kubernetes/neo4j-service.yaml +++ b/kubernetes/neo4j-service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: annotations: - kompose.cmd: kompose -f docker-compose.yml convert + kompose.cmd: kompose convert -f ../docker-compose.yml kompose.version: 1.16.0 (0c01309) creationTimestamp: null labels: From 5e47b5fb9967b2c06aa69d41fb7dfa92b6fb34eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 2 Nov 2018 14:28:26 +0100 Subject: [PATCH 052/554] Set imagePullPolicity to fix image pull errors --- kubernetes/backend-deployment.yaml | 1 + kubernetes/neo4j-deployment.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/kubernetes/backend-deployment.yaml b/kubernetes/backend-deployment.yaml index 87a5080ea..cf7f34063 100644 --- a/kubernetes/backend-deployment.yaml +++ b/kubernetes/backend-deployment.yaml @@ -36,5 +36,6 @@ spec: ports: - containerPort: 4000 resources: {} + imagePullPolicy: IfNotPresent restartPolicy: Always status: {} diff --git a/kubernetes/neo4j-deployment.yaml b/kubernetes/neo4j-deployment.yaml index 32a0cd303..13f4d52e3 100644 --- a/kubernetes/neo4j-deployment.yaml +++ b/kubernetes/neo4j-deployment.yaml @@ -28,6 +28,7 @@ spec: - containerPort: 7687 - containerPort: 7474 resources: {} + imagePullPolicy: IfNotPresent volumeMounts: - mountPath: /data name: neo4j-data From c37d58a9c3f33f0cedb3a3753b56c3b939eb32b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 2 Nov 2018 14:48:29 +0100 Subject: [PATCH 053/554] Automatically expose services --- kubernetes/README.md | 15 ++++-------- kubernetes/backend-service.json | 35 +++++++++++++++++++++++++++ kubernetes/backend-service.yaml | 19 --------------- kubernetes/neo4j-service.json | 43 +++++++++++++++++++++++++++++++++ kubernetes/neo4j-service.yaml | 22 ----------------- 5 files changed, 83 insertions(+), 51 deletions(-) create mode 100644 kubernetes/backend-service.json delete mode 100644 kubernetes/backend-service.yaml create mode 100644 kubernetes/neo4j-service.json delete mode 100644 kubernetes/neo4j-service.yaml diff --git a/kubernetes/README.md b/kubernetes/README.md index ed396a3a3..3f22e039a 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -4,6 +4,10 @@ First of all start minikube on your machine: ```sh minikube start ``` +You can always get an overview and see what's going on with your minikube: +```sh +minikube dashboard +``` Build Docker images, using the Minikube Docker daemon: ```sh @@ -21,22 +25,13 @@ Now change into directory kubernetes and create services and deployments: ```sh cd kubernetes -kubectl create -f neo4j-deployment.yaml,neo4j-data-persistentvolumeclaim.yaml,backend-deployment.yaml,backend-service.yaml,neo4j-service.yaml - -# expose the backend deployment -kubectl expose deployment backend --type=LoadBalancer -# opionally expose the neo4j deployment -kubectl expose deployment neo4j --type=LoadBalancer +kubectl create -f neo4j-deployment.yaml,neo4j-data-persistentvolumeclaim.yaml,backend-deployment.yaml,neo4j-service.json,backend-service.json ``` You can see the backend in action with: ```sh minikube service backend ``` -Get an overview with your minikube dashboard: -```sh -minikube dashboard -``` diff --git a/kubernetes/backend-service.json b/kubernetes/backend-service.json new file mode 100644 index 000000000..28581be45 --- /dev/null +++ b/kubernetes/backend-service.json @@ -0,0 +1,35 @@ +{ + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "backend", + "namespace": "default", + "selfLink": "/api/v1/namespaces/default/services/backend", + "uid": "57749bc1-dea3-11e8-ace2-080027b5d96d", + "resourceVersion": "8321", + "creationTimestamp": "2018-11-02T13:29:36Z", + "labels": { + "io.kompose.service": "backend" + } + }, + "spec": { + "ports": [ + { + "protocol": "TCP", + "port": 4000, + "targetPort": 4000, + "nodePort": 32633 + } + ], + "selector": { + "io.kompose.service": "backend" + }, + "clusterIP": "10.110.129.92", + "type": "LoadBalancer", + "sessionAffinity": "None", + "externalTrafficPolicy": "Cluster" + }, + "status": { + "loadBalancer": {} + } +} diff --git a/kubernetes/backend-service.yaml b/kubernetes/backend-service.yaml deleted file mode 100644 index 223e8a42b..000000000 --- a/kubernetes/backend-service.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - kompose.cmd: kompose convert -f ../docker-compose.yml - kompose.version: 1.16.0 (0c01309) - creationTimestamp: null - labels: - io.kompose.service: backend - name: backend -spec: - ports: - - name: "4000" - port: 4000 - targetPort: 4000 - selector: - io.kompose.service: backend -status: - loadBalancer: {} diff --git a/kubernetes/neo4j-service.json b/kubernetes/neo4j-service.json new file mode 100644 index 000000000..89ac10367 --- /dev/null +++ b/kubernetes/neo4j-service.json @@ -0,0 +1,43 @@ +{ + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "neo4j", + "namespace": "default", + "selfLink": "/api/v1/namespaces/default/services/neo4j", + "uid": "57de6181-dea3-11e8-ace2-080027b5d96d", + "resourceVersion": "8326", + "creationTimestamp": "2018-11-02T13:29:37Z", + "labels": { + "io.kompose.service": "neo4j" + } + }, + "spec": { + "ports": [ + { + "name": "port-1", + "protocol": "TCP", + "port": 7687, + "targetPort": 7687, + "nodePort": 30116 + }, + { + "name": "port-2", + "protocol": "TCP", + "port": 7474, + "targetPort": 7474, + "nodePort": 32658 + } + ], + "selector": { + "io.kompose.service": "neo4j" + }, + "clusterIP": "10.108.175.122", + "type": "LoadBalancer", + "sessionAffinity": "None", + "externalTrafficPolicy": "Cluster" + }, + "status": { + "loadBalancer": {} + } +} diff --git a/kubernetes/neo4j-service.yaml b/kubernetes/neo4j-service.yaml deleted file mode 100644 index 7ee0606c1..000000000 --- a/kubernetes/neo4j-service.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - kompose.cmd: kompose convert -f ../docker-compose.yml - kompose.version: 1.16.0 (0c01309) - creationTimestamp: null - labels: - io.kompose.service: neo4j - name: neo4j -spec: - ports: - - name: "7687" - port: 7687 - targetPort: 7687 - - name: "7474" - port: 7474 - targetPort: 7474 - selector: - io.kompose.service: neo4j -status: - loadBalancer: {} From 0fea8d8dd4ba287bb8de0afd22e2287f1a1e7819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sun, 4 Nov 2018 10:35:42 +0100 Subject: [PATCH 054/554] Add deployment to give dashboard user full access --- kubernetes/dashboard-admin.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 kubernetes/dashboard-admin.yml diff --git a/kubernetes/dashboard-admin.yml b/kubernetes/dashboard-admin.yml new file mode 100644 index 000000000..5d76d3902 --- /dev/null +++ b/kubernetes/dashboard-admin.yml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: kubernetes-dashboard + labels: + k8s-app: kubernetes-dashboard +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: kubernetes-dashboard + namespace: kube-system From cc65cfe175d268adda80d16998d2ad381f695369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sun, 4 Nov 2018 10:38:06 +0100 Subject: [PATCH 055/554] Delete .gitignored file .env On my machine, changes to .env are visible if I run `git status`. I think we should delete all .gitignored files and clearly state in the README what needs to be done. Also the .env.template did not have a JWT secret. Probably because sb. edited the local .env file and forgot to edit it in the template. --- .env | 10 ---------- .env.template | 2 ++ 2 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index dcb5cdb41..000000000 --- a/.env +++ /dev/null @@ -1,10 +0,0 @@ -NEO4J_URI=bolt://localhost:7687 -NEO4J_USER=neo4j -NEO4J_PASSWORD=letmein - -GRAPHQL_LISTEN_PORT=4000 -GRAPHQL_URI=http://localhost:4000 -CLIENT_URI=http://localhost:3000 -JWT_SECRET=b/&&7b78BF&fv/Vd - -MOCK=false diff --git a/.env.template b/.env.template index 4d849a121..df678a343 100644 --- a/.env.template +++ b/.env.template @@ -4,3 +4,5 @@ NEO4J_PASSWORD=letmein GRAPHQL_LISTEN_PORT=4000 GRAPHQL_URI=http://localhost:4000 MOCK=false + +JWT_SECRET=b/&&7b78BF&fv/Vd From 8af3790395eb617d40e6cdef61bd9ab83150e88b Mon Sep 17 00:00:00 2001 From: Armin Kunkel Date: Fri, 9 Nov 2018 13:15:51 +0100 Subject: [PATCH 056/554] Put APOC plugin in right directory + modify README --- Dockerfile.neo4j | 3 +-- README.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Dockerfile.neo4j b/Dockerfile.neo4j index 3675669f6..77cfd3cf6 100644 --- a/Dockerfile.neo4j +++ b/Dockerfile.neo4j @@ -1,3 +1,2 @@ FROM neo4j:3.4 -RUN mkdir /plugins && wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.4.0.3/apoc-3.4.0.3-all.jar -P /plugins - +RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.4.0.3/apoc-3.4.0.3-all.jar -P /var/lib/neo4j/plugins \ No newline at end of file diff --git a/README.md b/README.md index e00ac8306..fd321cb18 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ Note that grand-stack-starter does not currently bundle a distribution of Neo4j. You can download [Neo4j Desktop](https://neo4j.com/download/) and run locally for development, spin up a [hosted Neo4j Sandbox instance](https://neo4j.com/download/), run Neo4j in one of the [many cloud options](https://neo4j.com/developer/guide-cloud-deployment/), -or [spin up Neo4j in a Docker container](https://neo4j.com/developer/docker/). +[spin up Neo4j in a Docker container](https://neo4j.com/developer/docker/) or on Debian-based systems install [Neo4j from the Debian Repository](http://debian.neo4j.org/). Just be sure to update the Neo4j connection string and credentials accordingly in `.env`. ## Mocking API Results From 0f29c3513d4c714493801e20aaf466ac98ff85da Mon Sep 17 00:00:00 2001 From: Armin Kunkel Date: Fri, 9 Nov 2018 13:30:55 +0100 Subject: [PATCH 057/554] Add github issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 20 ++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 17 +++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..87e0ad52e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,20 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Authenticate '...' +2. Post following data to endpoint '...' +3. See error + +**Expected behavior** +A clear and concise description of what you expected to happen + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..066b2d920 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From fd0b3922d3a45e16e413149b2d41af8cff9ef27d Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 12 Nov 2018 12:16:49 +0100 Subject: [PATCH 058/554] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e00ac8306..4ed5408d7 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ npm run seedDb - [x] add jwt authentication - [ ] get directives working correctly (@toLower, @auth, @role, etc.) - [ ] check if search is working -- [ ] check if sorting is working +- [x] check if sorting is working - [x] check if pagination is working - [ ] check if upload is working (using graphql-yoga?) - [x] evaluate middleware From db719a2327101924f6531fc3a0948b8d7a44b1ea Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 12 Nov 2018 13:52:38 +0100 Subject: [PATCH 059/554] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 70bb27ea0..2cb57e264 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Human-Connection - NITRO API +# Human-Connection - NITRO Backend > This Prototype tries to resolve the biggest hurdle of connecting > our services together. This is not possible in a sane way using From 009b3898c1ad5b23c20e1d6b2084f2514a80ac18 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 12 Nov 2018 14:22:51 +0100 Subject: [PATCH 060/554] added locations --- package.json | 1 + src/graphql-schema.js | 4 +- src/middleware/dateTimeMiddleware.js | 18 +- src/middleware/index.js | 10 +- src/middleware/userMiddleware.js | 61 +++++++ src/schema.graphql | 20 ++- src/seed/seed-mutations.js | 32 ++-- yarn.lock | 252 ++++++++++++++++++++++++++- 8 files changed, 362 insertions(+), 36 deletions(-) create mode 100644 src/middleware/userMiddleware.js diff --git a/package.json b/package.json index 2e7d88f77..01bd57691 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "node-fetch": "^2.1.2", "passport": "^0.4.0", "passport-jwt": "^4.0.0", + "request": "^2.88.0", "sanitize-html": "^1.19.1", "slug": "^0.9.1", "trunc-html": "^1.1.2" diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 44ec8116d..72cca4e12 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -97,12 +97,14 @@ export const resolvers = { // } const session = driver.session() - const res = await session.run('MATCH (u:User {email: "' + email + '"}) RETURN u.id, u.slug, u.name, u.avatar, u.email, u.password, u.role LIMIT 1') + const res = await session.run('MATCH (u:User {email: "' + email + '"}) RETURN u.id, u.slug, u.name, u.avatar, u.locationId, u.about, u.email, u.password, u.role LIMIT 1') let u = res.records[0]._fields ? zipObject([ 'id', 'slug', 'name', 'avatar', + 'locationId', + 'about', 'email', 'password', 'role' diff --git a/src/middleware/dateTimeMiddleware.js b/src/middleware/dateTimeMiddleware.js index 8fd3c074b..97e6e2767 100644 --- a/src/middleware/dateTimeMiddleware.js +++ b/src/middleware/dateTimeMiddleware.js @@ -1,52 +1,50 @@ -import format from 'date-fns/format' - export default { Mutation: { CreateUser: async (resolve, root, args, context, info) => { - args.createdAt = format(new Date()) + args.createdAt = (new Date()).toISOString() args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) return result }, CreatePost: async (resolve, root, args, context, info) => { - args.createdAt = format(new Date()) + args.createdAt = (new Date()).toISOString() args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) return result }, CreateComment: async (resolve, root, args, context, info) => { - args.createdAt = format(new Date()) + args.createdAt = (new Date()).toISOString() args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) return result }, CreateOrganization: async (resolve, root, args, context, info) => { - args.createdAt = format(new Date()) + args.createdAt = (new Date()).toISOString() args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) return result }, UpdateUser: async (resolve, root, args, context, info) => { - args.updatedAt = format(new Date()) + args.updatedAt = (new Date()).toISOString() const result = await resolve(root, args, context, info) return result }, UpdatePost: async (resolve, root, args, context, info) => { - args.updatedAt = format(new Date()) + args.updatedAt = (new Date()).toISOString() const result = await resolve(root, args, context, info) return result }, UpdateComment: async (resolve, root, args, context, info) => { - args.updatedAt = format(new Date()) + args.updatedAt = (new Date()).toISOString() const result = await resolve(root, args, context, info) return result }, UpdateOrganization: async (resolve, root, args, context, info) => { - args.updatedAt = format(new Date()) + args.updatedAt = (new Date()).toISOString() const result = await resolve(root, args, context, info) return result } diff --git a/src/middleware/index.js b/src/middleware/index.js index f743ae74f..19673e875 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -3,9 +3,10 @@ import softDeleteMiddleware from './softDeleteMiddleware' import sluggifyMiddleware from './sluggifyMiddleware' import fixImageUrlsMiddleware from './fixImageUrlsMiddleware' import excerptMiddleware from './excerptMiddleware' -import dateTimeMiddleware from './dateTimeMiddleware'; -import xssMiddleware from './xssMiddleware'; -import permissionsMiddleware from './permissionsMiddleware'; +import dateTimeMiddleware from './dateTimeMiddleware' +import xssMiddleware from './xssMiddleware' +import permissionsMiddleware from './permissionsMiddleware' +import userMiddleware from './userMiddleware' export default schema => [ permissionsMiddleware.generate(schema), @@ -15,5 +16,6 @@ export default schema => [ excerptMiddleware, xssMiddleware, fixImageUrlsMiddleware, - softDeleteMiddleware + softDeleteMiddleware, + userMiddleware ] diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js new file mode 100644 index 000000000..5e1f14493 --- /dev/null +++ b/src/middleware/userMiddleware.js @@ -0,0 +1,61 @@ +import request from 'request' +import zipObject from 'lodash/zipObject' + +const fetch = url => { + return new Promise((resolve, reject) => { + request(url, function (error, response, body) { + if (error) { + reject(error) + } else { + resolve(JSON.parse(body)) + } + }) + }) +} + +const createOrUpdateLocations = async (userId, locationId, driver) =>{ + if (!locationId) { + return + } + console.log('userId', userId) + console.log('locationId', locationId) + + const mapboxToken = 'pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ' + const res = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${locationId}.json?access_token=${mapboxToken}&language=de`) + + // TODO: create location in db + + // TODO: get related region, district and country to build the location tree + + const data = res.features[0] + const session = driver.session() + const r = await session.run(`MERGE (l:Location {id: "${data.id}"}) SET l.name = "${data.place_name}", l.type = "${data.place_type[0]}", l.lat = "${data.center[0]}", l.lng = "${data.center[1]}" RETURN l.id, l.name, l.type, l.lat, l.lng`) + // let location = r.records[0]._fields ? zipObject([ + // 'id', + // 'name', + // 'type', + // 'lat', + // 'lng' + // ], r.records[0]._fields) : null + + // delete all current locations from user + await session.run(`MATCH (u:User {id: "${userId}"})-[r:IS_IN]->(l:Location) DETACH DELETE r`) + // connect user with location + await session.run(`MATCH (u:User {id: "${userId}"}), (l:Location {id: "${data.id}"}) MERGE (u)-[:IS_IN]->(l) RETURN l.id, u.id`) + session.close() +} + +export default { + Mutation: { + CreateUser: async (resolve, root, args, context, info) => { + const result = await resolve(root, args, context, info) + await createOrUpdateLocations(context.user.id, args.locationId, context.driver) + return result + }, + UpdateUser: async (resolve, root, args, context, info) => { + const result = await resolve(root, args, context, info) + await createOrUpdateLocations(context.user.id, args.locationId, context.driver) + return result + } + } +} diff --git a/src/schema.graphql b/src/schema.graphql index e6bb4f350..de398e005 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -13,6 +13,8 @@ type LoggedInUser { avatar:String! email: String! role: String! + locationId: String + about: String token: String! } @@ -59,6 +61,14 @@ type WrittenComment @relation(name: "WROTE") { timestamp: Int # TODO: change that to custom Date Type } +type Location { + id: ID! + name: String! + type: String! + lat: Float! + lng: Float! +} + type User { id: ID! name: String @@ -69,6 +79,11 @@ type User { deleted: Boolean disabled: Boolean role: UserGroupEnum + + location: [Location] @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l") + locationId: String + about: String + createdAt: String updatedAt: String @@ -105,6 +120,8 @@ type User { blacklisted: [User]! @relation(name: "BLACKLISTED", direction: "OUT") + categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT") + badges: [Badge]! @relation(name: "REWARDED", direction: "IN") badgesCount: Int! @cypher(statement: "MATCH (this)<-[:REWARDED]-(r:Badge) RETURN COUNT(r)") } @@ -199,7 +216,8 @@ type Tag { name: String! taggedPosts: [Post]! @relation(name: "TAGGED", direction: "IN") taggedOrganizations: [Organization]! @relation(name: "TAGGED", direction: "IN") - taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(r) RETURN COUNT(r)") + taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p) RETURN COUNT(p)") + taggedCountUnique: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p)<-[:WROTE]-(u:User) RETURN COUNT(DISTINCT u)") deleted: Boolean disabled: Boolean } diff --git a/src/seed/seed-mutations.js b/src/seed/seed-mutations.js index 8431e3c59..9aa80f984 100644 --- a/src/seed/seed-mutations.js +++ b/src/seed/seed-mutations.js @@ -83,22 +83,22 @@ export default ` b5_u4: AddUserBadges(from: {id: "b5"}, to: {id: "u4"}) { from { id } } # categories - cat1: CreateCategory( id: "cat1", name: "Just For Fun", slug: "justforfun", icon: "categories-justforfun" ) { name } - cat2: CreateCategory( id: "cat2", name: "Happyness & Values", slug: "happyness-values", icon: "categories-luck" ) { name } - cat3: CreateCategory( id: "cat3", name: "Health & Wellbeing", slug: "health-wellbeing", icon: "categories-health" ) { name } - cat4: CreateCategory( id: "cat4", name: "Environment & Nature", slug: "environment-nature", icon: "categories-environment" ) { name } - cat5: CreateCategory( id: "cat5", name: "Animal Protection", slug: "animalprotection", icon: "categories-animal-justice" ) { name } - cat6: CreateCategory( id: "cat6", name: "Humanrights Justice", slug: "humanrights-justice", icon: "categories-human-rights" ) { name } - cat7: CreateCategory( id: "cat7", name: "Education & Sciences", slug: "education-sciences", icon: "categories-education" ) { name } - cat8: CreateCategory( id: "cat8", name: "Cooperation & Development", slug: "cooperation-development", icon: "categories-cooperation" ) { name } - cat9: CreateCategory( id: "cat9", name: "Democracy & Politics", slug: "democracy-politics", icon: "categories-politics" ) { name } - cat10: CreateCategory( id: "cat10", name: "Economy & Finances", slug: "economy-finances", icon: "categories-economy" ) { name } - cat11: CreateCategory( id: "cat11", name: "Energy & Technology", slug: "energy-technology", icon: "categories-technology" ) { name } - cat12: CreateCategory( id: "cat12", name: "IT, Internet & Data Privacy", slug: "it-internet-dataprivacy", icon: "categories-internet" ) { name } - cat13: CreateCategory( id: "cat13", name: "Art, Curlure & Sport", slug: "art-culture-sport", icon: "categories-art" ) { name } - cat14: CreateCategory( id: "cat14", name: "Freedom of Speech", slug: "freedomofspeech", icon: "categories-freedom-of-speech" ) { name } - cat15: CreateCategory( id: "cat15", name: "Consumption & Sustainability", slug: "consumption-sustainability", icon: "categories-sustainability" ) { name } - cat16: CreateCategory( id: "cat16", name: "Global Peace & Nonviolence", slug: "globalpeace-nonviolence", icon: "categories-peace" ) { name } + cat1: CreateCategory( id: "cat1", name: "Just For Fun", slug: "justforfun", icon: "smile" ) { name } + cat2: CreateCategory( id: "cat2", name: "Happyness & Values", slug: "happyness-values", icon: "heart-o" ) { name } + cat3: CreateCategory( id: "cat3", name: "Health & Wellbeing", slug: "health-wellbeing", icon: "medkit" ) { name } + cat4: CreateCategory( id: "cat4", name: "Environment & Nature", slug: "environment-nature", icon: "tree" ) { name } + cat5: CreateCategory( id: "cat5", name: "Animal Protection", slug: "animalprotection", icon: "paw" ) { name } + cat6: CreateCategory( id: "cat6", name: "Humanrights Justice", slug: "humanrights-justice", icon: "balance-scale" ) { name } + cat7: CreateCategory( id: "cat7", name: "Education & Sciences", slug: "education-sciences", icon: "graduation-cap" ) { name } + cat8: CreateCategory( id: "cat8", name: "Cooperation & Development", slug: "cooperation-development", icon: "users" ) { name } + cat9: CreateCategory( id: "cat9", name: "Democracy & Politics", slug: "democracy-politics", icon: "university" ) { name } + cat10: CreateCategory( id: "cat10", name: "Economy & Finances", slug: "economy-finances", icon: "money" ) { name } + cat11: CreateCategory( id: "cat11", name: "Energy & Technology", slug: "energy-technology", icon: "flash" ) { name } + cat12: CreateCategory( id: "cat12", name: "IT, Internet & Data Privacy", slug: "it-internet-dataprivacy", icon: "mouse-pointer" ) { name } + cat13: CreateCategory( id: "cat13", name: "Art, Curlure & Sport", slug: "art-culture-sport", icon: "paint-brush" ) { name } + cat14: CreateCategory( id: "cat14", name: "Freedom of Speech", slug: "freedomofspeech", icon: "bullhorn" ) { name } + cat15: CreateCategory( id: "cat15", name: "Consumption & Sustainability", slug: "consumption-sustainability", icon: "shopping-cart" ) { name } + cat16: CreateCategory( id: "cat16", name: "Global Peace & Nonviolence", slug: "globalpeace-nonviolence", icon: "angellist" ) { name } # Posts p1: CreatePost( diff --git a/yarn.lock b/yarn.lock index c17a0c3c4..3aee688f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -176,6 +176,15 @@ accepts@^1.3.5, accepts@~1.3.5: mime-types "~2.1.18" negotiator "0.6.1" +ajv@^5.3.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + ansi-align@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" @@ -506,6 +515,16 @@ array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" @@ -532,6 +551,10 @@ async-retry@^1.2.1: dependencies: retry "0.12.0" +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -558,6 +581,14 @@ aws-sdk@^*: uuid "3.1.0" xml2js "0.4.19" +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + babel-cli@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" @@ -1077,6 +1108,12 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + dependencies: + tweetnacl "^0.14.3" + bcryptjs@^2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" @@ -1212,6 +1249,10 @@ capture-stack-trace@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -1310,6 +1351,10 @@ cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -1331,6 +1376,12 @@ color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + dependencies: + delayed-stream "~1.0.0" + commander@^2.11.0, commander@^2.5.0: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" @@ -1388,7 +1439,7 @@ core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.3, core-js@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" -core-util-is@~1.0.0: +core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1437,6 +1488,12 @@ css-what@2.1: version "2.1.2" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + date-fns@^2.0.0-alpha.24: version "2.0.0-alpha.24" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.24.tgz#2988c137c72275af29d7d21cc53eb52b3a8c2586" @@ -1486,6 +1543,10 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" @@ -1580,6 +1641,13 @@ duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.1" resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + ecdsa-sig-formatter@1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz#1c595000f04a8897dfb85000892a0f4c33af86c3" @@ -1751,6 +1819,10 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + external-editor@^2.0.1: version "2.2.0" resolved "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" @@ -1778,10 +1850,22 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + faker@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -1845,6 +1929,18 @@ for-own@^0.1.4: dependencies: for-in "^1.0.1" +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -1909,6 +2005,12 @@ get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" @@ -2138,6 +2240,17 @@ graphql-yoga@1.16.2: dependencies: iterall "^1.2.1" +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + +har-validator@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29" + dependencies: + ajv "^5.3.0" + har-schema "^2.0.0" + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -2227,6 +2340,14 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" @@ -2524,6 +2645,10 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.0" +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -2550,6 +2675,10 @@ isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + iterall@^1.1.3, iterall@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" @@ -2577,6 +2706,10 @@ js-yaml@^3.10.0: argparse "^1.0.7" esprima "^4.0.0" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -2585,6 +2718,18 @@ jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + json5@^0.5.1: version "0.5.1" resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -2603,6 +2748,15 @@ jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: lodash.once "^4.0.0" ms "^2.1.1" +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + jwa@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.6.tgz#87240e76c9808dbde18783cf2264ef4929ee50e6" @@ -2797,6 +2951,16 @@ mime-db@~1.36.0: version "1.36.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" +mime-db@~1.37.0: + version "1.37.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.21" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" + dependencies: + mime-db "~1.37.0" + mime-types@~2.1.18: version "2.1.20" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" @@ -3022,6 +3186,10 @@ numeral@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -3221,6 +3389,10 @@ pause@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" @@ -3305,6 +3477,10 @@ pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" +psl@^1.1.24: + version "1.1.29" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" + pstree.remy@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.0.tgz#f2af27265bd3e5b32bbfcc10e80bac55ba78688b" @@ -3315,11 +3491,15 @@ punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" -qs@6.5.2: +qs@6.5.2, qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -3498,6 +3678,31 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" +request@^2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -3543,7 +3748,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -3749,6 +3954,20 @@ srcset@^1.0.0: array-uniq "^1.0.2" number-is-nan "^1.0.0" +sshpk@^1.7.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.2.tgz#c946d6bd9b1a39d0e8635763f5242d6ed6dcb629" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -3908,6 +4127,13 @@ touch@^3.1.0: dependencies: nopt "~1.0.10" +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -3924,6 +4150,16 @@ trunc-text@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + type-is@^1.6.16, type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" @@ -4040,7 +4276,7 @@ uuid@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" -uuid@^3.1.0: +uuid@^3.1.0, uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" @@ -4054,6 +4290,14 @@ vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + whatwg-fetch@2.0.4: version "2.0.4" resolved "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" From 3287d96ff7f4344af4838ee5071bdf3d930a939e Mon Sep 17 00:00:00 2001 From: mcwimpy Date: Wed, 14 Nov 2018 13:24:26 +0100 Subject: [PATCH 061/554] Update README.md adding info about my experience of getting this to work --- kubernetes/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kubernetes/README.md b/kubernetes/README.md index 3f22e039a..74dbff6fe 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -1,9 +1,14 @@ # Usage with minikube +assuming you installed the packages minikube and virtualbox here... + First of all start minikube on your machine: ```sh minikube start ``` +If you get an error message along th lines of 'The vboxdrv kernel module is not loaded.' - then you have the same issue i had. to solve this you need to install the propper linux kernel host modules package. Here an example for Manjaro: +https://forum.manjaro.org/t/installing-virtualbox-kernel-modules/6999 + You can always get an overview and see what's going on with your minikube: ```sh minikube dashboard From a0a194b288fcd6f0e204c04a67b2e39ce3c3cdbf Mon Sep 17 00:00:00 2001 From: mcwimpy Date: Wed, 14 Nov 2018 13:44:22 +0100 Subject: [PATCH 062/554] Update README.md adding dashboard issue solution --- kubernetes/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index 74dbff6fe..95a9abce8 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -6,13 +6,17 @@ First of all start minikube on your machine: ```sh minikube start ``` -If you get an error message along th lines of 'The vboxdrv kernel module is not loaded.' - then you have the same issue i had. to solve this you need to install the propper linux kernel host modules package. Here an example for Manjaro: +[troubleshoot] If you get an error message along th lines of 'The vboxdrv kernel module is not loaded.' - then you have the same issue i had. to solve this you need to install the propper linux kernel host modules package. Here an example for Manjaro: https://forum.manjaro.org/t/installing-virtualbox-kernel-modules/6999 You can always get an overview and see what's going on with your minikube: ```sh minikube dashboard ``` +[troubleshoot] now again you might run into trouble with an error like 'kubectl could not be found on your path.' In this case run the following command: +```sh +curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.10.0/bin/linux/amd64/kubectl && chmod +x kubectl && sudo cp kubectl /usr/local/bin/ && rm kubectl +``` Build Docker images, using the Minikube Docker daemon: ```sh From d5895bfaca269b65bcd8ba65ad7a410aa60b14fd Mon Sep 17 00:00:00 2001 From: mcwimpy Date: Wed, 14 Nov 2018 17:33:39 +0100 Subject: [PATCH 063/554] Update README.md adding additontional install and download steps --- kubernetes/README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index 95a9abce8..3061f6d3a 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -1,6 +1,6 @@ # Usage with minikube -assuming you installed the packages minikube and virtualbox here... +assuming you installed the packages git, docker, minikube and virtualbox here... First of all start minikube on your machine: ```sh @@ -18,11 +18,17 @@ minikube dashboard curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.10.0/bin/linux/amd64/kubectl && chmod +x kubectl && sudo cp kubectl /usr/local/bin/ && rm kubectl ``` +From now on stay in your favorite work directory. First let's clone the necessary sources: +```sh +git clone https://github.com/Human-Connection/Nitro-Backend.git +git clone https://github.com/Human-Connection/Nitro-Web.git +``` + Build Docker images, using the Minikube Docker daemon: ```sh eval $(minikube docker-env) -docker build -t humanconnection/backend:latest . -docker build -t humanconnection/neo4j:latest -f Dockerfile.neo4j . +docker build -t humanconnection/backend:latest Nitro-Backend/ +docker build -t humanconnection/neo4j:latest -f Dockerfile.neo4j ``` check that the image is in Minikube’s Docker registry: From 3d10944c949f6c58c6df18d417f2593aedb4b6ee Mon Sep 17 00:00:00 2001 From: mcwimpy Date: Wed, 14 Nov 2018 17:43:45 +0100 Subject: [PATCH 064/554] Update README.md correcting little typo --- kubernetes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index 3061f6d3a..6f3a95e19 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -28,7 +28,7 @@ Build Docker images, using the Minikube Docker daemon: ```sh eval $(minikube docker-env) docker build -t humanconnection/backend:latest Nitro-Backend/ -docker build -t humanconnection/neo4j:latest -f Dockerfile.neo4j +docker build -t humanconnection/neo4j:latest -f Dockerfile.neo4j Nitro-Backend/ ``` check that the image is in Minikube’s Docker registry: From 9a7cb99d89a7df7e9a8d354b36a536bc8d30790f Mon Sep 17 00:00:00 2001 From: mcwimpy Date: Wed, 14 Nov 2018 17:58:40 +0100 Subject: [PATCH 065/554] Update README.md path corrections to have no problem copy pasting (had commands with a . at the end that could hardly be seen) --- kubernetes/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index 6f3a95e19..32d48fb75 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -28,7 +28,7 @@ Build Docker images, using the Minikube Docker daemon: ```sh eval $(minikube docker-env) docker build -t humanconnection/backend:latest Nitro-Backend/ -docker build -t humanconnection/neo4j:latest -f Dockerfile.neo4j Nitro-Backend/ +docker build -t humanconnection/neo4j:latest -f Nitro-Backend/Dockerfile.neo4j Nitro-Backend/ ``` check that the image is in Minikube’s Docker registry: @@ -36,7 +36,7 @@ check that the image is in Minikube’s Docker registry: minikube ssh docker images ``` -Now change into directory kubernetes and create services and deployments: +Now change into directory Nitro-Backend/kubernetes and create services and deployments: ```sh cd kubernetes From af57a6aa0263ce18cdc6801b662cadfa70244398 Mon Sep 17 00:00:00 2001 From: mcwimpy Date: Wed, 14 Nov 2018 18:01:02 +0100 Subject: [PATCH 066/554] Update README.md another minor fix on wrong path --- kubernetes/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index 32d48fb75..7699e5426 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -38,8 +38,7 @@ minikube ssh docker images Now change into directory Nitro-Backend/kubernetes and create services and deployments: ```sh -cd kubernetes - +cd Nitro-Backend/kubernetes kubectl create -f neo4j-deployment.yaml,neo4j-data-persistentvolumeclaim.yaml,backend-deployment.yaml,neo4j-service.json,backend-service.json ``` From 8b0be5fb89037e583862f61c42da54b96b5bc132 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 15 Nov 2018 12:33:05 +0100 Subject: [PATCH 067/554] try to fix seeder with authentication --- package.json | 3 ++- src/middleware/dateTimeMiddleware.js | 20 ++++++++++++++---- src/middleware/permissionsMiddleware.js | 16 ++++++++++++++ yarn.lock | 28 +++++++++++++++++++++++-- 4 files changed, 60 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 2e7d88f77..c671b12aa 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "test": "echo \"Error: no test specified\" && exit 1", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "seedDb": "./node_modules/.bin/babel-node src/seed/seed-db.js" + "seedDb": "cross-env IS_SEEDING='true' ./node_modules/.bin/babel-node src/seed/seed-db.js && cross-env IS_SEEDING=false" }, "author": "Grzegorz Leoniec", "license": "MIT", @@ -19,6 +19,7 @@ "apollo-server": "^2.0.4", "bcryptjs": "^2.4.3", "cheerio": "^1.0.0-rc.2", + "cross-env": "^5.2.0", "date-fns": "^2.0.0-alpha.24", "dotenv": "^6.0.0", "graphql-custom-directives": "^0.2.13", diff --git a/src/middleware/dateTimeMiddleware.js b/src/middleware/dateTimeMiddleware.js index 8fd3c074b..7a83eb58d 100644 --- a/src/middleware/dateTimeMiddleware.js +++ b/src/middleware/dateTimeMiddleware.js @@ -3,28 +3,40 @@ import format from 'date-fns/format' export default { Mutation: { CreateUser: async (resolve, root, args, context, info) => { - args.createdAt = format(new Date()) + try { + args.createdAt = format(new Date()) + } catch (err) {} + args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) return result }, CreatePost: async (resolve, root, args, context, info) => { - args.createdAt = format(new Date()) + try { + args.createdAt = format(new Date()) + } catch (err) {} + args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) return result }, CreateComment: async (resolve, root, args, context, info) => { - args.createdAt = format(new Date()) + try { + args.createdAt = format(new Date()) + } catch (err) {} + args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) return result }, CreateOrganization: async (resolve, root, args, context, info) => { - args.createdAt = format(new Date()) + try { + args.createdAt = format(new Date()) + } catch (err) {} + args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 11b4aabe4..83e1742e9 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -1,16 +1,32 @@ import { rule, shield, and, or, not, allow } from 'graphql-shield' const isAuthenticated = rule()(async (parent, args, ctx, info) => { + console.log('isSeeding', process.env.IS_SEEDING) + if (process.env.IS_SEEDING === true) { + return true + } return ctx.user !== null }) const isOwner = rule()(async (parent, args, ctx, info) => { + console.log('isSeeding', process.env.IS_SEEDING) + if (process.env.IS_SEEDING === true) { + return true + } console.log('parent', parent) return ctx.user.id === parent.id }) const isAdmin = rule()(async (parent, args, ctx, info) => { + console.log('isSeeding', process.env.IS_SEEDING) + if (process.env.IS_SEEDING === true) { + return true + } return ctx.user.role === 'ADMIN' }) const isModerator = rule()(async (parent, args, ctx, info) => { + console.log('isSeeding', process.env.IS_SEEDING) + if (process.env.IS_SEEDING === true) { + return true + } return ctx.user.role === 'MODERATOR' }) diff --git a/yarn.lock b/yarn.lock index c17a0c3c4..da7252b6b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1405,6 +1405,14 @@ create-error-class@^3.0.0: dependencies: capture-stack-trace "^1.0.0" +cross-env@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2" + integrity sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg== + dependencies: + cross-spawn "^6.0.5" + is-windows "^1.0.0" + cross-fetch@2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.2.tgz#a47ff4f7fc712daba8f6a695a11c948440d45723" @@ -1420,6 +1428,17 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" @@ -2524,7 +2543,7 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.0" -is-windows@^1.0.2: +is-windows@^1.0.0, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -2918,6 +2937,11 @@ neo4j-graphql-js@1.0.5: lodash "^4.17.10" neo4j-driver "^1.6.1" +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + node-fetch@1.6.3: version "1.6.3" resolved "http://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" @@ -3203,7 +3227,7 @@ path-is-inside@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" -path-key@^2.0.0: +path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" From 59e9b9df1de56e6e5850663da699484ee56478c8 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 15 Nov 2018 12:44:41 +0100 Subject: [PATCH 068/554] fixed date format --- src/middleware/dateTimeMiddleware.js | 20 ++++---------------- src/middleware/permissionsMiddleware.js | 4 ++++ 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/middleware/dateTimeMiddleware.js b/src/middleware/dateTimeMiddleware.js index 7a83eb58d..b0ab1e539 100644 --- a/src/middleware/dateTimeMiddleware.js +++ b/src/middleware/dateTimeMiddleware.js @@ -3,40 +3,28 @@ import format from 'date-fns/format' export default { Mutation: { CreateUser: async (resolve, root, args, context, info) => { - try { - args.createdAt = format(new Date()) - } catch (err) {} - + args.createdAt = (new Date()).toISOString() args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) return result }, CreatePost: async (resolve, root, args, context, info) => { - try { - args.createdAt = format(new Date()) - } catch (err) {} - + args.createdAt = (new Date()).toISOString() args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) return result }, CreateComment: async (resolve, root, args, context, info) => { - try { - args.createdAt = format(new Date()) - } catch (err) {} - + args.createdAt = (new Date()).toISOString() args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) return result }, CreateOrganization: async (resolve, root, args, context, info) => { - try { - args.createdAt = format(new Date()) - } catch (err) {} - + args.createdAt = (new Date()).toISOString() args.disabled = false args.deleted = false const result = await resolve(root, args, context, info) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 83e1742e9..4956b9b15 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -1,6 +1,7 @@ import { rule, shield, and, or, not, allow } from 'graphql-shield' const isAuthenticated = rule()(async (parent, args, ctx, info) => { + // TODO: how to get this working while seeding? console.log('isSeeding', process.env.IS_SEEDING) if (process.env.IS_SEEDING === true) { return true @@ -8,6 +9,7 @@ const isAuthenticated = rule()(async (parent, args, ctx, info) => { return ctx.user !== null }) const isOwner = rule()(async (parent, args, ctx, info) => { + // TODO: how to get this working while seeding? console.log('isSeeding', process.env.IS_SEEDING) if (process.env.IS_SEEDING === true) { return true @@ -16,6 +18,7 @@ const isOwner = rule()(async (parent, args, ctx, info) => { return ctx.user.id === parent.id }) const isAdmin = rule()(async (parent, args, ctx, info) => { + // TODO: how to get this working while seeding? console.log('isSeeding', process.env.IS_SEEDING) if (process.env.IS_SEEDING === true) { return true @@ -23,6 +26,7 @@ const isAdmin = rule()(async (parent, args, ctx, info) => { return ctx.user.role === 'ADMIN' }) const isModerator = rule()(async (parent, args, ctx, info) => { + // TODO: how to get this working while seeding? console.log('isSeeding', process.env.IS_SEEDING) if (process.env.IS_SEEDING === true) { return true From 96da90a25514cbf30d133d51cf71194c004a0d88 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 16 Nov 2018 20:59:05 +0100 Subject: [PATCH 069/554] first attempt to automate dynamic seeding --- src/middleware/permissionsMiddleware.js | 12 +- src/seed/data/badges.js | 12 ++ src/seed/data/index.js | 27 +++++ src/seed/data/users-badges.js | 12 ++ src/seed/data/users.js | 68 +++++++++++ src/seed/seed-db.js | 7 +- src/seed/seed-helpers.js | 145 ++++++++++++++++++++++++ 7 files changed, 276 insertions(+), 7 deletions(-) create mode 100644 src/seed/data/badges.js create mode 100644 src/seed/data/index.js create mode 100644 src/seed/data/users-badges.js create mode 100644 src/seed/data/users.js create mode 100644 src/seed/seed-helpers.js diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 4956b9b15..0386994cc 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -37,17 +37,19 @@ const isModerator = rule()(async (parent, args, ctx, info) => { // Permissions const permissions = shield({ Query: { - statistics: isAdmin + statistics: isAdmin, // fruits: and(isAuthenticated, or(isAdmin, isModerator)), // customers: and(isAuthenticated, isAdmin) }, Mutation: { // addFruitToBasket: isAuthenticated + CreateUser: allow }, - User: { - email: isOwner, - password: isOwner - }, + // TODO: re-activate this after fixing the initial seed + // User: { + // email: isOwner, + // password: isOwner + // }, Post: isAuthenticated }) diff --git a/src/seed/data/badges.js b/src/seed/data/badges.js new file mode 100644 index 000000000..d4144d30e --- /dev/null +++ b/src/seed/data/badges.js @@ -0,0 +1,12 @@ +export default function (data) { + return ` + mutation { + b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_racoon.svg") { id } + b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_rabbit.svg") { id } + b3: CreateBadge(id: "b3", key: "indiegogo_en_wolf", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_wolf.svg") { id } + b4: CreateBadge(id: "b4", key: "indiegogo_en_bear", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_bear.svg") { id } + b5: CreateBadge(id: "b5", key: "indiegogo_en_turtle", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_turtle.svg") { id } + b6: CreateBadge(id: "b6", key: "indiegogo_en_rhino", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_rhino.svg") { id } + } + ` +} diff --git a/src/seed/data/index.js b/src/seed/data/index.js new file mode 100644 index 000000000..0ac7681aa --- /dev/null +++ b/src/seed/data/index.js @@ -0,0 +1,27 @@ +import gql from 'graphql-tag' +import helper from '../seed-helpers' + +const seed = { + Badges: require('./badges.js').default, + User: require('./users.js').default, + UserBadges: require('./users-badges.js').default +}; + +let data = {} + +export default async function (client) { + // iterate through seeds + await helper.asyncForEach(Object.keys(seed), async key => { + const mutations = seed[key] + try { + const res = await client + .mutate({ + mutation: gql(mutations(data)) + }) + data[key] = Object.assign(data[key] || {}, res.data) + } catch (err) { + console.error(err) + } + }) + console.log('Seeded Data', data) +} diff --git a/src/seed/data/users-badges.js b/src/seed/data/users-badges.js new file mode 100644 index 000000000..1a8bc1fe1 --- /dev/null +++ b/src/seed/data/users-badges.js @@ -0,0 +1,12 @@ +export default function (data) { + return ` + mutation { + b1_u1: AddUserBadges(from: {id: "b1"}, to: {id: "u1"}) { from { id } } + b2_u1: AddUserBadges(from: {id: "b2"}, to: {id: "u1"}) { from { id } } + b3_u1: AddUserBadges(from: {id: "b3"}, to: {id: "u1"}) { from { id } } + b6_u2: AddUserBadges(from: {id: "b6"}, to: {id: "u2"}) { from { id } } + b3_u3: AddUserBadges(from: {id: "b3"}, to: {id: "u3"}) { from { id } } + b5_u4: AddUserBadges(from: {id: "b5"}, to: {id: "u4"}) { from { id } } + } + ` +} diff --git a/src/seed/data/users.js b/src/seed/data/users.js new file mode 100644 index 000000000..2c148bc0c --- /dev/null +++ b/src/seed/data/users.js @@ -0,0 +1,68 @@ +import faker from 'faker' + +export default function (data) { + return ` + mutation { + u1: CreateUser( + id: "u1", + name: "Peter Lustig", + password: "1234", + email: "admin@example.org", + avatar: "${faker.internet.avatar()}", + role: admin, + disabled: false, + deleted: false) { + id + name + email + avatar + role + } + u2: CreateUser( + id: "u2", + name: "Bob der Bausmeister", + password: "1234", + email: "moderator@example.org", + avatar: "${faker.internet.avatar()}", + role: moderator, + disabled: false, + deleted: false) { + id + name + email + avatar + role + } + u3: CreateUser( + id: "u3", + name: "Jenny Rostock", + password: "1234", + email: "user@example.org", + avatar: "${faker.internet.avatar()}", + role: user, + disabled: false, + deleted: false) { + id + name + email + avatar + role + } + u4: CreateUser( + id: "u4", + name: "Angie Banjie", + password: "1234", + email: "angie@example.org", + avatar: "${faker.internet.avatar()}", + role: user, + disabled: false, + deleted: false) { + id + name + email + avatar + role + } + } + ` +} diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 1fa478fd1..0617a53fe 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -5,6 +5,7 @@ import seedMutations from "./seed-mutations"; import fetch from "node-fetch"; import { HttpLink } from "apollo-link-http"; import { InMemoryCache } from "apollo-cache-inmemory"; +import Seed from './data/index' dotenv.config(); @@ -13,9 +14,11 @@ const client = new ApolloClient({ cache: new InMemoryCache() }); -client +Seed(client) + +/* client .mutate({ mutation: gql(seedMutations) }) .then(data => console.log(data)) - .catch(error => console.error(error)); + .catch(error => console.error(error)); **/ diff --git a/src/seed/seed-helpers.js b/src/seed/seed-helpers.js new file mode 100644 index 000000000..590b9c514 --- /dev/null +++ b/src/seed/seed-helpers.js @@ -0,0 +1,145 @@ +const _ = require('lodash') +const faker = require('faker') +const unsplashTopics = [ + 'love', + 'family', + 'spring', + 'business', + 'nature', + 'travel', + 'happy', + 'landscape', + 'health', + 'friends', + 'computer', + 'autumn', + 'space', + 'animal', + 'smile', + 'face', + 'people', + 'portrait', + 'amazing' +] +let unsplashTopicsTmp = [] + +const ngoLogos = [ + 'http://www.fetchlogos.com/wp-content/uploads/2015/11/Girl-Scouts-Of-The-Usa-Logo.jpg', + 'http://logos.textgiraffe.com/logos/logo-name/Ngo-designstyle-friday-m.png', + 'http://seeklogo.com/images/N/ngo-logo-BD53A3E024-seeklogo.com.png', + 'https://dcassetcdn.com/design_img/10133/25833/25833_303600_10133_image.jpg', + 'https://cdn.tutsplus.com/vector/uploads/legacy/articles/08bad_ngologos/20.jpg', + 'https://cdn.tutsplus.com/vector/uploads/legacy/articles/08bad_ngologos/33.jpg', + null +] + +const difficulties = ['easy', 'medium', 'hard'] + +export default { + randomItem: (items, filter) => { + let ids = filter + ? Object.keys(items) + .filter(id => { + return filter(items[id]) + }) + : _.keys(items) + let randomIds = _.shuffle(ids) + return items[randomIds.pop()] + }, + randomItems: (items, key = '_id', min = 1, max = 1) => { + let randomIds = _.shuffle(_.keys(items)) + let res = [] + + const count = _.random(min, max) + + for (let i = 0; i < count; i++) { + let r = items[randomIds.pop()][key] + if (key === '_id') { + r = r.toString() + } + res.push(r) + } + return res + }, + random: (items) => { + return _.shuffle(items).pop() + }, + randomDifficulty: () => { + return _.shuffle(difficulties).pop() + }, + randomLogo: () => { + return _.shuffle(ngoLogos).pop() + }, + randomUnsplashUrl: () => { + if (Math.random() < 0.6) { + // do not attach images in 60 percent of the cases (faster seeding) + return + } + if (unsplashTopicsTmp.length < 2) { + unsplashTopicsTmp = _.shuffle(unsplashTopics) + } + return 'https://source.unsplash.com/daily?' + unsplashTopicsTmp.pop() + ',' + unsplashTopicsTmp.pop() + }, + randomCategories: (seederstore, allowEmpty = false) => { + let count = Math.round(Math.random() * 3) + if (allowEmpty === false && count === 0) { + count = 1 + } + let categorieIds = _.shuffle(_.keys(seederstore.categories)) + let ids = [] + for (let i = 0; i < count; i++) { + ids.push(categorieIds.pop()) + } + return ids + }, + randomAddresses: () => { + const count = Math.round(Math.random() * 3) + let addresses = [] + for (let i = 0; i < count; i++) { + addresses.push({ + city: faker.address.city(), + zipCode: faker.address.zipCode(), + street: faker.address.streetAddress(), + country: faker.address.countryCode(), + lat: 54.032726 - (Math.random() * 10), + lng: 6.558838 + (Math.random() * 10) + }) + } + return addresses + }, + /** + * Get array of ids from the given seederstore items after mapping them by the key in the values + * + * @param items items from the seederstore + * @param values values for which you need the ids + * @param key the field key that is represented in the values (slug, name, etc.) + */ + mapIdsByKey: (items, values, key) => { + let res = [] + values.forEach(value => { + res.push(_.find(items, [key, value])._id.toString()) + }) + return res + }, + /** + * Provide a way to iterate for each element in an array while waiting for async functions to finish + * + * @param array + * @param callback + * @returns {Promise} + */ + asyncForEach: async (array, callback) => { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array) + } + }, + genInviteCode: () => { + const chars = '23456789abcdefghkmnpqrstuvwxyzABCDEFGHJKLMNPRSTUVWXYZ' + let code = '' + for (let i = 0; i < 8; i++) { + const n = _.random(0, chars.length-1) + code += chars.substr(n, 1) + } + return code + } +} From 803e613c4b6e37e6b9108e9375b251daf41c83f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 20 Nov 2018 20:53:48 +0100 Subject: [PATCH 070/554] Clean way to seed the database 1. Temporarily open another backend with permissions disabled 2. Connect to this backend and run seed data --- package.json | 8 +- src/index.js | 2 +- src/middleware/index.js | 25 +- src/middleware/permissionsMiddleware.js | 21 - yarn.lock | 669 +++++++++++++++++++++++- 5 files changed, 681 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index c671b12aa..236dd805b 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "test": "echo \"Error: no test specified\" && exit 1", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "seedDb": "cross-env IS_SEEDING='true' ./node_modules/.bin/babel-node src/seed/seed-db.js && cross-env IS_SEEDING=false" + "db:seed": "concurrently --kill-others --success first 'cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_LISTEN_PORT=4001 yarn run start' 'wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js'" }, "author": "Grzegorz Leoniec", "license": "MIT", @@ -19,7 +19,6 @@ "apollo-server": "^2.0.4", "bcryptjs": "^2.4.3", "cheerio": "^1.0.0-rc.2", - "cross-env": "^5.2.0", "date-fns": "^2.0.0-alpha.24", "dotenv": "^6.0.0", "graphql-custom-directives": "^0.2.13", @@ -44,7 +43,10 @@ "devDependencies": { "babel-cli": "^6.26.0", "babel-preset-env": "^1.7.0", + "concurrently": "^4.1.0", + "cross-env": "^5.2.0", "faker": "^4.1.0", - "nodemon": "^1.18.4" + "nodemon": "^1.18.4", + "wait-on": "^3.2.0" } } diff --git a/src/index.js b/src/index.js index 5c3face1a..ff62bb7b0 100644 --- a/src/index.js +++ b/src/index.js @@ -67,7 +67,7 @@ server.express.use(passport.initialize()) server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) const serverConfig = { - port: 4000 + port: process.env.GRAPHQL_LISTEN_PORT // cors: { // credentials: true, // origin: [process.env.CLIENT_URI] // your frontend url. diff --git a/src/middleware/index.js b/src/middleware/index.js index f743ae74f..6ed0fa697 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -7,13 +7,18 @@ import dateTimeMiddleware from './dateTimeMiddleware'; import xssMiddleware from './xssMiddleware'; import permissionsMiddleware from './permissionsMiddleware'; -export default schema => [ - permissionsMiddleware.generate(schema), - passwordMiddleware, - dateTimeMiddleware, - sluggifyMiddleware, - excerptMiddleware, - xssMiddleware, - fixImageUrlsMiddleware, - softDeleteMiddleware -] +export default schema => { + let middleware = [ + passwordMiddleware, + dateTimeMiddleware, + sluggifyMiddleware, + excerptMiddleware, + xssMiddleware, + fixImageUrlsMiddleware, + softDeleteMiddleware + ] + if (process.env.PERMISSIONS !== 'disabled') { + middleware.push(permissionsMiddleware.generate(schema)) + } + return middleware +} diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 0386994cc..d82be9f5b 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -1,36 +1,15 @@ import { rule, shield, and, or, not, allow } from 'graphql-shield' const isAuthenticated = rule()(async (parent, args, ctx, info) => { - // TODO: how to get this working while seeding? - console.log('isSeeding', process.env.IS_SEEDING) - if (process.env.IS_SEEDING === true) { - return true - } return ctx.user !== null }) const isOwner = rule()(async (parent, args, ctx, info) => { - // TODO: how to get this working while seeding? - console.log('isSeeding', process.env.IS_SEEDING) - if (process.env.IS_SEEDING === true) { - return true - } - console.log('parent', parent) return ctx.user.id === parent.id }) const isAdmin = rule()(async (parent, args, ctx, info) => { - // TODO: how to get this working while seeding? - console.log('isSeeding', process.env.IS_SEEDING) - if (process.env.IS_SEEDING === true) { - return true - } return ctx.user.role === 'ADMIN' }) const isModerator = rule()(async (parent, args, ctx, info) => { - // TODO: how to get this working while seeding? - console.log('isSeeding', process.env.IS_SEEDING) - if (process.env.IS_SEEDING === true) { - return true - } return ctx.user.role === 'MODERATOR' }) diff --git a/yarn.lock b/yarn.lock index da7252b6b..091de27c8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -176,6 +176,16 @@ accepts@^1.3.5, accepts@~1.3.5: mime-types "~2.1.18" negotiator "0.6.1" +ajv@^6.5.5: + version "6.5.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" + integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ansi-align@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" @@ -506,6 +516,18 @@ array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" @@ -532,6 +554,11 @@ async-retry@^1.2.1: dependencies: retry "0.12.0" +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -558,6 +585,16 @@ aws-sdk@^*: uuid "3.1.0" xml2js "0.4.19" +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + babel-cli@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" @@ -1077,6 +1114,13 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + bcryptjs@^2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" @@ -1175,6 +1219,11 @@ buffer@4.9.1: ieee754 "^1.1.4" isarray "^1.0.0" +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + busboy@^0.2.14: version "0.2.14" resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" @@ -1204,6 +1253,11 @@ camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" +camelcase@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" + integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + caniuse-lite@^1.0.30000844: version "1.0.30000892" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000892.tgz#344d2b51ee3ff5977537da4aa449c90eec40b759" @@ -1212,6 +1266,11 @@ capture-stack-trace@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -1310,6 +1369,15 @@ cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -1331,6 +1399,13 @@ color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== + dependencies: + delayed-stream "~1.0.0" + commander@^2.11.0, commander@^2.5.0: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" @@ -1343,6 +1418,21 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" +concurrently@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-4.1.0.tgz#17fdf067da71210685d9ea554423ef239da30d33" + integrity sha512-pwzXCE7qtOB346LyO9eFWpkFJVO3JQZ/qU/feGeaAHiX1M3Rw3zgXKc5cZ8vSH5DGygkjzLFDzA/pwoQDkRNGg== + dependencies: + chalk "^2.4.1" + date-fns "^1.23.0" + lodash "^4.17.10" + read-pkg "^4.0.1" + rxjs "^6.3.3" + spawn-command "^0.0.2-1" + supports-color "^4.5.0" + tree-kill "^1.1.0" + yargs "^12.0.1" + configstore@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" @@ -1388,7 +1478,7 @@ core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.3, core-js@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" -core-util-is@~1.0.0: +core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1428,7 +1518,7 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.5: +cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -1456,6 +1546,18 @@ css-what@2.1: version "2.1.2" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +date-fns@^1.23.0: + version "1.29.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" + integrity sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw== + date-fns@^2.0.0-alpha.24: version "2.0.0-alpha.24" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.24.tgz#2988c137c72275af29d7d21cc53eb52b3a8c2586" @@ -1472,6 +1574,11 @@ debug@^3.1.0: dependencies: ms "^2.1.1" +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -1505,6 +1612,11 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" @@ -1599,6 +1711,14 @@ duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.1" resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + ecdsa-sig-formatter@1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz#1c595000f04a8897dfb85000892a0f4c33af86c3" @@ -1627,6 +1747,13 @@ entities@^1.1.1, entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + es-abstract@^1.5.1: version "1.12.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" @@ -1686,6 +1813,19 @@ events@1.1.1: version "1.1.1" resolved "http://registry.npmjs.org/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" +execa@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" + integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== + dependencies: + cross-spawn "^6.0.0" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -1770,6 +1910,11 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" +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== + external-editor@^2.0.1: version "2.2.0" resolved "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" @@ -1797,10 +1942,25 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + faker@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -1850,6 +2010,13 @@ finalhandler@1.1.1: statuses "~1.4.0" unpipe "~1.0.0" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + flatmap-stream@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.1.tgz#d34f39ef3b9aa5a2fc225016bd3adf28ac5ae6ea" @@ -1864,6 +2031,20 @@ for-own@^0.1.4: dependencies: for-in "^1.0.1" +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -1920,6 +2101,11 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + get-stream@^3.0.0: version "3.0.0" resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -1928,6 +2114,13 @@ get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" @@ -2157,12 +2350,30 @@ graphql-yoga@1.16.2: dependencies: iterall "^1.2.1" +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" dependencies: ansi-regex "^2.0.0" +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -2219,6 +2430,16 @@ he@0.5.0: version "0.5.0" resolved "http://registry.npmjs.org/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" +hoek@5.x.x: + version "5.0.4" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-5.0.4.tgz#0f7fa270a1cafeb364a4b2ddfaa33f864e4157da" + integrity sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w== + +hoek@6.x.x: + version "6.0.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.0.3.tgz#7884360426d927865a0a1251fc9c59313af5b798" + integrity sha512-TU6RyZ/XaQCTWRLrdqZZtZqwxUVr6PDMfi6MlWNURZ7A6czanQqX4pFE1mdOUQR9FdPCsZ0UzL8jI/izZ+eBSQ== + home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -2226,6 +2447,11 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" +hosted-git-info@^2.1.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + htmlparser2@^3.9.0, htmlparser2@^3.9.1: version "3.10.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" @@ -2246,6 +2472,15 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" @@ -2334,6 +2569,11 @@ invariant@^2.2.2: dependencies: loose-envify "^1.0.0" +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + ipaddr.js@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" @@ -2350,6 +2590,11 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -2360,6 +2605,13 @@ is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= + dependencies: + builtin-modules "^1.0.0" + is-callable@^1.1.3, is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" @@ -2543,6 +2795,11 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.0" +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + is-windows@^1.0.0, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -2555,6 +2812,13 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" +isemail@3.x.x: + version "3.2.0" + resolved "https://registry.yarnpkg.com/isemail/-/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c" + integrity sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg== + dependencies: + punycode "2.x.x" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2569,6 +2833,11 @@ isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + iterall@^1.1.3, iterall@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" @@ -2577,6 +2846,15 @@ jmespath@0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" +joi@^13.0.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-13.7.0.tgz#cfd85ebfe67e8a1900432400b4d03bbd93fb879f" + integrity sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q== + dependencies: + hoek "5.x.x" + isemail "3.x.x" + topo "3.x.x" + jquery@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca" @@ -2596,6 +2874,11 @@ js-yaml@^3.10.0: argparse "^1.0.7" esprima "^4.0.0" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -2604,6 +2887,26 @@ jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" +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-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + json5@^0.5.1: version "0.5.1" resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -2622,6 +2925,16 @@ jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: lodash.once "^4.0.0" ms "^2.1.1" +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + jwa@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.6.tgz#87240e76c9808dbde18783cf2264ef4929ee50e6" @@ -2663,6 +2976,13 @@ latest-version@^3.0.0: dependencies: package-json "^4.0.0" +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + linkifyjs@^2.1.7: version "2.1.7" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-2.1.7.tgz#e5d68d2ae30b9c055e1d74cc40f9a31d3abb4012" @@ -2671,6 +2991,14 @@ linkifyjs@^2.1.7: react "^16.4.2" react-dom "^16.4.2" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" @@ -2746,6 +3074,13 @@ make-dir@^1.0.0: dependencies: pify "^3.0.0" +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -2768,6 +3103,15 @@ media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" +mem@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" + integrity sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^1.0.0" + p-is-promise "^1.1.0" + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -2816,6 +3160,18 @@ mime-db@~1.36.0: version "1.36.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" +mime-db@~1.37.0: + version "1.37.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" + integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.21" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" + integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== + dependencies: + mime-db "~1.37.0" + mime-types@~2.1.18: version "2.1.20" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" @@ -3000,6 +3356,16 @@ nopt@~1.0.10: dependencies: abbrev "1" +normalize-package-data@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -3046,6 +3412,11 @@ numeral@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -3142,6 +3513,15 @@ os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" +os-locale@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" + integrity sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw== + dependencies: + execa "^0.10.0" + lcid "^2.0.0" + mem "^4.0.0" + os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -3161,10 +3541,39 @@ output-file-sync@^1.1.2: mkdirp "^0.5.1" object-assign "^4.1.0" +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + +p-limit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" + integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== + package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -3183,6 +3592,14 @@ parse-glob@^3.0.4: is-extglob "^1.0.0" is-glob "^2.0.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" + parse5@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" @@ -3219,6 +3636,11 @@ path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -3245,6 +3667,11 @@ pause@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" @@ -3329,6 +3756,11 @@ pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" +psl@^1.1.24: + version "1.1.29" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" + integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== + pstree.remy@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.0.tgz#f2af27265bd3e5b32bbfcc10e80bac55ba78688b" @@ -3339,11 +3771,16 @@ punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" -punycode@^2.1.0: +punycode@2.x.x, punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" -qs@6.5.2: +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +qs@6.5.2, qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -3399,6 +3836,15 @@ react@^16.4.2: prop-types "^15.6.2" scheduler "^0.10.0" +read-pkg@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" + integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= + dependencies: + normalize-package-data "^2.3.2" + parse-json "^4.0.0" + pify "^3.0.0" + readable-stream@1.1.x: version "1.1.14" resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" @@ -3522,6 +3968,42 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" +request@^2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -3557,6 +4039,13 @@ rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" +rxjs@^6.3.3: + version "6.3.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" + integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== + dependencies: + tslib "^1.9.0" + safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -3567,7 +4056,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -3607,7 +4096,7 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" @@ -3638,7 +4127,7 @@ serve-static@1.13.2: parseurl "~1.3.2" send "0.16.2" -set-blocking@~2.0.0: +set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -3750,6 +4239,37 @@ source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" +spawn-command@^0.0.2-1: + version "0.0.2-1" + resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" + integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A= + +spdx-correct@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" + integrity sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2" + integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg== + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -3773,6 +4293,21 @@ srcset@^1.0.0: array-uniq "^1.0.2" number-is-nan "^1.0.0" +sshpk@^1.7.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.2.tgz#c946d6bd9b1a39d0e8635763f5242d6ed6dcb629" + integrity sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -3858,6 +4393,13 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" +supports-color@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + integrity sha1-vnoN5ITexcXN34s9WRJQRJEvY1s= + dependencies: + has-flag "^2.0.0" + supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -3926,12 +4468,32 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +topo@3.x.x: + version "3.0.3" + resolved "https://registry.yarnpkg.com/topo/-/topo-3.0.3.tgz#d5a67fb2e69307ebeeb08402ec2a2a6f5f7ad95c" + integrity sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ== + dependencies: + hoek "6.x.x" + touch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" dependencies: nopt "~1.0.10" +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tree-kill@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.1.tgz#5398f374e2f292b9dcc7b2e71e30a5c3bb6c743a" + integrity sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q== + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -3948,6 +4510,23 @@ trunc-text@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" +tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + type-is@^1.6.16, type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" @@ -4014,7 +4593,7 @@ update-notifier@^2.3.0: semver-diff "^2.0.0" xdg-basedir "^3.0.0" -uri-js@^4.2.1: +uri-js@^4.2.1, uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" dependencies: @@ -4064,7 +4643,7 @@ uuid@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" -uuid@^3.1.0: +uuid@^3.1.0, uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" @@ -4074,14 +4653,47 @@ v8flags@^2.1.1: dependencies: user-home "^1.1.1" +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +wait-on@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-3.2.0.tgz#c83924df0fc42a675c678324c49c769d378bcb85" + integrity sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg== + dependencies: + core-js "^2.5.7" + joi "^13.0.0" + minimist "^1.2.0" + request "^2.88.0" + rx "^4.1.0" + whatwg-fetch@2.0.4: version "2.0.4" resolved "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -4100,6 +4712,14 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -4137,6 +4757,11 @@ xtend@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" +"y18n@^3.2.1 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" @@ -4145,6 +4770,32 @@ yallist@^3.0.0, yallist@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^12.0.1: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + zen-observable-ts@^0.8.10: version "0.8.10" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz#18e2ce1c89fe026e9621fd83cc05168228fce829" From 859b2b87790f6172bed27596df6947615cd57f99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 20 Nov 2018 21:06:56 +0100 Subject: [PATCH 071/554] Reactivate isOwner as suggested in the comments --- src/middleware/permissionsMiddleware.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index d82be9f5b..2eaac524a 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -24,11 +24,10 @@ const permissions = shield({ // addFruitToBasket: isAuthenticated CreateUser: allow }, - // TODO: re-activate this after fixing the initial seed - // User: { - // email: isOwner, - // password: isOwner - // }, + User: { + email: isOwner, + password: isOwner + }, Post: isAuthenticated }) From ab78785a43438572b8c735c94d46f7f98c0faaf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 20 Nov 2018 22:00:31 +0100 Subject: [PATCH 072/554] Add the remaining seeds --- src/seed/data/index.js | 3 +- .../miscellaneous.js} | 80 +------------------ src/seed/seed-db.js | 1 - 3 files changed, 5 insertions(+), 79 deletions(-) rename src/seed/{seed-mutations.js => data/miscellaneous.js} (85%) diff --git a/src/seed/data/index.js b/src/seed/data/index.js index 0ac7681aa..5082f50e3 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -4,7 +4,8 @@ import helper from '../seed-helpers' const seed = { Badges: require('./badges.js').default, User: require('./users.js').default, - UserBadges: require('./users-badges.js').default + UserBadges: require('./users-badges.js').default, + Miscellaneous: require('./miscellaneous.js').default }; let data = {} diff --git a/src/seed/seed-mutations.js b/src/seed/data/miscellaneous.js similarity index 85% rename from src/seed/seed-mutations.js rename to src/seed/data/miscellaneous.js index 8431e3c59..808b29479 100644 --- a/src/seed/seed-mutations.js +++ b/src/seed/data/miscellaneous.js @@ -1,86 +1,11 @@ import faker from 'faker' -export default ` - mutation { +export default () => { + return `mutation { - # Users - u1: CreateUser( - id: "u1", - name: "Peter Lustig", - password: "1234", - email: "admin@example.org", - avatar: "${faker.internet.avatar()}", - role: admin, - disabled: false, - deleted: false) { - id - name - email - avatar - role - } - u2: CreateUser( - id: "u2", - name: "Bob der Bausmeister", - password: "1234", - email: "moderator@example.org", - avatar: "${faker.internet.avatar()}", - role: moderator, - disabled: false, - deleted: false) { - id - name - email - avatar - role - } - u3: CreateUser( - id: "u3", - name: "Jenny Rostock", - password: "1234", - email: "user@example.org", - avatar: "${faker.internet.avatar()}", - role: user, - disabled: false, - deleted: false) { - id - name - email - avatar - role - } - u4: CreateUser( - id: "u4", - name: "Angie Banjie", - password: "1234", - email: "angie@example.org", - avatar: "${faker.internet.avatar()}", - role: user, - disabled: false, - deleted: false) { - id - name - email - avatar - role - } u1_blacklist_u4: AddUserBlacklisted(from: { id: "u1" }, to: { id: "u4" }) { from { id } } - # Badges - b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_racoon.svg") { id } - b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_rabbit.svg") { id } - b3: CreateBadge(id: "b3", key: "indiegogo_en_wolf", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_wolf.svg") { id } - b4: CreateBadge(id: "b4", key: "indiegogo_en_bear", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_bear.svg") { id } - b5: CreateBadge(id: "b5", key: "indiegogo_en_turtle", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_turtle.svg") { id } - b6: CreateBadge(id: "b6", key: "indiegogo_en_rhino", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_rhino.svg") { id } - - b1_u1: AddUserBadges(from: {id: "b1"}, to: {id: "u1"}) { from { id } } - b2_u1: AddUserBadges(from: {id: "b2"}, to: {id: "u1"}) { from { id } } - b3_u1: AddUserBadges(from: {id: "b3"}, to: {id: "u1"}) { from { id } } - b6_u2: AddUserBadges(from: {id: "b6"}, to: {id: "u2"}) { from { id } } - b3_u3: AddUserBadges(from: {id: "b3"}, to: {id: "u3"}) { from { id } } - b5_u4: AddUserBadges(from: {id: "b5"}, to: {id: "u4"}) { from { id } } # categories cat1: CreateCategory( id: "cat1", name: "Just For Fun", slug: "justforfun", icon: "categories-justforfun" ) { name } @@ -418,3 +343,4 @@ export default ` ) { from { id } } } ` +} diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 0617a53fe..7ffb2c4dd 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,7 +1,6 @@ import ApolloClient from "apollo-client"; import dotenv from "dotenv"; import gql from 'graphql-tag' -import seedMutations from "./seed-mutations"; import fetch from "node-fetch"; import { HttpLink } from "apollo-link-http"; import { InMemoryCache } from "apollo-cache-inmemory"; From 788bb7a9922c6123dec60e453a94e8c46564a3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 21 Nov 2018 00:24:24 +0100 Subject: [PATCH 073/554] .gitignore yarn-error.log (sensitive data?) --- .gitignore | 1 + yarn-error.log | 3862 ------------------------------------------------ 2 files changed, 1 insertion(+), 3862 deletions(-) delete mode 100644 yarn-error.log diff --git a/.gitignore b/.gitignore index ed579a2c7..d927e1c27 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ .env .vscode +yarn-error.log diff --git a/yarn-error.log b/yarn-error.log deleted file mode 100644 index 2277f3e46..000000000 --- a/yarn-error.log +++ /dev/null @@ -1,3862 +0,0 @@ -Arguments: - /usr/local/bin/node /usr/local/Cellar/yarn/1.9.4/libexec/bin/yarn.js add graph-middleware@1.7.6 graphql-yoga@1.16.2 - -PATH: - /usr/local/opt/mongodb@3.6/bin:/usr/local/opt/php@7.1/sbin:/usr/local/opt/php@7.1/bin:/usr/local/opt/libxml2/bin:/Users/Greg/.bin:/usr/local/sbin:/usr/local/opt/coreutils/libexec/gnubin:/Users/Greg/.composer/vendor/bin:/Users/Greg/.npm/bin:/usr/local/bin/npm:/usr/local/share/npm/bin:/usr/local/Cellar:/usr/local/sbin:/usr/local/bin:/Users/Greg/.yarn/bin:/Users/Greg/Projekte/HumanConnection/kube-vm/kubernetes/client/bin:/usr/local/opt/mysql@5.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/MacGPG2/bin:/usr/local/opt/mongodb@3.6/bin:/usr/local/opt/php@7.1/sbin:/usr/local/opt/php@7.1/bin:/usr/local/opt/libxml2/bin:/Users/Greg/.bin:/usr/local/sbin:/usr/local/opt/coreutils/libexec/gnubin:/Users/Greg/.composer/vendor/bin:/Users/Greg/.npm/bin:/usr/local/bin/npm:/usr/local/share/npm/bin:/usr/local/Cellar:/Users/Greg/.yarn/bin:/Users/Greg/Projekte/HumanConnection/kube-vm/kubernetes/client/bin:/usr/local/opt/mysql@5.7/bin:/Users/Greg/.composer/vendor/bin:/Users/Greg/.composer/vendor/bin - -Yarn version: - 1.9.4 - -Node version: - 10.11.0 - -Platform: - darwin x64 - -Trace: - Error: https://registry.yarnpkg.com/graph-middleware: Not found - at Request.params.callback [as _callback] (/usr/local/Cellar/yarn/1.9.4/libexec/lib/cli.js:64202:18) - at Request.self.callback (/usr/local/Cellar/yarn/1.9.4/libexec/lib/cli.js:137468:22) - at Request.emit (events.js:182:13) - at Request. (/usr/local/Cellar/yarn/1.9.4/libexec/lib/cli.js:138440:10) - at Request.emit (events.js:182:13) - at IncomingMessage. (/usr/local/Cellar/yarn/1.9.4/libexec/lib/cli.js:138362:12) - at Object.onceWrapper (events.js:273:13) - at IncomingMessage.emit (events.js:187:15) - at endReadableNT (_stream_readable.js:1092:12) - at process._tickCallback (internal/process/next_tick.js:63:19) - -npm manifest: - { - "name": "hc-prototype-api-", - "version": "0.0.1", - "description": "Graph API Protype for Human Connection", - "main": "src/index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", - "seedDb": "./node_modules/.bin/babel-node src/seed/seed-db.js" - }, - "author": "Grzegorz Leoniec", - "license": "MIT", - "dependencies": { - "apollo-boost": "^0.1.10", - "apollo-cache-inmemory": "^1.2.5", - "apollo-client": "^2.3.2", - "apollo-link-http": "^1.5.4", - "apollo-server": "^2.0.4", - "bcryptjs": "^2.4.3", - "dotenv": "^6.0.0", - "graphql-custom-directives": "^0.2.13", - "graphql-middleware": "^1.7.8", - "graphql-tag": "^2.9.2", - "graphql-yoga": "^1.16.6", - "jsonwebtoken": "^8.3.0", - "lodash": "^4.17.11", - "ms": "^2.1.1", - "neo4j-driver": "^1.6.1", - "neo4j-graphql-js": "1.0.2", - "node-fetch": "^2.1.2", - "passport": "^0.4.0", - "passport-jwt": "^4.0.0", - "slug": "^0.9.1", - "trunc-html": "^1.1.2" - }, - "devDependencies": { - "babel-cli": "^6.26.0", - "babel-preset-env": "^1.7.0", - "faker": "^4.1.0", - "nodemon": "^1.18.4" - } - } - -yarn manifest: - No manifest - -Lockfile: - # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. - # yarn lockfile v1 - - - "@apollographql/apollo-upload-server@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" - dependencies: - "@babel/runtime-corejs2" "^7.0.0-rc.1" - busboy "^0.2.14" - object-path "^0.11.4" - - "@apollographql/graphql-playground-html@^1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz#15e1a042b97d6834e6d70b17cc73e1514fde9027" - - "@babel/runtime-corejs2@^7.0.0-rc.1": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.1.2.tgz#8695811a3fd8091f54f274b9320334e5e8c62200" - dependencies: - core-js "^2.5.7" - regenerator-runtime "^0.12.0" - - "@babel/runtime@^7.0.0-beta.40": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.2.tgz#81c89935f4647706fc54541145e6b4ecfef4b8e3" - dependencies: - regenerator-runtime "^0.12.0" - - "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - - "@protobufjs/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - - "@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - - "@protobufjs/eventemitter@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - - "@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - dependencies: - "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" - - "@protobufjs/float@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - - "@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - - "@protobufjs/path@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - - "@protobufjs/pool@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - - "@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - - "@types/accepts@^1.3.5": - version "1.3.5" - resolved "http://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" - dependencies: - "@types/node" "*" - - "@types/async@2.0.49": - version "2.0.49" - resolved "http://registry.npmjs.org/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0" - - "@types/body-parser@*", "@types/body-parser@1.17.0": - version "1.17.0" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" - dependencies: - "@types/connect" "*" - "@types/node" "*" - - "@types/connect@*": - version "3.4.32" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" - dependencies: - "@types/node" "*" - - "@types/cors@^2.8.4": - version "2.8.4" - resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.4.tgz#50991a759a29c0b89492751008c6af7a7c8267b0" - dependencies: - "@types/express" "*" - - "@types/events@*": - version "1.2.0" - resolved "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" - - "@types/express-serve-static-core@*": - version "4.16.0" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz#fdfe777594ddc1fe8eb8eccce52e261b496e43e7" - dependencies: - "@types/events" "*" - "@types/node" "*" - "@types/range-parser" "*" - - "@types/express@*", "@types/express@4.16.0", "@types/express@^4.11.1": - version "4.16.0" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.0.tgz#6d8bc42ccaa6f35cf29a2b7c3333cb47b5a32a19" - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "*" - "@types/serve-static" "*" - - "@types/graphql-deduplicator@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/graphql-deduplicator/-/graphql-deduplicator-2.0.0.tgz#9e577b8f3feb3d067b0ca756f4a1fb356d533922" - - "@types/graphql@^14.0.0": - version "14.0.3" - resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-14.0.3.tgz#389e2e5b83ecdb376d9f98fae2094297bc112c1c" - - "@types/long@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" - - "@types/mime@*": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" - - "@types/node@*", "@types/node@^10.1.0": - version "10.12.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.0.tgz#ea6dcbddbc5b584c83f06c60e82736d8fbb0c235" - - "@types/range-parser@*": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.2.tgz#fa8e1ad1d474688a757140c91de6dace6f4abc8d" - - "@types/serve-static@*": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48" - dependencies: - "@types/express-serve-static-core" "*" - "@types/mime" "*" - - "@types/ws@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-5.1.2.tgz#f02d3b1cd46db7686734f3ce83bdf46c49decd64" - dependencies: - "@types/events" "*" - "@types/node" "*" - - "@types/zen-observable@^0.5.3": - version "0.5.4" - resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.4.tgz#b863a4191e525206819e008097ebf0fb2e3a1cdc" - - "@types/zen-observable@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" - - abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - - accepts@^1.3.5, accepts@~1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" - dependencies: - mime-types "~2.1.18" - negotiator "0.6.1" - - ansi-align@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" - dependencies: - string-width "^2.0.0" - - ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - - ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - - ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - - ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - dependencies: - color-convert "^1.9.0" - - anymatch@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" - dependencies: - micromatch "^2.1.5" - normalize-path "^2.0.0" - - anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - - apollo-boost@^0.1.10: - version "0.1.16" - resolved "https://registry.yarnpkg.com/apollo-boost/-/apollo-boost-0.1.16.tgz#77f73a30c49ab6d749ddc3e5683a7e322c15f07d" - dependencies: - apollo-cache "^1.1.17" - apollo-cache-inmemory "^1.2.10" - apollo-client "^2.4.2" - apollo-link "^1.0.6" - apollo-link-error "^1.0.3" - apollo-link-http "^1.3.1" - apollo-link-state "^0.4.0" - graphql-tag "^2.4.2" - - apollo-cache-control@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz#173d14ceb3eb9e7cb53de7eb8b61bee6159d4171" - dependencies: - graphql-extensions "^0.0.x" - - apollo-cache-control@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.2.5.tgz#0831ad796754a7beec858668f99e7517fe744a1e" - dependencies: - apollo-server-env "^2.0.3" - graphql-extensions "^0.2.1" - - apollo-cache-inmemory@^1.2.10, apollo-cache-inmemory@^1.2.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.5.tgz#7628ee598271cfffa611e15a7ce67652a84b07b0" - dependencies: - apollo-cache "^1.1.17" - apollo-utilities "^1.0.21" - optimism "^0.6.6" - - apollo-cache@1.1.17, apollo-cache@^1.1.17: - version "1.1.17" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.17.tgz#1fcca8423125223723b97fd72808be91a1a76490" - dependencies: - apollo-utilities "^1.0.21" - - apollo-client@^2.3.2, apollo-client@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.2.tgz#d2f044d8740723bf98a6d8d8b9684ee8c36150e6" - dependencies: - "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.17" - apollo-link "^1.0.0" - apollo-link-dedup "^1.0.0" - apollo-utilities "1.0.21" - symbol-observable "^1.0.2" - zen-observable "^0.8.0" - optionalDependencies: - "@types/async" "2.0.49" - - apollo-datasource@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.1.3.tgz#e7ae9d20f29a8a35f239b02f0c47169cfd78d70b" - dependencies: - apollo-server-caching "0.1.2" - apollo-server-env "2.0.3" - - apollo-engine-reporting-protobuf@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz#cd394f0f769c6f97d8621c4a7839095c84efcdb0" - dependencies: - protobufjs "^6.8.6" - - apollo-engine-reporting@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.0.6.tgz#c1a74dffce782525f8a3230e4e5228fbd05bbd59" - dependencies: - apollo-engine-reporting-protobuf "^0.0.1" - apollo-server-env "^2.0.3" - async-retry "^1.2.1" - graphql-extensions "^0.2.1" - lodash "^4.17.10" - - apollo-link-dedup@^1.0.0: - version "1.0.10" - resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.10.tgz#7b94589fe7f969777efd18a129043c78430800ae" - dependencies: - apollo-link "^1.2.3" - - apollo-link-error@^1.0.3: - version "1.1.1" - resolved "https://registry.yarnpkg.com/apollo-link-error/-/apollo-link-error-1.1.1.tgz#69d7124d4dc11ce60f505c940f05d4f1aa0945fb" - dependencies: - apollo-link "^1.2.3" - - apollo-link-http-common@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.5.tgz#d094beb7971523203359bf830bfbfa7b4e7c30ed" - dependencies: - apollo-link "^1.2.3" - - apollo-link-http@^1.3.1, apollo-link-http@^1.5.4: - version "1.5.5" - resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.5.tgz#7dbe851821771ad67fa29e3900c57f38cbd80da8" - dependencies: - apollo-link "^1.2.3" - apollo-link-http-common "^0.2.5" - - apollo-link-state@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/apollo-link-state/-/apollo-link-state-0.4.2.tgz#ac00e9be9b0ca89eae0be6ba31fe904b80bbe2e8" - dependencies: - apollo-utilities "^1.0.8" - graphql-anywhere "^4.1.0-alpha.0" - - apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.2, apollo-link@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.3.tgz#9bd8d5fe1d88d31dc91dae9ecc22474d451fb70d" - dependencies: - apollo-utilities "^1.0.0" - zen-observable-ts "^0.8.10" - - apollo-server-caching@0.1.2, apollo-server-caching@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.1.2.tgz#f5b85701945110a5fca1956450e8553576635936" - dependencies: - lru-cache "^4.1.3" - - apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592" - dependencies: - apollo-cache-control "^0.1.0" - apollo-tracing "^0.1.0" - graphql-extensions "^0.0.x" - - apollo-server-core@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.1.0.tgz#b56f9f1ddb948b257e738eb25c5fdfd2f2fb2e07" - dependencies: - "@apollographql/apollo-upload-server" "^5.0.3" - "@types/ws" "^5.1.2" - apollo-cache-control "^0.2.5" - apollo-datasource "^0.1.3" - apollo-engine-reporting "^0.0.6" - apollo-server-caching "^0.1.2" - apollo-server-env "^2.0.3" - apollo-server-errors "^2.0.2" - apollo-tracing "^0.2.5" - graphql-extensions "^0.2.1" - graphql-subscriptions "^0.5.8" - graphql-tag "^2.9.2" - graphql-tools "^3.0.4" - hash.js "^1.1.3" - lodash "^4.17.10" - subscriptions-transport-ws "^0.9.11" - ws "^5.2.0" - - apollo-server-env@2.0.3, apollo-server-env@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.0.3.tgz#3c13552cd33f400160076cf8e1c9b24be4d27e13" - dependencies: - node-fetch "^2.1.2" - util.promisify "^1.0.0" - - apollo-server-errors@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz#e9cbb1b74d2cd78aed23cd886ca2d0c186323b2b" - - apollo-server-express@^1.3.6: - version "1.4.0" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.4.0.tgz#7d7c58d6d6f9892b83fe575669093bb66738b125" - dependencies: - apollo-server-core "^1.4.0" - apollo-server-module-graphiql "^1.4.0" - - apollo-server-express@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.1.0.tgz#b2d423c2c934df5c4e0a1b0d5f0088a9461f3c86" - dependencies: - "@apollographql/apollo-upload-server" "^5.0.3" - "@apollographql/graphql-playground-html" "^1.6.0" - "@types/accepts" "^1.3.5" - "@types/body-parser" "1.17.0" - "@types/cors" "^2.8.4" - "@types/express" "4.16.0" - accepts "^1.3.5" - apollo-server-core "^2.1.0" - body-parser "^1.18.3" - cors "^2.8.4" - graphql-subscriptions "^0.5.8" - graphql-tools "^3.0.4" - type-is "^1.6.16" - - apollo-server-lambda@1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/apollo-server-lambda/-/apollo-server-lambda-1.3.6.tgz#bdaac37f143c6798e40b8ae75580ba673cea260e" - dependencies: - apollo-server-core "^1.3.6" - apollo-server-module-graphiql "^1.3.4" - - apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" - - apollo-server@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.1.0.tgz#abec7853647c59f386087352cc7f06a4f1f8afe2" - dependencies: - apollo-server-core "^2.1.0" - apollo-server-express "^2.1.0" - express "^4.0.0" - graphql-subscriptions "^0.5.8" - graphql-tools "^3.0.4" - - apollo-tracing@^0.1.0: - version "0.1.4" - resolved "http://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" - dependencies: - graphql-extensions "~0.0.9" - - apollo-tracing@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.2.5.tgz#15bb8d6f37efe8c1bb6351e8e21521dd4f14c5f2" - dependencies: - apollo-server-env "^2.0.3" - graphql-extensions "^0.2.1" - - apollo-upload-server@^5.0.0: - version "5.0.0" - resolved "http://registry.npmjs.org/apollo-upload-server/-/apollo-upload-server-5.0.0.tgz#c953b523608313966e0c8444637f4ae8ef77d5bc" - dependencies: - "@babel/runtime" "^7.0.0-beta.40" - busboy "^0.2.14" - object-path "^0.11.4" - - apollo-utilities@1.0.21, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.21, apollo-utilities@^1.0.8: - version "1.0.21" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.21.tgz#cb8b5779fe275850b16046ff8373f4af2de90765" - dependencies: - fast-json-stable-stringify "^2.0.0" - fclone "^1.0.11" - - aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - - are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - - argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - dependencies: - sprintf-js "~1.0.2" - - arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - - arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - - arr-flatten@^1.0.1, arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - - arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - - array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - - array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - - array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - - assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - - assignment@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.0.0.tgz#ffd17b21bf5d6b22e777b989681a815456a3dd3e" - - assignment@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.2.0.tgz#f5b5bc2d160d69986e8700cd38f567c0aabe101e" - - async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - - async-limiter@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - - async-retry@^1.2.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.2.3.tgz#a6521f338358d322b1a0012b79030c6f411d1ce0" - dependencies: - retry "0.12.0" - - atob@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - - aws-lambda@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/aws-lambda/-/aws-lambda-0.1.2.tgz#19b1585075df31679597b976a5f1def61f12ccee" - dependencies: - aws-sdk "^*" - commander "^2.5.0" - dotenv "^0.4.0" - - aws-sdk@^*: - version "2.336.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.336.0.tgz#b15371aff3e30ba77b74968c086375594be897c9" - dependencies: - buffer "4.9.1" - events "1.1.1" - ieee754 "1.1.8" - jmespath "0.15.0" - querystring "0.2.0" - sax "1.2.1" - url "0.10.3" - uuid "3.1.0" - xml2js "0.4.19" - - babel-cli@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" - dependencies: - babel-core "^6.26.0" - babel-polyfill "^6.26.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - commander "^2.11.0" - convert-source-map "^1.5.0" - fs-readdir-recursive "^1.0.0" - glob "^7.1.2" - lodash "^4.17.4" - output-file-sync "^1.1.2" - path-is-absolute "^1.0.1" - slash "^1.0.0" - source-map "^0.5.6" - v8flags "^2.1.1" - optionalDependencies: - chokidar "^1.6.1" - - babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - - babel-core@^6.26.0: - version "6.26.3" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.1" - debug "^2.6.9" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.8" - slash "^1.0.0" - source-map "^0.5.7" - - babel-generator@^6.26.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" - - babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - - babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - - babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - - babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - - babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - - babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - - babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - - babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - - babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - - babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - - babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - - babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - - babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - dependencies: - babel-runtime "^6.22.0" - - babel-plugin-check-es2015-constants@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - dependencies: - babel-runtime "^6.22.0" - - babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - - babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - - babel-plugin-syntax-trailing-function-commas@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - - babel-plugin-transform-async-to-generator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.22.0" - - babel-plugin-transform-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - dependencies: - babel-runtime "^6.22.0" - - babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - dependencies: - babel-runtime "^6.22.0" - - babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - dependencies: - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - - babel-plugin-transform-es2015-classes@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - - babel-plugin-transform-es2015-computed-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - - babel-plugin-transform-es2015-destructuring@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - dependencies: - babel-runtime "^6.22.0" - - babel-plugin-transform-es2015-duplicate-keys@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - - babel-plugin-transform-es2015-for-of@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - dependencies: - babel-runtime "^6.22.0" - - babel-plugin-transform-es2015-function-name@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - - babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - dependencies: - babel-runtime "^6.22.0" - - babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - - babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.2" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - - babel-plugin-transform-es2015-modules-systemjs@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - - babel-plugin-transform-es2015-modules-umd@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - - babel-plugin-transform-es2015-object-super@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - - babel-plugin-transform-es2015-parameters@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - - babel-plugin-transform-es2015-shorthand-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - - babel-plugin-transform-es2015-spread@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - dependencies: - babel-runtime "^6.22.0" - - babel-plugin-transform-es2015-sticky-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - - babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - dependencies: - babel-runtime "^6.22.0" - - babel-plugin-transform-es2015-typeof-symbol@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - dependencies: - babel-runtime "^6.22.0" - - babel-plugin-transform-es2015-unicode-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - - babel-plugin-transform-exponentiation-operator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.22.0" - - babel-plugin-transform-regenerator@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - dependencies: - regenerator-transform "^0.10.0" - - babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - - babel-polyfill@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" - dependencies: - babel-runtime "^6.26.0" - core-js "^2.5.0" - regenerator-runtime "^0.10.5" - - babel-preset-env@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^3.2.6" - invariant "^2.2.2" - semver "^5.3.0" - - babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - - babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - - babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - - babel-traverse@^6.24.1, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - - babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - - babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - - backo2@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" - - balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - - base64-js@^1.0.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - - base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - - bcryptjs@^2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" - - binary-extensions@^1.0.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" - - body-parser-graphql@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/body-parser-graphql/-/body-parser-graphql-1.1.0.tgz#80a80353c7cb623562fd375750dfe018d75f0f7c" - dependencies: - body-parser "^1.18.2" - - body-parser@1.18.3, body-parser@^1.18.2, body-parser@^1.18.3: - version "1.18.3" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" - dependencies: - bytes "3.0.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "~1.6.3" - iconv-lite "0.4.23" - on-finished "~2.3.0" - qs "6.5.2" - raw-body "2.3.3" - type-is "~1.6.16" - - boxen@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" - dependencies: - ansi-align "^2.0.0" - camelcase "^4.0.0" - chalk "^2.0.1" - cli-boxes "^1.0.0" - string-width "^2.0.0" - term-size "^1.2.0" - widest-line "^2.0.0" - - brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - - braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - - braces@^2.3.0, braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - - browserslist@^3.2.6: - version "3.2.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" - dependencies: - caniuse-lite "^1.0.30000844" - electron-to-chromium "^1.3.47" - - buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - - buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - - buffer@4.9.1: - version "4.9.1" - resolved "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - - busboy@^0.2.14: - version "0.2.14" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" - dependencies: - dicer "0.2.5" - readable-stream "1.1.x" - - bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - - cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - - camelcase@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - - caniuse-lite@^1.0.30000844: - version "1.0.30000892" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000892.tgz#344d2b51ee3ff5977537da4aa449c90eec40b759" - - capture-stack-trace@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" - - chalk@^1.1.3: - version "1.1.3" - resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - - chalk@^2.0.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - - chokidar@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" - dependencies: - anymatch "^1.3.0" - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^2.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - optionalDependencies: - fsevents "^1.0.0" - - chokidar@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" - dependencies: - anymatch "^2.0.0" - async-each "^1.0.0" - braces "^2.3.0" - glob-parent "^3.1.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - lodash.debounce "^4.0.8" - normalize-path "^2.1.1" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - upath "^1.0.5" - optionalDependencies: - fsevents "^1.2.2" - - chownr@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" - - ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - - class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - - cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - - code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - - collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - - color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - dependencies: - color-name "1.1.3" - - color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - - commander@^2.11.0, commander@^2.5.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - - component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - - concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - - configstore@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" - dependencies: - dot-prop "^4.1.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" - - console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - - content-disposition@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" - - content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - - convert-source-map@^1.5.0, convert-source-map@^1.5.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - dependencies: - safe-buffer "~5.1.1" - - cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - - cookie@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - - copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - - core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.3, core-js@^2.5.7: - version "2.5.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" - - core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - - cors@^2.8.4: - version "2.8.4" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.4.tgz#2bd381f2eb201020105cd50ea59da63090694686" - dependencies: - object-assign "^4" - vary "^1" - - create-error-class@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - dependencies: - capture-stack-trace "^1.0.0" - - cross-fetch@2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.2.tgz#a47ff4f7fc712daba8f6a695a11c948440d45723" - dependencies: - node-fetch "2.1.2" - whatwg-fetch "2.0.4" - - cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - - crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - - debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: - ms "2.0.0" - - debug@^3.1.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - dependencies: - ms "^2.1.1" - - decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - - deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - - define-properties@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - dependencies: - object-keys "^1.0.12" - - define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - dependencies: - is-descriptor "^0.1.0" - - define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - dependencies: - is-descriptor "^1.0.0" - - define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - - delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - - depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - - deprecated-decorator@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" - - destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - - detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" - - detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - - dicer@0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" - dependencies: - readable-stream "1.1.x" - streamsearch "0.1.2" - - dot-prop@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" - dependencies: - is-obj "^1.0.0" - - dotenv@^0.4.0: - version "0.4.0" - resolved "http://registry.npmjs.org/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" - - dotenv@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.1.0.tgz#9853b6ca98292acb7dec67a95018fa40bccff42c" - - duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - - duplexer@^0.1.1, duplexer@~0.1.1: - version "0.1.1" - resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - - ecdsa-sig-formatter@1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz#1c595000f04a8897dfb85000892a0f4c33af86c3" - dependencies: - safe-buffer "^5.0.1" - - ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - - electron-to-chromium@^1.3.47: - version "1.3.79" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.79.tgz#774718f06284a4bf8f578ac67e74508fe659f13a" - - encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - - es-abstract@^1.5.1: - version "1.12.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" - dependencies: - es-to-primitive "^1.1.1" - function-bind "^1.1.1" - has "^1.0.1" - is-callable "^1.1.3" - is-regex "^1.0.4" - - es-to-primitive@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - - escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - - escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - - esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - - esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - - etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - - event-stream@~3.3.0: - version "3.3.6" - resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.6.tgz#cac1230890e07e73ec9cacd038f60a5b66173eef" - dependencies: - duplexer "^0.1.1" - flatmap-stream "^0.1.0" - from "^0.1.7" - map-stream "0.0.7" - pause-stream "^0.0.11" - split "^1.0.1" - stream-combiner "^0.2.2" - through "^2.3.8" - - eventemitter3@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" - - events@1.1.1: - version "1.1.1" - resolved "http://registry.npmjs.org/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - - execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - - expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - dependencies: - is-posix-bracket "^0.1.0" - - expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - - expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - - express@^4.0.0, express@^4.16.3: - version "4.16.4" - resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" - dependencies: - accepts "~1.3.5" - array-flatten "1.1.1" - body-parser "1.18.3" - content-disposition "0.5.2" - content-type "~1.0.4" - cookie "0.3.1" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.1.1" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.2" - path-to-regexp "0.1.7" - proxy-addr "~2.0.4" - qs "6.5.2" - range-parser "~1.2.0" - safe-buffer "5.1.2" - send "0.16.2" - serve-static "1.13.2" - setprototypeof "1.1.0" - statuses "~1.4.0" - type-is "~1.6.16" - utils-merge "1.0.1" - vary "~1.1.2" - - extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - dependencies: - is-extendable "^0.1.0" - - extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - - extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - - extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - - faker@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" - - fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - - fclone@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640" - - filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - - fill-range@^2.1.0: - version "2.2.4" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^3.0.0" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - - fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - - finalhandler@1.1.1: - version "1.1.1" - resolved "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.2" - statuses "~1.4.0" - unpipe "~1.0.0" - - flatmap-stream@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.1.tgz#d34f39ef3b9aa5a2fc225016bd3adf28ac5ae6ea" - - for-in@^1.0.1, for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - - for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - dependencies: - for-in "^1.0.1" - - forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - - fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - dependencies: - map-cache "^0.2.2" - - fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - - from@^0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" - - fs-minipass@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - dependencies: - minipass "^2.2.1" - - fs-readdir-recursive@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" - - fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - - fsevents@^1.0.0, fsevents@^1.2.2: - version "1.2.4" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" - - function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - - gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - - get-stream@^3.0.0: - version "3.0.0" - resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - - get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - - glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - - glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" - - glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - - glob@^7.0.5, glob@^7.1.2: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - - global-dirs@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" - dependencies: - ini "^1.3.4" - - globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - - got@^6.7.1: - version "6.7.1" - resolved "http://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" - dependencies: - create-error-class "^3.0.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-redirect "^1.0.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - lowercase-keys "^1.0.0" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - unzip-response "^2.0.1" - url-parse-lax "^1.0.0" - - graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - - graphql-anywhere@^4.1.0-alpha.0: - version "4.1.19" - resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.19.tgz#5f6ca3b58218e5449f4798e3c6d942fcd2fef082" - dependencies: - apollo-utilities "^1.0.21" - - graphql-config@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-2.2.1.tgz#5fd0ec77ac7428ca5fb2026cf131be10151a0cb2" - dependencies: - graphql-import "^0.7.1" - graphql-request "^1.5.0" - js-yaml "^3.10.0" - lodash "^4.17.4" - minimatch "^3.0.4" - - graphql-custom-directives@^0.2.13: - version "0.2.13" - resolved "https://registry.yarnpkg.com/graphql-custom-directives/-/graphql-custom-directives-0.2.13.tgz#5e175069f5ff404f751d232e302007bc25488ea8" - dependencies: - lodash "^4.17.5" - moment "^2.22.2" - numeral "^2.0.6" - - graphql-deduplicator@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.1.tgz#20c6b39e3a6f096b46dfc8491432818739c0ee37" - - graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: - version "0.0.10" - resolved "http://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" - dependencies: - core-js "^2.5.3" - source-map-support "^0.5.1" - - graphql-extensions@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.2.1.tgz#7697e0fcea2e622afe9e24dd31fc84f533e84c70" - dependencies: - apollo-server-env "^2.0.3" - - graphql-import@^0.7.0, graphql-import@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.7.1.tgz#4add8d91a5f752d764b0a4a7a461fcd93136f223" - dependencies: - lodash "^4.17.4" - resolve-from "^4.0.0" - - graphql-middleware@1.7.7: - version "1.7.7" - resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.7.tgz#0a7a7193a873c4769401df2aef4ffb9c6ca97f43" - dependencies: - graphql-tools "^4.0.1" - - graphql-middleware@^1.7.8: - version "1.7.8" - resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.8.tgz#617940d3cd462e9553e582d2b6ce86cb0e95a3dd" - dependencies: - graphql-tools "^4.0.2" - - graphql-playground-html@1.6.4: - version "1.6.4" - resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.4.tgz#be7c5a6213d67aeedf03d90b7e7d55fec4d42212" - dependencies: - graphql-config "2.2.1" - - graphql-playground-middleware-express@1.7.6: - version "1.7.6" - resolved "https://registry.yarnpkg.com/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.6.tgz#aca38d2b8e5147914fc8fa613d151edd4ed0bc44" - dependencies: - graphql-playground-html "1.6.4" - - graphql-playground-middleware-lambda@1.7.6: - version "1.7.6" - resolved "https://registry.yarnpkg.com/graphql-playground-middleware-lambda/-/graphql-playground-middleware-lambda-1.7.6.tgz#03aa4e3592144f4eb390a216f09b39f6b29f12d2" - dependencies: - graphql-playground-html "1.6.4" - - graphql-request@^1.5.0: - version "1.8.2" - resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" - dependencies: - cross-fetch "2.2.2" - - graphql-subscriptions@^0.5.8: - version "0.5.8" - resolved "http://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7" - dependencies: - iterall "^1.2.1" - - graphql-tag@^2.4.2, graphql-tag@^2.9.2: - version "2.10.0" - resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" - - graphql-tools@^3.0.4: - version "3.1.1" - resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-3.1.1.tgz#d593358f01e7c8b1671a17b70ddb034dea9dbc50" - dependencies: - apollo-link "^1.2.2" - apollo-utilities "^1.0.1" - deprecated-decorator "^0.1.6" - iterall "^1.1.3" - uuid "^3.1.0" - - graphql-tools@^4.0.0, graphql-tools@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.2.tgz#9da22974cc6bf6524ed4f4af35556fd15aa6516d" - dependencies: - apollo-link "^1.2.3" - apollo-utilities "^1.0.1" - deprecated-decorator "^0.1.6" - iterall "^1.1.3" - uuid "^3.1.0" - - graphql-tools@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.1.tgz#c995a4e25c2967d108c975e508322d12969c8c0e" - dependencies: - apollo-link "^1.2.3" - apollo-utilities "^1.0.1" - deprecated-decorator "^0.1.6" - iterall "^1.1.3" - uuid "^3.1.0" - - graphql-yoga@^1.16.6: - version "1.16.6" - resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.16.6.tgz#fc0e75e0214b76afc57e0e7872479a65ff464412" - dependencies: - "@types/cors" "^2.8.4" - "@types/express" "^4.11.1" - "@types/graphql" "^14.0.0" - "@types/graphql-deduplicator" "^2.0.0" - "@types/zen-observable" "^0.5.3" - apollo-server-express "^1.3.6" - apollo-server-lambda "1.3.6" - apollo-upload-server "^5.0.0" - aws-lambda "^0.1.2" - body-parser-graphql "1.1.0" - cors "^2.8.4" - express "^4.16.3" - graphql "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0" - graphql-deduplicator "^2.0.1" - graphql-import "^0.7.0" - graphql-middleware "1.7.7" - graphql-playground-middleware-express "1.7.6" - graphql-playground-middleware-lambda "1.7.6" - graphql-subscriptions "^0.5.8" - graphql-tools "^4.0.0" - subscriptions-transport-ws "^0.9.8" - - "graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0": - version "14.0.2" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.0.2.tgz#7dded337a4c3fd2d075692323384034b357f5650" - dependencies: - iterall "^1.2.2" - - graphql@^0.13.2: - version "0.13.2" - resolved "http://registry.npmjs.org/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" - dependencies: - iterall "^1.2.1" - - has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - - has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - - has-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - - has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - - has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - - has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - - has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - - has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - - has@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - dependencies: - function-bind "^1.1.1" - - hash.js@^1.1.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - - he@0.5.0: - version "0.5.0" - resolved "http://registry.npmjs.org/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" - - home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - - http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: - version "1.6.3" - resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - - iconv-lite@0.4.23: - version "0.4.23" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" - dependencies: - safer-buffer ">= 2.1.2 < 3" - - iconv-lite@^0.4.4: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - dependencies: - safer-buffer ">= 2.1.2 < 3" - - ieee754@1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" - - ieee754@^1.1.4: - version "1.1.12" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" - - ignore-by-default@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" - - ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - dependencies: - minimatch "^3.0.4" - - immutable-tuple@^0.4.4: - version "0.4.8" - resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.8.tgz#f60b65b863d34be39d307d1bbf4a450e1ac3048a" - - import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - - imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - - inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - - inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - - ini@^1.3.4, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - - insane@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/insane/-/insane-2.6.1.tgz#c7dcae7b51c20346883b71078fad6ce0483c198f" - dependencies: - assignment "2.0.0" - he "0.5.0" - - invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - dependencies: - loose-envify "^1.0.0" - - ipaddr.js@1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" - - is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - dependencies: - kind-of "^3.0.2" - - is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - dependencies: - kind-of "^6.0.0" - - is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - dependencies: - binary-extensions "^1.0.0" - - is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - - is-callable@^1.1.3, is-callable@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - - is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - dependencies: - ci-info "^1.5.0" - - is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - dependencies: - kind-of "^3.0.2" - - is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - dependencies: - kind-of "^6.0.0" - - is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - - is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - - is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - - is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - - is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - - is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - - is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - dependencies: - is-plain-object "^2.0.4" - - is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - - is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - - is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - - is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - - is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - - is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" - - is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - dependencies: - is-extglob "^2.1.0" - - is-glob@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" - dependencies: - is-extglob "^2.1.1" - - is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" - - is-npm@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - - is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" - - is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - dependencies: - kind-of "^3.0.2" - - is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - - is-obj@^1.0.0: - version "1.0.1" - resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - - is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - dependencies: - path-is-inside "^1.0.1" - - is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - dependencies: - isobject "^3.0.1" - - is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - - is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - - is-redirect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - - is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - dependencies: - has "^1.0.1" - - is-retry-allowed@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" - - is-stream@^1.0.0, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - - is-symbol@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - dependencies: - has-symbols "^1.0.0" - - is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - - isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - - isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - - isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - - isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - - isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - - iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" - - jmespath@0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" - - "js-tokens@^3.0.0 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - - js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - - js-yaml@^3.10.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - - jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - - jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - - json5@^0.5.1: - version "0.5.1" - resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - - jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz#056c90eee9a65ed6e6c72ddb0a1d325109aaf643" - dependencies: - jws "^3.1.5" - lodash.includes "^4.3.0" - lodash.isboolean "^3.0.3" - lodash.isinteger "^4.0.4" - lodash.isnumber "^3.0.3" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.once "^4.0.0" - ms "^2.1.1" - - jwa@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.6.tgz#87240e76c9808dbde18783cf2264ef4929ee50e6" - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.10" - safe-buffer "^5.0.1" - - jws@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.5.tgz#80d12d05b293d1e841e7cb8b4e69e561adcf834f" - dependencies: - jwa "^1.1.5" - safe-buffer "^5.0.1" - - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - dependencies: - is-buffer "^1.1.5" - - kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - dependencies: - is-buffer "^1.1.5" - - kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - - kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - - latest-version@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" - dependencies: - package-json "^4.0.0" - - lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - - lodash.includes@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" - - lodash.isboolean@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - - lodash.isinteger@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - - lodash.isnumber@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - - lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - - lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - - lodash.once@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - - lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5: - version "4.17.11" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" - - long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - - loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - - lowercase-keys@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - - lru-cache@^4.0.1, lru-cache@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - - make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - dependencies: - pify "^3.0.0" - - map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - - map-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" - - map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - dependencies: - object-visit "^1.0.0" - - math-random@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" - - media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - - merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - - methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - - micromatch@^2.1.5: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - - micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - - mime-db@~1.36.0: - version "1.36.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" - - mime-types@~2.1.18: - version "2.1.20" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" - dependencies: - mime-db "~1.36.0" - - mime@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" - - minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - - minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - dependencies: - brace-expansion "^1.1.7" - - minimist@0.0.8: - version "0.0.8" - resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - - minimist@^1.2.0: - version "1.2.0" - resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - - minipass@^2.2.1, minipass@^2.3.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - - minizlib@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" - dependencies: - minipass "^2.2.1" - - mixin-deep@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - - mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - - moment@^2.22.2: - version "2.22.2" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" - - ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - - ms@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - - nan@^2.9.2: - version "2.11.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" - - nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - - needle@^2.2.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" - dependencies: - debug "^2.1.2" - iconv-lite "^0.4.4" - sax "^1.2.4" - - negotiator@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" - - neo4j-driver@^1.6.1: - version "1.6.3" - resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.6.3.tgz#b7a51bac401bd341082dff7766e8643d61752eb7" - dependencies: - babel-runtime "^6.18.0" - uri-js "^4.2.1" - - neo4j-graphql-js@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.2.tgz#e4dd66b85e817347efb13beaa8340f8eda9df24f" - dependencies: - graphql "^0.13.2" - lodash "^4.17.10" - neo4j-driver "^1.6.1" - - node-fetch@2.1.2: - version "2.1.2" - resolved "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" - - node-fetch@^2.1.2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5" - - node-pre-gyp@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - - nodemon@^1.18.4: - version "1.18.4" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.4.tgz#873f65fdb53220eb166180cf106b1354ac5d714d" - dependencies: - chokidar "^2.0.2" - debug "^3.1.0" - ignore-by-default "^1.0.1" - minimatch "^3.0.4" - pstree.remy "^1.1.0" - semver "^5.5.0" - supports-color "^5.2.0" - touch "^3.1.0" - undefsafe "^2.0.2" - update-notifier "^2.3.0" - - nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - dependencies: - abbrev "1" - osenv "^0.1.4" - - nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - dependencies: - abbrev "1" - - normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - dependencies: - remove-trailing-separator "^1.0.1" - - npm-bundled@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" - - npm-packlist@^1.1.6: - version "1.1.12" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - - 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" - dependencies: - path-key "^2.0.0" - - npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - - number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - - numeral@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" - - object-assign@^4, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - - object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - - object-keys@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" - - object-path@^0.11.4: - version "0.11.4" - resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" - - object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - dependencies: - isobject "^3.0.0" - - object.getownpropertydescriptors@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.1" - - object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - - object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - dependencies: - isobject "^3.0.1" - - on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - dependencies: - ee-first "1.1.1" - - once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - - optimism@^0.6.6: - version "0.6.6" - resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.6.tgz#5415b2d6a2f8b3745aedb9f97fdf4e52467ecd84" - dependencies: - immutable-tuple "^0.4.4" - - os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - - os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - - osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - - output-file-sync@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" - dependencies: - graceful-fs "^4.1.4" - mkdirp "^0.5.1" - object-assign "^4.1.0" - - p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - - package-json@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - dependencies: - got "^6.7.1" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" - - parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - - parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - - pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - - passport-jwt@^4.0.0: - version "4.0.0" - resolved "http://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" - dependencies: - jsonwebtoken "^8.2.0" - passport-strategy "^1.0.0" - - passport-strategy@1.x.x, passport-strategy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" - - passport@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" - dependencies: - passport-strategy "1.x.x" - pause "0.0.1" - - path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - - path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - - path-is-inside@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - - path-key@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - - path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - - pause-stream@^0.0.11: - version "0.0.11" - resolved "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" - dependencies: - through "~2.3" - - pause@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" - - pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - - posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - - prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - - preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - - private@^0.1.6, private@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - - process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - - protobufjs@^6.8.6: - version "6.8.8" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.0" - "@types/node" "^10.1.0" - long "^4.0.0" - - proxy-addr@~2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.8.0" - - ps-tree@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" - dependencies: - event-stream "~3.3.0" - - pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - - pstree.remy@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.0.tgz#f2af27265bd3e5b32bbfcc10e80bac55ba78688b" - dependencies: - ps-tree "^1.1.0" - - punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - - punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - - qs@6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - - querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - - randomatic@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.0.tgz#36f2ca708e9e567f5ed2ec01949026d50aa10116" - dependencies: - is-number "^4.0.0" - kind-of "^6.0.0" - math-random "^1.0.1" - - range-parser@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" - - raw-body@2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" - dependencies: - bytes "3.0.0" - http-errors "1.6.3" - iconv-lite "0.4.23" - unpipe "1.0.0" - - rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - - readable-stream@1.1.x: - version "1.1.14" - resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - - readable-stream@^2.0.2, readable-stream@^2.0.6: - version "2.3.6" - resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - - readdirp@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - - regenerate@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - - regenerator-runtime@^0.10.5: - version "0.10.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" - - regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - - regenerator-runtime@^0.12.0: - version "0.12.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" - - regenerator-transform@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - - regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - dependencies: - is-equal-shallow "^0.1.3" - - regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - - regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - - registry-auth-token@^3.0.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" - dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" - - registry-url@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - dependencies: - rc "^1.0.1" - - regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - - regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - dependencies: - jsesc "~0.5.0" - - remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - - repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - - repeat-string@^1.5.2, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - - repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - - resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - - resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - - ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - - retry@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - - rimraf@^2.6.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - dependencies: - glob "^7.0.5" - - safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - - safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - dependencies: - ret "~0.1.10" - - "safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - - sax@1.2.1: - version "1.2.1" - resolved "http://registry.npmjs.org/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" - - sax@>=0.6.0, sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - - semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" - dependencies: - semver "^5.0.3" - - semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - - send@0.16.2: - version "0.16.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.6.2" - mime "1.4.1" - ms "2.0.0" - on-finished "~2.3.0" - range-parser "~1.2.0" - statuses "~1.4.0" - - serve-static@1.13.2: - version "1.13.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.2" - send "0.16.2" - - set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - - set-value@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.1" - to-object-path "^0.3.0" - - set-value@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - - setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - - shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - dependencies: - shebang-regex "^1.0.0" - - shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - - signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - - slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - - slug@^0.9.1: - version "0.9.1" - resolved "http://registry.npmjs.org/slug/-/slug-0.9.1.tgz#af08f608a7c11516b61778aa800dce84c518cfda" - dependencies: - unicode ">= 0.3.1" - - snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - - snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - dependencies: - kind-of "^3.2.0" - - snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - - source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - dependencies: - atob "^2.1.1" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - - source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - dependencies: - source-map "^0.5.6" - - source-map-support@^0.5.1: - version "0.5.9" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - - source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - - source-map@^0.5.6, source-map@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - - source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - - split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - dependencies: - extend-shallow "^3.0.0" - - split@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - dependencies: - through "2" - - sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - - static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - - "statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - - statuses@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - - stream-combiner@^0.2.2: - version "0.2.2" - resolved "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" - dependencies: - duplexer "~0.1.1" - through "~2.3.4" - - streamsearch@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" - - string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - - "string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - - string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - - string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - dependencies: - safe-buffer "~5.1.0" - - strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - - strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - dependencies: - ansi-regex "^3.0.0" - - strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - - strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - - subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: - version "0.9.15" - resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz#68a8b7ba0037d8c489fb2f5a102d1494db297d0d" - dependencies: - backo2 "^1.0.2" - eventemitter3 "^3.1.0" - iterall "^1.2.1" - symbol-observable "^1.0.4" - ws "^5.2.0" - - supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - - supports-color@^5.2.0, supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - dependencies: - has-flag "^3.0.0" - - symbol-observable@^1.0.2, symbol-observable@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" - - tar@^4: - version "4.4.6" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" - dependencies: - chownr "^1.0.1" - fs-minipass "^1.2.5" - minipass "^2.3.3" - minizlib "^1.1.0" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.2" - - term-size@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" - dependencies: - execa "^0.7.0" - - through@2, through@^2.3.8, through@~2.3, through@~2.3.4: - version "2.3.8" - resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - - timed-out@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - - to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - - to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - dependencies: - kind-of "^3.0.2" - - 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" - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - - to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - - touch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - dependencies: - nopt "~1.0.10" - - trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - - trunc-html@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/trunc-html/-/trunc-html-1.1.2.tgz#1e97d51f67d470b67662b1a670e6d0ea7a8edafe" - dependencies: - assignment "2.2.0" - insane "2.6.1" - trunc-text "1.0.1" - - trunc-text@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" - - type-is@^1.6.16, type-is@~1.6.16: - version "1.6.16" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" - dependencies: - media-typer "0.3.0" - mime-types "~2.1.18" - - undefsafe@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76" - dependencies: - debug "^2.2.0" - - "unicode@>= 0.3.1": - version "11.0.1" - resolved "https://registry.yarnpkg.com/unicode/-/unicode-11.0.1.tgz#735bd422ec75cf28d396eb224d535d168d5f1db6" - - union-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^0.4.3" - - unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - dependencies: - crypto-random-string "^1.0.0" - - unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - - unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - - unzip-response@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - - upath@^1.0.5: - version "1.1.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" - - update-notifier@^2.3.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" - dependencies: - boxen "^1.2.1" - chalk "^2.0.1" - configstore "^3.0.0" - import-lazy "^2.1.0" - is-ci "^1.0.10" - is-installed-globally "^0.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" - - uri-js@^4.2.1: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - dependencies: - punycode "^2.1.0" - - urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - - url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - dependencies: - prepend-http "^1.0.1" - - url@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" - dependencies: - punycode "1.3.2" - querystring "0.2.0" - - use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - - user-home@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" - - util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - - util.promisify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - - utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - - uuid@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - - uuid@^3.1.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - - v8flags@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" - dependencies: - user-home "^1.1.1" - - vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - - whatwg-fetch@2.0.4: - version "2.0.4" - resolved "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" - - which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - dependencies: - isexe "^2.0.0" - - wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - dependencies: - string-width "^1.0.2 || 2" - - widest-line@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" - dependencies: - string-width "^2.1.1" - - wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - - write-file-atomic@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - - ws@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - dependencies: - async-limiter "~1.0.0" - - xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - - xml2js@0.4.19: - version "0.4.19" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" - dependencies: - sax ">=0.6.0" - xmlbuilder "~9.0.1" - - xmlbuilder@~9.0.1: - version "9.0.7" - resolved "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - - yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - - yallist@^3.0.0, yallist@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" - - zen-observable-ts@^0.8.10: - version "0.8.10" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz#18e2ce1c89fe026e9621fd83cc05168228fce829" - dependencies: - zen-observable "^0.8.0" - - zen-observable@^0.8.0: - version "0.8.9" - resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.9.tgz#0475c760ff0eda046bbdfa4dc3f95d392807ac53" From 936626af81c467e999317bb7de9878fffcbfef3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 20 Nov 2018 23:47:17 +0100 Subject: [PATCH 074/554] Update meta data in package.json --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2e7d88f77..da645abb2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "hc-prototype-api-", + "name": "human-connection-backend", "version": "0.0.1", - "description": "Graph API Protype for Human Connection", + "description": "GraphQL Backend for Human Connection", "main": "src/index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -9,7 +9,7 @@ "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "seedDb": "./node_modules/.bin/babel-node src/seed/seed-db.js" }, - "author": "Grzegorz Leoniec", + "author": "Human Connection gGmbh", "license": "MIT", "dependencies": { "apollo-boost": "^0.1.10", From 0eab41b5ef5bac69a8b7e3444f0f2cc123e40b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 20 Nov 2018 23:52:30 +0100 Subject: [PATCH 075/554] Use @babel packages --- .babelrc | 2 +- package.json | 7 +- yarn.lock | 2776 +++++++++++++++++++++++++++++++------------------- 3 files changed, 1750 insertions(+), 1035 deletions(-) diff --git a/.babelrc b/.babelrc index 684fff677..b7191e76e 100644 --- a/.babelrc +++ b/.babelrc @@ -1 +1 @@ -{ "presets": ["env"] } +{ "presets": ["@babel/preset-env"] } diff --git a/package.json b/package.json index da645abb2..43a3d1184 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,11 @@ "author": "Human Connection gGmbh", "license": "MIT", "dependencies": { + "@babel/cli": "^7.1.5", + "@babel/core": "^7.1.6", + "@babel/node": "^7.0.0", + "@babel/preset-env": "^7.1.6", + "@babel/register": "^7.0.0", "apollo-boost": "^0.1.10", "apollo-cache-inmemory": "^1.2.5", "apollo-client": "^2.3.2", @@ -41,8 +46,6 @@ "trunc-html": "^1.1.2" }, "devDependencies": { - "babel-cli": "^6.26.0", - "babel-preset-env": "^1.7.0", "faker": "^4.1.0", "nodemon": "^1.18.4" } diff --git a/yarn.lock b/yarn.lock index c17a0c3c4..62cdf11a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,50 +2,698 @@ # yarn lockfile v1 +"@apollographql/apollo-tools@^0.2.6": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.2.7.tgz#550502b315e49040e07d7e5065d15c5116c506e6" + integrity sha512-rsn4uN12gZWME+m9CLnUk+ImY+blKdWFFdS6TlQheXC7XA85twjQmOY0/n05qUtrxx1dM5QUXw1qLCZ4emWYbQ== + dependencies: + apollo-env "0.2.4" + "@apollographql/apollo-upload-server@^5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" + integrity sha512-tGAp3ULNyoA8b5o9LsU2Lq6SwgVPUOKAqKywu2liEtTvrFSGPrObwanhYwArq3GPeOqp2bi+JknSJCIU3oQN1Q== dependencies: "@babel/runtime-corejs2" "^7.0.0-rc.1" busboy "^0.2.14" object-path "^0.11.4" -"@apollographql/graphql-playground-html@^1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz#15e1a042b97d6834e6d70b17cc73e1514fde9027" +"@apollographql/graphql-playground-html@^1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.4.tgz#8945edf73df846d50e027bb3b813d018a1c5925f" + integrity sha512-gwvaQO6/Hv4DEwhDLmmu2tzCU9oPjC5Xl9Kk8Yd0IxyKhYLlLalmkMMjsZLzU5H3fGaalLD96OYfxHL0ClVUDQ== + +"@babel/cli@^7.1.5": + version "7.1.5" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.1.5.tgz#4ccf0a8cdabeefdd8ce955384530f050935bc4d7" + integrity sha512-zbO/DtTnaDappBflIU3zYEgATLToRDmW5uN/EGH1GXaes7ydfjqmAoK++xmJIA+8HfDw7UyPZNdM8fhGhfmMhw== + dependencies: + commander "^2.8.1" + convert-source-map "^1.1.0" + fs-readdir-recursive "^1.1.0" + glob "^7.0.0" + lodash "^4.17.10" + mkdirp "^0.5.1" + output-file-sync "^2.0.0" + slash "^2.0.0" + source-map "^0.5.0" + optionalDependencies: + chokidar "^2.0.3" + +"@babel/code-frame@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/core@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.6.tgz#3733cbee4317429bc87c62b29cf8587dba7baeb3" + integrity sha512-Hz6PJT6e44iUNpAn8AoyAs6B3bl60g7MJQaI0rZEar6ECzh6+srYO1xlIdssio34mPaUtAb1y+XlkkSJzok3yw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.1.6" + "@babel/helpers" "^7.1.5" + "@babel/parser" "^7.1.6" + "@babel/template" "^7.1.2" + "@babel/traverse" "^7.1.6" + "@babel/types" "^7.1.6" + convert-source-map "^1.1.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.10" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.6.tgz#001303cf87a5b9d093494a4bf251d7b5d03d3999" + integrity sha512-brwPBtVvdYdGxtenbQgfCdDPmtkmUBZPjUoK5SXJEBuHaA5BCubh9ly65fzXz7R6o5rA76Rs22ES8Z+HCc0YIQ== + dependencies: + "@babel/types" "^7.1.6" + jsesc "^2.5.1" + lodash "^4.17.10" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-annotate-as-pure@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" + integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" + integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-call-delegate@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz#6a957f105f37755e8645343d3038a22e1449cc4a" + integrity sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ== + dependencies: + "@babel/helper-hoist-variables" "^7.0.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-define-map@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c" + integrity sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/types" "^7.0.0" + lodash "^4.17.10" + +"@babel/helper-explode-assignable-expression@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" + integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== + dependencies: + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" + integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-hoist-variables@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz#46adc4c5e758645ae7a45deb92bab0918c23bb88" + integrity sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-member-expression-to-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" + integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-imports@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" + integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-transforms@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.1.0.tgz#470d4f9676d9fad50b324cdcce5fbabbc3da5787" + integrity sha512-0JZRd2yhawo79Rcm4w0LwSMILFmFXjugG3yqf+P/UsKsRS1mJCmMwwlHDlMg7Avr9LrvSpp4ZSULO9r8jpCzcw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + lodash "^4.17.10" + +"@babel/helper-optimise-call-expression@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" + integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-plugin-utils@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" + integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== + +"@babel/helper-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27" + integrity sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg== + dependencies: + lodash "^4.17.10" + +"@babel/helper-remap-async-to-generator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" + integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-wrap-function" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-replace-supers@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz#5fc31de522ec0ef0899dc9b3e7cf6a5dd655f362" + integrity sha512-BvcDWYZRWVuDeXTYZWxekQNO5D4kO55aArwZOTFXw6rlLQA8ZaDicJR1sO47h+HrnCiDFiww0fSPV0d713KBGQ== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-simple-access@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" + integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== + dependencies: + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-split-export-declaration@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" + integrity sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-wrap-function@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.1.0.tgz#8cf54e9190706067f016af8f75cb3df829cc8c66" + integrity sha512-R6HU3dete+rwsdAfrOzTlE9Mcpk4RjU3aX3gi9grtmugQY0u79X7eogUvfXA5sI81Mfq1cn6AgxihfN33STjJA== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helpers@^7.1.5": + version "7.1.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.1.5.tgz#68bfc1895d685f2b8f1995e788dbfe1f6ccb1996" + integrity sha512-2jkcdL02ywNBry1YNFAH/fViq4fXG0vdckHqeJk+75fpQ2OH+Az6076tX/M0835zA45E0Cqa6pV5Kiv9YOqjEg== + dependencies: + "@babel/template" "^7.1.2" + "@babel/traverse" "^7.1.5" + "@babel/types" "^7.1.5" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/node@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.0.0.tgz#20e55bb0e015700a0f6ff281c712de7619ad56f4" + integrity sha512-mKbN8Bb1TzH9YnKMWMhBRX+o5MVJHtUSalNcsiGa4FRgVfY7ozqkbttuIDWqeXxZ3rwI9ZqmCUr9XsPV2VYlSw== + dependencies: + "@babel/polyfill" "^7.0.0" + "@babel/register" "^7.0.0" + commander "^2.8.1" + fs-readdir-recursive "^1.0.0" + lodash "^4.17.10" + output-file-sync "^2.0.0" + v8flags "^3.1.1" + +"@babel/parser@^7.1.2", "@babel/parser@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.6.tgz#16e97aca1ec1062324a01c5a6a7d0df8dd189854" + integrity sha512-dWP6LJm9nKT6ALaa+bnL247GHHMWir3vSlZ2+IHgHgktZQx0L3Uvq2uAWcuzIe+fujRsYWBW2q622C5UvGK9iQ== + +"@babel/plugin-proposal-async-generator-functions@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce" + integrity sha512-Fq803F3Jcxo20MXUSDdmZZXrPe6BWyGcWBPPNB/M7WaUYESKDeKMOGIxEzQOjGSmW/NWb6UaPZrtTB2ekhB/ew== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/plugin-syntax-async-generators" "^7.0.0" + +"@babel/plugin-proposal-json-strings@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz#3b4d7b5cf51e1f2e70f52351d28d44fc2970d01e" + integrity sha512-kfVdUkIAGJIVmHmtS/40i/fg/AGnw/rsZBCaapY5yjeO5RA9m165Xbw9KMOu2nqXP5dTFjEjHdfNdoVcHv133Q== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.0.0" + +"@babel/plugin-proposal-object-rest-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e" + integrity sha512-14fhfoPcNu7itSen7Py1iGN0gEm87hX/B+8nZPqkdmANyyYWYMY2pjA3r8WXbWVKMzfnSNS0xY8GVS0IjXi/iw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425" + integrity sha512-JPqAvLG1s13B/AuoBjdBYvn38RqW6n1TzrQO839/sIpqLpbnXKacsAgpZHzLD83Sm8SDXMkkrAvEnJ25+0yIpw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz#498b39cd72536cd7c4b26177d030226eba08cd33" + integrity sha512-tM3icA6GhC3ch2SkmSxv7J/hCWKISzwycub6eGsDrFDgukD4dZ/I+x81XgW0YslS6mzNuQ1Cbzh5osjIMgepPQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.2.0" + +"@babel/plugin-syntax-async-generators@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz#bf0891dcdbf59558359d0c626fdc9490e20bc13c" + integrity sha512-im7ged00ddGKAjcZgewXmp1vxSZQQywuQXe2B1A7kajjZmDeY/ekMPmWr9zJgveSaQH0k7BcGrojQhcK06l0zA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-json-strings@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz#0d259a68090e15b383ce3710e01d5b23f3770cbd" + integrity sha512-UlSfNydC+XLj4bw7ijpldc1uZ/HB84vw+U6BTuqMdIEmz/LDe63w/GHtpQMdXWdqQZFeAI9PjnHe/vDhwirhKA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-object-rest-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b" + integrity sha512-5A0n4p6bIiVe5OvQPxBnesezsgFJdHhSs3uFSvaPdMqtsovajLZ+G2vZyvNe10EzJBWWo3AcHGKhAFUxqwp2dw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475" + integrity sha512-Wc+HVvwjcq5qBg1w5RG9o9RVzmCaAg/Vp0erHCKpAYV8La6I94o4GQAmFYNmkzoMO6gzoOSulpKeSSz6mPEoZw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-arrow-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749" + integrity sha512-2EZDBl1WIO/q4DIkIp4s86sdp4ZifL51MoIviLY/gG/mLSuOIEg7J8o6mhbxOTvUJkaN50n+8u41FVsr5KLy/w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-async-to-generator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811" + integrity sha512-rNmcmoQ78IrvNCIt/R9U+cixUHeYAzgusTFgIAv+wQb9HJU4szhpDD6e5GCACmj/JP5KxuCwM96bX3L9v4ZN/g== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + +"@babel/plugin-transform-block-scoped-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz#482b3f75103927e37288b3b67b65f848e2aa0d07" + integrity sha512-AOBiyUp7vYTqz2Jibe1UaAWL0Hl9JUXEgjFvvvcSc9MVDItv46ViXFw2F7SVt1B5k+KWjl44eeXOAk3UDEaJjQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-block-scoping@^7.1.5": + version "7.1.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.1.5.tgz#3e8e0bc9a5104519923302a24f748f72f2f61f37" + integrity sha512-jlYcDrz+5ayWC7mxgpn1Wj8zj0mmjCT2w0mPIMSwO926eXBRxpEgoN/uQVRBfjtr8ayjcmS+xk2G1jaP8JjMJQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + lodash "^4.17.10" + +"@babel/plugin-transform-classes@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249" + integrity sha512-rNaqoD+4OCBZjM7VaskladgqnZ1LO6o2UxuWSDzljzW21pN1KXkB7BstAVweZdxQkHAujps5QMNOTWesBciKFg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-define-map" "^7.1.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31" + integrity sha512-ubouZdChNAv4AAWAgU7QKbB93NU5sHwInEWfp+/OzJKA02E6Woh9RVoX4sZrbRwtybky/d7baTUqwFx+HgbvMA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-destructuring@^7.0.0": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.1.3.tgz#e69ff50ca01fac6cb72863c544e516c2b193012f" + integrity sha512-Mb9M4DGIOspH1ExHOUnn2UUXFOyVTiX84fXCd+6B5iWrQg/QMeeRmSwpZ9lnjYLSXtZwiw80ytVMr3zue0ucYw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-dotall-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz#73a24da69bc3c370251f43a3d048198546115e58" + integrity sha512-00THs8eJxOJUFVx1w8i1MBF4XH4PsAjKjQ1eqN/uCH3YKwP21GCKfrn6YZFZswbOk9+0cw1zGQPHVc1KBlSxig== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.1.3" + +"@babel/plugin-transform-duplicate-keys@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz#a0601e580991e7cace080e4cf919cfd58da74e86" + integrity sha512-w2vfPkMqRkdxx+C71ATLJG30PpwtTpW7DDdLqYt2acXU7YjztzeWW2Jk1T6hKqCLYCcEA5UQM/+xTAm+QCSnuQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-exponentiation-operator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73" + integrity sha512-uZt9kD1Pp/JubkukOGQml9tqAeI8NkE98oZnHZ2qHRElmeKCodbTZgOEUtujSCSLhHSBWbzNiFSDIMC4/RBTLQ== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-for-of@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39" + integrity sha512-TlxKecN20X2tt2UEr2LNE6aqA0oPeMT1Y3cgz8k4Dn1j5ObT8M3nl9aA37LLklx0PBZKETC9ZAf9n/6SujTuXA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb" + integrity sha512-VxOa1TMlFMtqPW2IDYZQaHsFrq/dDoIjgN098NowhexhZcz3UGlvPgZXuE1jEvNygyWyxRacqDpCZt+par1FNg== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-literals@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86" + integrity sha512-1NTDBWkeNXgpUcyoVFxbr9hS57EpZYXpje92zv0SUzjdu3enaRwF/l3cmyRnXLtIdyJASyiS6PtybK+CgKf7jA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-amd@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.1.0.tgz#f9e0a7072c12e296079b5a59f408ff5b97bf86a8" + integrity sha512-wt8P+xQ85rrnGNr2x1iV3DW32W8zrB6ctuBkYBbf5/ZzJY99Ob4MFgsZDFgczNU76iy9PWsy4EuxOliDjdKw6A== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-commonjs@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c" + integrity sha512-wtNwtMjn1XGwM0AXPspQgvmE6msSJP15CX2RVfpTSTNPLhKhaOjaIfBaVfj4iUZ/VrFSodcFedwtPg/NxwQlPA== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + +"@babel/plugin-transform-modules-systemjs@^7.0.0": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.1.3.tgz#2119a3e3db612fd74a19d88652efbfe9613a5db0" + integrity sha512-PvTxgjxQAq4pvVUZF3mD5gEtVDuId8NtWkJsZLEJZMZAW3TvgQl1pmydLLN1bM8huHFVVU43lf0uvjQj9FRkKw== + dependencies: + "@babel/helper-hoist-variables" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-umd@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.1.0.tgz#a29a7d85d6f28c3561c33964442257cc6a21f2a8" + integrity sha512-enrRtn5TfRhMmbRwm7F8qOj0qEYByqUvTttPEGimcBH4CJHphjyK1Vg7sdU7JjeEmgSpM890IT/efS2nMHwYig== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-new-target@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz#ae8fbd89517fa7892d20e6564e641e8770c3aa4a" + integrity sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-object-super@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.1.0.tgz#b1ae194a054b826d8d4ba7ca91486d4ada0f91bb" + integrity sha512-/O02Je1CRTSk2SSJaq0xjwQ8hG4zhZGNjE8psTsSNPXyLRCODv7/PBozqT5AmQMzp7MI3ndvMhGdqp9c96tTEw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.1.0" + +"@babel/plugin-transform-parameters@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed" + integrity sha512-vHV7oxkEJ8IHxTfRr3hNGzV446GAb+0hgbA7o/0Jd76s+YzccdWuTU296FOCOl/xweU4t/Ya4g41yWz80RFCRw== + dependencies: + "@babel/helper-call-delegate" "^7.1.0" + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-regenerator@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz#5b41686b4ed40bef874d7ed6a84bdd849c13e0c1" + integrity sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw== + dependencies: + regenerator-transform "^0.13.3" + +"@babel/plugin-transform-shorthand-properties@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15" + integrity sha512-g/99LI4vm5iOf5r1Gdxq5Xmu91zvjhEG5+yZDJW268AZELAu4J1EiFLnkSG3yuUsZyOipVOVUKoGPYwfsTymhw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b" + integrity sha512-L702YFy2EvirrR4shTj0g2xQp7aNwZoWNCkNu2mcoU0uyzMl0XRwDSwzB/xp6DSUFiBmEXuyAyEN16LsgVqGGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-sticky-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366" + integrity sha512-LFUToxiyS/WD+XEWpkx/XJBrUXKewSZpzX68s+yEOtIbdnsRjpryDw9U06gYc6klYEij/+KQVRnD3nz3AoKmjw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + +"@babel/plugin-transform-template-literals@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65" + integrity sha512-vA6rkTCabRZu7Nbl9DfLZE1imj4tzdWcg5vtdQGvj+OH9itNNB6hxuRMHuIY8SGnEt1T9g5foqs9LnrHzsqEFg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-typeof-symbol@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz#4dcf1e52e943e5267b7313bff347fdbe0f81cec9" + integrity sha512-1r1X5DO78WnaAIvs5uC48t41LLckxsYklJrZjNKcevyz83sF2l4RHbw29qrCPr/6ksFsdfRpT/ZgxNWHXRnffg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-unicode-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc" + integrity sha512-uJBrJhBOEa3D033P95nPHu3nbFwFE9ZgXsfEitzoIXIwqAZWk7uXcg06yFKXz9FSxBH5ucgU/cYdX0IV8ldHKw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.1.3" + +"@babel/polyfill@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.0.0.tgz#c8ff65c9ec3be6a1ba10113ebd40e8750fb90bff" + integrity sha512-dnrMRkyyr74CRelJwvgnnSUDh2ge2NCTyHVwpOdvRMHtJUyxLtMAfhBN3s64pY41zdw0kgiLPh6S20eb1NcX6Q== + dependencies: + core-js "^2.5.7" + regenerator-runtime "^0.11.1" + +"@babel/preset-env@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.1.6.tgz#a0bf4b96b6bfcf6e000afc5b72b4abe7cc13ae97" + integrity sha512-YIBfpJNQMBkb6MCkjz/A9J76SNCSuGVamOVBgoUkLzpJD/z8ghHi9I42LQ4pulVX68N/MmImz6ZTixt7Azgexw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-async-generator-functions" "^7.1.0" + "@babel/plugin-proposal-json-strings" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.0.0" + "@babel/plugin-syntax-async-generators" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-async-to-generator" "^7.1.0" + "@babel/plugin-transform-block-scoped-functions" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.1.5" + "@babel/plugin-transform-classes" "^7.1.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.0.0" + "@babel/plugin-transform-dotall-regex" "^7.0.0" + "@babel/plugin-transform-duplicate-keys" "^7.0.0" + "@babel/plugin-transform-exponentiation-operator" "^7.1.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.1.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-modules-amd" "^7.1.0" + "@babel/plugin-transform-modules-commonjs" "^7.1.0" + "@babel/plugin-transform-modules-systemjs" "^7.0.0" + "@babel/plugin-transform-modules-umd" "^7.1.0" + "@babel/plugin-transform-new-target" "^7.0.0" + "@babel/plugin-transform-object-super" "^7.1.0" + "@babel/plugin-transform-parameters" "^7.1.0" + "@babel/plugin-transform-regenerator" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-sticky-regex" "^7.0.0" + "@babel/plugin-transform-template-literals" "^7.0.0" + "@babel/plugin-transform-typeof-symbol" "^7.0.0" + "@babel/plugin-transform-unicode-regex" "^7.0.0" + browserslist "^4.1.0" + invariant "^2.2.2" + js-levenshtein "^1.1.3" + semver "^5.3.0" + +"@babel/register@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.0.0.tgz#fa634bae1bfa429f60615b754fc1f1d745edd827" + integrity sha512-f/+CRmaCe7rVEvcvPvxeA8j5aJhHC3aJie7YuqcMDhUOuyWLA7J/aNrTaHIzoWPEhpHA54mec4Mm8fv8KBlv3g== + dependencies: + core-js "^2.5.7" + find-cache-dir "^1.0.0" + home-or-tmp "^3.0.0" + lodash "^4.17.10" + mkdirp "^0.5.1" + pirates "^4.0.0" + source-map-support "^0.5.9" "@babel/runtime-corejs2@^7.0.0-rc.1": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.1.2.tgz#8695811a3fd8091f54f274b9320334e5e8c62200" + version "7.1.5" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.1.5.tgz#ec8341c9aec71d1139c985327314739d66b204a0" + integrity sha512-WsYRwQsFhVmxkAqwypPTZyV9GpkqMEaAr2zOItOmqSX2GBFaI+eq98CN81e13o0zaUKJOQGYyjhNVqj56nnkYg== dependencies: core-js "^2.5.7" regenerator-runtime "^0.12.0" "@babel/runtime@^7.0.0-beta.40": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.2.tgz#81c89935f4647706fc54541145e6b4ecfef4b8e3" + version "7.1.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.5.tgz#4170907641cf1f61508f563ece3725150cc6fe39" + integrity sha512-xKnPpXG/pvK1B90JkwwxSGii90rQGKtzcMt2gI5G6+M0REXaq6rOHsGC2ay6/d0Uje7zzvSzjEzfR3ENhFlrfA== dependencies: regenerator-runtime "^0.12.0" +"@babel/template@^7.1.0", "@babel/template@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" + integrity sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.1.2" + "@babel/types" "^7.1.2" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.6.tgz#c8db9963ab4ce5b894222435482bd8ea854b7b5c" + integrity sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.1.6" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/parser" "^7.1.6" + "@babel/types" "^7.1.6" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.10" + +"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.5", "@babel/types@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.6.tgz#0adb330c3a281348a190263aceb540e10f04bcce" + integrity sha512-DMiUzlY9DSjVsOylJssxLHSgj6tWM9PRFJOGW/RaOglVOK9nzTxoOMfTfRQXGUCUQ/HmlG2efwC+XqUEJ5ay4w== + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" + to-fast-properties "^2.0.0" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= "@protobufjs/base64@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== "@protobufjs/codegen@^2.0.4": version "2.0.4" resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== "@protobufjs/eventemitter@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= "@protobufjs/fetch@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= dependencies: "@protobufjs/aspromise" "^1.1.1" "@protobufjs/inquire" "^1.1.0" @@ -53,36 +701,44 @@ "@protobufjs/float@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= "@protobufjs/inquire@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= "@protobufjs/path@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= "@protobufjs/pool@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= "@protobufjs/utf8@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= "@types/accepts@^1.3.5": version "1.3.5" - resolved "http://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" + resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" + integrity sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ== dependencies: "@types/node" "*" -"@types/async@2.0.49": - version "2.0.49" - resolved "http://registry.npmjs.org/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0" +"@types/async@2.0.50": + version "2.0.50" + resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.50.tgz#117540e026d64e1846093abbd5adc7e27fda7bcb" + integrity sha512-VMhZMMQgV1zsR+lX/0IBfAk+8Eb7dPVMWiQGFAt3qjo5x7Ml6b77jUo0e1C3ToD+XRDXqtrfw+6AB0uUsPEr3Q== "@types/body-parser@*", "@types/body-parser@1.17.0": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" + integrity sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w== dependencies: "@types/connect" "*" "@types/node" "*" @@ -90,22 +746,26 @@ "@types/connect@*": version "3.4.32" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" + integrity sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg== dependencies: "@types/node" "*" "@types/cors@^2.8.4": version "2.8.4" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.4.tgz#50991a759a29c0b89492751008c6af7a7c8267b0" + integrity sha512-ipZjBVsm2tF/n8qFGOuGBkUij9X9ZswVi9G3bx/6dz7POpVa6gVHcj1wsX/LVEn9MMF41fxK/PnZPPoTD1UFPw== dependencies: "@types/express" "*" "@types/events@*": version "1.2.0" - resolved "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" + resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" + integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== "@types/express-serve-static-core@*": version "4.16.0" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz#fdfe777594ddc1fe8eb8eccce52e261b496e43e7" + integrity sha512-lTeoCu5NxJU4OD9moCgm0ESZzweAx0YqsAcab6OB0EB3+As1OaHtKnaGJvcngQxYsi9UNv0abn4/DRavrRxt4w== dependencies: "@types/events" "*" "@types/node" "*" @@ -114,6 +774,7 @@ "@types/express@*", "@types/express@4.16.0", "@types/express@^4.11.1": version "4.16.0" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.0.tgz#6d8bc42ccaa6f35cf29a2b7c3333cb47b5a32a19" + integrity sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "*" @@ -122,37 +783,45 @@ "@types/graphql-deduplicator@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/graphql-deduplicator/-/graphql-deduplicator-2.0.0.tgz#9e577b8f3feb3d067b0ca756f4a1fb356d533922" + integrity sha512-swUwj5hWF1yFzbUXStLJrUa0ksAt11B8+SwhsAjQAX0LYJ1LLioAyuDcJ9bovWbsNzIXJYXLvljSPQw8nR728w== "@types/graphql@^0.13.0": version "0.13.4" resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.13.4.tgz#55ae9c29f0fd6b85ee536f5c72b4769d5c5e06b1" + integrity sha512-B4yel4ro2nTb3v0pYO8vO6SjgvFJSrwUY+IO6TUSLdOSB+gQFslylrhRCHxvXMIhxB71mv5PEE9dAX+24S8sew== "@types/long@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" + integrity sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q== "@types/mime@*": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" + integrity sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA== "@types/node@*", "@types/node@^10.1.0": - version "10.12.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.0.tgz#ea6dcbddbc5b584c83f06c60e82736d8fbb0c235" + version "10.12.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.9.tgz#a07bfa74331471e1dc22a47eb72026843f7b95c8" + integrity sha512-eajkMXG812/w3w4a1OcBlaTwsFPO5F7fJ/amy+tieQxEMWBlbV1JGSjkFM+zkHNf81Cad+dfIRA+IBkvmvdAeA== "@types/range-parser@*": version "1.2.2" resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.2.tgz#fa8e1ad1d474688a757140c91de6dace6f4abc8d" + integrity sha512-HtKGu+qG1NPvYe1z7ezLsyIaXYyi8SoAVqWDZgDQ8dLrsZvSzUNCwZyfX33uhWxL/SU0ZDQZ3nwZ0nimt507Kw== "@types/serve-static@*": version "1.13.2" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48" + integrity sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q== dependencies: "@types/express-serve-static-core" "*" "@types/mime" "*" -"@types/ws@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-5.1.2.tgz#f02d3b1cd46db7686734f3ce83bdf46c49decd64" +"@types/ws@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28" + integrity sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q== dependencies: "@types/events" "*" "@types/node" "*" @@ -160,18 +829,22 @@ "@types/zen-observable@^0.5.3": version "0.5.4" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.4.tgz#b863a4191e525206819e008097ebf0fb2e3a1cdc" + integrity sha512-sW6xN96wUak4tgc89d0tbTg7QDGYhGv5hvQIS6h4mRCd8h2btiZ80loPU8cyLwsBbA4ZeQt0FjvUhJ4rNhdsGg== "@types/zen-observable@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" + integrity sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg== abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== accepts@^1.3.5, accepts@~1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= dependencies: mime-types "~2.1.18" negotiator "0.6.1" @@ -179,143 +852,164 @@ accepts@^1.3.5, accepts@~1.3.5: ansi-align@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= dependencies: string-width "^2.0.0" ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" -anymatch@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" - dependencies: - micromatch "^2.1.5" - normalize-path "^2.0.0" - anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== dependencies: micromatch "^3.1.4" normalize-path "^2.1.1" apollo-boost@^0.1.10: - version "0.1.16" - resolved "https://registry.yarnpkg.com/apollo-boost/-/apollo-boost-0.1.16.tgz#77f73a30c49ab6d749ddc3e5683a7e322c15f07d" + version "0.1.21" + resolved "https://registry.yarnpkg.com/apollo-boost/-/apollo-boost-0.1.21.tgz#1c6b5f53120bd46faa825715da40cf5578fd6fbb" + integrity sha512-3cA4LjzrMckbX02Vd02yfKsgunnqdZTLE5SRXr7SCzfJfkPjmD9VGS8eLUCd/FE5taM/FHNAuqy3u3PaPCjYvw== dependencies: - apollo-cache "^1.1.17" - apollo-cache-inmemory "^1.2.10" - apollo-client "^2.4.2" + apollo-cache "^1.1.20" + apollo-cache-inmemory "^1.3.10" + apollo-client "^2.4.6" apollo-link "^1.0.6" apollo-link-error "^1.0.3" apollo-link-http "^1.3.1" apollo-link-state "^0.4.0" graphql-tag "^2.4.2" +apollo-cache-control@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.2.tgz#fc98781e6df60346a20b0540450d02842c1212f2" + integrity sha512-/fhgCWGEoTsgyA83usy/1NvJWi6hbD4rSGO5jvyNNtMZ9ledOvKUvIdzSQ1r5hxK5yds/eehWXhMJ4Pu200qrQ== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.3.2" + apollo-cache-control@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz#173d14ceb3eb9e7cb53de7eb8b61bee6159d4171" + integrity sha512-XJQs167e9u+e5ybSi51nGYr70NPBbswdvTEHtbtXbwkZ+n9t0SLPvUcoqceayOSwjK1XYOdU/EKPawNdb3rLQA== dependencies: graphql-extensions "^0.0.x" -apollo-cache-control@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.2.5.tgz#0831ad796754a7beec858668f99e7517fe744a1e" +apollo-cache-inmemory@^1.2.5, apollo-cache-inmemory@^1.3.10: + version "1.3.10" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.10.tgz#2e5375ad7ac0d30d59aaae3a2b5967673d0cf968" + integrity sha512-cJL8xxX2iytludvxY4goxYJ41n8avXirAjQkEwgSvGqrEzC0PG2DwtHZZh1QTnRRuM1rgj4MKiUiX/Ykhc5L+Q== dependencies: - apollo-server-env "^2.0.3" - graphql-extensions "^0.2.1" - -apollo-cache-inmemory@^1.2.10, apollo-cache-inmemory@^1.2.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.5.tgz#7628ee598271cfffa611e15a7ce67652a84b07b0" - dependencies: - apollo-cache "^1.1.17" - apollo-utilities "^1.0.21" + apollo-cache "^1.1.20" + apollo-utilities "^1.0.25" optimism "^0.6.6" -apollo-cache@1.1.17, apollo-cache@^1.1.17: - version "1.1.17" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.17.tgz#1fcca8423125223723b97fd72808be91a1a76490" +apollo-cache@1.1.20, apollo-cache@^1.1.20: + version "1.1.20" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.20.tgz#6152cc4baf6a63e376efee79f75de4f5c84bf90e" + integrity sha512-+Du0/4kUSuf5PjPx0+pvgMGV12ezbHA8/hubYuqRQoy/4AWb4faa61CgJNI6cKz2mhDd9m94VTNKTX11NntwkQ== dependencies: - apollo-utilities "^1.0.21" + apollo-utilities "^1.0.25" -apollo-client@^2.3.2, apollo-client@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.2.tgz#d2f044d8740723bf98a6d8d8b9684ee8c36150e6" +apollo-client@^2.3.2, apollo-client@^2.4.6: + version "2.4.6" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.6.tgz#ba24a2def6ea9d487b41672652ca967cc7c05e4a" + integrity sha512-RsZVMYone7mu3Wj4sr7ehctN8pdaHsP4X1Sv6Ly4gZ/YDetCCVnhbmnk5q7kvDtfoo0jhhHblxgFyA3FLLImtA== dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.17" + apollo-cache "1.1.20" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "1.0.21" + apollo-utilities "1.0.25" symbol-observable "^1.0.2" zen-observable "^0.8.0" optionalDependencies: - "@types/async" "2.0.49" + "@types/async" "2.0.50" -apollo-datasource@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.1.3.tgz#e7ae9d20f29a8a35f239b02f0c47169cfd78d70b" +apollo-datasource@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.2.0.tgz#ea28313689073150b18f0dbe35bedffc86a62b57" + integrity sha512-WJM9Ix3uogIfAG7mjL1NZQM9+45rcikn4mPWhE1Iuyw2+Y857J3uKJqQgF5h9Fg64SlCJh9u5WL3N7N5mg1fVw== dependencies: - apollo-server-caching "0.1.2" - apollo-server-env "2.0.3" + apollo-server-caching "0.2.0" + apollo-server-env "2.2.0" -apollo-engine-reporting-protobuf@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz#cd394f0f769c6f97d8621c4a7839095c84efcdb0" +apollo-engine-reporting-protobuf@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.1.0.tgz#fbc220cac2a3b7800ffc155d7e54c21c56b7848e" + integrity sha512-GReJtAYTmpwg0drb9VgFtqObYYTCHkJhlHEYCeXY8bJV4fOgXsAZ7CIXR9nPKO0mBaoHIHaGYvXGcyCLrZ36VA== dependencies: protobufjs "^6.8.6" -apollo-engine-reporting@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.0.6.tgz#c1a74dffce782525f8a3230e4e5228fbd05bbd59" +apollo-engine-reporting@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.2.tgz#6247e8d618da5c084ccb1bc76c665ce7a1b1ba55" + integrity sha512-W6zBTypI2ZLe9ZpMI4EasyXJP2WG8CpxYOU3Q4iuCKh8HYJqrQC5QVFXRF7TRBQTE6tc1seYnAHdgqv0ozxBrw== dependencies: - apollo-engine-reporting-protobuf "^0.0.1" - apollo-server-env "^2.0.3" + apollo-engine-reporting-protobuf "0.1.0" + apollo-server-env "2.2.0" async-retry "^1.2.1" - graphql-extensions "^0.2.1" + graphql-extensions "0.3.2" lodash "^4.17.10" +apollo-env@0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.2.4.tgz#6af44ef0af1b8c8a4d7da5d66ff55909858a88fa" + integrity sha512-pphNvrS7JmgvkvhaNEh+u0GpolytboAQcNbwmgskvX0VaLPfrrVox0AwHCteReB8t8s87NhbLd0VTG1nxmjFfQ== + dependencies: + core-js "^3.0.0-beta.3" + node-fetch "^2.2.0" + apollo-link-dedup@^1.0.0: version "1.0.10" resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.10.tgz#7b94589fe7f969777efd18a129043c78430800ae" + integrity sha512-tpUI9lMZsidxdNygSY1FxflXEkUZnvKRkMUsXXuQUNoSLeNtEvUX7QtKRAl4k9ubLl8JKKc9X3L3onAFeGTK8w== dependencies: apollo-link "^1.2.3" apollo-link-error@^1.0.3: version "1.1.1" resolved "https://registry.yarnpkg.com/apollo-link-error/-/apollo-link-error-1.1.1.tgz#69d7124d4dc11ce60f505c940f05d4f1aa0945fb" + integrity sha512-/yPcaQWcBdB94vpJ4FsiCJt1dAGGRm+6Tsj3wKwP+72taBH+UsGRQQZk7U/1cpZwl1yqhHZn+ZNhVOebpPcIlA== dependencies: apollo-link "^1.2.3" apollo-link-http-common@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.5.tgz#d094beb7971523203359bf830bfbfa7b4e7c30ed" + integrity sha512-6FV1wr5AqAyJ64Em1dq5hhGgiyxZE383VJQmhIoDVc3MyNcFL92TkhxREOs4rnH2a9X2iJMko7nodHSGLC6d8w== dependencies: apollo-link "^1.2.3" apollo-link-http@^1.3.1, apollo-link-http@^1.5.4: version "1.5.5" resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.5.tgz#7dbe851821771ad67fa29e3900c57f38cbd80da8" + integrity sha512-C5N6N/mRwmepvtzO27dgMEU3MMtRKSqcljBkYNZmWwH11BxkUQ5imBLPM3V4QJXNE7NFuAQAB5PeUd4ligivTQ== dependencies: apollo-link "^1.2.3" apollo-link-http-common "^0.2.5" @@ -323,6 +1017,7 @@ apollo-link-http@^1.3.1, apollo-link-http@^1.5.4: apollo-link-state@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/apollo-link-state/-/apollo-link-state-0.4.2.tgz#ac00e9be9b0ca89eae0be6ba31fe904b80bbe2e8" + integrity sha512-xMPcAfuiPVYXaLwC6oJFIZrKgV3GmdO31Ag2eufRoXpvT0AfJZjdaPB4450Nu9TslHRePN9A3quxNueILlQxlw== dependencies: apollo-utilities "^1.0.8" graphql-anywhere "^4.1.0-alpha.0" @@ -330,85 +1025,97 @@ apollo-link-state@^0.4.0: apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.2, apollo-link@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.3.tgz#9bd8d5fe1d88d31dc91dae9ecc22474d451fb70d" + integrity sha512-iL9yS2OfxYhigme5bpTbmRyC+Htt6tyo2fRMHT3K1XRL/C5IQDDz37OjpPy4ndx7WInSvfSZaaOTKFja9VWqSw== dependencies: apollo-utilities "^1.0.0" zen-observable-ts "^0.8.10" -apollo-server-caching@0.1.2, apollo-server-caching@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.1.2.tgz#f5b85701945110a5fca1956450e8553576635936" +apollo-server-caching@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.2.0.tgz#fe560752d364f14d34c1eaacd9df629f8ed1cf5c" + integrity sha512-/v7xWEcyyahs3hwX4baH/GekuHz3LRt9NoIYwg869G1eeqjuwY6NsowRIujZ100anJQwm9v5A9/sLtHBFvbgYg== dependencies: lru-cache "^4.1.3" +apollo-server-core@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.2.tgz#66ca6b4af6c7cdd8155de946d0c4fea3357b0432" + integrity sha512-F6d4u5m1rJB4ucpLPGCoa9Dvo5OjGMIGdAzT9A35yOvlFWwvIR46jGmYmGmNp4Qx852rb1axSZVzNy7k/Dix0w== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" + "@apollographql/apollo-upload-server" "^5.0.3" + "@apollographql/graphql-playground-html" "^1.6.4" + "@types/ws" "^6.0.0" + apollo-cache-control "0.3.2" + apollo-datasource "0.2.0" + apollo-engine-reporting "0.1.2" + apollo-server-caching "0.2.0" + apollo-server-env "2.2.0" + apollo-server-errors "2.2.0" + apollo-server-plugin-base "0.1.2" + apollo-tracing "0.3.2" + graphql-extensions "0.3.2" + graphql-subscriptions "^1.0.0" + graphql-tag "^2.9.2" + graphql-tools "^4.0.0" + json-stable-stringify "^1.0.1" + lodash "^4.17.10" + subscriptions-transport-ws "^0.9.11" + ws "^6.0.0" + apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592" + integrity sha512-BP1Vh39krgEjkQxbjTdBURUjLHbFq1zeOChDJgaRsMxGtlhzuLWwwC6lLdPatN8jEPbeHq8Tndp9QZ3iQZOKKA== dependencies: apollo-cache-control "^0.1.0" apollo-tracing "^0.1.0" graphql-extensions "^0.0.x" -apollo-server-core@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.1.0.tgz#b56f9f1ddb948b257e738eb25c5fdfd2f2fb2e07" - dependencies: - "@apollographql/apollo-upload-server" "^5.0.3" - "@types/ws" "^5.1.2" - apollo-cache-control "^0.2.5" - apollo-datasource "^0.1.3" - apollo-engine-reporting "^0.0.6" - apollo-server-caching "^0.1.2" - apollo-server-env "^2.0.3" - apollo-server-errors "^2.0.2" - apollo-tracing "^0.2.5" - graphql-extensions "^0.2.1" - graphql-subscriptions "^0.5.8" - graphql-tag "^2.9.2" - graphql-tools "^3.0.4" - hash.js "^1.1.3" - lodash "^4.17.10" - subscriptions-transport-ws "^0.9.11" - ws "^5.2.0" - -apollo-server-env@2.0.3, apollo-server-env@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.0.3.tgz#3c13552cd33f400160076cf8e1c9b24be4d27e13" +apollo-server-env@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.2.0.tgz#5eec5dbf46581f663fd6692b2e05c7e8ae6d6034" + integrity sha512-wjJiI5nQWPBpNmpiLP389Ezpstp71szS6DHAeTgYLb/ulCw3CTuuA+0/E1bsThVWiQaDeHZE0sE3yI8q2zrYiA== dependencies: node-fetch "^2.1.2" util.promisify "^1.0.0" -apollo-server-errors@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz#e9cbb1b74d2cd78aed23cd886ca2d0c186323b2b" +apollo-server-errors@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" + integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== -apollo-server-express@^1.3.6: - version "1.4.0" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.4.0.tgz#7d7c58d6d6f9892b83fe575669093bb66738b125" - dependencies: - apollo-server-core "^1.4.0" - apollo-server-module-graphiql "^1.4.0" - -apollo-server-express@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.1.0.tgz#b2d423c2c934df5c4e0a1b0d5f0088a9461f3c86" +apollo-server-express@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.2.2.tgz#e6811024cac695351600c18985331b43ba24f556" + integrity sha512-DPxHOUd0Waztuix0r1ed6xfdlR7P7RzIXPmybhPXj1bZJtYHz5If0ngYNjtFqnXVrC8aSRtMz108SQUAnduYwA== dependencies: "@apollographql/apollo-upload-server" "^5.0.3" - "@apollographql/graphql-playground-html" "^1.6.0" + "@apollographql/graphql-playground-html" "^1.6.4" "@types/accepts" "^1.3.5" "@types/body-parser" "1.17.0" "@types/cors" "^2.8.4" "@types/express" "4.16.0" accepts "^1.3.5" - apollo-server-core "^2.1.0" + apollo-server-core "2.2.2" body-parser "^1.18.3" cors "^2.8.4" - graphql-subscriptions "^0.5.8" - graphql-tools "^3.0.4" + graphql-subscriptions "^1.0.0" + graphql-tools "^4.0.0" type-is "^1.6.16" +apollo-server-express@^1.3.6: + version "1.4.0" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.4.0.tgz#7d7c58d6d6f9892b83fe575669093bb66738b125" + integrity sha512-zkH00nxhLnJfO0HgnNPBTfZw8qI5ILaPZ5TecMCI9+Y9Ssr2b0bFr9pBRsXy9eudPhI+/O4yqegSUsnLdF/CPw== + dependencies: + apollo-server-core "^1.4.0" + apollo-server-module-graphiql "^1.4.0" + apollo-server-lambda@1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/apollo-server-lambda/-/apollo-server-lambda-1.3.6.tgz#bdaac37f143c6798e40b8ae75580ba673cea260e" + integrity sha1-varDfxQ8Z5jkC4rnVYC6ZzzqJg4= dependencies: apollo-server-core "^1.3.6" apollo-server-module-graphiql "^1.3.4" @@ -416,52 +1123,64 @@ apollo-server-lambda@1.3.6: apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" + integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== + +apollo-server-plugin-base@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.2.tgz#4c1ebb769b630a16ff8ade03f12759cde17a21dc" + integrity sha512-+uicMcNctlP6YwIhzLLEycZzao/810OSzcxgPYKItXr5lGa1GuHD7sRIWldT3YoSdpw6Gal2lBuw6/DmnoDsPg== apollo-server@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.1.0.tgz#abec7853647c59f386087352cc7f06a4f1f8afe2" + version "2.2.2" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.2.2.tgz#b17f91730ef399b42c2ba6ea366320ed0d6a9774" + integrity sha512-LiVId1s7o+4IqReyzqfqxVyNYr6BOGsaYyqUH4R5Vb0gRw5igmZEiYz4g+dqTrUT4Ktv2gDyFumM+MxNm+Gjqg== dependencies: - apollo-server-core "^2.1.0" - apollo-server-express "^2.1.0" + apollo-server-core "2.2.2" + apollo-server-express "2.2.2" express "^4.0.0" - graphql-subscriptions "^0.5.8" - graphql-tools "^3.0.4" + graphql-subscriptions "^1.0.0" + graphql-tools "^4.0.0" + +apollo-tracing@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.2.tgz#1a6b695813791b8404b5adaa10925a7f2642f15d" + integrity sha512-YwN1m1k0JJsxGh0QWsEM3OLnyem0GT2tZnGeO2OogCr6dH5lE0SjKPc6UzpcI/3fPyxRrx5QvpUiP+DJeehhTA== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.3.2" apollo-tracing@^0.1.0: version "0.1.4" - resolved "http://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" + integrity sha512-Uv+1nh5AsNmC3m130i2u3IqbS+nrxyVV3KYimH5QKsdPjxxIQB3JAT+jJmpeDxBel8gDVstNmCh82QSLxLSIdQ== dependencies: graphql-extensions "~0.0.9" -apollo-tracing@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.2.5.tgz#15bb8d6f37efe8c1bb6351e8e21521dd4f14c5f2" - dependencies: - apollo-server-env "^2.0.3" - graphql-extensions "^0.2.1" - apollo-upload-server@^5.0.0: version "5.0.0" - resolved "http://registry.npmjs.org/apollo-upload-server/-/apollo-upload-server-5.0.0.tgz#c953b523608313966e0c8444637f4ae8ef77d5bc" + resolved "https://registry.yarnpkg.com/apollo-upload-server/-/apollo-upload-server-5.0.0.tgz#c953b523608313966e0c8444637f4ae8ef77d5bc" + integrity sha512-CzbHvMo/6TO5XrovzmV/ojTft17s9Cd+vKLGngChpB0UW1ObxKlNLlcXRLD+yt6Nec32/Kt209HmA31hnwxB/g== dependencies: "@babel/runtime" "^7.0.0-beta.40" busboy "^0.2.14" object-path "^0.11.4" -apollo-utilities@1.0.21, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.21, apollo-utilities@^1.0.8: - version "1.0.21" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.21.tgz#cb8b5779fe275850b16046ff8373f4af2de90765" +apollo-utilities@1.0.25, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.25, apollo-utilities@^1.0.8: + version "1.0.25" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.25.tgz#899b00f5f990fb451675adf84cb3de82eb6372ea" + integrity sha512-AXvqkhni3Ir1ffm4SA1QzXn8k8I5BBl4PVKEyak734i4jFdp+xgfUyi2VCqF64TJlFTA/B73TRDUvO2D+tKtZg== dependencies: fast-json-stable-stringify "^2.0.0" - fclone "^1.0.11" aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== are-we-there-yet@~1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== dependencies: delegates "^1.0.0" readable-stream "^2.0.6" @@ -469,84 +1188,90 @@ are-we-there-yet@~1.1.2: argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= -arr-flatten@^1.0.1, arr-flatten@^1.1.0: +arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= array-uniq@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= assignment@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.0.0.tgz#ffd17b21bf5d6b22e777b989681a815456a3dd3e" + integrity sha1-/9F7Ib9dayLnd7mJaBqBVFaj3T4= assignment@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.2.0.tgz#f5b5bc2d160d69986e8700cd38f567c0aabe101e" + integrity sha1-9bW8LRYNaZhuhwDNOPVnwKq+EB4= async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + integrity sha1-GdOGodntxufByF04iu28xW0zYC0= async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== async-retry@^1.2.1: version "1.2.3" resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.2.3.tgz#a6521f338358d322b1a0012b79030c6f411d1ce0" + integrity sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q== dependencies: retry "0.12.0" atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== aws-lambda@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/aws-lambda/-/aws-lambda-0.1.2.tgz#19b1585075df31679597b976a5f1def61f12ccee" + integrity sha1-GbFYUHXfMWeVl7l2pfHe9h8SzO4= dependencies: aws-sdk "^*" commander "^2.5.0" dotenv "^0.4.0" aws-sdk@^*: - version "2.336.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.336.0.tgz#b15371aff3e30ba77b74968c086375594be897c9" + version "2.360.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.360.0.tgz#f640acbc7de07aa7a381a31b110fc3502fe90288" + integrity sha512-bzr2j6s1LNlkWDTgnFszr2r7eJ2/DfWx4GJbGV17LKnxC9ZHkHKtX50sEa1g4Yzb1RveSXlC3Hfyus92gPQ4BQ== dependencies: buffer "4.9.1" events "1.1.1" @@ -558,516 +1283,42 @@ aws-sdk@^*: uuid "3.1.0" xml2js "0.4.19" -babel-cli@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" - dependencies: - babel-core "^6.26.0" - babel-polyfill "^6.26.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - commander "^2.11.0" - convert-source-map "^1.5.0" - fs-readdir-recursive "^1.0.0" - glob "^7.1.2" - lodash "^4.17.4" - output-file-sync "^1.1.2" - path-is-absolute "^1.0.1" - slash "^1.0.0" - source-map "^0.5.6" - v8flags "^2.1.1" - optionalDependencies: - chokidar "^1.6.1" - -babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.26.0: - version "6.26.3" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.1" - debug "^2.6.9" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.8" - slash "^1.0.0" - source-map "^0.5.7" - -babel-generator@^6.26.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-check-es2015-constants@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - -babel-plugin-syntax-trailing-function-commas@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - -babel-plugin-transform-async-to-generator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - dependencies: - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-plugin-transform-es2015-classes@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-computed-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.2" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - -babel-plugin-transform-es2015-modules-systemjs@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-umd@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-object-super@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-shorthand-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-exponentiation-operator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-regenerator@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - dependencies: - regenerator-transform "^0.10.0" - -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - babel-polyfill@6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" + integrity sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0= dependencies: babel-runtime "^6.22.0" core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-polyfill@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" - dependencies: - babel-runtime "^6.26.0" - core-js "^2.5.0" - regenerator-runtime "^0.10.5" - -babel-preset-env@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^3.2.6" - invariant "^2.2.2" - semver "^5.3.0" - -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: +babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= dependencies: core-js "^2.4.0" regenerator-runtime "^0.11.0" -babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.24.1, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - backo2@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2: version "1.3.0" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: cache-base "^1.0.1" class-utils "^0.3.5" @@ -1080,20 +1331,24 @@ base@^0.11.1: bcryptjs@^2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= binary-extensions@^1.0.0: version "1.12.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" + integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== body-parser-graphql@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/body-parser-graphql/-/body-parser-graphql-1.1.0.tgz#80a80353c7cb623562fd375750dfe018d75f0f7c" + integrity sha512-bOBF4n1AnUjcY1SzLeibeIx4XOuYqEkjn/Lm4yKhnN6KedoXMv4hVqgcKHGRnxOMJP64tErqrQU+4cihhpbJXg== dependencies: body-parser "^1.18.2" body-parser@1.18.3, body-parser@^1.18.2, body-parser@^1.18.3: version "1.18.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= dependencies: bytes "3.0.0" content-type "~1.0.4" @@ -1109,10 +1364,12 @@ body-parser@1.18.3, body-parser@^1.18.2, body-parser@^1.18.3: boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= boxen@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== dependencies: ansi-align "^2.0.0" camelcase "^4.0.0" @@ -1125,21 +1382,15 @@ boxen@^1.2.1: brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - braces@^2.3.0, braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: arr-flatten "^1.1.0" array-unique "^0.3.2" @@ -1152,24 +1403,29 @@ braces@^2.3.0, braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -browserslist@^3.2.6: - version "3.2.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" +browserslist@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.4.tgz#4477b737db6a1b07077275b24791e680d4300425" + integrity sha512-u5iz+ijIMUlmV8blX82VGFrB9ecnUg5qEt55CMZ/YJEhha+d8qpBfOFuutJ6F/VKRXjZoD33b6uvarpPxcl3RA== dependencies: - caniuse-lite "^1.0.30000844" - electron-to-chromium "^1.3.47" + caniuse-lite "^1.0.30000899" + electron-to-chromium "^1.3.82" + node-releases "^1.0.1" buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== buffer@4.9.1: version "4.9.1" - resolved "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -1178,6 +1434,7 @@ buffer@4.9.1: busboy@^0.2.14: version "0.2.14" resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" + integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= dependencies: dicer "0.2.5" readable-stream "1.1.x" @@ -1185,10 +1442,12 @@ busboy@^0.2.14: bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: collection-visit "^1.0.0" component-emitter "^1.2.1" @@ -1203,18 +1462,22 @@ cache-base@^1.0.1: camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= -caniuse-lite@^1.0.30000844: - version "1.0.30000892" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000892.tgz#344d2b51ee3ff5977537da4aa449c90eec40b759" +caniuse-lite@^1.0.30000899: + version "1.0.30000909" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000909.tgz#697e8f447ca5f758e7c6cef39ec429ce18b908d3" + integrity sha512-4Ix9ArKpo3s/dLGVn/el9SAk6Vn2kGhg8XeE4eRTsGEsmm9RnTkwnBsVZs7p4wA8gB+nsgP36vZWYbG8a4nYrg== capture-stack-trace@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== -chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: +chalk@1.1.3, chalk@^1.0.0: version "1.1.3" - resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -1222,9 +1485,10 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" @@ -1233,10 +1497,12 @@ chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= cheerio@^1.0.0-rc.2: version "1.0.0-rc.2" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" + integrity sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs= dependencies: css-select "~1.2.0" dom-serializer "~0.1.0" @@ -1245,24 +1511,10 @@ cheerio@^1.0.0-rc.2: lodash "^4.15.0" parse5 "^3.0.1" -chokidar@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" - dependencies: - anymatch "^1.3.0" - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^2.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - optionalDependencies: - fsevents "^1.0.0" - -chokidar@^2.0.2: +chokidar@^2.0.3, chokidar@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== dependencies: anymatch "^2.0.0" async-each "^1.0.0" @@ -1279,17 +1531,20 @@ chokidar@^2.0.2: optionalDependencies: fsevents "^1.2.2" -chownr@^1.0.1: +chownr@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== ci-info@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== dependencies: arr-union "^3.1.0" define-property "^0.2.5" @@ -1299,24 +1554,29 @@ class-utils@^0.3.5: cli-boxes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: restore-cursor "^2.0.0" cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= dependencies: map-visit "^1.0.0" object-visit "^1.0.0" @@ -1324,28 +1584,39 @@ collection-visit@^1.0.0: color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -commander@^2.11.0, commander@^2.5.0: +commander@^2.5.0, commander@^2.8.1: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= configstore@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== dependencies: dot-prop "^4.1.0" graceful-fs "^4.1.2" @@ -1357,44 +1628,59 @@ configstore@^3.0.0: console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.5.0, convert-source-map@^1.5.1: +convert-source-map@^1.1.0: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== dependencies: safe-buffer "~5.1.1" cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.3, core-js@^2.5.7: +core-js@^2.4.0, core-js@^2.5.3, core-js@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== + +core-js@^3.0.0-beta.3: + version "3.0.0-beta.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.3.tgz#b0f22009972b8c6c04550ebf38513ca4b3cc9559" + integrity sha512-kM/OfrnMThP5PwGAj5HhQLdjUqzjrllqN2EVnk/X9qrLsfYjR2hzZ+E/8CzH0xuosexZtqMTLQrk//BULrBj9w== core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= cors@^2.8.4: - version "2.8.4" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.4.tgz#2bd381f2eb201020105cd50ea59da63090694686" + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== dependencies: object-assign "^4" vary "^1" @@ -1402,12 +1688,14 @@ cors@^2.8.4: create-error-class@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= dependencies: capture-stack-trace "^1.0.0" cross-fetch@2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.2.tgz#a47ff4f7fc712daba8f6a695a11c948440d45723" + integrity sha1-pH/09/xxLauo9qaVoRyUhEDUVyM= dependencies: node-fetch "2.1.2" whatwg-fetch "2.0.4" @@ -1415,6 +1703,7 @@ cross-fetch@2.2.2: cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= dependencies: lru-cache "^4.0.1" shebang-command "^1.2.0" @@ -1423,10 +1712,12 @@ cross-spawn@^5.0.1: crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= css-select@~1.2.0: version "1.2.0" - resolved "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= dependencies: boolbase "~1.0.0" css-what "2.1" @@ -1436,52 +1727,69 @@ css-select@~1.2.0: css-what@2.1: version "2.1.2" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" + integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ== date-fns@^2.0.0-alpha.24: - version "2.0.0-alpha.24" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.24.tgz#2988c137c72275af29d7d21cc53eb52b3a8c2586" + version "2.0.0-alpha.25" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.25.tgz#651a5d1f59a01af6cf0371e39b2ae29df5d521ee" + integrity sha512-iQzJkHF0L4wah9Ae9PkvwemwFz6qmRLuNZcghmvf2t+ptLs1qXzONLiGtjmPQzL6+JpC01JjlTopY2AEy4NFAg== -debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" + integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== dependencies: ms "^2.1.1" decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== define-properties@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== dependencies: object-keys "^1.0.12" define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= dependencies: is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== dependencies: is-descriptor "^1.0.2" isobject "^3.0.1" @@ -1489,32 +1797,32 @@ define-property@^2.0.2: delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= deprecated-decorator@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" + integrity sha1-AJZjF7ehL+kvPMgx91g68ym4bDc= destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= dicer@0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" + integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= dependencies: readable-stream "1.1.x" streamsearch "0.1.2" @@ -1522,6 +1830,7 @@ dicer@0.2.5: dom-serializer@0, dom-serializer@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" + integrity sha1-BzxpdUbOB4DOI75KKOKT5AvDDII= dependencies: domelementtype "~1.1.1" entities "~1.1.1" @@ -1529,24 +1838,29 @@ dom-serializer@0, dom-serializer@~0.1.0: domelementtype@1: version "1.2.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.2.1.tgz#578558ef23befac043a1abb0db07635509393479" + integrity sha512-SQVCLFS2E7G5CRCMdn6K9bIhRj1bS6QBWZfF0TUPh4V/BbqrQ619IdSS3/izn0FZ+9l+uODzaZjb08fjOfablA== domelementtype@^1.3.0: version "1.3.0" - resolved "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" + integrity sha1-sXrtguirWeUt2cGbF1bg/BhyBMI= domelementtype@~1.1.1: version "1.1.3" - resolved "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" + integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs= domhandler@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== dependencies: domelementtype "1" domutils@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= dependencies: dom-serializer "0" domelementtype "1" @@ -1554,6 +1868,7 @@ domutils@1.5.1: domutils@^1.5.1: version "1.7.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== dependencies: dom-serializer "0" domelementtype "1" @@ -1561,56 +1876,68 @@ domutils@^1.5.1: dot-prop@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== dependencies: is-obj "^1.0.0" dotenv@^0.4.0: version "0.4.0" - resolved "http://registry.npmjs.org/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" + integrity sha1-9vs1E2PC2SIHJFxzeALJq1rhSVo= dotenv@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.1.0.tgz#9853b6ca98292acb7dec67a95018fa40bccff42c" + integrity sha512-/veDn2ztgRlB7gKmE3i9f6CmDIyXAy6d5nBq+whO9SLX+Zs1sXEgFLPi+aSuWqUuusMfbi84fT8j34fs1HaYUw== duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.1" - resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= ecdsa-sig-formatter@1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz#1c595000f04a8897dfb85000892a0f4c33af86c3" + integrity sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM= dependencies: safe-buffer "^5.0.1" ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.47: - version "1.3.79" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.79.tgz#774718f06284a4bf8f578ac67e74508fe659f13a" +electron-to-chromium@^1.3.82: + version "1.3.84" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.84.tgz#2e55df59e818f150a9f61b53471ebf4f0feecc65" + integrity sha512-IYhbzJYOopiTaNWMBp7RjbecUBsbnbDneOP86f3qvS0G0xfzwNSvMJpTrvi5/Y1gU7tg2NAgeg8a8rCYvW9Whw== encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= encoding@^0.1.11: version "0.1.12" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= dependencies: iconv-lite "~0.4.13" entities@^1.1.1, entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== es-abstract@^1.5.1: version "1.12.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== dependencies: es-to-primitive "^1.1.1" function-bind "^1.1.1" @@ -1621,6 +1948,7 @@ es-abstract@^1.5.1: es-to-primitive@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== dependencies: is-callable "^1.1.4" is-date-object "^1.0.1" @@ -1629,26 +1957,32 @@ es-to-primitive@^1.1.1: escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= event-stream@~3.3.0: version "3.3.6" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.6.tgz#cac1230890e07e73ec9cacd038f60a5b66173eef" + integrity sha512-dGXNg4F/FgVzlApjzItL+7naHutA3fDqbV/zAZqDDlXTjiMnQmZKu+prImWKszeBM5UQeGvAl3u1wBiKeDh61g== dependencies: duplexer "^0.1.1" flatmap-stream "^0.1.0" @@ -1662,14 +1996,17 @@ event-stream@~3.3.0: eventemitter3@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" + integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== events@1.1.1: version "1.1.1" - resolved "http://registry.npmjs.org/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -1679,15 +2016,10 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - dependencies: - is-posix-bracket "^0.1.0" - expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= dependencies: debug "^2.3.3" define-property "^0.2.5" @@ -1697,15 +2029,10 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - express@^4.0.0, express@^4.16.3: version "4.16.4" resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" + integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== dependencies: accepts "~1.3.5" array-flatten "1.1.1" @@ -1741,33 +2068,31 @@ express@^4.0.0, express@^4.16.3: extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= dependencies: assign-symbols "^1.0.0" is-extendable "^1.0.1" external-editor@^2.0.1: version "2.2.0" - resolved "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== dependencies: chardet "^0.4.0" iconv-lite "^0.4.17" tmp "^0.0.33" -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: array-unique "^0.3.2" define-property "^1.0.0" @@ -1781,38 +2106,24 @@ extglob@^2.0.4: faker@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" + integrity sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8= fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - -fclone@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= dependencies: escape-string-regexp "^1.0.5" -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - -fill-range@^2.1.0: - version "2.2.4" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^3.0.0" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= dependencies: extend-shallow "^2.0.1" is-number "^3.0.0" @@ -1821,7 +2132,8 @@ fill-range@^4.0.0: finalhandler@1.1.1: version "1.1.1" - resolved "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== dependencies: debug "2.6.9" encodeurl "~1.0.2" @@ -1831,55 +2143,75 @@ finalhandler@1.1.1: statuses "~1.4.0" unpipe "~1.0.0" -flatmap-stream@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.1.tgz#d34f39ef3b9aa5a2fc225016bd3adf28ac5ae6ea" +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + integrity sha1-kojj6ePMN0hxfTnq3hfPcfww7m8= + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^2.0.0" -for-in@^1.0.1, for-in@^1.0.2: +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +flatmap-stream@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.2.tgz#b1da359a93f24f6d96e46f948552d997e3c2863d" + integrity sha512-ucyr6WkLXjyMuHPtOUq4l+nSAxgWi7v4QO508eQ9resnGj+lSup26oIsUI5aH8k4Qfpjsxa8dDf9UCKkS2KHzQ== + +for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - dependencies: - for-in "^1.0.1" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: map-cache "^0.2.2" fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= from@^0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== dependencies: minipass "^2.2.1" -fs-readdir-recursive@^1.0.0: +fs-readdir-recursive@^1.0.0, fs-readdir-recursive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.0.0, fsevents@^1.2.2: +fsevents@^1.2.2: version "1.2.4" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== dependencies: nan "^2.9.2" node-pre-gyp "^0.10.0" @@ -1887,10 +2219,12 @@ fsevents@^1.0.0, fsevents@^1.2.2: 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== gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= dependencies: aproba "^1.0.3" console-control-strings "^1.0.0" @@ -1903,35 +2237,26 @@ gauge@~2.7.3: get-stream@^3.0.0: version "3.0.0" - resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= dependencies: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.5, glob@^7.1.2: +glob@^7.0.0, glob@^7.0.5: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -1943,16 +2268,19 @@ glob@^7.0.5, glob@^7.1.2: global-dirs@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= dependencies: ini "^1.3.4" -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" +globals@^11.1.0: + version "11.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" + integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== got@^6.7.1: version "6.7.1" - resolved "http://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= dependencies: create-error-class "^3.0.0" duplexer3 "^0.1.4" @@ -1966,19 +2294,22 @@ got@^6.7.1: unzip-response "^2.0.1" url-parse-lax "^1.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" +graceful-fs@^4.1.11, graceful-fs@^4.1.2: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== graphql-anywhere@^4.1.0-alpha.0: - version "4.1.19" - resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.19.tgz#5f6ca3b58218e5449f4798e3c6d942fcd2fef082" + version "4.1.22" + resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.22.tgz#1c831ba3c9e5664a0dd24d10d23a9e9512d92056" + integrity sha512-qm2/1cKM8nfotxDhm4J0r1znVlK0Yge/yEKt26EVVBgpIhvxjXYFALCGbr7cvfDlvzal1iSPpaYa+8YTtjsxQA== dependencies: - apollo-utilities "^1.0.21" + apollo-utilities "^1.0.25" graphql-config@2.0.0: version "2.0.0" - resolved "http://registry.npmjs.org/graphql-config/-/graphql-config-2.0.0.tgz#daf69091055c6f675d63893a2d14c48f3fec3327" + resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-2.0.0.tgz#daf69091055c6f675d63893a2d14c48f3fec3327" + integrity sha512-//hZmROEk79zzPlH6SVTQeXd8NVV65rquz1zxZeO6oEuX5KNnii8+oznLu7d897EfJ+NShTZtsY9FMmxxkWmJw== dependencies: graphql-import "^0.4.0" graphql-request "^1.4.0" @@ -1987,108 +2318,134 @@ graphql-config@2.0.0: minimatch "^3.0.4" graphql-custom-directives@^0.2.13: - version "0.2.13" - resolved "https://registry.yarnpkg.com/graphql-custom-directives/-/graphql-custom-directives-0.2.13.tgz#5e175069f5ff404f751d232e302007bc25488ea8" + 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-deduplicator@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.1.tgz#20c6b39e3a6f096b46dfc8491432818739c0ee37" + version "2.0.2" + resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3" + integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA== + +graphql-extensions@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.2.tgz#a19dd62b62d769f4d1b9c4b4781cc353b2174998" + integrity sha512-eIAWwtZNlUAHtHF6uNP6+4M+GCksqUYfNBxW5rTAlCB4/ZcuIvchVtN1CgVM7MooW3akPM1Eci11WyeXvgOugQ== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: version "0.0.10" - resolved "http://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" + integrity sha512-TnQueqUDCYzOSrpQb3q1ngDSP2otJSF+9yNLrQGPzkMsvnQ+v6e2d5tl+B35D4y+XpmvVnAn4T3ZK28mkILveA== dependencies: core-js "^2.5.3" source-map-support "^0.5.1" -graphql-extensions@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.2.1.tgz#7697e0fcea2e622afe9e24dd31fc84f533e84c70" - dependencies: - apollo-server-env "^2.0.3" - graphql-import@^0.4.0: version "0.4.5" - resolved "http://registry.npmjs.org/graphql-import/-/graphql-import-0.4.5.tgz#e2f18c28d335733f46df8e0733d8deb1c6e2a645" + resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.4.5.tgz#e2f18c28d335733f46df8e0733d8deb1c6e2a645" + integrity sha512-G/+I08Qp6/QGTb9qapknCm3yPHV0ZL7wbaalWFpxsfR8ZhZoTBe//LsbsCKlbALQpcMegchpJhpTSKiJjhaVqQ== dependencies: lodash "^4.17.4" graphql-import@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.6.0.tgz#c00cb8a269ceea263e062922c8c81a2272d1ffcb" + integrity sha512-S6Aj4pTzehCwyh7hKUKlWLgE6soDdW/T6JPePC16exzFDNdZHXRj7lqv75yMWJCkBY0pBtWicMLinb4ni6QRyg== dependencies: lodash "^4.17.4" 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@1.6.6: version "1.6.6" resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.6.6.tgz#f40f4e836ced479df718dbc1869ea4cd3b64027b" + integrity sha512-1rSSPEJOhBMwNCBCp5CCh3YZFvo8qN/pzQM8k50pd/w2hBsBvOx0AVU9Or6JQbTXxYrKFXvKFUxC5Lp+2oeUtw== dependencies: graphql-tools "^3.0.5" graphql-middleware@1.7.6: version "1.7.6" resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.6.tgz#f226bf6671f3d82a9378f8b335804c8e44d21733" + integrity sha512-nKWd6BVgsh6S2eDRIcm3TjJPmXEEmqK6DY2a8/nK11NrNAFpZCq+esSSPG1F0HZShsDdE/h3M+/jLcD/zKlMvA== dependencies: graphql-tools "^4.0.0" graphql-playground-html@1.5.5: version "1.5.5" - resolved "http://registry.npmjs.org/graphql-playground-html/-/graphql-playground-html-1.5.5.tgz#e2aca543eb66b435ead495b45244b2604d6b2d48" + resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.5.5.tgz#e2aca543eb66b435ead495b45244b2604d6b2d48" + integrity sha512-PzSywpEKcjbDUkV6e3ivEixvAuUJGyYmBUvuittzySe/RgwHRo0xKLD7HouUCTbpFfWMw8kRKhAUVtt7Ys97uw== dependencies: graphql-config "2.0.0" graphql-playground-html@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz#6ec4d54325ab2e5352506fdb89eb37c3fc718bf8" + integrity sha512-et3huQFEuAZgAiUfs9a+1Wo/JDX94k7XqNRc8LhpGT8k2NwIhMAbZKqudVF/Ww4+XDoEB4LUTSFGRPBYvKrcKQ== dependencies: graphql-config "2.0.0" graphql-playground-middleware-express@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.2.tgz#5f7bf3683494fe17893d1b54bbecee5e222c2e78" + integrity sha512-JvKsVOR/U5QguBtEvTt0ozQ49uh1C6cW8O1xR6krQpJZIxjLYqpgusLUddTiVkka6Q/A4/AXBohY85jPudxYDg== dependencies: graphql-playground-html "1.6.0" graphql-playground-middleware-lambda@1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/graphql-playground-middleware-lambda/-/graphql-playground-middleware-lambda-1.6.1.tgz#e0f1944558136dd3975570c92c702d6009cc779c" + integrity sha512-FO6XG9QRs+0AkwfAnL80u8A02xTg1rPUH+Ay13ASTs0nEePav5GkrWfL59ZY+sK4ZzFvz72aImuXAs3Ajn8VtA== dependencies: graphql-playground-html "1.5.5" graphql-request@^1.4.0: version "1.8.2" resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" + integrity sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg== dependencies: cross-fetch "2.2.2" graphql-shield@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.0.1.tgz#731fca9a69a540ff446edf9e5bec610da295f5cb" + version "4.1.0" + resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.1.0.tgz#8bd55179fd28d00e64ca5a7dbd3cffe82e282e73" + integrity sha512-r3m5t7FpLDyJQIby0IKyNrtp8k62hP/syhPcrpdT67UVNKh0jjjl+zpjXh/3PXeNZHPEAiBQTHhFjnC7H2B4SA== dependencies: object-hash "^1.3.0" opencollective "1.0.3" graphql-subscriptions@^0.5.8: version "0.5.8" - resolved "http://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7" + resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7" + integrity sha512-0CaZnXKBw2pwnIbvmVckby5Ge5e2ecmjofhYCdyeACbCly2j3WXDP/pl+s+Dqd2GQFC7y99NB+53jrt55CKxYQ== + dependencies: + iterall "^1.2.1" + +graphql-subscriptions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-1.0.0.tgz#475267694b3bd465af6477dbab4263a3f62702b8" + integrity sha512-+ytmryoHF1LVf58NKEaNPRUzYyXplm120ntxfPcgOBC7TnK7Tv/4VRHeh4FAR9iL+O1bqhZs4nkibxQ+OA5cDQ== dependencies: iterall "^1.2.1" graphql-tag@^2.4.2, graphql-tag@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" + integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w== -graphql-tools@^3.0.0, graphql-tools@^3.0.4, graphql-tools@^3.0.5: +graphql-tools@^3.0.0, graphql-tools@^3.0.5: version "3.1.1" resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-3.1.1.tgz#d593358f01e7c8b1671a17b70ddb034dea9dbc50" + integrity sha512-yHvPkweUB0+Q/GWH5wIG60bpt8CTwBklCSzQdEHmRUgAdEQKxw+9B7zB3dG7wB3Ym7M7lfrS4Ej+jtDZfA2UXg== dependencies: apollo-link "^1.2.2" apollo-utilities "^1.0.1" @@ -2097,8 +2454,9 @@ graphql-tools@^3.0.0, graphql-tools@^3.0.4, graphql-tools@^3.0.5: uuid "^3.1.0" graphql-tools@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.2.tgz#9da22974cc6bf6524ed4f4af35556fd15aa6516d" + version "4.0.3" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.3.tgz#23b5cb52c519212b1b2e4630a361464396ad264b" + integrity sha512-NNZM0WSnVLX1zIMUxu7SjzLZ4prCp15N5L2T2ro02OVyydZ0fuCnZYRnx/yK9xjGWbZA0Q58yEO//Bv/psJWrg== dependencies: apollo-link "^1.2.3" apollo-utilities "^1.0.1" @@ -2109,6 +2467,7 @@ graphql-tools@^4.0.0: graphql-yoga@1.16.2: version "1.16.2" resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.16.2.tgz#083293a9cecab6283e883c5a482c5c920fa66585" + integrity sha512-dV7uEUm/tzl3K/gkHPBt718N+F0gmhZKsg8HJpj35SEniGyXVI3VjDWd7Na3bWdue4p8Sxb+/JguuK8jpe8dWg== dependencies: "@types/cors" "^2.8.4" "@types/express" "^4.11.1" @@ -2134,31 +2493,37 @@ graphql-yoga@1.16.2: "graphql@^0.11.0 || ^0.12.0 || ^0.13.0", graphql@^0.13.2: version "0.13.2" - resolved "http://registry.npmjs.org/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" + integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== dependencies: iterall "^1.2.1" has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= dependencies: ansi-regex "^2.0.0" has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: get-value "^2.0.3" has-values "^0.1.4" @@ -2167,6 +2532,7 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= dependencies: get-value "^2.0.6" has-values "^1.0.0" @@ -2175,10 +2541,12 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= has-values@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= dependencies: is-number "^3.0.0" kind-of "^4.0.0" @@ -2186,30 +2554,31 @@ has-values@^1.0.0: has@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" -hash.js@^1.1.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - he@0.5.0: version "0.5.0" - resolved "http://registry.npmjs.org/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" + resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" + integrity sha1-LAX/rvkLaOhg8/0rVO9YCYknfuI= -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" +home-or-tmp@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-3.0.0.tgz#57a8fe24cf33cdd524860a15821ddc25c86671fb" + integrity sha1-V6j+JM8zzdUkhgoVgh3cJchmcfs= + +homedir-polyfill@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" + integrity sha1-TCu8inWJmP7r9e1oWA921GdotLw= dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" + parse-passwd "^1.0.0" htmlparser2@^3.9.0, htmlparser2@^3.9.1: version "3.10.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" + integrity sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ== dependencies: domelementtype "^1.3.0" domhandler "^2.3.0" @@ -2220,7 +2589,8 @@ htmlparser2@^3.9.0, htmlparser2@^3.9.1: http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: version "1.6.3" - resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= dependencies: depd "~1.1.2" inherits "2.0.3" @@ -2230,48 +2600,58 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== dependencies: safer-buffer ">= 2.1.2 < 3" iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" ieee754@1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + integrity sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q= ieee754@^1.1.4: version "1.1.12" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= ignore-walk@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== dependencies: minimatch "^3.0.4" -immutable-tuple@^0.4.4: - version "0.4.8" - resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.8.tgz#f60b65b863d34be39d307d1bbf4a450e1ac3048a" +immutable-tuple@^0.4.9: + version "0.4.9" + resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.9.tgz#473ebdd6c169c461913a454bf87ef8f601a20ff0" + integrity sha512-LWbJPZnidF8eczu7XmcnLBsumuyRBkpwIRPCZxlojouhBo5jEBO4toj6n7hMy6IxHU/c+MqDSWkvaTpPlMQcyA== import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" wrappy "1" @@ -2279,14 +2659,17 @@ inflight@^1.0.4: inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== inquirer@3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" + integrity sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c= dependencies: ansi-escapes "^1.1.0" chalk "^1.0.0" @@ -2305,6 +2688,7 @@ inquirer@3.0.6: insane@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/insane/-/insane-2.6.1.tgz#c7dcae7b51c20346883b71078fad6ce0483c198f" + integrity sha1-x9yue1HCA0aIO3EHj61s4Eg8GY8= dependencies: assignment "2.0.0" he "0.5.0" @@ -2312,64 +2696,76 @@ insane@2.6.1: invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== dependencies: loose-envify "^1.0.0" ipaddr.js@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" + integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= dependencies: kind-of "^3.0.2" is-accessor-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== dependencies: kind-of "^6.0.0" is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= dependencies: binary-extensions "^1.0.0" is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-callable@^1.1.3, is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== is-ci@^1.0.10: version "1.2.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== dependencies: ci-info "^1.5.0" is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= dependencies: kind-of "^3.0.2" is-data-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== dependencies: kind-of "^6.0.0" is-date-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== dependencies: is-accessor-descriptor "^0.1.6" is-data-descriptor "^0.1.4" @@ -2378,76 +2774,59 @@ is-descriptor@^0.1.0: is-descriptor@^1.0.0, is-descriptor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== dependencies: is-accessor-descriptor "^1.0.0" is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= is-extendable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= dependencies: is-extglob "^2.1.0" is-glob@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= dependencies: is-extglob "^2.1.1" is-installed-globally@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= dependencies: global-dirs "^0.1.0" is-path-inside "^1.0.0" @@ -2455,143 +2834,171 @@ is-installed-globally@^0.1.0: is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" + integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= dependencies: kind-of "^3.0.2" -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - is-obj@^1.0.0: version "1.0.1" - resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= is-path-inside@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= dependencies: path-is-inside "^1.0.1" +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= is-regex@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= dependencies: has "^1.0.1" is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== dependencies: has-symbols "^1.0.0" is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= iterall@^1.1.3, iterall@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" + integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== jmespath@0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= jquery@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca" + integrity sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg== -"js-tokens@^3.0.0 || ^4.0.0": +js-levenshtein@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.4.tgz#3a56e3cbf589ca0081eb22cd9ba0b1290a16d26e" + integrity sha512-PxfGzSs0ztShKrUYPIn5r0MtyAhYcCwmndozzpz8YObbPnD1jFxzlBGbRnX2mIu6Z13xN6+PTu05TQFnZFlzow== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.10.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== dependencies: argparse "^1.0.7" esprima "^4.0.0" -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= -json5@^0.5.1: - version "0.5.1" - resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json5@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz#056c90eee9a65ed6e6c72ddb0a1d325109aaf643" + version "8.4.0" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz#8757f7b4cb7440d86d5e2f3becefa70536c8e46a" + integrity sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg== dependencies: jws "^3.1.5" lodash.includes "^4.3.0" @@ -2606,6 +3013,7 @@ jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: jwa@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.6.tgz#87240e76c9808dbde18783cf2264ef4929ee50e6" + integrity sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw== dependencies: buffer-equal-constant-time "1.0.1" ecdsa-sig-formatter "1.0.10" @@ -2614,6 +3022,7 @@ jwa@^1.1.5: jws@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.5.tgz#80d12d05b293d1e841e7cb8b4e69e561adcf834f" + integrity sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ== dependencies: jwa "^1.1.5" safe-buffer "^5.0.1" @@ -2621,102 +3030,141 @@ jws@^3.1.5: kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= dependencies: is-buffer "^1.1.5" kind-of@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== latest-version@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= dependencies: package-json "^4.0.0" +libphonenumber-js@^1.6.4: + version "1.6.7" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.6.7.tgz#cb4501f6d1e5e0b4c8ccbd10ba489359f649dd73" + integrity sha512-vdt8x1ILa7pjpkQilAuS58xgFPBrgGLBoAQV4jEusIwvjqUV+tgr5po1sifP2RmAcmKaM1NdyIDXgmpyb4V8bg== + dependencies: + minimist "^1.2.0" + semver-compare "^1.0.0" + xml2js "^0.4.17" + linkifyjs@^2.1.7: version "2.1.7" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-2.1.7.tgz#e5d68d2ae30b9c055e1d74cc40f9a31d3abb4012" + integrity sha512-Cbn77BnYEslpAObZZoP6GVQHF1j5T6RsDydNq5RVxIy4eiZAiADRx7qHfWzfEMQecc1PtZFog1AsCGGX2WjQLA== optionalDependencies: jquery "^3.3.1" react "^16.4.2" react-dom "^16.4.2" +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= lodash.escaperegexp@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" + integrity sha1-ZHYsSGGAglGKw99Mz11YhtriA0c= lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= lodash.isboolean@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= lodash.isinteger@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= lodash.isnumber@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= lodash.isstring@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= lodash.mergewith@^4.6.0: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" + integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" 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== lru-cache@^4.0.1, lru-cache@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== dependencies: pseudomap "^1.0.2" yallist "^2.1.2" @@ -2724,60 +3172,46 @@ lru-cache@^4.0.1, lru-cache@^4.1.3: make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== dependencies: pify "^3.0.0" map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= map-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" + integrity sha1-ih8HiW2CsQkmvTdEokIACfiJdKg= map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: object-visit "^1.0.0" -math-random@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - -micromatch@^2.1.5: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -2793,91 +3227,104 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -mime-db@~1.36.0: - version "1.36.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" +mime-db@~1.37.0: + version "1.37.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" + integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== mime-types@~2.1.18: - version "2.1.20" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" + version "2.1.21" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" + integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== dependencies: - mime-db "~1.36.0" + mime-db "~1.37.0" mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - -minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@0.0.8: version "0.0.8" - resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= minimist@1.2.0, minimist@^1.2.0: version "1.2.0" - resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= -minipass@^2.2.1, minipass@^2.3.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" +minipass@^2.2.1, minipass@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" -minizlib@^1.1.0: +minizlib@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" + integrity sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg== dependencies: minipass "^2.2.1" mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" - resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" moment@^2.22.2: version "2.22.2" resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" + integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y= ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= nan@^2.9.2: version "2.11.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" + integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -2894,6 +3341,7 @@ nanomatch@^1.2.9: needle@^2.2.1: version "2.2.4" resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== dependencies: debug "^2.1.2" iconv-lite "^0.4.4" @@ -2902,17 +3350,21 @@ needle@^2.2.1: negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= neo4j-driver@^1.6.1: - version "1.6.3" - resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.6.3.tgz#b7a51bac401bd341082dff7766e8643d61752eb7" + version "1.7.1" + resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.1.tgz#f21571d18e632ff03be7e84c06b38e1bc66fb111" + integrity sha512-erJPOF8gv22zd/T/8XwJQ2xdXspNtUquUfi1YFMZ2BYRDdXp/NGzmVEH4DeCEk4dF5GkGA91WPuQVBOEOfmTdw== dependencies: - babel-runtime "^6.18.0" + babel-runtime "^6.26.0" + text-encoding "^0.6.4" uri-js "^4.2.1" neo4j-graphql-js@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.5.tgz#ef5d59d2e7cf46971af49bceec2f4bcd2debc835" + integrity sha512-Fn+lsynWeUy6AT2Xnzpl4vuBWTroUtAyK38qbBVd26z8SeWuQrlxtJFUEifU4VrQxw7tMfbLUSKt7Av+eDQiPw== dependencies: graphql "^0.13.2" lodash "^4.17.10" @@ -2920,22 +3372,31 @@ neo4j-graphql-js@1.0.5: node-fetch@1.6.3: version "1.6.3" - resolved "http://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" + integrity sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ= dependencies: encoding "^0.1.11" is-stream "^1.0.1" node-fetch@2.1.2: version "2.1.2" - resolved "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= -node-fetch@^2.1.2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5" +node-fetch@^2.1.2, node-fetch@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" + integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== + +node-modules-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" + integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= node-pre-gyp@^0.10.0: version "0.10.3" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== dependencies: detect-libc "^1.0.2" mkdirp "^0.5.1" @@ -2948,11 +3409,19 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -nodemon@^1.18.4: - version "1.18.4" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.4.tgz#873f65fdb53220eb166180cf106b1354ac5d714d" +node-releases@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.4.tgz#2d585de8c6c81d00017e063e7810a63889aa6756" + integrity sha512-GqRV9GcHw8JCRDaP/JoeNMNzEGzHAknMvIHqMb2VeTOmg1Cf9+ej8bkV12tHfzWHQMCkQ5zUFgwFUkfraynNCw== dependencies: - chokidar "^2.0.2" + semver "^5.3.0" + +nodemon@^1.18.4: + version "1.18.6" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.6.tgz#89b1136634d6c0afc7de24cc932a760e999e2c76" + integrity sha512-4pHQNYEZun+IkIC2jCaXEhkZnfA7rQe73i8RkdRyDJls/K+WxR7IpI5uNUsAvQ0zWvYcCDNGD+XVtw2ZG86/uQ== + dependencies: + chokidar "^2.0.4" debug "^3.1.0" ignore-by-default "^1.0.1" minimatch "^3.0.4" @@ -2966,6 +3435,7 @@ nodemon@^1.18.4: nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= dependencies: abbrev "1" osenv "^0.1.4" @@ -2973,22 +3443,26 @@ nopt@^4.0.1: nopt@~1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= dependencies: abbrev "1" -normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: +normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= dependencies: remove-trailing-separator "^1.0.1" npm-bundled@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== npm-packlist@^1.1.6: version "1.1.12" resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" + integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -2996,12 +3470,14 @@ npm-packlist@^1.1.6: 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" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= dependencies: path-key "^2.0.0" npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: are-we-there-yet "~1.1.2" console-control-strings "~1.1.0" @@ -3011,88 +3487,96 @@ npmlog@^4.0.2: nth-check@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== dependencies: boolbase "~1.0.0" number-is-nan@^1.0.0: version "1.0.1" 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= object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= dependencies: copy-descriptor "^0.1.0" define-property "^0.2.5" kind-of "^3.0.3" object-hash@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.0.tgz#76d9ba6ff113cf8efc0d996102851fe6723963e2" + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== object-keys@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== object-path@^0.11.4: version "0.11.4" resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" + integrity sha1-NwrnUvvzfePqcKhhwju6iRVpGUk= object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= dependencies: isobject "^3.0.0" object.getownpropertydescriptors@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= dependencies: define-properties "^1.1.2" es-abstract "^1.5.1" -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= dependencies: isobject "^3.0.1" on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= dependencies: ee-first "1.1.1" once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= dependencies: mimic-fn "^1.0.0" opencollective@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/opencollective/-/opencollective-1.0.3.tgz#aee6372bc28144583690c3ca8daecfc120dd0ef1" + integrity sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE= dependencies: babel-polyfill "6.23.0" chalk "1.1.3" @@ -3103,79 +3587,106 @@ opencollective@1.0.3: opn@4.0.2: version "4.0.2" - resolved "http://registry.npmjs.org/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" + resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" + integrity sha1-erwi5kTf9jsKltWrfyeQwPAavJU= dependencies: object-assign "^4.0.1" pinkie-promise "^2.0.0" optimism@^0.6.6: - version "0.6.6" - resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.6.tgz#5415b2d6a2f8b3745aedb9f97fdf4e52467ecd84" + version "0.6.8" + resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.8.tgz#0780b546da8cd0a72e5207e0c3706c990c8673a6" + integrity sha512-bN5n1KCxSqwBDnmgDnzMtQTHdL+uea2HYFx1smvtE+w2AMl0Uy31g0aXnP/Nt85OINnMJPRpJyfRQLTCqn5Weg== dependencies: - immutable-tuple "^0.4.4" + immutable-tuple "^0.4.9" os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= osenv@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -output-file-sync@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" +output-file-sync@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-2.0.1.tgz#f53118282f5f553c2799541792b723a4c71430c0" + integrity sha512-mDho4qm7WgIXIGf4eYU1RHN2UU5tPfVYVSRwDJw0uTmj35DQUt/eNp19N7v6T3SrR0ESTEf2up2CGO73qI35zQ== dependencies: - graceful-fs "^4.1.4" + graceful-fs "^4.1.11" + is-plain-obj "^1.1.0" mkdirp "^0.5.1" - object-assign "^4.1.0" p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= dependencies: got "^6.7.1" registry-auth-token "^3.0.1" registry-url "^3.0.3" semver "^5.1.0" -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= parse5@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" + integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== dependencies: "@types/node" "*" parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= passport-jwt@^4.0.0: version "4.0.0" - resolved "http://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" + resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" + integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg== dependencies: jsonwebtoken "^8.2.0" passport-strategy "^1.0.0" @@ -3183,10 +3694,12 @@ passport-jwt@^4.0.0: passport-strategy@1.x.x, passport-strategy@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= passport@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" + integrity sha1-xQlWkTR71a07XhgCOMORTRbwWBE= dependencies: passport-strategy "1.x.x" pause "0.0.1" @@ -3194,54 +3707,90 @@ passport@^0.4.0: path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-is-inside@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= path-key@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= pause-stream@^0.0.11: version "0.0.11" - resolved "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= dependencies: through "~2.3" pause@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pirates@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.0.tgz#850b18781b4ac6ec58a43c9ed9ec5fe6796addbd" + integrity sha512-8t5BsXy1LUIjn3WWOlOuFDuKswhQb/tkak641lvBgmPOBUQHXveORtlMCp6OdPV1dtuTaEahKA8VNz6uLfKBtA== + dependencies: + node-modules-regexp "^1.0.0" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= postcss@^6.0.14: version "6.0.23" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== dependencies: chalk "^2.4.1" source-map "^0.6.1" @@ -3250,22 +3799,22 @@ postcss@^6.0.14: prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - -private@^0.1.6, private@^0.1.8: +private@^0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" + integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== dependencies: loose-envify "^1.3.1" object-assign "^4.1.1" @@ -3273,6 +3822,7 @@ prop-types@^15.6.2: protobufjs@^6.8.6: version "6.8.8" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" + integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -3291,6 +3841,7 @@ protobufjs@^6.8.6: proxy-addr@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" + integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== dependencies: forwarded "~0.1.2" ipaddr.js "1.8.0" @@ -3298,50 +3849,51 @@ proxy-addr@~2.0.4: ps-tree@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" + integrity sha1-tCGyQUDWID8e08dplrRCewjowBQ= dependencies: event-stream "~3.3.0" pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= pstree.remy@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.0.tgz#f2af27265bd3e5b32bbfcc10e80bac55ba78688b" + integrity sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q== dependencies: ps-tree "^1.1.0" punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== qs@6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - -randomatic@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.0.tgz#36f2ca708e9e567f5ed2ec01949026d50aa10116" - dependencies: - is-number "^4.0.0" - kind-of "^6.0.0" - math-random "^1.0.1" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= raw-body@2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== dependencies: bytes "3.0.0" http-errors "1.6.3" @@ -3351,6 +3903,7 @@ raw-body@2.3.3: rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== dependencies: deep-extend "^0.6.0" ini "~1.3.0" @@ -3358,26 +3911,29 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: strip-json-comments "~2.0.1" react-dom@^16.4.2: - version "16.6.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.0.tgz#6375b8391e019a632a89a0988bce85f0cc87a92f" + version "16.6.3" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.3.tgz#8fa7ba6883c85211b8da2d0efeffc9d3825cccc0" + integrity sha512-8ugJWRCWLGXy+7PmNh8WJz3g1TaTUt1XyoIcFN+x0Zbkoz+KKdUyx1AQLYJdbFXjuF41Nmjn5+j//rxvhFjgSQ== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.10.0" + scheduler "^0.11.2" react@^16.4.2: - version "16.6.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.6.0.tgz#b34761cfaf3e30f5508bc732fb4736730b7da246" + version "16.6.3" + resolved "https://registry.yarnpkg.com/react/-/react-16.6.3.tgz#25d77c91911d6bbdd23db41e70fb094cc1e0871c" + integrity sha512-zCvmH2vbEolgKxtqXL2wmGCUxUyNheYn/C+PD1YAjfxHC54+MhdruyhO7QieQrYsYeTxrn93PM2y0jRH1zEExw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.10.0" + scheduler "^0.11.2" readable-stream@1.1.x: version "1.1.14" - resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= dependencies: core-util-is "~1.0.0" inherits "~2.0.1" @@ -3386,7 +3942,8 @@ readable-stream@1.1.x: readable-stream@^2.0.2, readable-stream@^2.0.6: version "2.3.6" - resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -3399,6 +3956,7 @@ readable-stream@^2.0.2, readable-stream@^2.0.6: readable-stream@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.0.6.tgz#351302e4c68b5abd6a2ed55376a7f9a25be3057a" + integrity sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" @@ -3407,59 +3965,70 @@ readable-stream@^3.0.6: readdirp@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: graceful-fs "^4.1.11" micromatch "^3.1.10" readable-stream "^2.0.2" -regenerate@^1.2.1: +regenerate-unicode-properties@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" + integrity sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== -regenerator-runtime@^0.10.0, regenerator-runtime@^0.10.5: +regenerator-runtime@^0.10.0: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= -regenerator-runtime@^0.11.0: +regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== regenerator-runtime@^0.12.0: version "0.12.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" + integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== -regenerator-transform@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" +regenerator-transform@^0.13.3: + version "0.13.3" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb" + integrity sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA== dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" private "^0.1.6" -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - dependencies: - is-equal-shallow "^0.1.3" - regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" +regexpu-core@^4.1.3, regexpu-core@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.2.0.tgz#a3744fa03806cffe146dea4421a3e73bdcc47b1d" + integrity sha512-Z835VSnJJ46CNBttalHD/dB+Sj2ezmY6Xp38npwU87peK6mqOzOpV8eYktdkLTEkzzD+JsTcxd84ozd8I14+rw== dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" + regenerate "^1.4.0" + regenerate-unicode-properties "^7.0.0" + regjsgen "^0.4.0" + regjsparser "^0.3.0" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.0.2" registry-auth-token@^3.0.1: version "3.3.2" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" + integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== dependencies: rc "^1.1.6" safe-buffer "^5.0.1" @@ -3467,44 +4036,53 @@ registry-auth-token@^3.0.1: registry-url@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= dependencies: rc "^1.0.1" -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" +regjsgen@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.4.0.tgz#c1eb4c89a209263f8717c782591523913ede2561" + integrity sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA== -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" +regjsparser@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.3.0.tgz#3c326da7fcfd69fa0d332575a41c8c0cdf588c96" + integrity sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA== dependencies: jsesc "~0.5.0" remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.5.2, repeat-string@^1.6.1: +repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.3.2: + version "1.8.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" + integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== + dependencies: + path-parse "^1.0.5" restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= dependencies: onetime "^2.0.0" signal-exit "^3.0.2" @@ -3512,44 +4090,53 @@ restore-cursor@^2.0.0: ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== retry@0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== dependencies: glob "^7.0.5" run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= dependencies: is-promise "^2.1.0" rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= dependencies: ret "~0.1.10" "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sanitize-html@^1.19.1: version "1.19.1" resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.1.tgz#e8b33c69578054d6ee4f57ea152d6497f3f6fb7d" + integrity sha512-zNYr6FvBn4bZukr9x2uny6od/9YdjCLwF+FqxivqI0YOt/m9GIxfX+tWhm52tBAPUXiTTb4bJTGVagRz5b06bw== dependencies: chalk "^2.3.0" htmlparser2 "^3.9.0" @@ -3564,32 +4151,43 @@ sanitize-html@^1.19.1: sax@1.2.1: version "1.2.1" - resolved "http://registry.npmjs.org/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= sax@>=0.6.0, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.10.0.tgz#7988de90fe7edccc774ea175a783e69c40c521e1" +scheduler@^0.11.2: + version "0.11.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.2.tgz#a8db5399d06eba5abac51b705b7151d2319d33d3" + integrity sha512-+WCP3s3wOaW4S7C1tl3TEXp4l9lJn0ZK8G3W3WKRWmw77Z2cIFUW2MiNTMHn5sCjxN+t7N43HAOOgMjyAg5hlg== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= dependencies: semver "^5.0.3" -semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: +semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== send@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== dependencies: debug "2.6.9" depd "~1.1.2" @@ -3608,6 +4206,7 @@ send@0.16.2: serve-static@1.13.2: version "1.13.2" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" @@ -3617,10 +4216,12 @@ serve-static@1.13.2: set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= set-value@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -3630,6 +4231,7 @@ set-value@^0.4.3: set-value@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -3639,34 +4241,41 @@ set-value@^2.0.0: setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= dependencies: shebang-regex "^1.0.0" shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== slug@^0.9.1: - version "0.9.1" - resolved "http://registry.npmjs.org/slug/-/slug-0.9.1.tgz#af08f608a7c11516b61778aa800dce84c518cfda" + version "0.9.2" + resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.2.tgz#e409e4dae3a4bd2fd283557e2806e0a8abb98242" + integrity sha512-WULwxWq6NBM/i24pV9st/WI9TwzjXYpNzxbWr9mRDj74Lqwb3ahsnWsWJtXHfBPpBqXb4m1hYt9S7eMyDkZsKA== dependencies: unicode ">= 0.3.1" snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: define-property "^1.0.0" isobject "^3.0.0" @@ -3675,12 +4284,14 @@ snapdragon-node@^2.0.1: snapdragon-util@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: kind-of "^3.2.0" snapdragon@^0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== dependencies: base "^0.11.1" debug "^2.2.0" @@ -3694,6 +4305,7 @@ snapdragon@^0.8.1: source-map-resolve@^0.5.0: version "0.5.2" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== dependencies: atob "^2.1.1" decode-uri-component "^0.2.0" @@ -3701,15 +4313,10 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - dependencies: - source-map "^0.5.6" - -source-map-support@^0.5.1: +source-map-support@^0.5.1, source-map-support@^0.5.9: version "0.5.9" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -3717,34 +4324,41 @@ source-map-support@^0.5.1: source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.6, source-map@^0.5.7: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: extend-shallow "^3.0.0" split@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== dependencies: through "2" sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= srcset@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/srcset/-/srcset-1.0.0.tgz#a5669de12b42f3b1d5e83ed03c71046fc48f41ef" + integrity sha1-pWad4StC87HV6D7QPHEEb8SPQe8= dependencies: array-uniq "^1.0.2" number-is-nan "^1.0.0" @@ -3752,6 +4366,7 @@ srcset@^1.0.0: static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= dependencies: define-property "^0.2.5" object-copy "^0.1.0" @@ -3759,14 +4374,17 @@ static-extend@^0.1.1: "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= statuses@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== stream-combiner@^0.2.2: version "0.2.2" - resolved "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" + integrity sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg= dependencies: duplexer "~0.1.1" through "~2.3.4" @@ -3774,10 +4392,12 @@ stream-combiner@^0.2.2: streamsearch@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" @@ -3786,6 +4406,7 @@ string-width@^1.0.1: "string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" @@ -3793,36 +4414,43 @@ string-width@^1.0.1: string_decoder@^1.1.1, string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" - resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= dependencies: ansi-regex "^3.0.0" strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: version "0.9.15" resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz#68a8b7ba0037d8c489fb2f5a102d1494db297d0d" + integrity sha512-f9eBfWdHsePQV67QIX+VRhf++dn1adyC/PZHP6XI5AfKnZ4n0FW+v5omxwdHVpd4xq2ZijaHEcmlQrhBY79ZWQ== dependencies: backo2 "^1.0.2" eventemitter3 "^3.1.0" @@ -3833,25 +4461,29 @@ subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" symbol-observable@^1.0.2, symbol-observable@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== tar@^4: - version "4.4.6" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" + version "4.4.8" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" + integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== dependencies: - chownr "^1.0.1" + chownr "^1.1.1" fs-minipass "^1.2.5" - minipass "^2.3.3" - minizlib "^1.1.0" + minipass "^2.3.4" + minizlib "^1.1.1" mkdirp "^0.5.0" safe-buffer "^5.1.2" yallist "^3.0.2" @@ -3859,36 +4491,48 @@ tar@^4: term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= dependencies: execa "^0.7.0" +text-encoding@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" + integrity sha1-45mpgiV6J22uQou5KEXLcb3CbRk= + through@2, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.4: version "2.3.8" - resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= timed-out@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: kind-of "^3.0.2" 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" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: is-number "^3.0.0" repeat-string "^1.6.1" @@ -3896,6 +4540,7 @@ to-regex-range@^2.1.0: to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: define-property "^2.0.2" extend-shallow "^3.0.2" @@ -3905,16 +4550,19 @@ to-regex@^3.0.1, to-regex@^3.0.2: touch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== dependencies: nopt "~1.0.10" trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= trunc-html@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/trunc-html/-/trunc-html-1.1.2.tgz#1e97d51f67d470b67662b1a670e6d0ea7a8edafe" + integrity sha1-HpfVH2fUcLZ2YrGmcObQ6nqO2v4= dependencies: assignment "2.2.0" insane "2.6.1" @@ -3923,10 +4571,12 @@ trunc-html@^1.1.2: trunc-text@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" + integrity sha1-WPh22KxZsiS3mDS7R4uGVuaWIrU= type-is@^1.6.16, type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== dependencies: media-typer "0.3.0" mime-types "~2.1.18" @@ -3934,16 +4584,42 @@ type-is@^1.6.16, type-is@~1.6.16: undefsafe@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76" + integrity sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY= dependencies: debug "^2.2.0" +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz#9f1dc76926d6ccf452310564fd834ace059663d4" + integrity sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz#5a533f31b4317ea76f17d807fa0d116546111dd0" + integrity sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg== + "unicode@>= 0.3.1": version "11.0.1" resolved "https://registry.yarnpkg.com/unicode/-/unicode-11.0.1.tgz#735bd422ec75cf28d396eb224d535d168d5f1db6" + integrity sha512-+cHtykLb+eF1yrSLWTwcYBrqJkTfX7Quoyg7Juhe6uylF43ZbMdxMuSHNYlnyLT8T7POAvavgBthzUF9AIaQvQ== union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= dependencies: arr-union "^3.1.0" get-value "^2.0.6" @@ -3953,16 +4629,19 @@ union-value@^1.0.0: unique-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= dependencies: crypto-random-string "^1.0.0" unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= dependencies: has-value "^0.3.1" isobject "^3.0.0" @@ -3970,14 +4649,17 @@ unset-value@^1.0.0: unzip-response@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= upath@^1.0.5: version "1.1.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== update-notifier@^2.3.0: version "2.5.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== dependencies: boxen "^1.2.1" chalk "^2.0.1" @@ -3993,22 +4675,26 @@ update-notifier@^2.3.0: uri-js@^4.2.1: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== dependencies: punycode "^2.1.0" urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= url-parse-lax@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= dependencies: prepend-http "^1.0.1" url@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ= dependencies: punycode "1.3.2" querystring "0.2.0" @@ -4016,18 +4702,17 @@ url@0.10.3: use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - -user-home@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= util.promisify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== dependencies: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" @@ -4035,54 +4720,65 @@ util.promisify@^1.0.0: utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= uuid@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== uuid@^3.1.0: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== -v8flags@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" +v8flags@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.1.tgz#42259a1461c08397e37fe1d4f1cfb59cad85a053" + integrity sha512-iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ== dependencies: - user-home "^1.1.1" + homedir-polyfill "^1.0.1" vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= whatwg-fetch@2.0.4: version "2.0.4" - resolved "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: string-width "^1.0.2 || 2" widest-line@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== dependencies: string-width "^2.1.1" wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= write-file-atomic@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== dependencies: graceful-fs "^4.1.11" imurmurhash "^0.1.4" @@ -4091,42 +4787,58 @@ write-file-atomic@^2.0.0: ws@^5.2.0: version "5.2.2" resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== + dependencies: + async-limiter "~1.0.0" + +ws@^6.0.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" + integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== dependencies: async-limiter "~1.0.0" xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= -xml2js@0.4.19: +xml2js@0.4.19, xml2js@^0.4.17: version "0.4.19" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== dependencies: sax ">=0.6.0" xmlbuilder "~9.0.1" xmlbuilder@~9.0.1: version "9.0.7" - resolved "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= xtend@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= yallist@^3.0.0, yallist@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= zen-observable-ts@^0.8.10: version "0.8.10" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz#18e2ce1c89fe026e9621fd83cc05168228fce829" + integrity sha512-5vqMtRggU/2GhePC9OU4sYEWOdvmayp2k3gjPf4F0mXwB3CSbbNznfDUvDJx9O2ZTa1EIXdJhPchQveFKwNXPQ== dependencies: zen-observable "^0.8.0" zen-observable@^0.8.0: - version "0.8.9" - resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.9.tgz#0475c760ff0eda046bbdfa4dc3f95d392807ac53" + version "0.8.11" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.11.tgz#d3415885eeeb42ee5abb9821c95bb518fcd6d199" + integrity sha512-N3xXQVr4L61rZvGMpWe8XoCGX8vhU35dPyQ4fm5CY/KDlG0F75un14hjbckPXTDuKUY6V0dqR2giT6xN8Y4GEQ== From 0df58f00a13581f6e8ccf6af8be19cdd60a76c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 20 Nov 2018 23:31:58 +0100 Subject: [PATCH 076/554] Setup unit/integration testing with mocha --- package.json | 4 +- src/middleware/permissionsMiddleware.test.js | 21 + yarn.lock | 1225 ++++++------------ 3 files changed, 392 insertions(+), 858 deletions(-) create mode 100644 src/middleware/permissionsMiddleware.test.js diff --git a/package.json b/package.json index 43a3d1184..7eedbc429 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "GraphQL Backend for Human Connection", "main": "src/index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test": "mocha --require @babel/register src/**/*.test.js", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "seedDb": "./node_modules/.bin/babel-node src/seed/seed-db.js" @@ -46,7 +46,9 @@ "trunc-html": "^1.1.2" }, "devDependencies": { + "chai": "^4.2.0", "faker": "^4.1.0", + "mocha": "^5.2.0", "nodemon": "^1.18.4" } } diff --git a/src/middleware/permissionsMiddleware.test.js b/src/middleware/permissionsMiddleware.test.js new file mode 100644 index 000000000..777395d74 --- /dev/null +++ b/src/middleware/permissionsMiddleware.test.js @@ -0,0 +1,21 @@ +import { describe, it } from 'mocha' +import { expect } from 'chai' + + +describe('query', () => { + describe('statistics', () => { + describe('authenticated user', () => { + describe('read', () => { + it('is forbidden', () => { + }) + }) + }) + + context('admin', () => { + describe('read', () => { + it('is permitted', () => { + }) + }) + }) + }) +}) diff --git a/yarn.lock b/yarn.lock index 62cdf11a7..7502a96f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,26 +2,17 @@ # yarn lockfile v1 -"@apollographql/apollo-tools@^0.2.6": - version "0.2.7" - resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.2.7.tgz#550502b315e49040e07d7e5065d15c5116c506e6" - integrity sha512-rsn4uN12gZWME+m9CLnUk+ImY+blKdWFFdS6TlQheXC7XA85twjQmOY0/n05qUtrxx1dM5QUXw1qLCZ4emWYbQ== - dependencies: - apollo-env "0.2.4" - "@apollographql/apollo-upload-server@^5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" - integrity sha512-tGAp3ULNyoA8b5o9LsU2Lq6SwgVPUOKAqKywu2liEtTvrFSGPrObwanhYwArq3GPeOqp2bi+JknSJCIU3oQN1Q== dependencies: "@babel/runtime-corejs2" "^7.0.0-rc.1" busboy "^0.2.14" object-path "^0.11.4" -"@apollographql/graphql-playground-html@^1.6.4": - version "1.6.4" - resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.4.tgz#8945edf73df846d50e027bb3b813d018a1c5925f" - integrity sha512-gwvaQO6/Hv4DEwhDLmmu2tzCU9oPjC5Xl9Kk8Yd0IxyKhYLlLalmkMMjsZLzU5H3fGaalLD96OYfxHL0ClVUDQ== +"@apollographql/graphql-playground-html@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz#15e1a042b97d6834e6d70b17cc73e1514fde9027" "@babel/cli@^7.1.5": version "7.1.5" @@ -623,17 +614,15 @@ source-map-support "^0.5.9" "@babel/runtime-corejs2@^7.0.0-rc.1": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.1.5.tgz#ec8341c9aec71d1139c985327314739d66b204a0" - integrity sha512-WsYRwQsFhVmxkAqwypPTZyV9GpkqMEaAr2zOItOmqSX2GBFaI+eq98CN81e13o0zaUKJOQGYyjhNVqj56nnkYg== + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.1.2.tgz#8695811a3fd8091f54f274b9320334e5e8c62200" dependencies: core-js "^2.5.7" regenerator-runtime "^0.12.0" "@babel/runtime@^7.0.0-beta.40": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.5.tgz#4170907641cf1f61508f563ece3725150cc6fe39" - integrity sha512-xKnPpXG/pvK1B90JkwwxSGii90rQGKtzcMt2gI5G6+M0REXaq6rOHsGC2ay6/d0Uje7zzvSzjEzfR3ENhFlrfA== + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.2.tgz#81c89935f4647706fc54541145e6b4ecfef4b8e3" dependencies: regenerator-runtime "^0.12.0" @@ -673,27 +662,22 @@ "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= "@protobufjs/base64@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== "@protobufjs/codegen@^2.0.4": version "2.0.4" resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== "@protobufjs/eventemitter@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= "@protobufjs/fetch@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= dependencies: "@protobufjs/aspromise" "^1.1.1" "@protobufjs/inquire" "^1.1.0" @@ -701,44 +685,36 @@ "@protobufjs/float@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= "@protobufjs/inquire@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= "@protobufjs/path@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= "@protobufjs/pool@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= "@protobufjs/utf8@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= "@types/accepts@^1.3.5": version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" - integrity sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ== + resolved "http://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" dependencies: "@types/node" "*" -"@types/async@2.0.50": - version "2.0.50" - resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.50.tgz#117540e026d64e1846093abbd5adc7e27fda7bcb" - integrity sha512-VMhZMMQgV1zsR+lX/0IBfAk+8Eb7dPVMWiQGFAt3qjo5x7Ml6b77jUo0e1C3ToD+XRDXqtrfw+6AB0uUsPEr3Q== +"@types/async@2.0.49": + version "2.0.49" + resolved "http://registry.npmjs.org/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0" "@types/body-parser@*", "@types/body-parser@1.17.0": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" - integrity sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w== dependencies: "@types/connect" "*" "@types/node" "*" @@ -746,26 +722,22 @@ "@types/connect@*": version "3.4.32" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" - integrity sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg== dependencies: "@types/node" "*" "@types/cors@^2.8.4": version "2.8.4" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.4.tgz#50991a759a29c0b89492751008c6af7a7c8267b0" - integrity sha512-ipZjBVsm2tF/n8qFGOuGBkUij9X9ZswVi9G3bx/6dz7POpVa6gVHcj1wsX/LVEn9MMF41fxK/PnZPPoTD1UFPw== dependencies: "@types/express" "*" "@types/events@*": version "1.2.0" - resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" - integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== + resolved "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" "@types/express-serve-static-core@*": version "4.16.0" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz#fdfe777594ddc1fe8eb8eccce52e261b496e43e7" - integrity sha512-lTeoCu5NxJU4OD9moCgm0ESZzweAx0YqsAcab6OB0EB3+As1OaHtKnaGJvcngQxYsi9UNv0abn4/DRavrRxt4w== dependencies: "@types/events" "*" "@types/node" "*" @@ -774,7 +746,6 @@ "@types/express@*", "@types/express@4.16.0", "@types/express@^4.11.1": version "4.16.0" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.0.tgz#6d8bc42ccaa6f35cf29a2b7c3333cb47b5a32a19" - integrity sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "*" @@ -783,45 +754,37 @@ "@types/graphql-deduplicator@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/graphql-deduplicator/-/graphql-deduplicator-2.0.0.tgz#9e577b8f3feb3d067b0ca756f4a1fb356d533922" - integrity sha512-swUwj5hWF1yFzbUXStLJrUa0ksAt11B8+SwhsAjQAX0LYJ1LLioAyuDcJ9bovWbsNzIXJYXLvljSPQw8nR728w== "@types/graphql@^0.13.0": version "0.13.4" resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.13.4.tgz#55ae9c29f0fd6b85ee536f5c72b4769d5c5e06b1" - integrity sha512-B4yel4ro2nTb3v0pYO8vO6SjgvFJSrwUY+IO6TUSLdOSB+gQFslylrhRCHxvXMIhxB71mv5PEE9dAX+24S8sew== "@types/long@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" - integrity sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q== "@types/mime@*": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" - integrity sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA== "@types/node@*", "@types/node@^10.1.0": - version "10.12.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.9.tgz#a07bfa74331471e1dc22a47eb72026843f7b95c8" - integrity sha512-eajkMXG812/w3w4a1OcBlaTwsFPO5F7fJ/amy+tieQxEMWBlbV1JGSjkFM+zkHNf81Cad+dfIRA+IBkvmvdAeA== + version "10.12.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.0.tgz#ea6dcbddbc5b584c83f06c60e82736d8fbb0c235" "@types/range-parser@*": version "1.2.2" resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.2.tgz#fa8e1ad1d474688a757140c91de6dace6f4abc8d" - integrity sha512-HtKGu+qG1NPvYe1z7ezLsyIaXYyi8SoAVqWDZgDQ8dLrsZvSzUNCwZyfX33uhWxL/SU0ZDQZ3nwZ0nimt507Kw== "@types/serve-static@*": version "1.13.2" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48" - integrity sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q== dependencies: "@types/express-serve-static-core" "*" "@types/mime" "*" -"@types/ws@^6.0.0": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28" - integrity sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q== +"@types/ws@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-5.1.2.tgz#f02d3b1cd46db7686734f3ce83bdf46c49decd64" dependencies: "@types/events" "*" "@types/node" "*" @@ -829,22 +792,18 @@ "@types/zen-observable@^0.5.3": version "0.5.4" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.4.tgz#b863a4191e525206819e008097ebf0fb2e3a1cdc" - integrity sha512-sW6xN96wUak4tgc89d0tbTg7QDGYhGv5hvQIS6h4mRCd8h2btiZ80loPU8cyLwsBbA4ZeQt0FjvUhJ4rNhdsGg== "@types/zen-observable@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" - integrity sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg== abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== accepts@^1.3.5, accepts@~1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" - integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= dependencies: mime-types "~2.1.18" negotiator "0.6.1" @@ -852,164 +811,136 @@ accepts@^1.3.5, accepts@~1.3.5: ansi-align@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" - integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= dependencies: string-width "^2.0.0" ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== dependencies: micromatch "^3.1.4" normalize-path "^2.1.1" apollo-boost@^0.1.10: - version "0.1.21" - resolved "https://registry.yarnpkg.com/apollo-boost/-/apollo-boost-0.1.21.tgz#1c6b5f53120bd46faa825715da40cf5578fd6fbb" - integrity sha512-3cA4LjzrMckbX02Vd02yfKsgunnqdZTLE5SRXr7SCzfJfkPjmD9VGS8eLUCd/FE5taM/FHNAuqy3u3PaPCjYvw== + version "0.1.16" + resolved "https://registry.yarnpkg.com/apollo-boost/-/apollo-boost-0.1.16.tgz#77f73a30c49ab6d749ddc3e5683a7e322c15f07d" dependencies: - apollo-cache "^1.1.20" - apollo-cache-inmemory "^1.3.10" - apollo-client "^2.4.6" + apollo-cache "^1.1.17" + apollo-cache-inmemory "^1.2.10" + apollo-client "^2.4.2" apollo-link "^1.0.6" apollo-link-error "^1.0.3" apollo-link-http "^1.3.1" apollo-link-state "^0.4.0" graphql-tag "^2.4.2" -apollo-cache-control@0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.2.tgz#fc98781e6df60346a20b0540450d02842c1212f2" - integrity sha512-/fhgCWGEoTsgyA83usy/1NvJWi6hbD4rSGO5jvyNNtMZ9ledOvKUvIdzSQ1r5hxK5yds/eehWXhMJ4Pu200qrQ== - dependencies: - apollo-server-env "2.2.0" - graphql-extensions "0.3.2" - apollo-cache-control@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz#173d14ceb3eb9e7cb53de7eb8b61bee6159d4171" - integrity sha512-XJQs167e9u+e5ybSi51nGYr70NPBbswdvTEHtbtXbwkZ+n9t0SLPvUcoqceayOSwjK1XYOdU/EKPawNdb3rLQA== dependencies: graphql-extensions "^0.0.x" -apollo-cache-inmemory@^1.2.5, apollo-cache-inmemory@^1.3.10: - version "1.3.10" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.10.tgz#2e5375ad7ac0d30d59aaae3a2b5967673d0cf968" - integrity sha512-cJL8xxX2iytludvxY4goxYJ41n8avXirAjQkEwgSvGqrEzC0PG2DwtHZZh1QTnRRuM1rgj4MKiUiX/Ykhc5L+Q== +apollo-cache-control@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.2.5.tgz#0831ad796754a7beec858668f99e7517fe744a1e" dependencies: - apollo-cache "^1.1.20" - apollo-utilities "^1.0.25" + apollo-server-env "^2.0.3" + graphql-extensions "^0.2.1" + +apollo-cache-inmemory@^1.2.10, apollo-cache-inmemory@^1.2.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.5.tgz#7628ee598271cfffa611e15a7ce67652a84b07b0" + dependencies: + apollo-cache "^1.1.17" + apollo-utilities "^1.0.21" optimism "^0.6.6" -apollo-cache@1.1.20, apollo-cache@^1.1.20: - version "1.1.20" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.20.tgz#6152cc4baf6a63e376efee79f75de4f5c84bf90e" - integrity sha512-+Du0/4kUSuf5PjPx0+pvgMGV12ezbHA8/hubYuqRQoy/4AWb4faa61CgJNI6cKz2mhDd9m94VTNKTX11NntwkQ== +apollo-cache@1.1.17, apollo-cache@^1.1.17: + version "1.1.17" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.17.tgz#1fcca8423125223723b97fd72808be91a1a76490" dependencies: - apollo-utilities "^1.0.25" + apollo-utilities "^1.0.21" -apollo-client@^2.3.2, apollo-client@^2.4.6: - version "2.4.6" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.6.tgz#ba24a2def6ea9d487b41672652ca967cc7c05e4a" - integrity sha512-RsZVMYone7mu3Wj4sr7ehctN8pdaHsP4X1Sv6Ly4gZ/YDetCCVnhbmnk5q7kvDtfoo0jhhHblxgFyA3FLLImtA== +apollo-client@^2.3.2, apollo-client@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.2.tgz#d2f044d8740723bf98a6d8d8b9684ee8c36150e6" dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.20" + apollo-cache "1.1.17" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "1.0.25" + apollo-utilities "1.0.21" symbol-observable "^1.0.2" zen-observable "^0.8.0" optionalDependencies: - "@types/async" "2.0.50" + "@types/async" "2.0.49" -apollo-datasource@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.2.0.tgz#ea28313689073150b18f0dbe35bedffc86a62b57" - integrity sha512-WJM9Ix3uogIfAG7mjL1NZQM9+45rcikn4mPWhE1Iuyw2+Y857J3uKJqQgF5h9Fg64SlCJh9u5WL3N7N5mg1fVw== +apollo-datasource@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.1.3.tgz#e7ae9d20f29a8a35f239b02f0c47169cfd78d70b" dependencies: - apollo-server-caching "0.2.0" - apollo-server-env "2.2.0" + apollo-server-caching "0.1.2" + apollo-server-env "2.0.3" -apollo-engine-reporting-protobuf@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.1.0.tgz#fbc220cac2a3b7800ffc155d7e54c21c56b7848e" - integrity sha512-GReJtAYTmpwg0drb9VgFtqObYYTCHkJhlHEYCeXY8bJV4fOgXsAZ7CIXR9nPKO0mBaoHIHaGYvXGcyCLrZ36VA== +apollo-engine-reporting-protobuf@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz#cd394f0f769c6f97d8621c4a7839095c84efcdb0" dependencies: protobufjs "^6.8.6" -apollo-engine-reporting@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.2.tgz#6247e8d618da5c084ccb1bc76c665ce7a1b1ba55" - integrity sha512-W6zBTypI2ZLe9ZpMI4EasyXJP2WG8CpxYOU3Q4iuCKh8HYJqrQC5QVFXRF7TRBQTE6tc1seYnAHdgqv0ozxBrw== +apollo-engine-reporting@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.0.6.tgz#c1a74dffce782525f8a3230e4e5228fbd05bbd59" dependencies: - apollo-engine-reporting-protobuf "0.1.0" - apollo-server-env "2.2.0" + apollo-engine-reporting-protobuf "^0.0.1" + apollo-server-env "^2.0.3" async-retry "^1.2.1" - graphql-extensions "0.3.2" + graphql-extensions "^0.2.1" lodash "^4.17.10" -apollo-env@0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.2.4.tgz#6af44ef0af1b8c8a4d7da5d66ff55909858a88fa" - integrity sha512-pphNvrS7JmgvkvhaNEh+u0GpolytboAQcNbwmgskvX0VaLPfrrVox0AwHCteReB8t8s87NhbLd0VTG1nxmjFfQ== - dependencies: - core-js "^3.0.0-beta.3" - node-fetch "^2.2.0" - apollo-link-dedup@^1.0.0: version "1.0.10" resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.10.tgz#7b94589fe7f969777efd18a129043c78430800ae" - integrity sha512-tpUI9lMZsidxdNygSY1FxflXEkUZnvKRkMUsXXuQUNoSLeNtEvUX7QtKRAl4k9ubLl8JKKc9X3L3onAFeGTK8w== dependencies: apollo-link "^1.2.3" apollo-link-error@^1.0.3: version "1.1.1" resolved "https://registry.yarnpkg.com/apollo-link-error/-/apollo-link-error-1.1.1.tgz#69d7124d4dc11ce60f505c940f05d4f1aa0945fb" - integrity sha512-/yPcaQWcBdB94vpJ4FsiCJt1dAGGRm+6Tsj3wKwP+72taBH+UsGRQQZk7U/1cpZwl1yqhHZn+ZNhVOebpPcIlA== dependencies: apollo-link "^1.2.3" apollo-link-http-common@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.5.tgz#d094beb7971523203359bf830bfbfa7b4e7c30ed" - integrity sha512-6FV1wr5AqAyJ64Em1dq5hhGgiyxZE383VJQmhIoDVc3MyNcFL92TkhxREOs4rnH2a9X2iJMko7nodHSGLC6d8w== dependencies: apollo-link "^1.2.3" apollo-link-http@^1.3.1, apollo-link-http@^1.5.4: version "1.5.5" resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.5.tgz#7dbe851821771ad67fa29e3900c57f38cbd80da8" - integrity sha512-C5N6N/mRwmepvtzO27dgMEU3MMtRKSqcljBkYNZmWwH11BxkUQ5imBLPM3V4QJXNE7NFuAQAB5PeUd4ligivTQ== dependencies: apollo-link "^1.2.3" apollo-link-http-common "^0.2.5" @@ -1017,7 +948,6 @@ apollo-link-http@^1.3.1, apollo-link-http@^1.5.4: apollo-link-state@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/apollo-link-state/-/apollo-link-state-0.4.2.tgz#ac00e9be9b0ca89eae0be6ba31fe904b80bbe2e8" - integrity sha512-xMPcAfuiPVYXaLwC6oJFIZrKgV3GmdO31Ag2eufRoXpvT0AfJZjdaPB4450Nu9TslHRePN9A3quxNueILlQxlw== dependencies: apollo-utilities "^1.0.8" graphql-anywhere "^4.1.0-alpha.0" @@ -1025,97 +955,85 @@ apollo-link-state@^0.4.0: apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.2, apollo-link@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.3.tgz#9bd8d5fe1d88d31dc91dae9ecc22474d451fb70d" - integrity sha512-iL9yS2OfxYhigme5bpTbmRyC+Htt6tyo2fRMHT3K1XRL/C5IQDDz37OjpPy4ndx7WInSvfSZaaOTKFja9VWqSw== dependencies: apollo-utilities "^1.0.0" zen-observable-ts "^0.8.10" -apollo-server-caching@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.2.0.tgz#fe560752d364f14d34c1eaacd9df629f8ed1cf5c" - integrity sha512-/v7xWEcyyahs3hwX4baH/GekuHz3LRt9NoIYwg869G1eeqjuwY6NsowRIujZ100anJQwm9v5A9/sLtHBFvbgYg== +apollo-server-caching@0.1.2, apollo-server-caching@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.1.2.tgz#f5b85701945110a5fca1956450e8553576635936" dependencies: lru-cache "^4.1.3" -apollo-server-core@2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.2.tgz#66ca6b4af6c7cdd8155de946d0c4fea3357b0432" - integrity sha512-F6d4u5m1rJB4ucpLPGCoa9Dvo5OjGMIGdAzT9A35yOvlFWwvIR46jGmYmGmNp4Qx852rb1axSZVzNy7k/Dix0w== - dependencies: - "@apollographql/apollo-tools" "^0.2.6" - "@apollographql/apollo-upload-server" "^5.0.3" - "@apollographql/graphql-playground-html" "^1.6.4" - "@types/ws" "^6.0.0" - apollo-cache-control "0.3.2" - apollo-datasource "0.2.0" - apollo-engine-reporting "0.1.2" - apollo-server-caching "0.2.0" - apollo-server-env "2.2.0" - apollo-server-errors "2.2.0" - apollo-server-plugin-base "0.1.2" - apollo-tracing "0.3.2" - graphql-extensions "0.3.2" - graphql-subscriptions "^1.0.0" - graphql-tag "^2.9.2" - graphql-tools "^4.0.0" - json-stable-stringify "^1.0.1" - lodash "^4.17.10" - subscriptions-transport-ws "^0.9.11" - ws "^6.0.0" - apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592" - integrity sha512-BP1Vh39krgEjkQxbjTdBURUjLHbFq1zeOChDJgaRsMxGtlhzuLWwwC6lLdPatN8jEPbeHq8Tndp9QZ3iQZOKKA== dependencies: apollo-cache-control "^0.1.0" apollo-tracing "^0.1.0" graphql-extensions "^0.0.x" -apollo-server-env@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.2.0.tgz#5eec5dbf46581f663fd6692b2e05c7e8ae6d6034" - integrity sha512-wjJiI5nQWPBpNmpiLP389Ezpstp71szS6DHAeTgYLb/ulCw3CTuuA+0/E1bsThVWiQaDeHZE0sE3yI8q2zrYiA== +apollo-server-core@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.1.0.tgz#b56f9f1ddb948b257e738eb25c5fdfd2f2fb2e07" + dependencies: + "@apollographql/apollo-upload-server" "^5.0.3" + "@types/ws" "^5.1.2" + apollo-cache-control "^0.2.5" + apollo-datasource "^0.1.3" + apollo-engine-reporting "^0.0.6" + apollo-server-caching "^0.1.2" + apollo-server-env "^2.0.3" + apollo-server-errors "^2.0.2" + apollo-tracing "^0.2.5" + graphql-extensions "^0.2.1" + graphql-subscriptions "^0.5.8" + graphql-tag "^2.9.2" + graphql-tools "^3.0.4" + hash.js "^1.1.3" + lodash "^4.17.10" + subscriptions-transport-ws "^0.9.11" + ws "^5.2.0" + +apollo-server-env@2.0.3, apollo-server-env@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.0.3.tgz#3c13552cd33f400160076cf8e1c9b24be4d27e13" dependencies: node-fetch "^2.1.2" util.promisify "^1.0.0" -apollo-server-errors@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" - integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== +apollo-server-errors@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz#e9cbb1b74d2cd78aed23cd886ca2d0c186323b2b" -apollo-server-express@2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.2.2.tgz#e6811024cac695351600c18985331b43ba24f556" - integrity sha512-DPxHOUd0Waztuix0r1ed6xfdlR7P7RzIXPmybhPXj1bZJtYHz5If0ngYNjtFqnXVrC8aSRtMz108SQUAnduYwA== +apollo-server-express@^1.3.6: + version "1.4.0" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.4.0.tgz#7d7c58d6d6f9892b83fe575669093bb66738b125" + dependencies: + apollo-server-core "^1.4.0" + apollo-server-module-graphiql "^1.4.0" + +apollo-server-express@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.1.0.tgz#b2d423c2c934df5c4e0a1b0d5f0088a9461f3c86" dependencies: "@apollographql/apollo-upload-server" "^5.0.3" - "@apollographql/graphql-playground-html" "^1.6.4" + "@apollographql/graphql-playground-html" "^1.6.0" "@types/accepts" "^1.3.5" "@types/body-parser" "1.17.0" "@types/cors" "^2.8.4" "@types/express" "4.16.0" accepts "^1.3.5" - apollo-server-core "2.2.2" + apollo-server-core "^2.1.0" body-parser "^1.18.3" cors "^2.8.4" - graphql-subscriptions "^1.0.0" - graphql-tools "^4.0.0" + graphql-subscriptions "^0.5.8" + graphql-tools "^3.0.4" type-is "^1.6.16" -apollo-server-express@^1.3.6: - version "1.4.0" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.4.0.tgz#7d7c58d6d6f9892b83fe575669093bb66738b125" - integrity sha512-zkH00nxhLnJfO0HgnNPBTfZw8qI5ILaPZ5TecMCI9+Y9Ssr2b0bFr9pBRsXy9eudPhI+/O4yqegSUsnLdF/CPw== - dependencies: - apollo-server-core "^1.4.0" - apollo-server-module-graphiql "^1.4.0" - apollo-server-lambda@1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/apollo-server-lambda/-/apollo-server-lambda-1.3.6.tgz#bdaac37f143c6798e40b8ae75580ba673cea260e" - integrity sha1-varDfxQ8Z5jkC4rnVYC6ZzzqJg4= dependencies: apollo-server-core "^1.3.6" apollo-server-module-graphiql "^1.3.4" @@ -1123,64 +1041,52 @@ apollo-server-lambda@1.3.6: apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" - integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== - -apollo-server-plugin-base@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.2.tgz#4c1ebb769b630a16ff8ade03f12759cde17a21dc" - integrity sha512-+uicMcNctlP6YwIhzLLEycZzao/810OSzcxgPYKItXr5lGa1GuHD7sRIWldT3YoSdpw6Gal2lBuw6/DmnoDsPg== apollo-server@^2.0.4: - version "2.2.2" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.2.2.tgz#b17f91730ef399b42c2ba6ea366320ed0d6a9774" - integrity sha512-LiVId1s7o+4IqReyzqfqxVyNYr6BOGsaYyqUH4R5Vb0gRw5igmZEiYz4g+dqTrUT4Ktv2gDyFumM+MxNm+Gjqg== + version "2.1.0" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.1.0.tgz#abec7853647c59f386087352cc7f06a4f1f8afe2" dependencies: - apollo-server-core "2.2.2" - apollo-server-express "2.2.2" + apollo-server-core "^2.1.0" + apollo-server-express "^2.1.0" express "^4.0.0" - graphql-subscriptions "^1.0.0" - graphql-tools "^4.0.0" - -apollo-tracing@0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.2.tgz#1a6b695813791b8404b5adaa10925a7f2642f15d" - integrity sha512-YwN1m1k0JJsxGh0QWsEM3OLnyem0GT2tZnGeO2OogCr6dH5lE0SjKPc6UzpcI/3fPyxRrx5QvpUiP+DJeehhTA== - dependencies: - apollo-server-env "2.2.0" - graphql-extensions "0.3.2" + graphql-subscriptions "^0.5.8" + graphql-tools "^3.0.4" apollo-tracing@^0.1.0: version "0.1.4" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" - integrity sha512-Uv+1nh5AsNmC3m130i2u3IqbS+nrxyVV3KYimH5QKsdPjxxIQB3JAT+jJmpeDxBel8gDVstNmCh82QSLxLSIdQ== + resolved "http://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" dependencies: graphql-extensions "~0.0.9" +apollo-tracing@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.2.5.tgz#15bb8d6f37efe8c1bb6351e8e21521dd4f14c5f2" + dependencies: + apollo-server-env "^2.0.3" + graphql-extensions "^0.2.1" + apollo-upload-server@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/apollo-upload-server/-/apollo-upload-server-5.0.0.tgz#c953b523608313966e0c8444637f4ae8ef77d5bc" - integrity sha512-CzbHvMo/6TO5XrovzmV/ojTft17s9Cd+vKLGngChpB0UW1ObxKlNLlcXRLD+yt6Nec32/Kt209HmA31hnwxB/g== + resolved "http://registry.npmjs.org/apollo-upload-server/-/apollo-upload-server-5.0.0.tgz#c953b523608313966e0c8444637f4ae8ef77d5bc" dependencies: "@babel/runtime" "^7.0.0-beta.40" busboy "^0.2.14" object-path "^0.11.4" -apollo-utilities@1.0.25, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.25, apollo-utilities@^1.0.8: - version "1.0.25" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.25.tgz#899b00f5f990fb451675adf84cb3de82eb6372ea" - integrity sha512-AXvqkhni3Ir1ffm4SA1QzXn8k8I5BBl4PVKEyak734i4jFdp+xgfUyi2VCqF64TJlFTA/B73TRDUvO2D+tKtZg== +apollo-utilities@1.0.21, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.21, apollo-utilities@^1.0.8: + version "1.0.21" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.21.tgz#cb8b5779fe275850b16046ff8373f4af2de90765" dependencies: fast-json-stable-stringify "^2.0.0" + fclone "^1.0.11" aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== are-we-there-yet@~1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== dependencies: delegates "^1.0.0" readable-stream "^2.0.6" @@ -1188,90 +1094,79 @@ are-we-there-yet@~1.1.2: argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= array-uniq@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= assignment@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.0.0.tgz#ffd17b21bf5d6b22e777b989681a815456a3dd3e" - integrity sha1-/9F7Ib9dayLnd7mJaBqBVFaj3T4= assignment@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.2.0.tgz#f5b5bc2d160d69986e8700cd38f567c0aabe101e" - integrity sha1-9bW8LRYNaZhuhwDNOPVnwKq+EB4= async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - integrity sha1-GdOGodntxufByF04iu28xW0zYC0= async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== async-retry@^1.2.1: version "1.2.3" resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.2.3.tgz#a6521f338358d322b1a0012b79030c6f411d1ce0" - integrity sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q== dependencies: retry "0.12.0" atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== aws-lambda@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/aws-lambda/-/aws-lambda-0.1.2.tgz#19b1585075df31679597b976a5f1def61f12ccee" - integrity sha1-GbFYUHXfMWeVl7l2pfHe9h8SzO4= dependencies: aws-sdk "^*" commander "^2.5.0" dotenv "^0.4.0" aws-sdk@^*: - version "2.360.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.360.0.tgz#f640acbc7de07aa7a381a31b110fc3502fe90288" - integrity sha512-bzr2j6s1LNlkWDTgnFszr2r7eJ2/DfWx4GJbGV17LKnxC9ZHkHKtX50sEa1g4Yzb1RveSXlC3Hfyus92gPQ4BQ== + version "2.336.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.336.0.tgz#b15371aff3e30ba77b74968c086375594be897c9" dependencies: buffer "4.9.1" events "1.1.1" @@ -1286,16 +1181,14 @@ aws-sdk@^*: babel-polyfill@6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" - integrity sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0= dependencies: babel-runtime "^6.22.0" core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-runtime@^6.22.0, babel-runtime@^6.26.0: +babel-runtime@^6.18.0, babel-runtime@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= dependencies: core-js "^2.4.0" regenerator-runtime "^0.11.0" @@ -1303,22 +1196,18 @@ babel-runtime@^6.22.0, babel-runtime@^6.26.0: backo2@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" - integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2: version "1.3.0" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: cache-base "^1.0.1" class-utils "^0.3.5" @@ -1331,24 +1220,20 @@ base@^0.11.1: bcryptjs@^2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" - integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= binary-extensions@^1.0.0: version "1.12.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" - integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== body-parser-graphql@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/body-parser-graphql/-/body-parser-graphql-1.1.0.tgz#80a80353c7cb623562fd375750dfe018d75f0f7c" - integrity sha512-bOBF4n1AnUjcY1SzLeibeIx4XOuYqEkjn/Lm4yKhnN6KedoXMv4hVqgcKHGRnxOMJP64tErqrQU+4cihhpbJXg== dependencies: body-parser "^1.18.2" body-parser@1.18.3, body-parser@^1.18.2, body-parser@^1.18.3: version "1.18.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" - integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= dependencies: bytes "3.0.0" content-type "~1.0.4" @@ -1364,12 +1249,10 @@ body-parser@1.18.3, body-parser@^1.18.2, body-parser@^1.18.3: boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= boxen@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" - integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== dependencies: ansi-align "^2.0.0" camelcase "^4.0.0" @@ -1382,7 +1265,6 @@ boxen@^1.2.1: brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -1390,7 +1272,6 @@ brace-expansion@^1.1.7: braces@^2.3.0, braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: arr-flatten "^1.1.0" array-unique "^0.3.2" @@ -1403,6 +1284,11 @@ braces@^2.3.0, braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + browserslist@^4.1.0: version "4.3.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.4.tgz#4477b737db6a1b07077275b24791e680d4300425" @@ -1415,17 +1301,14 @@ browserslist@^4.1.0: buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== buffer@4.9.1: version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + resolved "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -1434,7 +1317,6 @@ buffer@4.9.1: busboy@^0.2.14: version "0.2.14" resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" - integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= dependencies: dicer "0.2.5" readable-stream "1.1.x" @@ -1442,12 +1324,10 @@ busboy@^0.2.14: bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: collection-visit "^1.0.0" component-emitter "^1.2.1" @@ -1462,7 +1342,6 @@ cache-base@^1.0.1: camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= caniuse-lite@^1.0.30000899: version "1.0.30000909" @@ -1472,12 +1351,22 @@ caniuse-lite@^1.0.30000899: capture-stack-trace@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" - integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + +chai@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" + integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^3.0.1" + get-func-name "^2.0.0" + pathval "^1.1.0" + type-detect "^4.0.5" chalk@1.1.3, chalk@^1.0.0: version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -1497,12 +1386,15 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" - integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= + +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= cheerio@^1.0.0-rc.2: version "1.0.0-rc.2" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" - integrity sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs= dependencies: css-select "~1.2.0" dom-serializer "~0.1.0" @@ -1511,7 +1403,7 @@ cheerio@^1.0.0-rc.2: lodash "^4.15.0" parse5 "^3.0.1" -chokidar@^2.0.3, chokidar@^2.0.4: +chokidar@^2.0.2, chokidar@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== @@ -1531,20 +1423,17 @@ chokidar@^2.0.3, chokidar@^2.0.4: optionalDependencies: fsevents "^1.2.2" -chownr@^1.1.1: +chownr@^1.0.1: version "1.1.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" - integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== ci-info@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== dependencies: arr-union "^3.1.0" define-property "^0.2.5" @@ -1554,29 +1443,24 @@ class-utils@^0.3.5: cli-boxes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: restore-cursor "^2.0.0" cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= dependencies: map-visit "^1.0.0" object-visit "^1.0.0" @@ -1584,14 +1468,17 @@ collection-visit@^1.0.0: color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== commander@^2.5.0, commander@^2.8.1: version "2.19.0" @@ -1606,17 +1493,14 @@ commondir@^1.0.1: component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= configstore@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" - integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== dependencies: dot-prop "^4.1.0" graceful-fs "^4.1.2" @@ -1628,17 +1512,14 @@ configstore@^3.0.0: console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" - integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== convert-source-map@^1.1.0: version "1.6.0" @@ -1650,37 +1531,26 @@ convert-source-map@^1.1.0: cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js@^2.4.0, core-js@^2.5.3, core-js@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" - integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== - -core-js@^3.0.0-beta.3: - version "3.0.0-beta.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.3.tgz#b0f22009972b8c6c04550ebf38513ca4b3cc9559" - integrity sha512-kM/OfrnMThP5PwGAj5HhQLdjUqzjrllqN2EVnk/X9qrLsfYjR2hzZ+E/8CzH0xuosexZtqMTLQrk//BULrBj9w== core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= cors@^2.8.4: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + version "2.8.4" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.4.tgz#2bd381f2eb201020105cd50ea59da63090694686" dependencies: object-assign "^4" vary "^1" @@ -1688,14 +1558,12 @@ cors@^2.8.4: create-error-class@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= dependencies: capture-stack-trace "^1.0.0" cross-fetch@2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.2.tgz#a47ff4f7fc712daba8f6a695a11c948440d45723" - integrity sha1-pH/09/xxLauo9qaVoRyUhEDUVyM= dependencies: node-fetch "2.1.2" whatwg-fetch "2.0.4" @@ -1703,7 +1571,6 @@ cross-fetch@2.2.2: cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= dependencies: lru-cache "^4.0.1" shebang-command "^1.2.0" @@ -1712,12 +1579,10 @@ cross-spawn@^5.0.1: crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= css-select@~1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + resolved "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" dependencies: boolbase "~1.0.0" css-what "2.1" @@ -1727,24 +1592,27 @@ css-select@~1.2.0: css-what@2.1: version "2.1.2" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" - integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ== date-fns@^2.0.0-alpha.24: - version "2.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.25.tgz#651a5d1f59a01af6cf0371e39b2ae29df5d521ee" - integrity sha512-iQzJkHF0L4wah9Ae9PkvwemwFz6qmRLuNZcghmvf2t+ptLs1qXzONLiGtjmPQzL6+JpC01JjlTopY2AEy4NFAg== + version "2.0.0-alpha.24" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.24.tgz#2988c137c72275af29d7d21cc53eb52b3a8c2586" debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== dependencies: ms "2.0.0" debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== dependencies: ms "^2.1.1" @@ -1758,38 +1626,39 @@ debug@^4.1.0: decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== define-properties@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== dependencies: object-keys "^1.0.12" define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= dependencies: is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== dependencies: is-descriptor "^1.0.2" isobject "^3.0.1" @@ -1797,40 +1666,38 @@ define-property@^2.0.2: delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= deprecated-decorator@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" - integrity sha1-AJZjF7ehL+kvPMgx91g68ym4bDc= destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= dicer@0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" - integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= dependencies: readable-stream "1.1.x" streamsearch "0.1.2" +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + dom-serializer@0, dom-serializer@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" - integrity sha1-BzxpdUbOB4DOI75KKOKT5AvDDII= dependencies: domelementtype "~1.1.1" entities "~1.1.1" @@ -1838,29 +1705,24 @@ dom-serializer@0, dom-serializer@~0.1.0: domelementtype@1: version "1.2.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.2.1.tgz#578558ef23befac043a1abb0db07635509393479" - integrity sha512-SQVCLFS2E7G5CRCMdn6K9bIhRj1bS6QBWZfF0TUPh4V/BbqrQ619IdSS3/izn0FZ+9l+uODzaZjb08fjOfablA== domelementtype@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" - integrity sha1-sXrtguirWeUt2cGbF1bg/BhyBMI= + resolved "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" domelementtype@~1.1.1: version "1.1.3" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" - integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs= + resolved "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" domhandler@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== dependencies: domelementtype "1" domutils@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= dependencies: dom-serializer "0" domelementtype "1" @@ -1868,7 +1730,6 @@ domutils@1.5.1: domutils@^1.5.1: version "1.7.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== dependencies: dom-serializer "0" domelementtype "1" @@ -1876,41 +1737,34 @@ domutils@^1.5.1: dot-prop@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" - integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== dependencies: is-obj "^1.0.0" dotenv@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" - integrity sha1-9vs1E2PC2SIHJFxzeALJq1rhSVo= + resolved "http://registry.npmjs.org/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" dotenv@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.1.0.tgz#9853b6ca98292acb7dec67a95018fa40bccff42c" - integrity sha512-/veDn2ztgRlB7gKmE3i9f6CmDIyXAy6d5nBq+whO9SLX+Zs1sXEgFLPi+aSuWqUuusMfbi84fT8j34fs1HaYUw== duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + resolved "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" ecdsa-sig-formatter@1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz#1c595000f04a8897dfb85000892a0f4c33af86c3" - integrity sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM= dependencies: safe-buffer "^5.0.1" ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.82: version "1.3.84" @@ -1920,24 +1774,20 @@ electron-to-chromium@^1.3.82: encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= encoding@^0.1.11: version "0.1.12" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= dependencies: iconv-lite "~0.4.13" entities@^1.1.1, entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== es-abstract@^1.5.1: version "1.12.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" - integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== dependencies: es-to-primitive "^1.1.1" function-bind "^1.1.1" @@ -1948,7 +1798,6 @@ es-abstract@^1.5.1: es-to-primitive@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== dependencies: is-callable "^1.1.4" is-date-object "^1.0.1" @@ -1957,32 +1806,26 @@ es-to-primitive@^1.1.1: escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= event-stream@~3.3.0: version "3.3.6" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.6.tgz#cac1230890e07e73ec9cacd038f60a5b66173eef" - integrity sha512-dGXNg4F/FgVzlApjzItL+7naHutA3fDqbV/zAZqDDlXTjiMnQmZKu+prImWKszeBM5UQeGvAl3u1wBiKeDh61g== dependencies: duplexer "^0.1.1" flatmap-stream "^0.1.0" @@ -1996,17 +1839,14 @@ event-stream@~3.3.0: eventemitter3@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" - integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== events@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + resolved "http://registry.npmjs.org/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -2019,7 +1859,6 @@ execa@^0.7.0: expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= dependencies: debug "^2.3.3" define-property "^0.2.5" @@ -2032,7 +1871,6 @@ expand-brackets@^2.1.4: express@^4.0.0, express@^4.16.3: version "4.16.4" resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" - integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== dependencies: accepts "~1.3.5" array-flatten "1.1.1" @@ -2068,22 +1906,19 @@ express@^4.0.0, express@^4.16.3: extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= dependencies: assign-symbols "^1.0.0" is-extendable "^1.0.1" external-editor@^2.0.1: version "2.2.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" - integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== + resolved "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" dependencies: chardet "^0.4.0" iconv-lite "^0.4.17" @@ -2092,7 +1927,6 @@ external-editor@^2.0.1: extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: array-unique "^0.3.2" define-property "^1.0.0" @@ -2106,24 +1940,24 @@ extglob@^2.0.4: faker@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" - integrity sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8= fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fclone@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640" figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= dependencies: escape-string-regexp "^1.0.5" fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= dependencies: extend-shallow "^2.0.1" is-number "^3.0.0" @@ -2132,8 +1966,7 @@ fill-range@^4.0.0: finalhandler@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" - integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== + resolved "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" dependencies: debug "2.6.9" encodeurl "~1.0.2" @@ -2160,41 +1993,34 @@ find-up@^2.1.0: locate-path "^2.0.0" flatmap-stream@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.2.tgz#b1da359a93f24f6d96e46f948552d997e3c2863d" - integrity sha512-ucyr6WkLXjyMuHPtOUq4l+nSAxgWi7v4QO508eQ9resnGj+lSup26oIsUI5aH8k4Qfpjsxa8dDf9UCKkS2KHzQ== + version "0.1.1" + resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.1.tgz#d34f39ef3b9aa5a2fc225016bd3adf28ac5ae6ea" for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: map-cache "^0.2.2" fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= from@^0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" - integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== dependencies: minipass "^2.2.1" @@ -2206,12 +2032,10 @@ fs-readdir-recursive@^1.0.0, fs-readdir-recursive@^1.1.0: fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.2: version "1.2.4" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== dependencies: nan "^2.9.2" node-pre-gyp "^0.10.0" @@ -2219,12 +2043,10 @@ fsevents@^1.2.2: 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== gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= dependencies: aproba "^1.0.3" console-control-strings "^1.0.0" @@ -2235,28 +2057,41 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + get-stream@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= dependencies: is-glob "^3.1.0" path-dirname "^1.0.0" +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.0.0, glob@^7.0.5: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -2268,7 +2103,6 @@ glob@^7.0.0, glob@^7.0.5: global-dirs@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" - integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= dependencies: ini "^1.3.4" @@ -2279,8 +2113,7 @@ globals@^11.1.0: got@^6.7.1: version "6.7.1" - resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" - integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= + resolved "http://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" dependencies: create-error-class "^3.0.0" duplexer3 "^0.1.4" @@ -2295,21 +2128,18 @@ got@^6.7.1: url-parse-lax "^1.0.0" graceful-fs@^4.1.11, graceful-fs@^4.1.2: - version "4.1.15" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" - integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" graphql-anywhere@^4.1.0-alpha.0: - version "4.1.22" - resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.22.tgz#1c831ba3c9e5664a0dd24d10d23a9e9512d92056" - integrity sha512-qm2/1cKM8nfotxDhm4J0r1znVlK0Yge/yEKt26EVVBgpIhvxjXYFALCGbr7cvfDlvzal1iSPpaYa+8YTtjsxQA== + version "4.1.19" + resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.19.tgz#5f6ca3b58218e5449f4798e3c6d942fcd2fef082" dependencies: - apollo-utilities "^1.0.25" + apollo-utilities "^1.0.21" graphql-config@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-2.0.0.tgz#daf69091055c6f675d63893a2d14c48f3fec3327" - integrity sha512-//hZmROEk79zzPlH6SVTQeXd8NVV65rquz1zxZeO6oEuX5KNnii8+oznLu7d897EfJ+NShTZtsY9FMmxxkWmJw== + resolved "http://registry.npmjs.org/graphql-config/-/graphql-config-2.0.0.tgz#daf69091055c6f675d63893a2d14c48f3fec3327" dependencies: graphql-import "^0.4.0" graphql-request "^1.4.0" @@ -2318,134 +2148,108 @@ graphql-config@2.0.0: minimatch "^3.0.4" graphql-custom-directives@^0.2.13: - 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== + version "0.2.13" + resolved "https://registry.yarnpkg.com/graphql-custom-directives/-/graphql-custom-directives-0.2.13.tgz#5e175069f5ff404f751d232e302007bc25488ea8" dependencies: - libphonenumber-js "^1.6.4" lodash "^4.17.5" moment "^2.22.2" numeral "^2.0.6" graphql-deduplicator@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3" - integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA== - -graphql-extensions@0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.2.tgz#a19dd62b62d769f4d1b9c4b4781cc353b2174998" - integrity sha512-eIAWwtZNlUAHtHF6uNP6+4M+GCksqUYfNBxW5rTAlCB4/ZcuIvchVtN1CgVM7MooW3akPM1Eci11WyeXvgOugQ== - dependencies: - "@apollographql/apollo-tools" "^0.2.6" + version "2.0.1" + resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.1.tgz#20c6b39e3a6f096b46dfc8491432818739c0ee37" graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: version "0.0.10" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" - integrity sha512-TnQueqUDCYzOSrpQb3q1ngDSP2otJSF+9yNLrQGPzkMsvnQ+v6e2d5tl+B35D4y+XpmvVnAn4T3ZK28mkILveA== + resolved "http://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" dependencies: core-js "^2.5.3" source-map-support "^0.5.1" +graphql-extensions@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.2.1.tgz#7697e0fcea2e622afe9e24dd31fc84f533e84c70" + dependencies: + apollo-server-env "^2.0.3" + graphql-import@^0.4.0: version "0.4.5" - resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.4.5.tgz#e2f18c28d335733f46df8e0733d8deb1c6e2a645" - integrity sha512-G/+I08Qp6/QGTb9qapknCm3yPHV0ZL7wbaalWFpxsfR8ZhZoTBe//LsbsCKlbALQpcMegchpJhpTSKiJjhaVqQ== + resolved "http://registry.npmjs.org/graphql-import/-/graphql-import-0.4.5.tgz#e2f18c28d335733f46df8e0733d8deb1c6e2a645" dependencies: lodash "^4.17.4" graphql-import@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.6.0.tgz#c00cb8a269ceea263e062922c8c81a2272d1ffcb" - integrity sha512-S6Aj4pTzehCwyh7hKUKlWLgE6soDdW/T6JPePC16exzFDNdZHXRj7lqv75yMWJCkBY0pBtWicMLinb4ni6QRyg== dependencies: lodash "^4.17.4" 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@1.6.6: version "1.6.6" resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.6.6.tgz#f40f4e836ced479df718dbc1869ea4cd3b64027b" - integrity sha512-1rSSPEJOhBMwNCBCp5CCh3YZFvo8qN/pzQM8k50pd/w2hBsBvOx0AVU9Or6JQbTXxYrKFXvKFUxC5Lp+2oeUtw== dependencies: graphql-tools "^3.0.5" graphql-middleware@1.7.6: version "1.7.6" resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.6.tgz#f226bf6671f3d82a9378f8b335804c8e44d21733" - integrity sha512-nKWd6BVgsh6S2eDRIcm3TjJPmXEEmqK6DY2a8/nK11NrNAFpZCq+esSSPG1F0HZShsDdE/h3M+/jLcD/zKlMvA== dependencies: graphql-tools "^4.0.0" graphql-playground-html@1.5.5: version "1.5.5" - resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.5.5.tgz#e2aca543eb66b435ead495b45244b2604d6b2d48" - integrity sha512-PzSywpEKcjbDUkV6e3ivEixvAuUJGyYmBUvuittzySe/RgwHRo0xKLD7HouUCTbpFfWMw8kRKhAUVtt7Ys97uw== + resolved "http://registry.npmjs.org/graphql-playground-html/-/graphql-playground-html-1.5.5.tgz#e2aca543eb66b435ead495b45244b2604d6b2d48" dependencies: graphql-config "2.0.0" graphql-playground-html@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz#6ec4d54325ab2e5352506fdb89eb37c3fc718bf8" - integrity sha512-et3huQFEuAZgAiUfs9a+1Wo/JDX94k7XqNRc8LhpGT8k2NwIhMAbZKqudVF/Ww4+XDoEB4LUTSFGRPBYvKrcKQ== dependencies: graphql-config "2.0.0" graphql-playground-middleware-express@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.2.tgz#5f7bf3683494fe17893d1b54bbecee5e222c2e78" - integrity sha512-JvKsVOR/U5QguBtEvTt0ozQ49uh1C6cW8O1xR6krQpJZIxjLYqpgusLUddTiVkka6Q/A4/AXBohY85jPudxYDg== dependencies: graphql-playground-html "1.6.0" graphql-playground-middleware-lambda@1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/graphql-playground-middleware-lambda/-/graphql-playground-middleware-lambda-1.6.1.tgz#e0f1944558136dd3975570c92c702d6009cc779c" - integrity sha512-FO6XG9QRs+0AkwfAnL80u8A02xTg1rPUH+Ay13ASTs0nEePav5GkrWfL59ZY+sK4ZzFvz72aImuXAs3Ajn8VtA== dependencies: graphql-playground-html "1.5.5" graphql-request@^1.4.0: version "1.8.2" resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" - integrity sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg== dependencies: cross-fetch "2.2.2" graphql-shield@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.1.0.tgz#8bd55179fd28d00e64ca5a7dbd3cffe82e282e73" - integrity sha512-r3m5t7FpLDyJQIby0IKyNrtp8k62hP/syhPcrpdT67UVNKh0jjjl+zpjXh/3PXeNZHPEAiBQTHhFjnC7H2B4SA== + version "4.0.1" + resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.0.1.tgz#731fca9a69a540ff446edf9e5bec610da295f5cb" dependencies: object-hash "^1.3.0" opencollective "1.0.3" graphql-subscriptions@^0.5.8: version "0.5.8" - resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7" - integrity sha512-0CaZnXKBw2pwnIbvmVckby5Ge5e2ecmjofhYCdyeACbCly2j3WXDP/pl+s+Dqd2GQFC7y99NB+53jrt55CKxYQ== - dependencies: - iterall "^1.2.1" - -graphql-subscriptions@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-1.0.0.tgz#475267694b3bd465af6477dbab4263a3f62702b8" - integrity sha512-+ytmryoHF1LVf58NKEaNPRUzYyXplm120ntxfPcgOBC7TnK7Tv/4VRHeh4FAR9iL+O1bqhZs4nkibxQ+OA5cDQ== + resolved "http://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7" dependencies: iterall "^1.2.1" graphql-tag@^2.4.2, graphql-tag@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" - integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w== -graphql-tools@^3.0.0, graphql-tools@^3.0.5: +graphql-tools@^3.0.0, graphql-tools@^3.0.4, graphql-tools@^3.0.5: version "3.1.1" resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-3.1.1.tgz#d593358f01e7c8b1671a17b70ddb034dea9dbc50" - integrity sha512-yHvPkweUB0+Q/GWH5wIG60bpt8CTwBklCSzQdEHmRUgAdEQKxw+9B7zB3dG7wB3Ym7M7lfrS4Ej+jtDZfA2UXg== dependencies: apollo-link "^1.2.2" apollo-utilities "^1.0.1" @@ -2454,9 +2258,8 @@ graphql-tools@^3.0.0, graphql-tools@^3.0.5: uuid "^3.1.0" graphql-tools@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.3.tgz#23b5cb52c519212b1b2e4630a361464396ad264b" - integrity sha512-NNZM0WSnVLX1zIMUxu7SjzLZ4prCp15N5L2T2ro02OVyydZ0fuCnZYRnx/yK9xjGWbZA0Q58yEO//Bv/psJWrg== + version "4.0.2" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.2.tgz#9da22974cc6bf6524ed4f4af35556fd15aa6516d" dependencies: apollo-link "^1.2.3" apollo-utilities "^1.0.1" @@ -2467,7 +2270,6 @@ graphql-tools@^4.0.0: graphql-yoga@1.16.2: version "1.16.2" resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.16.2.tgz#083293a9cecab6283e883c5a482c5c920fa66585" - integrity sha512-dV7uEUm/tzl3K/gkHPBt718N+F0gmhZKsg8HJpj35SEniGyXVI3VjDWd7Na3bWdue4p8Sxb+/JguuK8jpe8dWg== dependencies: "@types/cors" "^2.8.4" "@types/express" "^4.11.1" @@ -2493,37 +2295,36 @@ graphql-yoga@1.16.2: "graphql@^0.11.0 || ^0.12.0 || ^0.13.0", graphql@^0.13.2: version "0.13.2" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" - integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== + resolved "http://registry.npmjs.org/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" dependencies: iterall "^1.2.1" +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= dependencies: ansi-regex "^2.0.0" has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: get-value "^2.0.3" has-values "^0.1.4" @@ -2532,7 +2333,6 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= dependencies: get-value "^2.0.6" has-values "^1.0.0" @@ -2541,12 +2341,10 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= has-values@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= dependencies: is-number "^3.0.0" kind-of "^4.0.0" @@ -2554,14 +2352,24 @@ has-values@^1.0.0: has@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" +hash.js@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + he@0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" - integrity sha1-LAX/rvkLaOhg8/0rVO9YCYknfuI= + resolved "http://registry.npmjs.org/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= home-or-tmp@^3.0.0: version "3.0.0" @@ -2578,7 +2386,6 @@ homedir-polyfill@^1.0.1: htmlparser2@^3.9.0, htmlparser2@^3.9.1: version "3.10.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" - integrity sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ== dependencies: domelementtype "^1.3.0" domhandler "^2.3.0" @@ -2589,8 +2396,7 @@ htmlparser2@^3.9.0, htmlparser2@^3.9.1: http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" dependencies: depd "~1.1.2" inherits "2.0.3" @@ -2600,58 +2406,48 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" - integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== dependencies: safer-buffer ">= 2.1.2 < 3" iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" ieee754@1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" - integrity sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q= ieee754@^1.1.4: version "1.1.12" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" - integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" - integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= ignore-walk@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== dependencies: minimatch "^3.0.4" -immutable-tuple@^0.4.9: - version "0.4.9" - resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.9.tgz#473ebdd6c169c461913a454bf87ef8f601a20ff0" - integrity sha512-LWbJPZnidF8eczu7XmcnLBsumuyRBkpwIRPCZxlojouhBo5jEBO4toj6n7hMy6IxHU/c+MqDSWkvaTpPlMQcyA== +immutable-tuple@^0.4.4: + version "0.4.8" + resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.8.tgz#f60b65b863d34be39d307d1bbf4a450e1ac3048a" import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" wrappy "1" @@ -2659,17 +2455,14 @@ inflight@^1.0.4: inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== inquirer@3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" - integrity sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c= dependencies: ansi-escapes "^1.1.0" chalk "^1.0.0" @@ -2688,7 +2481,6 @@ inquirer@3.0.6: insane@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/insane/-/insane-2.6.1.tgz#c7dcae7b51c20346883b71078fad6ce0483c198f" - integrity sha1-x9yue1HCA0aIO3EHj61s4Eg8GY8= dependencies: assignment "2.0.0" he "0.5.0" @@ -2696,76 +2488,64 @@ insane@2.6.1: invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== dependencies: loose-envify "^1.0.0" ipaddr.js@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" - integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= dependencies: kind-of "^3.0.2" is-accessor-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== dependencies: kind-of "^6.0.0" is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= dependencies: binary-extensions "^1.0.0" is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-callable@^1.1.3, is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== is-ci@^1.0.10: version "1.2.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== dependencies: ci-info "^1.5.0" is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= dependencies: kind-of "^3.0.2" is-data-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== dependencies: kind-of "^6.0.0" is-date-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== dependencies: is-accessor-descriptor "^0.1.6" is-data-descriptor "^0.1.4" @@ -2774,7 +2554,6 @@ is-descriptor@^0.1.0: is-descriptor@^1.0.0, is-descriptor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== dependencies: is-accessor-descriptor "^1.0.0" is-data-descriptor "^1.0.0" @@ -2783,50 +2562,42 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= is-extendable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= dependencies: is-extglob "^2.1.0" is-glob@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" - integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= dependencies: is-extglob "^2.1.1" is-installed-globally@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= dependencies: global-dirs "^0.1.0" is-path-inside "^1.0.0" @@ -2834,24 +2605,20 @@ is-installed-globally@^0.1.0: is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= dependencies: kind-of "^3.0.2" is-obj@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" is-path-inside@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= dependencies: path-is-inside "^1.0.1" @@ -2863,90 +2630,74 @@ is-plain-obj@^1.1.0: is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= is-regex@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= dependencies: has "^1.0.1" is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" - integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== dependencies: has-symbols "^1.0.0" is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= iterall@^1.1.3, iterall@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" - integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== jmespath@0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" - integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= jquery@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca" - integrity sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg== js-levenshtein@^1.1.3: version "1.1.4" @@ -2961,7 +2712,6 @@ js-levenshtein@^1.1.3: js-yaml@^3.10.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" - integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -2974,14 +2724,6 @@ jsesc@^2.5.1: jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" json5@^2.1.0: version "2.1.0" @@ -2990,15 +2732,9 @@ json5@^2.1.0: dependencies: minimist "^1.2.0" -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz#8757f7b4cb7440d86d5e2f3becefa70536c8e46a" - integrity sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg== + version "8.3.0" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz#056c90eee9a65ed6e6c72ddb0a1d325109aaf643" dependencies: jws "^3.1.5" lodash.includes "^4.3.0" @@ -3013,7 +2749,6 @@ jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: jwa@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.6.tgz#87240e76c9808dbde18783cf2264ef4929ee50e6" - integrity sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw== dependencies: buffer-equal-constant-time "1.0.1" ecdsa-sig-formatter "1.0.10" @@ -3022,7 +2757,6 @@ jwa@^1.1.5: jws@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.5.tgz#80d12d05b293d1e841e7cb8b4e69e561adcf834f" - integrity sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ== dependencies: jwa "^1.1.5" safe-buffer "^5.0.1" @@ -3030,47 +2764,32 @@ jws@^3.1.5: kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= dependencies: is-buffer "^1.1.5" kind-of@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== latest-version@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" - integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= dependencies: package-json "^4.0.0" -libphonenumber-js@^1.6.4: - version "1.6.7" - resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.6.7.tgz#cb4501f6d1e5e0b4c8ccbd10ba489359f649dd73" - integrity sha512-vdt8x1ILa7pjpkQilAuS58xgFPBrgGLBoAQV4jEusIwvjqUV+tgr5po1sifP2RmAcmKaM1NdyIDXgmpyb4V8bg== - dependencies: - minimist "^1.2.0" - semver-compare "^1.0.0" - xml2js "^0.4.17" - linkifyjs@^2.1.7: version "2.1.7" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-2.1.7.tgz#e5d68d2ae30b9c055e1d74cc40f9a31d3abb4012" - integrity sha512-Cbn77BnYEslpAObZZoP6GVQHF1j5T6RsDydNq5RVxIy4eiZAiADRx7qHfWzfEMQecc1PtZFog1AsCGGX2WjQLA== optionalDependencies: jquery "^3.3.1" react "^16.4.2" @@ -3087,84 +2806,68 @@ locate-path@^2.0.0: lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= lodash.escaperegexp@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" - integrity sha1-ZHYsSGGAglGKw99Mz11YhtriA0c= lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" - integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= lodash.isboolean@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= lodash.isinteger@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= lodash.isnumber@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= lodash.isstring@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= lodash.mergewith@^4.6.0: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" - integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" - integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" 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== lru-cache@^4.0.1, lru-cache@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" - integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== dependencies: pseudomap "^1.0.2" yallist "^2.1.2" @@ -3172,46 +2875,38 @@ lru-cache@^4.0.1, lru-cache@^4.1.3: make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== dependencies: pify "^3.0.0" map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= map-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" - integrity sha1-ih8HiW2CsQkmvTdEokIACfiJdKg= map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: object-visit "^1.0.0" media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -3227,104 +2922,108 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -mime-db@~1.37.0: - version "1.37.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" - integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== +mime-db@~1.36.0: + version "1.36.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" mime-types@~2.1.18: - version "2.1.21" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" - integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== + version "2.1.20" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" dependencies: - mime-db "~1.37.0" + mime-db "~1.36.0" mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" - integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -minimatch@^3.0.4: +minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + +minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@0.0.8: version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" minimist@1.2.0, minimist@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" -minipass@^2.2.1, minipass@^2.3.4: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== +minipass@^2.2.1, minipass@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" -minizlib@^1.1.1: +minizlib@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" - integrity sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg== dependencies: minipass "^2.2.1" mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.0, mkdirp@^0.5.1: +mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" +mocha@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + moment@^2.22.2: version "2.22.2" resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" - integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y= ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= nan@^2.9.2: version "2.11.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" - integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -3341,7 +3040,6 @@ nanomatch@^1.2.9: needle@^2.2.1: version "2.2.4" resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" - integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== dependencies: debug "^2.1.2" iconv-lite "^0.4.4" @@ -3350,21 +3048,17 @@ needle@^2.2.1: negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" - integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= neo4j-driver@^1.6.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.1.tgz#f21571d18e632ff03be7e84c06b38e1bc66fb111" - integrity sha512-erJPOF8gv22zd/T/8XwJQ2xdXspNtUquUfi1YFMZ2BYRDdXp/NGzmVEH4DeCEk4dF5GkGA91WPuQVBOEOfmTdw== + version "1.6.3" + resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.6.3.tgz#b7a51bac401bd341082dff7766e8643d61752eb7" dependencies: - babel-runtime "^6.26.0" - text-encoding "^0.6.4" + babel-runtime "^6.18.0" uri-js "^4.2.1" neo4j-graphql-js@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.5.tgz#ef5d59d2e7cf46971af49bceec2f4bcd2debc835" - integrity sha512-Fn+lsynWeUy6AT2Xnzpl4vuBWTroUtAyK38qbBVd26z8SeWuQrlxtJFUEifU4VrQxw7tMfbLUSKt7Av+eDQiPw== dependencies: graphql "^0.13.2" lodash "^4.17.10" @@ -3372,21 +3066,18 @@ neo4j-graphql-js@1.0.5: node-fetch@1.6.3: version "1.6.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" - integrity sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ= + resolved "http://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" dependencies: encoding "^0.1.11" is-stream "^1.0.1" node-fetch@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" - integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= + resolved "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" -node-fetch@^2.1.2, node-fetch@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" - integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== +node-fetch@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5" node-modules-regexp@^1.0.0: version "1.0.0" @@ -3396,7 +3087,6 @@ node-modules-regexp@^1.0.0: node-pre-gyp@^0.10.0: version "0.10.3" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" - integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== dependencies: detect-libc "^1.0.2" mkdirp "^0.5.1" @@ -3417,11 +3107,10 @@ node-releases@^1.0.1: semver "^5.3.0" nodemon@^1.18.4: - version "1.18.6" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.6.tgz#89b1136634d6c0afc7de24cc932a760e999e2c76" - integrity sha512-4pHQNYEZun+IkIC2jCaXEhkZnfA7rQe73i8RkdRyDJls/K+WxR7IpI5uNUsAvQ0zWvYcCDNGD+XVtw2ZG86/uQ== + version "1.18.4" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.4.tgz#873f65fdb53220eb166180cf106b1354ac5d714d" dependencies: - chokidar "^2.0.4" + chokidar "^2.0.2" debug "^3.1.0" ignore-by-default "^1.0.1" minimatch "^3.0.4" @@ -3435,7 +3124,6 @@ nodemon@^1.18.4: nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= dependencies: abbrev "1" osenv "^0.1.4" @@ -3443,26 +3131,22 @@ nopt@^4.0.1: nopt@~1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= dependencies: abbrev "1" normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= dependencies: remove-trailing-separator "^1.0.1" npm-bundled@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" - integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== npm-packlist@^1.1.6: version "1.1.12" resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" - integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -3470,14 +3154,12 @@ npm-packlist@^1.1.6: 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" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= dependencies: path-key "^2.0.0" npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: are-we-there-yet "~1.1.2" console-control-strings "~1.1.0" @@ -3487,60 +3169,50 @@ npmlog@^4.0.2: nth-check@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== dependencies: boolbase "~1.0.0" number-is-nan@^1.0.0: version "1.0.1" 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= object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= dependencies: copy-descriptor "^0.1.0" define-property "^0.2.5" kind-of "^3.0.3" object-hash@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" - integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.0.tgz#76d9ba6ff113cf8efc0d996102851fe6723963e2" object-keys@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" - integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== object-path@^0.11.4: version "0.11.4" resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" - integrity sha1-NwrnUvvzfePqcKhhwju6iRVpGUk= object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= dependencies: isobject "^3.0.0" object.getownpropertydescriptors@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= dependencies: define-properties "^1.1.2" es-abstract "^1.5.1" @@ -3548,35 +3220,30 @@ object.getownpropertydescriptors@^2.0.3: object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= dependencies: isobject "^3.0.1" on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= dependencies: ee-first "1.1.1" once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= dependencies: mimic-fn "^1.0.0" opencollective@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/opencollective/-/opencollective-1.0.3.tgz#aee6372bc28144583690c3ca8daecfc120dd0ef1" - integrity sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE= dependencies: babel-polyfill "6.23.0" chalk "1.1.3" @@ -3587,33 +3254,28 @@ opencollective@1.0.3: opn@4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" - integrity sha1-erwi5kTf9jsKltWrfyeQwPAavJU= + resolved "http://registry.npmjs.org/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" dependencies: object-assign "^4.0.1" pinkie-promise "^2.0.0" optimism@^0.6.6: - version "0.6.8" - resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.8.tgz#0780b546da8cd0a72e5207e0c3706c990c8673a6" - integrity sha512-bN5n1KCxSqwBDnmgDnzMtQTHdL+uea2HYFx1smvtE+w2AMl0Uy31g0aXnP/Nt85OINnMJPRpJyfRQLTCqn5Weg== + version "0.6.6" + resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.6.tgz#5415b2d6a2f8b3745aedb9f97fdf4e52467ecd84" dependencies: - immutable-tuple "^0.4.9" + immutable-tuple "^0.4.4" os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= osenv@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.0" @@ -3630,7 +3292,6 @@ output-file-sync@^2.0.0: p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= p-limit@^1.1.0: version "1.3.0" @@ -3654,7 +3315,6 @@ p-try@^1.0.0: package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= dependencies: got "^6.7.1" registry-auth-token "^3.0.1" @@ -3669,24 +3329,20 @@ parse-passwd@^1.0.0: parse5@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" - integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== dependencies: "@types/node" "*" parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= passport-jwt@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" - integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg== + resolved "http://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" dependencies: jsonwebtoken "^8.2.0" passport-strategy "^1.0.0" @@ -3694,12 +3350,10 @@ passport-jwt@^4.0.0: passport-strategy@1.x.x, passport-strategy@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" - integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= passport@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" - integrity sha1-xQlWkTR71a07XhgCOMORTRbwWBE= dependencies: passport-strategy "1.x.x" pause "0.0.1" @@ -3707,7 +3361,6 @@ passport@^0.4.0: path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= path-exists@^3.0.0: version "3.0.0" @@ -3717,17 +3370,14 @@ path-exists@^3.0.0: path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-is-inside@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= path-key@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= path-parse@^1.0.5: version "1.0.6" @@ -3737,36 +3387,35 @@ path-parse@^1.0.5: path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +pathval@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= pause-stream@^0.0.11: version "0.0.11" - resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" - integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= + resolved "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" dependencies: through "~2.3" pause@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" - integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= pirates@^4.0.0: version "4.0.0" @@ -3785,12 +3434,10 @@ pkg-dir@^2.0.0: posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= postcss@^6.0.14: version "6.0.23" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" - integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== dependencies: chalk "^2.4.1" source-map "^0.6.1" @@ -3799,22 +3446,18 @@ postcss@^6.0.14: prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= private@^0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" - integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== dependencies: loose-envify "^1.3.1" object-assign "^4.1.1" @@ -3822,7 +3465,6 @@ prop-types@^15.6.2: protobufjs@^6.8.6: version "6.8.8" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" - integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -3841,7 +3483,6 @@ protobufjs@^6.8.6: proxy-addr@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" - integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== dependencies: forwarded "~0.1.2" ipaddr.js "1.8.0" @@ -3849,51 +3490,42 @@ proxy-addr@~2.0.4: ps-tree@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" - integrity sha1-tCGyQUDWID8e08dplrRCewjowBQ= dependencies: event-stream "~3.3.0" pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= pstree.remy@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.0.tgz#f2af27265bd3e5b32bbfcc10e80bac55ba78688b" - integrity sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q== dependencies: ps-tree "^1.1.0" punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== qs@6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" - integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= raw-body@2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" - integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== dependencies: bytes "3.0.0" http-errors "1.6.3" @@ -3903,7 +3535,6 @@ raw-body@2.3.3: rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== dependencies: deep-extend "^0.6.0" ini "~1.3.0" @@ -3911,29 +3542,26 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: strip-json-comments "~2.0.1" react-dom@^16.4.2: - version "16.6.3" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.3.tgz#8fa7ba6883c85211b8da2d0efeffc9d3825cccc0" - integrity sha512-8ugJWRCWLGXy+7PmNh8WJz3g1TaTUt1XyoIcFN+x0Zbkoz+KKdUyx1AQLYJdbFXjuF41Nmjn5+j//rxvhFjgSQ== + version "16.6.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.0.tgz#6375b8391e019a632a89a0988bce85f0cc87a92f" dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.11.2" + scheduler "^0.10.0" react@^16.4.2: - version "16.6.3" - resolved "https://registry.yarnpkg.com/react/-/react-16.6.3.tgz#25d77c91911d6bbdd23db41e70fb094cc1e0871c" - integrity sha512-zCvmH2vbEolgKxtqXL2wmGCUxUyNheYn/C+PD1YAjfxHC54+MhdruyhO7QieQrYsYeTxrn93PM2y0jRH1zEExw== + version "16.6.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.6.0.tgz#b34761cfaf3e30f5508bc732fb4736730b7da246" dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.11.2" + scheduler "^0.10.0" readable-stream@1.1.x: version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" dependencies: core-util-is "~1.0.0" inherits "~2.0.1" @@ -3942,8 +3570,7 @@ readable-stream@1.1.x: 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== + resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -3956,7 +3583,6 @@ readable-stream@^2.0.2, readable-stream@^2.0.6: readable-stream@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.0.6.tgz#351302e4c68b5abd6a2ed55376a7f9a25be3057a" - integrity sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" @@ -3965,7 +3591,6 @@ readable-stream@^3.0.6: readdirp@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: graceful-fs "^4.1.11" micromatch "^3.1.10" @@ -3986,7 +3611,6 @@ regenerate@^1.4.0: regenerator-runtime@^0.10.0: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" - integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: version "0.11.1" @@ -3996,7 +3620,6 @@ regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: regenerator-runtime@^0.12.0: version "0.12.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" - integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== regenerator-transform@^0.13.3: version "0.13.3" @@ -4008,7 +3631,6 @@ regenerator-transform@^0.13.3: regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: extend-shallow "^3.0.2" safe-regex "^1.1.0" @@ -4028,7 +3650,6 @@ regexpu-core@^4.1.3, regexpu-core@^4.2.0: registry-auth-token@^3.0.1: version "3.3.2" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" - integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== dependencies: rc "^1.1.6" safe-buffer "^5.0.1" @@ -4036,7 +3657,6 @@ registry-auth-token@^3.0.1: registry-url@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= dependencies: rc "^1.0.1" @@ -4055,22 +3675,18 @@ regjsparser@^0.3.0: remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.3.2: version "1.8.1" @@ -4082,7 +3698,6 @@ resolve@^1.3.2: restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= dependencies: onetime "^2.0.0" signal-exit "^3.0.2" @@ -4090,53 +3705,44 @@ restore-cursor@^2.0.0: ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== retry@0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== dependencies: glob "^7.0.5" run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= dependencies: is-promise "^2.1.0" rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" - integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= dependencies: ret "~0.1.10" "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sanitize-html@^1.19.1: version "1.19.1" resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.1.tgz#e8b33c69578054d6ee4f57ea152d6497f3f6fb7d" - integrity sha512-zNYr6FvBn4bZukr9x2uny6od/9YdjCLwF+FqxivqI0YOt/m9GIxfX+tWhm52tBAPUXiTTb4bJTGVagRz5b06bw== dependencies: chalk "^2.3.0" htmlparser2 "^3.9.0" @@ -4151,43 +3757,32 @@ sanitize-html@^1.19.1: sax@1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" - integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= + resolved "http://registry.npmjs.org/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" sax@>=0.6.0, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.11.2: - version "0.11.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.2.tgz#a8db5399d06eba5abac51b705b7151d2319d33d3" - integrity sha512-+WCP3s3wOaW4S7C1tl3TEXp4l9lJn0ZK8G3W3WKRWmw77Z2cIFUW2MiNTMHn5sCjxN+t7N43HAOOgMjyAg5hlg== +scheduler@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.10.0.tgz#7988de90fe7edccc774ea175a783e69c40c521e1" dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" -semver-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" - integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= - semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" - integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= dependencies: semver "^5.0.3" semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== send@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" - integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== dependencies: debug "2.6.9" depd "~1.1.2" @@ -4206,7 +3801,6 @@ send@0.16.2: serve-static@1.13.2: version "1.13.2" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" - integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" @@ -4216,12 +3810,10 @@ serve-static@1.13.2: set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= set-value@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -4231,7 +3823,6 @@ set-value@^0.4.3: set-value@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -4241,24 +3832,20 @@ set-value@^2.0.0: setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= dependencies: shebang-regex "^1.0.0" shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= slash@^2.0.0: version "2.0.0" @@ -4266,16 +3853,14 @@ slash@^2.0.0: integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== slug@^0.9.1: - version "0.9.2" - resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.2.tgz#e409e4dae3a4bd2fd283557e2806e0a8abb98242" - integrity sha512-WULwxWq6NBM/i24pV9st/WI9TwzjXYpNzxbWr9mRDj74Lqwb3ahsnWsWJtXHfBPpBqXb4m1hYt9S7eMyDkZsKA== + version "0.9.1" + resolved "http://registry.npmjs.org/slug/-/slug-0.9.1.tgz#af08f608a7c11516b61778aa800dce84c518cfda" dependencies: unicode ">= 0.3.1" snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: define-property "^1.0.0" isobject "^3.0.0" @@ -4284,14 +3869,12 @@ snapdragon-node@^2.0.1: snapdragon-util@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: kind-of "^3.2.0" snapdragon@^0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== dependencies: base "^0.11.1" debug "^2.2.0" @@ -4305,7 +3888,6 @@ snapdragon@^0.8.1: source-map-resolve@^0.5.0: version "0.5.2" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== dependencies: atob "^2.1.1" decode-uri-component "^0.2.0" @@ -4324,7 +3906,6 @@ source-map-support@^0.5.1, source-map-support@^0.5.9: source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" @@ -4334,31 +3915,26 @@ source-map@^0.5.0, source-map@^0.5.6: source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: extend-shallow "^3.0.0" split@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== dependencies: through "2" sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= srcset@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/srcset/-/srcset-1.0.0.tgz#a5669de12b42f3b1d5e83ed03c71046fc48f41ef" - integrity sha1-pWad4StC87HV6D7QPHEEb8SPQe8= dependencies: array-uniq "^1.0.2" number-is-nan "^1.0.0" @@ -4366,7 +3942,6 @@ srcset@^1.0.0: static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= dependencies: define-property "^0.2.5" object-copy "^0.1.0" @@ -4374,17 +3949,14 @@ static-extend@^0.1.1: "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= statuses@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== stream-combiner@^0.2.2: version "0.2.2" - resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" - integrity sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg= + resolved "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" dependencies: duplexer "~0.1.1" through "~2.3.4" @@ -4392,12 +3964,10 @@ stream-combiner@^0.2.2: streamsearch@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" - integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" @@ -4406,7 +3976,6 @@ string-width@^1.0.1: "string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" @@ -4414,43 +3983,36 @@ string-width@^1.0.1: string_decoder@^1.1.1, string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= dependencies: ansi-regex "^3.0.0" strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: version "0.9.15" resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz#68a8b7ba0037d8c489fb2f5a102d1494db297d0d" - integrity sha512-f9eBfWdHsePQV67QIX+VRhf++dn1adyC/PZHP6XI5AfKnZ4n0FW+v5omxwdHVpd4xq2ZijaHEcmlQrhBY79ZWQ== dependencies: backo2 "^1.0.2" eventemitter3 "^3.1.0" @@ -4458,32 +4020,35 @@ subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: symbol-observable "^1.0.4" ws "^5.2.0" +supports-color@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== + dependencies: + has-flag "^3.0.0" + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" symbol-observable@^1.0.2, symbol-observable@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" - integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== tar@^4: - version "4.4.8" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" - integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== + version "4.4.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" dependencies: - chownr "^1.1.1" + chownr "^1.0.1" fs-minipass "^1.2.5" - minipass "^2.3.4" - minizlib "^1.1.1" + minipass "^2.3.3" + minizlib "^1.1.0" mkdirp "^0.5.0" safe-buffer "^5.1.2" yallist "^3.0.2" @@ -4491,29 +4056,20 @@ tar@^4: term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" - integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= dependencies: execa "^0.7.0" -text-encoding@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" - integrity sha1-45mpgiV6J22uQou5KEXLcb3CbRk= - through@2, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.4: version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" timed-out@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" @@ -4525,14 +4081,12 @@ to-fast-properties@^2.0.0: to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: kind-of "^3.0.2" 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" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: is-number "^3.0.0" repeat-string "^1.6.1" @@ -4540,7 +4094,6 @@ to-regex-range@^2.1.0: to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: define-property "^2.0.2" extend-shallow "^3.0.2" @@ -4550,19 +4103,16 @@ to-regex@^3.0.1, to-regex@^3.0.2: touch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== dependencies: nopt "~1.0.10" trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= trunc-html@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/trunc-html/-/trunc-html-1.1.2.tgz#1e97d51f67d470b67662b1a670e6d0ea7a8edafe" - integrity sha1-HpfVH2fUcLZ2YrGmcObQ6nqO2v4= dependencies: assignment "2.2.0" insane "2.6.1" @@ -4571,12 +4121,15 @@ trunc-html@^1.1.2: trunc-text@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" - integrity sha1-WPh22KxZsiS3mDS7R4uGVuaWIrU= + +type-detect@^4.0.0, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== type-is@^1.6.16, type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" - integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== dependencies: media-typer "0.3.0" mime-types "~2.1.18" @@ -4584,7 +4137,6 @@ type-is@^1.6.16, type-is@~1.6.16: undefsafe@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76" - integrity sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY= dependencies: debug "^2.2.0" @@ -4614,12 +4166,10 @@ unicode-property-aliases-ecmascript@^1.0.4: "unicode@>= 0.3.1": version "11.0.1" resolved "https://registry.yarnpkg.com/unicode/-/unicode-11.0.1.tgz#735bd422ec75cf28d396eb224d535d168d5f1db6" - integrity sha512-+cHtykLb+eF1yrSLWTwcYBrqJkTfX7Quoyg7Juhe6uylF43ZbMdxMuSHNYlnyLT8T7POAvavgBthzUF9AIaQvQ== union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= dependencies: arr-union "^3.1.0" get-value "^2.0.6" @@ -4629,19 +4179,16 @@ union-value@^1.0.0: unique-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= dependencies: crypto-random-string "^1.0.0" unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= dependencies: has-value "^0.3.1" isobject "^3.0.0" @@ -4649,17 +4196,14 @@ unset-value@^1.0.0: unzip-response@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= upath@^1.0.5: version "1.1.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" - integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== update-notifier@^2.3.0: version "2.5.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" - integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== dependencies: boxen "^1.2.1" chalk "^2.0.1" @@ -4675,26 +4219,22 @@ update-notifier@^2.3.0: uri-js@^4.2.1: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== dependencies: punycode "^2.1.0" urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= url-parse-lax@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= dependencies: prepend-http "^1.0.1" url@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" - integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ= dependencies: punycode "1.3.2" querystring "0.2.0" @@ -4702,17 +4242,14 @@ url@0.10.3: use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= util.promisify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== dependencies: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" @@ -4720,17 +4257,14 @@ util.promisify@^1.0.0: utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= uuid@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== uuid@^3.1.0: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== v8flags@^3.1.1: version "3.1.1" @@ -4742,43 +4276,36 @@ v8flags@^3.1.1: vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= whatwg-fetch@2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" - integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + resolved "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: string-width "^1.0.2 || 2" widest-line@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" - integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== dependencies: string-width "^2.1.1" wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= write-file-atomic@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" - integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== dependencies: graceful-fs "^4.1.11" imurmurhash "^0.1.4" @@ -4787,58 +4314,42 @@ write-file-atomic@^2.0.0: ws@^5.2.0: version "5.2.2" resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== - dependencies: - async-limiter "~1.0.0" - -ws@^6.0.0: - version "6.1.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" - integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== dependencies: async-limiter "~1.0.0" xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= -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== dependencies: sax ">=0.6.0" xmlbuilder "~9.0.1" xmlbuilder@~9.0.1: version "9.0.7" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= + resolved "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" xtend@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= yallist@^3.0.0, yallist@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" - integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= zen-observable-ts@^0.8.10: version "0.8.10" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz#18e2ce1c89fe026e9621fd83cc05168228fce829" - integrity sha512-5vqMtRggU/2GhePC9OU4sYEWOdvmayp2k3gjPf4F0mXwB3CSbbNznfDUvDJx9O2ZTa1EIXdJhPchQveFKwNXPQ== dependencies: zen-observable "^0.8.0" zen-observable@^0.8.0: - version "0.8.11" - resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.11.tgz#d3415885eeeb42ee5abb9821c95bb518fcd6d199" - integrity sha512-N3xXQVr4L61rZvGMpWe8XoCGX8vhU35dPyQ4fm5CY/KDlG0F75un14hjbckPXTDuKUY6V0dqR2giT6xN8Y4GEQ== + version "0.8.9" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.9.tgz#0475c760ff0eda046bbdfa4dc3f95d392807ac53" From 99bb1e0ae9eaa6c78a11ad3c4989a6996e502921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 21 Nov 2018 00:39:19 +0100 Subject: [PATCH 077/554] Install apollo-server-testing --- package.json | 1 + yarn.lock | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) diff --git a/package.json b/package.json index 7eedbc429..9e7bda645 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "trunc-html": "^1.1.2" }, "devDependencies": { + "apollo-server-testing": "^2.2.2", "chai": "^4.2.0", "faker": "^4.1.0", "mocha": "^5.2.0", diff --git a/yarn.lock b/yarn.lock index 7502a96f8..e8125ad39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,13 @@ # yarn lockfile v1 +"@apollographql/apollo-tools@^0.2.6": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.2.7.tgz#550502b315e49040e07d7e5065d15c5116c506e6" + integrity sha512-rsn4uN12gZWME+m9CLnUk+ImY+blKdWFFdS6TlQheXC7XA85twjQmOY0/n05qUtrxx1dM5QUXw1qLCZ4emWYbQ== + dependencies: + apollo-env "0.2.4" + "@apollographql/apollo-upload-server@^5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" @@ -14,6 +21,11 @@ version "1.6.0" resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz#15e1a042b97d6834e6d70b17cc73e1514fde9027" +"@apollographql/graphql-playground-html@^1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.4.tgz#8945edf73df846d50e027bb3b813d018a1c5925f" + integrity sha512-gwvaQO6/Hv4DEwhDLmmu2tzCU9oPjC5Xl9Kk8Yd0IxyKhYLlLalmkMMjsZLzU5H3fGaalLD96OYfxHL0ClVUDQ== + "@babel/cli@^7.1.5": version "7.1.5" resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.1.5.tgz#4ccf0a8cdabeefdd8ce955384530f050935bc4d7" @@ -789,6 +801,14 @@ "@types/events" "*" "@types/node" "*" +"@types/ws@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28" + integrity sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q== + dependencies: + "@types/events" "*" + "@types/node" "*" + "@types/zen-observable@^0.5.3": version "0.5.4" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.4.tgz#b863a4191e525206819e008097ebf0fb2e3a1cdc" @@ -856,6 +876,14 @@ apollo-boost@^0.1.10: apollo-link-state "^0.4.0" graphql-tag "^2.4.2" +apollo-cache-control@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.2.tgz#fc98781e6df60346a20b0540450d02842c1212f2" + integrity sha512-/fhgCWGEoTsgyA83usy/1NvJWi6hbD4rSGO5jvyNNtMZ9ledOvKUvIdzSQ1r5hxK5yds/eehWXhMJ4Pu200qrQ== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.3.2" + apollo-cache-control@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz#173d14ceb3eb9e7cb53de7eb8b61bee6159d4171" @@ -897,6 +925,14 @@ apollo-client@^2.3.2, apollo-client@^2.4.2: optionalDependencies: "@types/async" "2.0.49" +apollo-datasource@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.2.0.tgz#ea28313689073150b18f0dbe35bedffc86a62b57" + integrity sha512-WJM9Ix3uogIfAG7mjL1NZQM9+45rcikn4mPWhE1Iuyw2+Y857J3uKJqQgF5h9Fg64SlCJh9u5WL3N7N5mg1fVw== + dependencies: + apollo-server-caching "0.2.0" + apollo-server-env "2.2.0" + apollo-datasource@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.1.3.tgz#e7ae9d20f29a8a35f239b02f0c47169cfd78d70b" @@ -904,12 +940,30 @@ apollo-datasource@^0.1.3: apollo-server-caching "0.1.2" apollo-server-env "2.0.3" +apollo-engine-reporting-protobuf@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.1.0.tgz#fbc220cac2a3b7800ffc155d7e54c21c56b7848e" + integrity sha512-GReJtAYTmpwg0drb9VgFtqObYYTCHkJhlHEYCeXY8bJV4fOgXsAZ7CIXR9nPKO0mBaoHIHaGYvXGcyCLrZ36VA== + dependencies: + protobufjs "^6.8.6" + apollo-engine-reporting-protobuf@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz#cd394f0f769c6f97d8621c4a7839095c84efcdb0" dependencies: protobufjs "^6.8.6" +apollo-engine-reporting@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.2.tgz#6247e8d618da5c084ccb1bc76c665ce7a1b1ba55" + integrity sha512-W6zBTypI2ZLe9ZpMI4EasyXJP2WG8CpxYOU3Q4iuCKh8HYJqrQC5QVFXRF7TRBQTE6tc1seYnAHdgqv0ozxBrw== + dependencies: + apollo-engine-reporting-protobuf "0.1.0" + apollo-server-env "2.2.0" + async-retry "^1.2.1" + graphql-extensions "0.3.2" + lodash "^4.17.10" + apollo-engine-reporting@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.0.6.tgz#c1a74dffce782525f8a3230e4e5228fbd05bbd59" @@ -920,6 +974,14 @@ apollo-engine-reporting@^0.0.6: graphql-extensions "^0.2.1" lodash "^4.17.10" +apollo-env@0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.2.4.tgz#6af44ef0af1b8c8a4d7da5d66ff55909858a88fa" + integrity sha512-pphNvrS7JmgvkvhaNEh+u0GpolytboAQcNbwmgskvX0VaLPfrrVox0AwHCteReB8t8s87NhbLd0VTG1nxmjFfQ== + dependencies: + core-js "^3.0.0-beta.3" + node-fetch "^2.2.0" + apollo-link-dedup@^1.0.0: version "1.0.10" resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.10.tgz#7b94589fe7f969777efd18a129043c78430800ae" @@ -965,6 +1027,39 @@ apollo-server-caching@0.1.2, apollo-server-caching@^0.1.2: dependencies: lru-cache "^4.1.3" +apollo-server-caching@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.2.0.tgz#fe560752d364f14d34c1eaacd9df629f8ed1cf5c" + integrity sha512-/v7xWEcyyahs3hwX4baH/GekuHz3LRt9NoIYwg869G1eeqjuwY6NsowRIujZ100anJQwm9v5A9/sLtHBFvbgYg== + dependencies: + lru-cache "^4.1.3" + +apollo-server-core@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.2.tgz#66ca6b4af6c7cdd8155de946d0c4fea3357b0432" + integrity sha512-F6d4u5m1rJB4ucpLPGCoa9Dvo5OjGMIGdAzT9A35yOvlFWwvIR46jGmYmGmNp4Qx852rb1axSZVzNy7k/Dix0w== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" + "@apollographql/apollo-upload-server" "^5.0.3" + "@apollographql/graphql-playground-html" "^1.6.4" + "@types/ws" "^6.0.0" + apollo-cache-control "0.3.2" + apollo-datasource "0.2.0" + apollo-engine-reporting "0.1.2" + apollo-server-caching "0.2.0" + apollo-server-env "2.2.0" + apollo-server-errors "2.2.0" + apollo-server-plugin-base "0.1.2" + apollo-tracing "0.3.2" + graphql-extensions "0.3.2" + graphql-subscriptions "^1.0.0" + graphql-tag "^2.9.2" + graphql-tools "^4.0.0" + json-stable-stringify "^1.0.1" + lodash "^4.17.10" + subscriptions-transport-ws "^0.9.11" + ws "^6.0.0" + apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592" @@ -1002,6 +1097,19 @@ apollo-server-env@2.0.3, apollo-server-env@^2.0.3: node-fetch "^2.1.2" util.promisify "^1.0.0" +apollo-server-env@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.2.0.tgz#5eec5dbf46581f663fd6692b2e05c7e8ae6d6034" + integrity sha512-wjJiI5nQWPBpNmpiLP389Ezpstp71szS6DHAeTgYLb/ulCw3CTuuA+0/E1bsThVWiQaDeHZE0sE3yI8q2zrYiA== + dependencies: + node-fetch "^2.1.2" + util.promisify "^1.0.0" + +apollo-server-errors@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" + integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== + apollo-server-errors@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz#e9cbb1b74d2cd78aed23cd886ca2d0c186323b2b" @@ -1042,6 +1150,18 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" +apollo-server-plugin-base@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.2.tgz#4c1ebb769b630a16ff8ade03f12759cde17a21dc" + integrity sha512-+uicMcNctlP6YwIhzLLEycZzao/810OSzcxgPYKItXr5lGa1GuHD7sRIWldT3YoSdpw6Gal2lBuw6/DmnoDsPg== + +apollo-server-testing@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.2.2.tgz#e496d9ca7e1a3e74257b1e426ac52fc3a7e4406d" + integrity sha512-hLumzMAejOL7V10Fjgij2J10B1PuFWS3RXGNPjrYafEhR/RfaI5ruOIEpeuyOH5qadcI6Deswq8AWqoacWzXGA== + dependencies: + apollo-server-core "2.2.2" + apollo-server@^2.0.4: version "2.1.0" resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.1.0.tgz#abec7853647c59f386087352cc7f06a4f1f8afe2" @@ -1052,6 +1172,14 @@ apollo-server@^2.0.4: graphql-subscriptions "^0.5.8" graphql-tools "^3.0.4" +apollo-tracing@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.2.tgz#1a6b695813791b8404b5adaa10925a7f2642f15d" + integrity sha512-YwN1m1k0JJsxGh0QWsEM3OLnyem0GT2tZnGeO2OogCr6dH5lE0SjKPc6UzpcI/3fPyxRrx5QvpUiP+DJeehhTA== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.3.2" + apollo-tracing@^0.1.0: version "0.1.4" resolved "http://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" @@ -1544,6 +1672,11 @@ core-js@^2.4.0, core-js@^2.5.3, core-js@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" +core-js@^3.0.0-beta.3: + version "3.0.0-beta.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.3.tgz#b0f22009972b8c6c04550ebf38513ca4b3cc9559" + integrity sha512-kM/OfrnMThP5PwGAj5HhQLdjUqzjrllqN2EVnk/X9qrLsfYjR2hzZ+E/8CzH0xuosexZtqMTLQrk//BULrBj9w== + core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -2159,6 +2292,13 @@ graphql-deduplicator@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.1.tgz#20c6b39e3a6f096b46dfc8491432818739c0ee37" +graphql-extensions@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.2.tgz#a19dd62b62d769f4d1b9c4b4781cc353b2174998" + integrity sha512-eIAWwtZNlUAHtHF6uNP6+4M+GCksqUYfNBxW5rTAlCB4/ZcuIvchVtN1CgVM7MooW3akPM1Eci11WyeXvgOugQ== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" + graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: version "0.0.10" resolved "http://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" @@ -2243,6 +2383,13 @@ graphql-subscriptions@^0.5.8: dependencies: iterall "^1.2.1" +graphql-subscriptions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-1.0.0.tgz#475267694b3bd465af6477dbab4263a3f62702b8" + integrity sha512-+ytmryoHF1LVf58NKEaNPRUzYyXplm120ntxfPcgOBC7TnK7Tv/4VRHeh4FAR9iL+O1bqhZs4nkibxQ+OA5cDQ== + dependencies: + iterall "^1.2.1" + graphql-tag@^2.4.2, graphql-tag@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" @@ -2725,6 +2872,13 @@ jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + json5@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" @@ -2732,6 +2886,11 @@ json5@^2.1.0: dependencies: minimist "^1.2.0" +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz#056c90eee9a65ed6e6c72ddb0a1d325109aaf643" @@ -3079,6 +3238,11 @@ node-fetch@^2.1.2: version "2.2.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5" +node-fetch@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" + integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== + node-modules-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" @@ -4317,6 +4481,13 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" +ws@^6.0.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" + integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== + dependencies: + async-limiter "~1.0.0" + xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" From 491102c02bffc67eb639e3055a94561adfc88c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 21 Nov 2018 00:39:27 +0100 Subject: [PATCH 078/554] Move reusable part in server.js --- src/index.js | 68 +------------------------------------------------- src/server.js | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 67 deletions(-) create mode 100644 src/server.js diff --git a/src/index.js b/src/index.js index 5c3face1a..1827b5a22 100644 --- a/src/index.js +++ b/src/index.js @@ -1,70 +1,4 @@ -import { GraphQLServer } from 'graphql-yoga' -import { makeExecutableSchema } from 'apollo-server' -import { augmentSchema } from 'neo4j-graphql-js' -import { typeDefs, resolvers } from './graphql-schema' -import { v1 as neo4j } from 'neo4j-driver' -import dotenv from 'dotenv' -import mocks from './mocks' -import middleware from './middleware' -import applyDirectives from './bootstrap/directives' -import applyScalars from './bootstrap/scalars' - -import passport from 'passport' -import jwtStrategy from './jwt/strategy' -import jwt from 'jsonwebtoken' - -dotenv.config() - -let schema = makeExecutableSchema({ - typeDefs, - resolvers -}) - -const driver = neo4j.driver( - process.env.NEO4J_URI || 'bolt://localhost:7687', - neo4j.auth.basic( - process.env.NEO4J_USER || 'neo4j', - process.env.NEO4J_PASSWORD || 'neo4j' - ) -) - -const MOCK = (process.env.MOCK === 'true') -console.log('MOCK:', MOCK) - -schema = augmentSchema(schema, { - query: { - exclude: ['Statistics', 'LoggedInUser'] - }, - mutation: { - exclude: ['Statistics', 'LoggedInUser'] - } -}) -schema = applyScalars(applyDirectives(schema)) - -const server = new GraphQLServer({ - context: async (req) => { - const payload = { - driver, - user: null, - req: req.request - } - try { - const token = payload.req.headers.authorization.replace('Bearer ', '') - payload.user = await jwt.verify(token, process.env.JWT_SECRET) - } catch (err) {} - - return payload - }, - schema: schema, - tracing: true, - middlewares: middleware(schema), - mocks: MOCK ? mocks : false -}) - -passport.use('jwt', jwtStrategy()) -server.express.use(passport.initialize()) - -server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) +import server from './server' const serverConfig = { port: 4000 diff --git a/src/server.js b/src/server.js new file mode 100644 index 000000000..be890a9b2 --- /dev/null +++ b/src/server.js @@ -0,0 +1,69 @@ +import { GraphQLServer } from 'graphql-yoga' +import { makeExecutableSchema } from 'apollo-server' +import { augmentSchema } from 'neo4j-graphql-js' +import { typeDefs, resolvers } from './graphql-schema' +import { v1 as neo4j } from 'neo4j-driver' +import dotenv from 'dotenv' +import mocks from './mocks' +import middleware from './middleware' +import applyDirectives from './bootstrap/directives' +import applyScalars from './bootstrap/scalars' + +import passport from 'passport' +import jwtStrategy from './jwt/strategy' +import jwt from 'jsonwebtoken' + +dotenv.config() + +let schema = makeExecutableSchema({ + typeDefs, + resolvers +}) + +const driver = neo4j.driver( + process.env.NEO4J_URI || 'bolt://localhost:7687', + neo4j.auth.basic( + process.env.NEO4J_USER || 'neo4j', + process.env.NEO4J_PASSWORD || 'neo4j' + ) +) + +const MOCK = (process.env.MOCK === 'true') +console.log('MOCK:', MOCK) + +schema = augmentSchema(schema, { + query: { + exclude: ['Statistics', 'LoggedInUser'] + }, + mutation: { + exclude: ['Statistics', 'LoggedInUser'] + } +}) +schema = applyScalars(applyDirectives(schema)) + +const server = new GraphQLServer({ + context: async (req) => { + const payload = { + driver, + user: null, + req: req.request + } + try { + const token = payload.req.headers.authorization.replace('Bearer ', '') + payload.user = await jwt.verify(token, process.env.JWT_SECRET) + } catch (err) {} + + return payload + }, + schema: schema, + tracing: true, + middlewares: middleware(schema), + mocks: MOCK ? mocks : false +}) + +passport.use('jwt', jwtStrategy()) +server.express.use(passport.initialize()) + +server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) + +export default server From c6420b535139e0a18f2e2e29c3d0cb409a691ed7 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 21 Nov 2018 15:16:55 +0100 Subject: [PATCH 079/554] simplyfied schema and modulized seeding process --- package.json | 2 +- src/bootstrap/neo4j.js | 20 +++++ src/index.js | 10 +-- src/middleware/index.js | 2 +- src/middleware/permissionsMiddleware.js | 28 +----- src/middleware/softDeleteMiddleware.js | 12 +-- src/schema.graphql | 27 ++---- src/seed/data/categories.js | 22 +++++ src/seed/data/comments.js | 80 +++++++++++++++++ src/seed/data/index.js | 14 ++- src/seed/data/posts.js | 112 ++++++++++++++++++++++++ src/seed/data/tags.js | 22 +++++ src/seed/data/users-badges.js | 7 +- src/seed/data/users-blacklist.js | 12 +++ src/seed/data/users-follows.js | 26 ++++++ src/seed/data/users-friends.js | 14 +++ src/seed/data/users-shouts.js | 30 +++++++ src/seed/seed-db.js | 12 +-- src/seed/seed-mutations.js | 4 - 19 files changed, 375 insertions(+), 81 deletions(-) create mode 100644 src/bootstrap/neo4j.js create mode 100644 src/seed/data/categories.js create mode 100644 src/seed/data/comments.js create mode 100644 src/seed/data/posts.js create mode 100644 src/seed/data/tags.js create mode 100644 src/seed/data/users-blacklist.js create mode 100644 src/seed/data/users-follows.js create mode 100644 src/seed/data/users-friends.js create mode 100644 src/seed/data/users-shouts.js diff --git a/package.json b/package.json index c671b12aa..33cb7461a 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "test": "echo \"Error: no test specified\" && exit 1", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "seedDb": "cross-env IS_SEEDING='true' ./node_modules/.bin/babel-node src/seed/seed-db.js && cross-env IS_SEEDING=false" + "db:seed": "./node_modules/.bin/babel-node src/seed/seed-db.js" }, "author": "Grzegorz Leoniec", "license": "MIT", diff --git a/src/bootstrap/neo4j.js b/src/bootstrap/neo4j.js new file mode 100644 index 000000000..9b17361fa --- /dev/null +++ b/src/bootstrap/neo4j.js @@ -0,0 +1,20 @@ +import { v1 as neo4j } from 'neo4j-driver' + +let driver + +export default function () { + return { + getDriver() { + if (!driver) { + driver = neo4j.driver( + process.env.NEO4J_URI || 'bolt://localhost:7687', + neo4j.auth.basic( + process.env.NEO4J_USER || 'neo4j', + process.env.NEO4J_PASSWORD || 'neo4j' + ) + ) + } + return driver + } + } +} diff --git a/src/index.js b/src/index.js index 5c3face1a..9530ee121 100644 --- a/src/index.js +++ b/src/index.js @@ -2,12 +2,12 @@ import { GraphQLServer } from 'graphql-yoga' import { makeExecutableSchema } from 'apollo-server' import { augmentSchema } from 'neo4j-graphql-js' import { typeDefs, resolvers } from './graphql-schema' -import { v1 as neo4j } from 'neo4j-driver' import dotenv from 'dotenv' import mocks from './mocks' import middleware from './middleware' import applyDirectives from './bootstrap/directives' import applyScalars from './bootstrap/scalars' +import neo4j from './bootstrap/neo4j' import passport from 'passport' import jwtStrategy from './jwt/strategy' @@ -20,13 +20,7 @@ let schema = makeExecutableSchema({ resolvers }) -const driver = neo4j.driver( - process.env.NEO4J_URI || 'bolt://localhost:7687', - neo4j.auth.basic( - process.env.NEO4J_USER || 'neo4j', - process.env.NEO4J_PASSWORD || 'neo4j' - ) -) +const driver = neo4j().getDriver() const MOCK = (process.env.MOCK === 'true') console.log('MOCK:', MOCK) diff --git a/src/middleware/index.js b/src/middleware/index.js index f743ae74f..819d51055 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -8,7 +8,7 @@ import xssMiddleware from './xssMiddleware'; import permissionsMiddleware from './permissionsMiddleware'; export default schema => [ - permissionsMiddleware.generate(schema), + // permissionsMiddleware.generate(schema), passwordMiddleware, dateTimeMiddleware, sluggifyMiddleware, diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 0386994cc..68206d24d 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -1,36 +1,16 @@ import { rule, shield, and, or, not, allow } from 'graphql-shield' const isAuthenticated = rule()(async (parent, args, ctx, info) => { - // TODO: how to get this working while seeding? - console.log('isSeeding', process.env.IS_SEEDING) - if (process.env.IS_SEEDING === true) { - return true - } return ctx.user !== null }) const isOwner = rule()(async (parent, args, ctx, info) => { - // TODO: how to get this working while seeding? - console.log('isSeeding', process.env.IS_SEEDING) - if (process.env.IS_SEEDING === true) { - return true - } console.log('parent', parent) return ctx.user.id === parent.id }) const isAdmin = rule()(async (parent, args, ctx, info) => { - // TODO: how to get this working while seeding? - console.log('isSeeding', process.env.IS_SEEDING) - if (process.env.IS_SEEDING === true) { - return true - } return ctx.user.role === 'ADMIN' }) const isModerator = rule()(async (parent, args, ctx, info) => { - // TODO: how to get this working while seeding? - console.log('isSeeding', process.env.IS_SEEDING) - if (process.env.IS_SEEDING === true) { - return true - } return ctx.user.role === 'MODERATOR' }) @@ -46,10 +26,10 @@ const permissions = shield({ CreateUser: allow }, // TODO: re-activate this after fixing the initial seed - // User: { - // email: isOwner, - // password: isOwner - // }, + User: { + email: isOwner, + password: isOwner + }, Post: isAuthenticated }) diff --git a/src/middleware/softDeleteMiddleware.js b/src/middleware/softDeleteMiddleware.js index c413961bc..79e4a7d08 100644 --- a/src/middleware/softDeleteMiddleware.js +++ b/src/middleware/softDeleteMiddleware.js @@ -11,12 +11,12 @@ export default { return result }, Comment: async (resolve, root, args, context, info) => { - // if (typeof args.deleted !== 'boolean') { - // args.deleted = false - // } - // if (typeof args.disabled !== 'boolean') { - // args.disabled = false - // } + if (typeof args.deleted !== 'boolean') { + args.deleted = false + } + if (typeof args.disabled !== 'boolean') { + args.disabled = false + } const result = await resolve(root, args, context, info) return result }, diff --git a/src/schema.graphql b/src/schema.graphql index e6bb4f350..f5f58818b 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -44,21 +44,6 @@ enum UserGroupEnum { user } -type WrittenPost @relation(name: "WROTE") { - from: User - to: Post - timestamp: Int # TODO: change that to custom Date Type -} -# type WrittenPost2 { -# Post: Post! -# timestamp: Int # TODO: change that to custom Date Type -# } -type WrittenComment @relation(name: "WROTE") { - from: User - to: Comment - timestamp: Int # TODO: change that to custom Date Type -} - type User { id: ID! name: String @@ -94,7 +79,7 @@ type User { RETURN COUNT(r)""" ) - comments: [WrittenComment]! + comments: [Comment]! @relation(name: "WROTE", direction: "OUT") commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) WHERE NOT r.deleted = true RETURN COUNT(r)") shouted: [Post]! @relation(name: "SHOUTED", direction: "OUT") @@ -111,7 +96,7 @@ type User { type Post { id: ID! - author: WrittenPost + author: User @relation(name: "WROTE", direction: "IN") title: String! slug: String content: String! @@ -141,12 +126,12 @@ type Post { type Comment { id: ID! - author: WrittenComment + author: User @relation(name: "WROTE", direction: "IN") content: String! contentExcerpt: String - post: Post @relation(name: "COMMENT", direction: "OUT") - createdAt: String, - updatedAt: String, + post: Post @relation(name: "COMMENTS", direction: "OUT") + createdAt: String + updatedAt: String deleted: Boolean disabled: Boolean } diff --git a/src/seed/data/categories.js b/src/seed/data/categories.js new file mode 100644 index 000000000..c070d5056 --- /dev/null +++ b/src/seed/data/categories.js @@ -0,0 +1,22 @@ +export default function (data) { + return ` + mutation { + cat1: CreateCategory( id: "cat1", name: "Just For Fun", slug: "justforfun", icon: "categories-justforfun" ) { name } + cat2: CreateCategory( id: "cat2", name: "Happyness & Values", slug: "happyness-values", icon: "categories-luck" ) { name } + cat3: CreateCategory( id: "cat3", name: "Health & Wellbeing", slug: "health-wellbeing", icon: "categories-health" ) { name } + cat4: CreateCategory( id: "cat4", name: "Environment & Nature", slug: "environment-nature", icon: "categories-environment" ) { name } + cat5: CreateCategory( id: "cat5", name: "Animal Protection", slug: "animalprotection", icon: "categories-animal-justice" ) { name } + cat6: CreateCategory( id: "cat6", name: "Humanrights Justice", slug: "humanrights-justice", icon: "categories-human-rights" ) { name } + cat7: CreateCategory( id: "cat7", name: "Education & Sciences", slug: "education-sciences", icon: "categories-education" ) { name } + cat8: CreateCategory( id: "cat8", name: "Cooperation & Development", slug: "cooperation-development", icon: "categories-cooperation" ) { name } + cat9: CreateCategory( id: "cat9", name: "Democracy & Politics", slug: "democracy-politics", icon: "categories-politics" ) { name } + cat10: CreateCategory( id: "cat10", name: "Economy & Finances", slug: "economy-finances", icon: "categories-economy" ) { name } + cat11: CreateCategory( id: "cat11", name: "Energy & Technology", slug: "energy-technology", icon: "categories-technology" ) { name } + cat12: CreateCategory( id: "cat12", name: "IT, Internet & Data Privacy", slug: "it-internet-dataprivacy", icon: "categories-internet" ) { name } + cat13: CreateCategory( id: "cat13", name: "Art, Curlure & Sport", slug: "art-culture-sport", icon: "categories-art" ) { name } + cat14: CreateCategory( id: "cat14", name: "Freedom of Speech", slug: "freedomofspeech", icon: "categories-freedom-of-speech" ) { name } + cat15: CreateCategory( id: "cat15", name: "Consumption & Sustainability", slug: "consumption-sustainability", icon: "categories-sustainability" ) { name } + cat16: CreateCategory( id: "cat16", name: "Global Peace & Nonviolence", slug: "globalpeace-nonviolence", icon: "categories-peace" ) { name } + } + ` +} diff --git a/src/seed/data/comments.js b/src/seed/data/comments.js new file mode 100644 index 000000000..ac1849b86 --- /dev/null +++ b/src/seed/data/comments.js @@ -0,0 +1,80 @@ +import faker from 'faker' + +/** + * TODO: add a comment automatically to the correct post and relate it to the current user + */ +export default function (data) { + return ` + mutation { + c1: CreateComment( + id: "c1", + content: "

da stimm ich dir zu. Mir ging das auch nie in den kopf, und hatte jesus nie als gott gesehen

" + ) { id } + c1_u1: AddCommentAuthor(from: { id: "u3" }, to: { id: "c1" }) { from { id } } + c1_p1: AddCommentPost( + from: { id: "c1" }, + to: { id: "p1" } + ) { from { id } } + + c2: CreateComment( + id: "c2", + content: "

Schön das es dich gibt ❤️❤️❤️❤️❤️❤️❤️❤️❤️

" + ) { id } + c2_u1: AddCommentAuthor(from: { id: "u1" }, to: { id: "c2" }) { from { id } } + c2_p1: AddCommentPost( + from: { id: "c2" }, + to: { id: "p1" } + ) { from { id } } + + c3: CreateComment( + id: "c3", + content: "

Hi Dieter,

danke fĂźr Deine Info. Hast Du mal ein Foto von Deinem Cabrio mit dem Logo drauf?

" + ) { id } + c3_u2: AddCommentAuthor(from: { id: "u1" }, to: { id: "c3" }) { from { id } } + c3_p3: AddCommentPost( + from: { id: "c3" }, + to: { id: "p3" } + ) { from { id } } + + c4: CreateComment( + id: "c4", + content: "

Das ZusammenfĂźhren aller Gruppen, die mit uns am gleichen Strang in die gleiche Richtung ziehen, in eine gemeinsame Adressenstruktur sehe ich auch als Haupt - Aufgabe fĂźr unsere neue Netzwerkbildung an.

" + ) { id } + c4_u3: AddCommentAuthor(from: { id: "u4" }, to: { id: "c4" }) { from { id } } + c4_p2: AddCommentPost( + from: { id: "c4" }, + to: { id: "p2" } + ) { from { id } } + + c5: CreateComment( + id: "c5", + content: "${faker.lorem.paragraph()}" + ) { id } + c5_u4: AddCommentAuthor(from: { id: "u4" }, to: { id: "c5" }) { from { id } } + c5_p3: AddCommentPost( + from: { id: "c5" }, + to: { id: "p3" } + ) { from { id } } + + c6: CreateComment( + id: "c6", + content: "${faker.lorem.paragraph()}" + ) { id } + c6_u3: AddCommentAuthor(from: { id: "u3" }, to: { id: "c6" }) { from { id } } + c6_p4: AddCommentPost( + from: { id: "c6" }, + to: { id: "p4" } + ) { from { id } } + + c7: CreateComment( + id: "c7", + content: "${faker.lorem.paragraph()}" + ) { id } + c7_u2: AddCommentAuthor(from: { id: "u2" }, to: { id: "c7" }) { from { id } } + c7_p2: AddCommentPost( + from: { id: "c7" }, + to: { id: "p2" } + ) { from { id } } + } + ` +} diff --git a/src/seed/data/index.js b/src/seed/data/index.js index 0ac7681aa..c65fb431c 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -2,9 +2,19 @@ import gql from 'graphql-tag' import helper from '../seed-helpers' const seed = { - Badges: require('./badges.js').default, + Badge: require('./badges.js').default, + Category: require('./categories.js').default, + Tags: require('./tags.js').default, + User: require('./users.js').default, - UserBadges: require('./users-badges.js').default + UserBadges: require('./users-badges.js').default, + UserBlacklist: require('./users-blacklist.js').default, + UserFollows: require('./users-follows.js').default, + UserFriends: require('./users-friends.js').default, + + Post: require('./posts.js').default, + Comment: require('./comments.js').default, + UserShouts: require('./users-shouts.js').default }; let data = {} diff --git a/src/seed/data/posts.js b/src/seed/data/posts.js new file mode 100644 index 000000000..e94f63f69 --- /dev/null +++ b/src/seed/data/posts.js @@ -0,0 +1,112 @@ +import faker from 'faker' + +export default function (data) { + return ` + mutation { + p1: CreatePost( + id: "p1", + title: "Gedanken eines Polizisten zum Einsatz im Hambacher Forst", + content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", + image: "https://picsum.photos/1280/1024?image=352", + visibility: public, + disabled: false, + deleted: false + ) { title } + p1_cat1: AddPostCategories(from: {id: "p1"}, to: {id: "cat1"}) { from { id } } + p1_cat2: AddPostCategories(from: {id: "p1"}, to: {id: "cat2"}) { from { id } } + ur1: AddUserContributions(from: { id: "u1" }, to: { id: "p1" }) { from { id } } + p1_t1: AddPostTags( + from: { id: "p1" } + to: { id: "t1" } + ) { from { id } } + p1_t2: AddPostTags( + from: { id: "p1" } + to: { id: "t2" } + ) { from { id } } + p1_t3: AddPostTags( + from: { id: "p1" } + to: { id: "t3" } + ) { from { id } } + + p2: CreatePost( + id: "p2", + title: "Julian Assange", + content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", + image: "https://picsum.photos/1280/1024?image=72", + visibility: public, + disabled: false, + deleted: false + ) { title } + p2_cat1: AddPostCategories(from: {id: "p2"}, to: {id: "cat1"}) { from { id } } + p2_cat16: AddPostCategories(from: {id: "p2"}, to: {id: "cat16"}) { from { id } } + ur2: AddUserContributions(from: { id: "u2" }, to: { id: "p2" }) { from { id } } + p2_t4: AddPostTags( + from: { id: "p2" } + to: { id: "t4" } + ) { from { id } } + + p3: CreatePost( + id: "p3", + title: "Hacker, Freaks und Funktionäre...Der CCC", + content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", + image: "https://picsum.photos/1280/1024?image=121", + visibility: public, + disabled: false, + deleted: false + ) { title } + p3_cat1: AddPostCategories(from: {id: "p3"}, to: {id: "cat1"}) { from { id } } + p3_cat3: AddPostCategories(from: {id: "p3"}, to: {id: "cat3"}) { from { id } } + p3_cat14: AddPostCategories(from: {id: "p3"}, to: {id: "cat14"}) { from { id } } + ur3: AddUserContributions(from: { id: "u3" }, to: { id: "p3" }) { from { id } } + p3_t2: AddPostTags( + from: { id: "p3" } + to: { id: "t2" } + ) { from { id } } + p3_t4: AddPostTags( + from: { id: "p3" } + to: { id: "t4" } + ) { from { id } } + + p4: CreatePost( + id: "p4", + title: "Lebensmittel (?)", + content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", + image: "https://picsum.photos/1280/1024?image=142", + visibility: public, + disabled: false, + deleted: false + ) { title } + p4_cat1: AddPostCategories(from: {id: "p4"}, to: {id: "cat1"}) { from { id } } + p4_cat9: AddPostCategories(from: {id: "p4"}, to: {id: "cat9"}) { from { id } } + p4_cat4: AddPostCategories(from: {id: "p4"}, to: {id: "cat4"}) { from { id } } + ur4: AddUserContributions(from: { id: "u4" }, to: { id: "p4" }) { from { id } } + + p5: CreatePost( + id: "p5", + title: "${faker.lorem.sentence()}", + content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", + image: "https://picsum.photos/1280/1024?image=231", + visibility: public, + disabled: false, + deleted: false + ) { title } + p5_cat8: AddPostCategories(from: {id: "p5"}, to: {id: "cat8"}) { from { id } } + p5_cat12: AddPostCategories(from: {id: "p5"}, to: {id: "cat12"}) { from { id } } + ur5: AddUserContributions(from: { id: "u2" }, to: { id: "p5" }) { from { id } } + + p6: CreatePost( + id: "p6", + title: "${faker.lorem.sentence()}", + content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", + image: "https://picsum.photos/1280/1024?image=424", + visibility: public, + disabled: false, + deleted: false + ) { title } + p6_cat1: AddPostCategories(from: {id: "p6"}, to: {id: "cat1"}) { from { id } } + p6_cat2: AddPostCategories(from: {id: "p6"}, to: {id: "cat2"}) { from { id } } + p6_cat5: AddPostCategories(from: {id: "p6"}, to: {id: "cat5"}) { from { id } } + ur6: AddUserContributions(from: { id: "u4" }, to: { id: "p6" }) { from { id } } + } + ` +} diff --git a/src/seed/data/tags.js b/src/seed/data/tags.js new file mode 100644 index 000000000..be4b3da90 --- /dev/null +++ b/src/seed/data/tags.js @@ -0,0 +1,22 @@ +export default function (data) { + return ` + mutation { + t1: CreateTag( + id: "t1", + name: "Umwelt" + ) { name } + t2: CreateTag( + id: "t2", + name: "Naturschutz" + ) { name } + t3: CreateTag( + id: "t3", + name: "Demokratie" + ) { name } + t4: CreateTag( + id: "t4", + name: "Freiheit" + ) { name } + } + ` +} diff --git a/src/seed/data/users-badges.js b/src/seed/data/users-badges.js index 1a8bc1fe1..e303c6157 100644 --- a/src/seed/data/users-badges.js +++ b/src/seed/data/users-badges.js @@ -1,12 +1,7 @@ export default function (data) { return ` mutation { - b1_u1: AddUserBadges(from: {id: "b1"}, to: {id: "u1"}) { from { id } } - b2_u1: AddUserBadges(from: {id: "b2"}, to: {id: "u1"}) { from { id } } - b3_u1: AddUserBadges(from: {id: "b3"}, to: {id: "u1"}) { from { id } } - b6_u2: AddUserBadges(from: {id: "b6"}, to: {id: "u2"}) { from { id } } - b3_u3: AddUserBadges(from: {id: "b3"}, to: {id: "u3"}) { from { id } } - b5_u4: AddUserBadges(from: {id: "b5"}, to: {id: "u4"}) { from { id } } + u1_blacklist_u4: AddUserBlacklisted(from: { id: "u1" }, to: { id: "u4" }) { from { id } } } ` } diff --git a/src/seed/data/users-blacklist.js b/src/seed/data/users-blacklist.js new file mode 100644 index 000000000..1a8bc1fe1 --- /dev/null +++ b/src/seed/data/users-blacklist.js @@ -0,0 +1,12 @@ +export default function (data) { + return ` + mutation { + b1_u1: AddUserBadges(from: {id: "b1"}, to: {id: "u1"}) { from { id } } + b2_u1: AddUserBadges(from: {id: "b2"}, to: {id: "u1"}) { from { id } } + b3_u1: AddUserBadges(from: {id: "b3"}, to: {id: "u1"}) { from { id } } + b6_u2: AddUserBadges(from: {id: "b6"}, to: {id: "u2"}) { from { id } } + b3_u3: AddUserBadges(from: {id: "b3"}, to: {id: "u3"}) { from { id } } + b5_u4: AddUserBadges(from: {id: "b5"}, to: {id: "u4"}) { from { id } } + } + ` +} diff --git a/src/seed/data/users-follows.js b/src/seed/data/users-follows.js new file mode 100644 index 000000000..af6467e7f --- /dev/null +++ b/src/seed/data/users-follows.js @@ -0,0 +1,26 @@ +export default function (data) { + return ` + mutation { + u1_follow_u2: AddUserFollowing( + from: { id: "u1" }, + to: { id: "u2" } + ) { from { id } } + u2_follow_u1: AddUserFollowing( + from: { id: "u2" }, + to: { id: "u1" } + ) { from { id } } + u2_follow_u3: AddUserFollowing( + from: { id: "u2" }, + to: { id: "u3" } + ) { from { id } } + u2_follow_u4: AddUserFollowing( + from: { id: "u2" }, + to: { id: "u4" } + ) { from { id } } + u4_follow_u2: AddUserFollowing( + from: { id: "u4" }, + to: { id: "u2" } + ) { from { id } } + } + ` +} diff --git a/src/seed/data/users-friends.js b/src/seed/data/users-friends.js new file mode 100644 index 000000000..33d7db7e4 --- /dev/null +++ b/src/seed/data/users-friends.js @@ -0,0 +1,14 @@ +export default function (data) { + return ` + mutation { + u1_friends_u2: AddUserFriends( + from: { id: "u1" }, + to: { id: "u2" } + ) { from { id } } + u1_friends_u3: AddUserFriends( + from: { id: "u1" }, + to: { id: "u3" } + ) { from { id } } + } + ` +} diff --git a/src/seed/data/users-shouts.js b/src/seed/data/users-shouts.js new file mode 100644 index 000000000..9c0f2d1bf --- /dev/null +++ b/src/seed/data/users-shouts.js @@ -0,0 +1,30 @@ +export default function (data) { + return ` + mutation { + u1s2: AddUserShouted( + from: { id: "u1" }, + to: { id: "p2" } + ) { from { id } } + u1s3: AddUserShouted( + from: { id: "u1" }, + to: { id: "p3" } + ) { from { id } } + u2s1: AddUserShouted( + from: { id: "u2" }, + to: { id: "p1" } + ) { from { id } } + u3s1: AddUserShouted( + from: { id: "u3" }, + to: { id: "p1" } + ) { from { id } } + u3s4: AddUserShouted( + from: { id: "u3" }, + to: { id: "p4" } + ) { from { id } } + u4s1: AddUserShouted( + from: { id: "u4" }, + to: { id: "p1" } + ) { from { id } } + } + ` +} diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 0617a53fe..df6999426 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,7 +1,6 @@ import ApolloClient from "apollo-client"; import dotenv from "dotenv"; import gql from 'graphql-tag' -import seedMutations from "./seed-mutations"; import fetch from "node-fetch"; import { HttpLink } from "apollo-link-http"; import { InMemoryCache } from "apollo-cache-inmemory"; @@ -9,16 +8,13 @@ import Seed from './data/index' dotenv.config(); +if (process.env.NODE_ENV === 'production') { + throw new Error('YOU CAN`T SEED IN PRODUCTION MODE') +} + const client = new ApolloClient({ link: new HttpLink({ uri: process.env.GRAPHQL_URI, fetch }), cache: new InMemoryCache() }); Seed(client) - -/* client - .mutate({ - mutation: gql(seedMutations) - }) - .then(data => console.log(data)) - .catch(error => console.error(error)); **/ diff --git a/src/seed/seed-mutations.js b/src/seed/seed-mutations.js index 8431e3c59..6a06675a6 100644 --- a/src/seed/seed-mutations.js +++ b/src/seed/seed-mutations.js @@ -263,10 +263,6 @@ export default ` from: { id: "c6" }, to: { id: "p4" } ) { from { id } } - c6_p1: AddCommentPost( - from: { id: "c6" }, - to: { id: "p1" } - ) { from { id } } c7_p2: AddCommentPost( from: { id: "c7" }, to: { id: "p2" } From fa2c3fc24bf4e7405a5adfc8341f73871b927aba Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 21 Nov 2018 15:30:26 +0100 Subject: [PATCH 080/554] shortened GRAPHQL_LISTEN_PORT to GRAPHQL_PORT --- .env.template | 2 +- docker-compose.yml | 2 +- kubernetes/backend-deployment.yaml | 2 +- package.json | 2 +- src/index.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.env.template b/.env.template index df678a343..59ae471c9 100644 --- a/.env.template +++ b/.env.template @@ -1,7 +1,7 @@ NEO4J_URI=bolt://localhost:7687 NEO4J_USER=neo4j NEO4J_PASSWORD=letmein -GRAPHQL_LISTEN_PORT=4000 +GRAPHQL_PORT=4000 GRAPHQL_URI=http://localhost:4000 MOCK=false diff --git a/docker-compose.yml b/docker-compose.yml index 0a47bb3c0..af63a3b56 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,7 +12,7 @@ services: - 4000:4000 environment: - NEO4J_URI=bolt://neo4j:7687 - - GRAPHQL_LISTEN_PORT=4000 + - GRAPHQL_PORT=4000 - GRAPHQL_URI=http://localhost:4000 - CLIENT_URI=http://localhost:3000 - JWT_SECRET=b/&&7b78BF&fv/Vd diff --git a/kubernetes/backend-deployment.yaml b/kubernetes/backend-deployment.yaml index cf7f34063..95613f3ac 100644 --- a/kubernetes/backend-deployment.yaml +++ b/kubernetes/backend-deployment.yaml @@ -21,7 +21,7 @@ spec: - env: - name: CLIENT_URI value: http://localhost:3000 - - name: GRAPHQL_LISTEN_PORT + - name: GRAPHQL_PORT value: "4000" - name: GRAPHQL_URI value: http://localhost:4000 diff --git a/package.json b/package.json index 236dd805b..b6c0130f8 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "test": "echo \"Error: no test specified\" && exit 1", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "db:seed": "concurrently --kill-others --success first 'cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_LISTEN_PORT=4001 yarn run start' 'wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js'" + "db:seed": "concurrently --kill-others --success first 'cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start' 'wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js'" }, "author": "Grzegorz Leoniec", "license": "MIT", diff --git a/src/index.js b/src/index.js index 666384a2b..dc8d30ff1 100644 --- a/src/index.js +++ b/src/index.js @@ -61,7 +61,7 @@ server.express.use(passport.initialize()) server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) const serverConfig = { - port: process.env.GRAPHQL_LISTEN_PORT + port: process.env.GRAPHQL_PORT // cors: { // credentials: true, // origin: [process.env.CLIENT_URI] // your frontend url. From 8c72c88e596746bd71923d9532e930fe474c9a01 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 21 Nov 2018 15:38:47 +0100 Subject: [PATCH 081/554] made permissions accessible for the outside --- src/middleware/permissionsMiddleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index e788d08e0..3a77d1136 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -16,7 +16,7 @@ const isModerator = rule()(async (parent, args, ctx, info) => { // Permissions const permissions = shield({ Query: { - statistics: isAdmin, + statistics: allow // fruits: and(isAuthenticated, or(isAdmin, isModerator)), // customers: and(isAuthenticated, isAdmin) }, From c1387f262d19029edce081b20e25c815aab93916 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 22 Nov 2018 11:36:49 +0100 Subject: [PATCH 082/554] added permissions as first item. --- src/middleware/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/middleware/index.js b/src/middleware/index.js index 6ed0fa697..f3b036d63 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -17,8 +17,10 @@ export default schema => { fixImageUrlsMiddleware, softDeleteMiddleware ] + + // add permisions middleware if we are not seeding to the first position if (process.env.PERMISSIONS !== 'disabled') { - middleware.push(permissionsMiddleware.generate(schema)) + middleware.unshift(permissionsMiddleware.generate(schema)) } return middleware } From 3912515c2580e5b82cfbcb38d954be4b34bde0bd Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 22 Nov 2018 12:22:22 +0100 Subject: [PATCH 083/554] do not allow disabling permissions in production --- src/middleware/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/middleware/index.js b/src/middleware/index.js index f3b036d63..4d3b5f72f 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -19,7 +19,8 @@ export default schema => { ] // add permisions middleware if we are not seeding to the first position - if (process.env.PERMISSIONS !== 'disabled') { + // NOTE: DO NOT SET THE PERMISSION FLAT YOUR SELF + if (process.env.PERMISSIONS !== 'disabled' && process.env.NODE_ENV !== 'production') { middleware.unshift(permissionsMiddleware.generate(schema)) } return middleware From e5b89dc1c6e52511d5260b19ef9d66be00707baa Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 23 Nov 2018 16:08:02 +0100 Subject: [PATCH 084/554] Added travis configuration --- .travis.yml | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..d9c22693f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,45 @@ +language: node_js +node_js: + - "10" +cache: + yarn: true + directories: + - node_modules +services: + # we need docker for building the image and mongo for testing + - docker +# install: + # nothing! + +jobs: + include: + - stage: Prepare Cache + script: true + - stage: Build and Test + script: + - docker build -t humanconnection/backend . + - script: + - yarn install --frozen-lockfile --non-interactive --ignore-engines + - yarn global add codacy-coverage + - yarn run ci + - cat ./coverage/lcov.info | codacy-coverage + +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 + docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; + docker tag humanconnection/backend humanconnection/backend:latest; + docker push humanconnection/backend:alpha; + fi +# - if [ $TRAVIS_BRANCH == "develop" ] && [ $TRAVIS_EVENT_TYPE == "push" ]; then +# docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; +# docker tag humanconnection/backend humanconnection/backend:latest; +# docker push humanconnection/backend:edge; +# 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 From 2f67cfc741ec9be26057d23170e379357319bdee Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 23 Nov 2018 16:09:59 +0100 Subject: [PATCH 085/554] fixed tag --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d9c22693f..f663eba38 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,12 +31,12 @@ after_success: - if [ $TRAVIS_BRANCH == "master" ] && [ $TRAVIS_EVENT_TYPE == "push" ]; then docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; docker tag humanconnection/backend humanconnection/backend:latest; - docker push humanconnection/backend:alpha; + docker push humanconnection/backend:latest; fi # - if [ $TRAVIS_BRANCH == "develop" ] && [ $TRAVIS_EVENT_TYPE == "push" ]; then # docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; # docker tag humanconnection/backend humanconnection/backend:latest; -# docker push humanconnection/backend:edge; +# docker push humanconnection/backend:latest; # fi after_failure: From 68b143be7e689e79f914c1c35c7507b6b2de654f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 23 Nov 2018 16:51:29 +0100 Subject: [PATCH 086/554] Update src/middleware/index.js Co-Authored-By: appinteractive --- src/middleware/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/index.js b/src/middleware/index.js index 4d3b5f72f..6b17eb5f6 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -18,7 +18,7 @@ export default schema => { softDeleteMiddleware ] - // add permisions middleware if we are not seeding to the first position + // add permisions middleware at the first position (unless we're seeding) // NOTE: DO NOT SET THE PERMISSION FLAT YOUR SELF if (process.env.PERMISSIONS !== 'disabled' && process.env.NODE_ENV !== 'production') { middleware.unshift(permissionsMiddleware.generate(schema)) From d74aa6dd027be73d8782d08d4adfb781f20a0d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 23 Nov 2018 20:45:17 +0100 Subject: [PATCH 087/554] Build and run docker container on Travis The docker container environment should be the single source of truth --- .travis.yml | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/.travis.yml b/.travis.yml index f663eba38..05142b9ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,18 +11,10 @@ services: # install: # nothing! -jobs: - include: - - stage: Prepare Cache - script: true - - stage: Build and Test - script: - - docker build -t humanconnection/backend . - - script: - - yarn install --frozen-lockfile --non-interactive --ignore-engines - - yarn global add codacy-coverage - - yarn run ci - - cat ./coverage/lcov.info | codacy-coverage +before_script: + - docker build -t humanconnection/backend . +script: + - docker run humanconnection/backend yarn run db:seed after_success: - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh @@ -33,11 +25,6 @@ after_success: docker tag humanconnection/backend humanconnection/backend:latest; docker push humanconnection/backend:latest; fi -# - if [ $TRAVIS_BRANCH == "develop" ] && [ $TRAVIS_EVENT_TYPE == "push" ]; then -# docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; -# docker tag humanconnection/backend humanconnection/backend:latest; -# docker push humanconnection/backend:latest; -# fi after_failure: - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh From 8bb90e52a6c5fa2acc3c207f8c154611d7f920e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 23 Nov 2018 20:49:09 +0100 Subject: [PATCH 088/554] Copy .env.template in Dockerfile to seed on travis --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 5e3f8c650..1b90de2b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,5 +14,6 @@ COPY yarn.lock . RUN yarn install --production=false --frozen-lockfile --non-interactive COPY . . +COPY .env.template .env CMD ["yarn", "run", "start"] From 89d30c01a01cb7ad72eb2ef3e3d7fd1c621c3124 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sat, 24 Nov 2018 12:10:50 +0100 Subject: [PATCH 089/554] unified travis.yml and prefixed docker image --- .travis.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 05142b9ea..6841b22bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,20 @@ language: node_js node_js: - "10" +services: + - docker cache: yarn: true directories: - node_modules -services: - # we need docker for building the image and mongo for testing - - docker # install: # nothing! before_script: - - docker build -t humanconnection/backend . + - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend . + script: - - docker run humanconnection/backend yarn run db:seed + - docker run humanconnection/nitro-backend yarn run db:seed after_success: - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh @@ -22,8 +22,8 @@ after_success: - ./send.sh success $WEBHOOK_URL - if [ $TRAVIS_BRANCH == "master" ] && [ $TRAVIS_EVENT_TYPE == "push" ]; then docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - docker tag humanconnection/backend humanconnection/backend:latest; - docker push humanconnection/backend:latest; + docker tag humanconnection/nitro-backend humanconnection/nitro-backend:latest; + docker push humanconnection/nitro-backend:latest; fi after_failure: From 80e036c0fbef2d81dd5c04d21c32e6c305069c51 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sat, 24 Nov 2018 12:38:51 +0100 Subject: [PATCH 090/554] updated travis build --- .travis.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6841b22bb..e451f968e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,6 @@ cache: yarn: true directories: - node_modules -# install: - # nothing! before_script: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend . @@ -17,9 +15,9 @@ script: - docker run humanconnection/nitro-backend yarn run db:seed after_success: - - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh - - chmod +x send.sh - - ./send.sh success $WEBHOOK_URL + # - 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 docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; docker tag humanconnection/nitro-backend humanconnection/nitro-backend:latest; From b25a7d673e088fe66776dc62832cdb14597eea3c Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sat, 24 Nov 2018 12:41:17 +0100 Subject: [PATCH 091/554] user humanconnection/nitro-backend --- kubernetes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index 7699e5426..81c6c4f88 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -27,7 +27,7 @@ git clone https://github.com/Human-Connection/Nitro-Web.git Build Docker images, using the Minikube Docker daemon: ```sh eval $(minikube docker-env) -docker build -t humanconnection/backend:latest Nitro-Backend/ +docker build -t humanconnection/nitro-backend:latest Nitro-Backend/ docker build -t humanconnection/neo4j:latest -f Nitro-Backend/Dockerfile.neo4j Nitro-Backend/ ``` From e2f7bc516c071d768b5ec601de07890334ee099f Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sat, 24 Nov 2018 12:58:13 +0100 Subject: [PATCH 092/554] improved docker file --- Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1b90de2b1..45d68e8b6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,14 @@ FROM node:10-alpine -LABEL Description="Server part of the social network Human Connection" Vendor="Human-Connection gGmbH" Version="0.0.1" Maintainer="Human-Connection gGmbH (developer@human-connection.org)" +LABEL Description="Backend of the Social Network Human-Connection.org" Vendor="Human-Connection gGmbH" Version="0.0.1" Maintainer="Human-Connection gGmbH (developer@human-connection.org)" -# expose the app port +# Expose the app port EXPOSE 4000 -ARG WORKDIR=/backend - +ARG WORKDIR=/nitro-backend RUN mkdir -p $WORKDIR WORKDIR $WORKDIR +# Install the Application Dependencies COPY package.json . COPY yarn.lock . RUN yarn install --production=false --frozen-lockfile --non-interactive From e218773dd5eccbd278f1b931864144af22f2eec8 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 25 Nov 2018 14:23:52 +0100 Subject: [PATCH 093/554] fixed build by using install instead before_script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e451f968e..62f05c96a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ cache: directories: - node_modules -before_script: +install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend . script: From 5597e34dab8198d0cf4b4476b28b142f40e25f7b Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 26 Nov 2018 17:18:09 +0100 Subject: [PATCH 094/554] Fixed Badges Seeder and URL Fix Middleware --- src/middleware/fixImageUrlsMiddleware.js | 9 +++++++-- src/seed/data/badges.js | 12 ++++++------ src/seed/data/users-badges.js | 7 ++++++- src/seed/data/users-blacklist.js | 7 +------ 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/middleware/fixImageUrlsMiddleware.js b/src/middleware/fixImageUrlsMiddleware.js index 864726a54..919a46ab6 100644 --- a/src/middleware/fixImageUrlsMiddleware.js +++ b/src/middleware/fixImageUrlsMiddleware.js @@ -1,9 +1,14 @@ +const urlSearchAlpha = 'https://api-alpha.human-connection.org' +const urlSearchLocal = 'http://localhost:3000' + export const fixUrl = (url) => { - return url.replace('https://api-alpha.human-connection.org', 'http://localhost:3000') + url = url.replace(urlSearchAlpha, '') + url = url.replace(urlSearchLocal, '') + return url } const fixImageURLs = (result, recursive) => { - if (result && typeof result === 'string' && result.indexOf('https://api-alpha.human-connection.org') === 0) { + if (result && typeof result === 'string' && (result.indexOf(urlSearchAlpha) === 0 || result.indexOf(urlSearchLocal) === 0)) { result = fixUrl(result) } else if (result && Array.isArray(result)) { result.forEach((res, index) => { diff --git a/src/seed/data/badges.js b/src/seed/data/badges.js index d4144d30e..bb3ad06c7 100644 --- a/src/seed/data/badges.js +++ b/src/seed/data/badges.js @@ -1,12 +1,12 @@ export default function (data) { return ` mutation { - b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_racoon.svg") { id } - b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_rabbit.svg") { id } - b3: CreateBadge(id: "b3", key: "indiegogo_en_wolf", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_wolf.svg") { id } - b4: CreateBadge(id: "b4", key: "indiegogo_en_bear", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_bear.svg") { id } - b5: CreateBadge(id: "b5", key: "indiegogo_en_turtle", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_turtle.svg") { id } - b6: CreateBadge(id: "b6", key: "indiegogo_en_rhino", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_rhino.svg") { id } + b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_racoon.svg") { id } + b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_rabbit.svg") { id } + b3: CreateBadge(id: "b3", key: "indiegogo_en_wolf", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_wolf.svg") { id } + b4: CreateBadge(id: "b4", key: "indiegogo_en_bear", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_bear.svg") { id } + b5: CreateBadge(id: "b5", key: "indiegogo_en_turtle", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_turtle.svg") { id } + b6: CreateBadge(id: "b6", key: "indiegogo_en_rhino", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_rhino.svg") { id } } ` } diff --git a/src/seed/data/users-badges.js b/src/seed/data/users-badges.js index e303c6157..1a8bc1fe1 100644 --- a/src/seed/data/users-badges.js +++ b/src/seed/data/users-badges.js @@ -1,7 +1,12 @@ export default function (data) { return ` mutation { - u1_blacklist_u4: AddUserBlacklisted(from: { id: "u1" }, to: { id: "u4" }) { from { id } } + b1_u1: AddUserBadges(from: {id: "b1"}, to: {id: "u1"}) { from { id } } + b2_u1: AddUserBadges(from: {id: "b2"}, to: {id: "u1"}) { from { id } } + b3_u1: AddUserBadges(from: {id: "b3"}, to: {id: "u1"}) { from { id } } + b6_u2: AddUserBadges(from: {id: "b6"}, to: {id: "u2"}) { from { id } } + b3_u3: AddUserBadges(from: {id: "b3"}, to: {id: "u3"}) { from { id } } + b5_u4: AddUserBadges(from: {id: "b5"}, to: {id: "u4"}) { from { id } } } ` } diff --git a/src/seed/data/users-blacklist.js b/src/seed/data/users-blacklist.js index 1a8bc1fe1..e303c6157 100644 --- a/src/seed/data/users-blacklist.js +++ b/src/seed/data/users-blacklist.js @@ -1,12 +1,7 @@ export default function (data) { return ` mutation { - b1_u1: AddUserBadges(from: {id: "b1"}, to: {id: "u1"}) { from { id } } - b2_u1: AddUserBadges(from: {id: "b2"}, to: {id: "u1"}) { from { id } } - b3_u1: AddUserBadges(from: {id: "b3"}, to: {id: "u1"}) { from { id } } - b6_u2: AddUserBadges(from: {id: "b6"}, to: {id: "u2"}) { from { id } } - b3_u3: AddUserBadges(from: {id: "b3"}, to: {id: "u3"}) { from { id } } - b5_u4: AddUserBadges(from: {id: "b5"}, to: {id: "u4"}) { from { id } } + u1_blacklist_u4: AddUserBlacklisted(from: { id: "u1" }, to: { id: "u4" }) { from { id } } } ` } From ebcec50a09e69ed8b89944f261e8d2ea0d631488 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 26 Nov 2018 18:03:59 +0100 Subject: [PATCH 095/554] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2cb57e264..653068a1d 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ Optionally you can seed the GraphQL service by executing mutations that will write sample data to the database: ```bash -yarn seedDb +yarn db:seed # -or- -npm run seedDb +npm run db:seed ``` ## Todo`s From 28ed218d9933c4f6e229157e8cc9fa88e66e3ed1 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 27 Nov 2018 11:27:19 +0100 Subject: [PATCH 096/554] updated nodemon due to possible security issue: https://github.com/dominictarr/event-stream/issues/116 --- package.json | 2 +- yarn.lock | 85 +++++++--------------------------------------------- 2 files changed, 11 insertions(+), 76 deletions(-) diff --git a/package.json b/package.json index f2f667236..268f2e1a7 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "concurrently": "^4.1.0", "cross-env": "^5.2.0", "faker": "^4.1.0", - "nodemon": "^1.18.4", + "nodemon": "^1.18.7", "wait-on": "^3.2.0" } } diff --git a/yarn.lock b/yarn.lock index 0adbbdbab..1d79d8da6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2026,11 +2026,6 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= -duplexer@^0.1.1, duplexer@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= - ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -2125,20 +2120,6 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= -event-stream@~3.3.0: - version "3.3.6" - resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.6.tgz#cac1230890e07e73ec9cacd038f60a5b66173eef" - integrity sha512-dGXNg4F/FgVzlApjzItL+7naHutA3fDqbV/zAZqDDlXTjiMnQmZKu+prImWKszeBM5UQeGvAl3u1wBiKeDh61g== - dependencies: - duplexer "^0.1.1" - flatmap-stream "^0.1.0" - from "^0.1.7" - map-stream "0.0.7" - pause-stream "^0.0.11" - split "^1.0.1" - stream-combiner "^0.2.2" - through "^2.3.8" - eventemitter3@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" @@ -2345,11 +2326,6 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -flatmap-stream@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/flatmap-stream/-/flatmap-stream-0.1.2.tgz#b1da359a93f24f6d96e46f948552d997e3c2863d" - integrity sha512-ucyr6WkLXjyMuHPtOUq4l+nSAxgWi7v4QO508eQ9resnGj+lSup26oIsUI5aH8k4Qfpjsxa8dDf9UCKkS2KHzQ== - for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -2386,11 +2362,6 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -from@^0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" - integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= - fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" @@ -3535,11 +3506,6 @@ map-cache@^0.2.2: resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= -map-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" - integrity sha1-ih8HiW2CsQkmvTdEokIACfiJdKg= - map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -3784,16 +3750,16 @@ node-releases@^1.0.1: dependencies: semver "^5.3.0" -nodemon@^1.18.4: - version "1.18.6" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.6.tgz#89b1136634d6c0afc7de24cc932a760e999e2c76" - integrity sha512-4pHQNYEZun+IkIC2jCaXEhkZnfA7rQe73i8RkdRyDJls/K+WxR7IpI5uNUsAvQ0zWvYcCDNGD+XVtw2ZG86/uQ== +nodemon@^1.18.7: + version "1.18.7" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.7.tgz#716b66bf3e89ac4fcfb38a9e61887a03fc82efbb" + integrity sha512-xuC1V0F5EcEyKQ1VhHYD13owznQbUw29JKvZ8bVH7TmuvVNHvvbp9pLgE4PjTMRJVe0pJ8fGRvwR2nMiosIsPQ== dependencies: chokidar "^2.0.4" debug "^3.1.0" ignore-by-default "^1.0.1" minimatch "^3.0.4" - pstree.remy "^1.1.0" + pstree.remy "^1.1.2" semver "^5.5.0" supports-color "^5.2.0" touch "^3.1.0" @@ -4168,13 +4134,6 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -pause-stream@^0.0.11: - version "0.0.11" - resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" - integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= - dependencies: - through "~2.3" - pause@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" @@ -4280,13 +4239,6 @@ proxy-addr@~2.0.4: forwarded "~0.1.2" ipaddr.js "1.8.0" -ps-tree@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" - integrity sha1-tCGyQUDWID8e08dplrRCewjowBQ= - dependencies: - event-stream "~3.3.0" - pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -4297,12 +4249,10 @@ psl@^1.1.24: resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== -pstree.remy@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.0.tgz#f2af27265bd3e5b32bbfcc10e80bac55ba78688b" - integrity sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q== - dependencies: - ps-tree "^1.1.0" +pstree.remy@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.2.tgz#4448bbeb4b2af1fed242afc8dc7416a6f504951a" + integrity sha512-vL6NLxNHzkNTjGJUpMm5PLC+94/0tTlC1vkP9bdU0pOHih+EujMjgMTwfZopZvHWRFbqJ5Y73OMoau50PewDDA== punycode@1.3.2: version "1.3.2" @@ -4870,13 +4820,6 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" -split@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== - dependencies: - through "2" - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -4923,14 +4866,6 @@ statuses@~1.4.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== -stream-combiner@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" - integrity sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg= - dependencies: - duplexer "~0.1.1" - through "~2.3.4" - streamsearch@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" @@ -5049,7 +4984,7 @@ text-encoding@^0.6.4: resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" integrity sha1-45mpgiV6J22uQou5KEXLcb3CbRk= -through@2, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.4: +through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= From 834aae1ed293c108be5c267534561afcf09a5faf Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 29 Nov 2018 19:45:35 +0100 Subject: [PATCH 097/554] removed seeding on build for now --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 62f05c96a..1f4076178 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend . script: - - docker run humanconnection/nitro-backend yarn run db:seed + # - docker run humanconnection/nitro-backend yarn run db:seed after_success: # - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh From 86662eb56c18a28379c81ed730243b480f65ea64 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 30 Nov 2018 09:13:13 +0100 Subject: [PATCH 098/554] do not abort on test command --- .travis.yml | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1f4076178..e9a1878ce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend . script: + # TODO: re-add when testing is setup properly # - docker run humanconnection/nitro-backend yarn run db:seed after_success: diff --git a/package.json b/package.json index 268f2e1a7..8d5705641 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "GraphQL Backend for Human Connection", "main": "src/index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test": "echo \"Error: no test specified\" && exit 0", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "db:seed": "concurrently --kill-others --success first 'cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start' 'wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js'" From 2fb239de7cd746a3dfb7df855bd406b0a336e530 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 30 Nov 2018 09:34:31 +0100 Subject: [PATCH 099/554] fixed docker-compose to use humanconnection/nitro-backend:latest --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index af63a3b56..71ea7355c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.7" services: backend: - image: humanconnection/backend:latest + image: humanconnection/nitro-backend:latest build: . networks: - hc-network From 27a9410089ecb4b8f2878188bdd0f7f4837efd5c Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 30 Nov 2018 09:36:03 +0100 Subject: [PATCH 100/554] use humanconnection/nitro-backend --- kubernetes/backend-deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/backend-deployment.yaml b/kubernetes/backend-deployment.yaml index 95613f3ac..f75920f0d 100644 --- a/kubernetes/backend-deployment.yaml +++ b/kubernetes/backend-deployment.yaml @@ -31,7 +31,7 @@ spec: value: "false" - name: NEO4J_URI value: bolt://neo4j:7687 - image: humanconnection/backend:latest + image: humanconnection/nitro-backend:latest name: backend ports: - containerPort: 4000 From 38c6323d1f33fcd5a22e141dd5937fa4a6a89b2d Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 30 Nov 2018 09:38:20 +0100 Subject: [PATCH 101/554] fixed vendor name --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 45d68e8b6..269b74ea5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM node:10-alpine -LABEL Description="Backend of the Social Network Human-Connection.org" Vendor="Human-Connection gGmbH" Version="0.0.1" Maintainer="Human-Connection gGmbH (developer@human-connection.org)" +LABEL Description="Backend of the Social Network Human-Connection.org" Vendor="Human Connection gGmbH" Version="0.0.1" Maintainer="Human Connection gGmbH (developer@human-connection.org)" # Expose the app port EXPOSE 4000 From 6aa711b3ab569ba2ccd03f460e5a5d93e47cbaa3 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 30 Nov 2018 10:15:17 +0100 Subject: [PATCH 102/554] fix tests on build --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e9a1878ce..5aa20ed1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,9 +11,10 @@ cache: install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend . -script: +test: # TODO: re-add when testing is setup properly # - docker run humanconnection/nitro-backend yarn run db:seed + - docker run humanconnection/nitro-backend yarn run test after_success: # - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh From c2a4e48446e6c3947bc918734bd7bb278a3e66f0 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 30 Nov 2018 10:29:46 +0100 Subject: [PATCH 103/554] Use script instead of test key in travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5aa20ed1e..ca93e0ae2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ cache: install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend . -test: +script: # TODO: re-add when testing is setup properly # - docker run humanconnection/nitro-backend yarn run db:seed - docker run humanconnection/nitro-backend yarn run test From 7780c4b846830d88d473783fb90fb2731101bf2f Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 30 Nov 2018 11:37:19 +0100 Subject: [PATCH 104/554] uppgraded packages --- package.json | 3 +- yarn.lock | 288 ++++++++++++++++++++++++--------------------------- 2 files changed, 138 insertions(+), 153 deletions(-) diff --git a/package.json b/package.json index 8d5705641..3a7a5311d 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "db:seed": "concurrently --kill-others --success first 'cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start' 'wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js'" }, - "author": "Human Connection gGmbh", + "author": "Human Connection gGmbH", "license": "MIT", "dependencies": { "@babel/cli": "^7.1.5", @@ -17,7 +17,6 @@ "@babel/node": "^7.0.0", "@babel/preset-env": "^7.1.6", "@babel/register": "^7.0.0", - "apollo-boost": "^0.1.10", "apollo-cache-inmemory": "^1.2.5", "apollo-client": "^2.3.2", "apollo-link-http": "^1.5.4", diff --git a/yarn.lock b/yarn.lock index 1d79d8da6..fc6cc1c35 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3,11 +3,11 @@ "@apollographql/apollo-tools@^0.2.6": - version "0.2.7" - resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.2.7.tgz#550502b315e49040e07d7e5065d15c5116c506e6" - integrity sha512-rsn4uN12gZWME+m9CLnUk+ImY+blKdWFFdS6TlQheXC7XA85twjQmOY0/n05qUtrxx1dM5QUXw1qLCZ4emWYbQ== + version "0.2.8" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.2.8.tgz#f755baa3576eabdd93afa2782be61f5ae8a856dc" + integrity sha512-A7FTUigtpGCFBaLT1ILicdjM6pZ7LQNw7Vgos0t4aLYtvlKO/L1nMi/NO7bPypzZaJSToTgcxHJPRydP1Md+Kw== dependencies: - apollo-env "0.2.4" + apollo-env "0.2.5" "@apollographql/apollo-upload-server@^5.0.3": version "5.0.3" @@ -18,10 +18,10 @@ busboy "^0.2.14" object-path "^0.11.4" -"@apollographql/graphql-playground-html@^1.6.4": - version "1.6.4" - resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.4.tgz#8945edf73df846d50e027bb3b813d018a1c5925f" - integrity sha512-gwvaQO6/Hv4DEwhDLmmu2tzCU9oPjC5Xl9Kk8Yd0IxyKhYLlLalmkMMjsZLzU5H3fGaalLD96OYfxHL0ClVUDQ== +"@apollographql/graphql-playground-html@^1.6.6": + version "1.6.6" + resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz#022209e28a2b547dcde15b219f0c50f47aa5beb3" + integrity sha512-lqK94b+caNtmKFs5oUVXlSpN3sm5IXZ+KfhMxOtr0LR2SqErzkoJilitjDvJ1WbjHlxLI7WtCjRmOLdOGJqtMQ== "@babel/cli@^7.1.5": version "7.1.5" @@ -801,9 +801,9 @@ integrity sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA== "@types/node@*", "@types/node@^10.1.0": - version "10.12.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.9.tgz#a07bfa74331471e1dc22a47eb72026843f7b95c8" - integrity sha512-eajkMXG812/w3w4a1OcBlaTwsFPO5F7fJ/amy+tieQxEMWBlbV1JGSjkFM+zkHNf81Cad+dfIRA+IBkvmvdAeA== + version "10.12.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.10.tgz#4fa76e6598b7de3f0cb6ec3abacc4f59e5b3a2ce" + integrity sha512-8xZEYckCbUVgK8Eg7lf5Iy4COKJ5uXlnIOnePN0WUwSQggy9tolM+tDJf7wMOnT/JT/W9xDYIaYggt3mRV2O5w== "@types/range-parser@*": version "1.2.2" @@ -901,27 +901,13 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -apollo-boost@^0.1.10: - version "0.1.21" - resolved "https://registry.yarnpkg.com/apollo-boost/-/apollo-boost-0.1.21.tgz#1c6b5f53120bd46faa825715da40cf5578fd6fbb" - integrity sha512-3cA4LjzrMckbX02Vd02yfKsgunnqdZTLE5SRXr7SCzfJfkPjmD9VGS8eLUCd/FE5taM/FHNAuqy3u3PaPCjYvw== - dependencies: - apollo-cache "^1.1.20" - apollo-cache-inmemory "^1.3.10" - apollo-client "^2.4.6" - apollo-link "^1.0.6" - apollo-link-error "^1.0.3" - apollo-link-http "^1.3.1" - apollo-link-state "^0.4.0" - graphql-tag "^2.4.2" - -apollo-cache-control@0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.2.tgz#fc98781e6df60346a20b0540450d02842c1212f2" - integrity sha512-/fhgCWGEoTsgyA83usy/1NvJWi6hbD4rSGO5jvyNNtMZ9ledOvKUvIdzSQ1r5hxK5yds/eehWXhMJ4Pu200qrQ== +apollo-cache-control@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.3.tgz#ad71d8f786e06f0275b2432004c15c2d37c48484" + integrity sha512-X6JhKfIaMLfl2jpsK/880BflXA+2lmm2sAsOZL4Bn2VrMsDtOssI1Ij9vNRbch9k9cA4WJvKed7Sql/wUIa1Eg== dependencies: apollo-server-env "2.2.0" - graphql-extensions "0.3.2" + graphql-extensions "0.3.3" apollo-cache-control@^0.1.0: version "0.1.1" @@ -930,43 +916,43 @@ apollo-cache-control@^0.1.0: dependencies: graphql-extensions "^0.0.x" -apollo-cache-inmemory@^1.2.5, apollo-cache-inmemory@^1.3.10: - version "1.3.10" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.10.tgz#2e5375ad7ac0d30d59aaae3a2b5967673d0cf968" - integrity sha512-cJL8xxX2iytludvxY4goxYJ41n8avXirAjQkEwgSvGqrEzC0PG2DwtHZZh1QTnRRuM1rgj4MKiUiX/Ykhc5L+Q== +apollo-cache-inmemory@^1.2.5: + version "1.3.11" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.11.tgz#6cb8f24ec812715169f9acbb0b67833f9a19ec90" + integrity sha512-fSoyjBV5RV57J3i/VHDDB74ZgXc0PFiogheNFHEhC0mL6rg5e/DjTx0Vg+csIBk23gvlzTvV+eypx7Q2NJ+dYg== dependencies: - apollo-cache "^1.1.20" - apollo-utilities "^1.0.25" + apollo-cache "^1.1.21" + apollo-utilities "^1.0.26" optimism "^0.6.6" -apollo-cache@1.1.20, apollo-cache@^1.1.20: - version "1.1.20" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.20.tgz#6152cc4baf6a63e376efee79f75de4f5c84bf90e" - integrity sha512-+Du0/4kUSuf5PjPx0+pvgMGV12ezbHA8/hubYuqRQoy/4AWb4faa61CgJNI6cKz2mhDd9m94VTNKTX11NntwkQ== +apollo-cache@1.1.21, apollo-cache@^1.1.21: + version "1.1.21" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.21.tgz#950025e2272741ba8e5064419906e3ac4072925d" + integrity sha512-5ErNb78KHtrJNimkDBTEigcvHkIqUmS7QJIk4lpZZ+XLVVgvk2fD+GhD1PLP+s8vHfAKVbO6vdbRxCCjGGrh5w== dependencies: - apollo-utilities "^1.0.25" + apollo-utilities "^1.0.26" -apollo-client@^2.3.2, apollo-client@^2.4.6: - version "2.4.6" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.6.tgz#ba24a2def6ea9d487b41672652ca967cc7c05e4a" - integrity sha512-RsZVMYone7mu3Wj4sr7ehctN8pdaHsP4X1Sv6Ly4gZ/YDetCCVnhbmnk5q7kvDtfoo0jhhHblxgFyA3FLLImtA== +apollo-client@^2.3.2: + version "2.4.7" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.7.tgz#b6712fd4c9ba346e3c44cfec7e6868e532b6a957" + integrity sha512-6aAm+16AFBYZhJF8eKxrup6AbYni01InDiwTfZhMMTP2xaXQWjsQnfaHbI2oE+hd3+AZFy1drkse8RZKghR/WQ== dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.20" + apollo-cache "1.1.21" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "1.0.25" + apollo-utilities "1.0.26" symbol-observable "^1.0.2" zen-observable "^0.8.0" optionalDependencies: "@types/async" "2.0.50" -apollo-datasource@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.2.0.tgz#ea28313689073150b18f0dbe35bedffc86a62b57" - integrity sha512-WJM9Ix3uogIfAG7mjL1NZQM9+45rcikn4mPWhE1Iuyw2+Y857J3uKJqQgF5h9Fg64SlCJh9u5WL3N7N5mg1fVw== +apollo-datasource@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.2.1.tgz#3ecef4efe64f7a04a43862f32027d38ac09e142c" + integrity sha512-r185+JTa5KuF1INeTAk7AEP76zwMN6c8Ph1lmpzJMNwBUEzTGnLClrccCskCBx4SxfnkdKbuQdwn9JwCJUWrdg== dependencies: - apollo-server-caching "0.2.0" + apollo-server-caching "0.2.1" apollo-server-env "2.2.0" apollo-engine-reporting-protobuf@0.1.0: @@ -976,63 +962,56 @@ apollo-engine-reporting-protobuf@0.1.0: dependencies: protobufjs "^6.8.6" -apollo-engine-reporting@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.2.tgz#6247e8d618da5c084ccb1bc76c665ce7a1b1ba55" - integrity sha512-W6zBTypI2ZLe9ZpMI4EasyXJP2WG8CpxYOU3Q4iuCKh8HYJqrQC5QVFXRF7TRBQTE6tc1seYnAHdgqv0ozxBrw== +apollo-engine-reporting@0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.3.tgz#85ad6ffd71db8f877202ce8b3d7dbfa7cabfbcf9" + integrity sha512-VkjiifHMHIAxydXecT+ck0WtqpFIsMlylKnKeuNAXfIfAXHX/JYtLhbArTTyhDunLrphMiUewfFv9P0K+aX2jw== dependencies: apollo-engine-reporting-protobuf "0.1.0" apollo-server-env "2.2.0" async-retry "^1.2.1" - graphql-extensions "0.3.2" + graphql-extensions "0.3.3" lodash "^4.17.10" -apollo-env@0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.2.4.tgz#6af44ef0af1b8c8a4d7da5d66ff55909858a88fa" - integrity sha512-pphNvrS7JmgvkvhaNEh+u0GpolytboAQcNbwmgskvX0VaLPfrrVox0AwHCteReB8t8s87NhbLd0VTG1nxmjFfQ== +apollo-env@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.2.5.tgz#162c785bccd2aea69350a7600fab4b7147fc9da5" + integrity sha512-Gc7TEbwCl7jJVutnn8TWfzNSkrrqyoo0DP92BQJFU9pZbJhpidoXf2Sw1YwOJl82rRKH3ujM3C8vdZLOgpFcFA== dependencies: core-js "^3.0.0-beta.3" node-fetch "^2.2.0" apollo-link-dedup@^1.0.0: - version "1.0.10" - resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.10.tgz#7b94589fe7f969777efd18a129043c78430800ae" - integrity sha512-tpUI9lMZsidxdNygSY1FxflXEkUZnvKRkMUsXXuQUNoSLeNtEvUX7QtKRAl4k9ubLl8JKKc9X3L3onAFeGTK8w== + version "1.0.11" + resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.11.tgz#6f34ea748d2834850329ad03111ef18445232b05" + integrity sha512-RcvkXR0CNbQcsw6LdrPksGa+9YjZ1ghk0k2PKal6rSBCyyqzokcBawXOtoMN8q+0FLR1dGs5GnAQVeucQuY28g== dependencies: - apollo-link "^1.2.3" + apollo-link "^1.2.4" -apollo-link-error@^1.0.3: - version "1.1.1" - resolved "https://registry.yarnpkg.com/apollo-link-error/-/apollo-link-error-1.1.1.tgz#69d7124d4dc11ce60f505c940f05d4f1aa0945fb" - integrity sha512-/yPcaQWcBdB94vpJ4FsiCJt1dAGGRm+6Tsj3wKwP+72taBH+UsGRQQZk7U/1cpZwl1yqhHZn+ZNhVOebpPcIlA== +apollo-link-http-common@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.6.tgz#47b9012500599fe343e2e87378026384b4fc8c1f" + integrity sha512-LUOMWvrZuBP1hyWLBXyaW0KyFeKo79j+k3N+Q4HSkXKbLibnllXQ+JxxoSKGhm0bhREygiLtJAG9JnGlhxGO/Q== dependencies: - apollo-link "^1.2.3" + apollo-link "^1.2.4" -apollo-link-http-common@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.5.tgz#d094beb7971523203359bf830bfbfa7b4e7c30ed" - integrity sha512-6FV1wr5AqAyJ64Em1dq5hhGgiyxZE383VJQmhIoDVc3MyNcFL92TkhxREOs4rnH2a9X2iJMko7nodHSGLC6d8w== +apollo-link-http@^1.5.4: + version "1.5.7" + resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.7.tgz#098615c427a910ec8c5817476bbabe68c586b339" + integrity sha512-EZ9nynHjwYCpGYP5IsRrZGTWidUVpshk7MuSG4joqGtJMwpFCgMQz+y3BHdUhowHtfAd9z60XmeOTG9FJolb8A== dependencies: - apollo-link "^1.2.3" + apollo-link "^1.2.4" + apollo-link-http-common "^0.2.6" -apollo-link-http@^1.3.1, apollo-link-http@^1.5.4: - version "1.5.5" - resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.5.tgz#7dbe851821771ad67fa29e3900c57f38cbd80da8" - integrity sha512-C5N6N/mRwmepvtzO27dgMEU3MMtRKSqcljBkYNZmWwH11BxkUQ5imBLPM3V4QJXNE7NFuAQAB5PeUd4ligivTQ== +apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.4.tgz#ab4d21d2e428db848e88b5e8f4adc717b19c954b" + integrity sha512-B1z+9H2nTyWEhMXRFSnoZ1vSuAYP+V/EdUJvRx9uZ8yuIBZMm6reyVtr1n0BWlKeSFyPieKJy2RLzmITAAQAMQ== dependencies: - apollo-link "^1.2.3" - apollo-link-http-common "^0.2.5" + apollo-utilities "^1.0.0" + zen-observable-ts "^0.8.11" -apollo-link-state@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/apollo-link-state/-/apollo-link-state-0.4.2.tgz#ac00e9be9b0ca89eae0be6ba31fe904b80bbe2e8" - integrity sha512-xMPcAfuiPVYXaLwC6oJFIZrKgV3GmdO31Ag2eufRoXpvT0AfJZjdaPB4450Nu9TslHRePN9A3quxNueILlQxlw== - dependencies: - apollo-utilities "^1.0.8" - graphql-anywhere "^4.1.0-alpha.0" - -apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.2, apollo-link@^1.2.3: +apollo-link@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.3.tgz#9bd8d5fe1d88d31dc91dae9ecc22474d451fb70d" integrity sha512-iL9yS2OfxYhigme5bpTbmRyC+Htt6tyo2fRMHT3K1XRL/C5IQDDz37OjpPy4ndx7WInSvfSZaaOTKFja9VWqSw== @@ -1040,31 +1019,31 @@ apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.2, apollo-link@^1.2.3: apollo-utilities "^1.0.0" zen-observable-ts "^0.8.10" -apollo-server-caching@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.2.0.tgz#fe560752d364f14d34c1eaacd9df629f8ed1cf5c" - integrity sha512-/v7xWEcyyahs3hwX4baH/GekuHz3LRt9NoIYwg869G1eeqjuwY6NsowRIujZ100anJQwm9v5A9/sLtHBFvbgYg== +apollo-server-caching@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.2.1.tgz#7e67f8c8cac829e622b394f0fb82579cabbeadfd" + integrity sha512-+U9F3X297LL8Gqy6ypfDNEv/DfV/tDht9Dr2z3AMaEkNW1bwO6rmdDL01zYxDuVDVq6Z3qSiNCSO2pXE2F0zmA== dependencies: - lru-cache "^4.1.3" + lru-cache "^5.0.0" -apollo-server-core@2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.2.tgz#66ca6b4af6c7cdd8155de946d0c4fea3357b0432" - integrity sha512-F6d4u5m1rJB4ucpLPGCoa9Dvo5OjGMIGdAzT9A35yOvlFWwvIR46jGmYmGmNp4Qx852rb1axSZVzNy7k/Dix0w== +apollo-server-core@2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.5.tgz#bf1538c10213be38a37dd8e6461461f7b808c57e" + integrity sha512-obz6VSJI7vSR+pEAZFwqOe/HAOuF4l1fYU9WNtVcQvxaKhykDgcu+byO0sXrOf/iB7uUIyaFdhinwzuwkqB8XQ== dependencies: "@apollographql/apollo-tools" "^0.2.6" "@apollographql/apollo-upload-server" "^5.0.3" - "@apollographql/graphql-playground-html" "^1.6.4" + "@apollographql/graphql-playground-html" "^1.6.6" "@types/ws" "^6.0.0" - apollo-cache-control "0.3.2" - apollo-datasource "0.2.0" - apollo-engine-reporting "0.1.2" - apollo-server-caching "0.2.0" + apollo-cache-control "0.3.3" + apollo-datasource "0.2.1" + apollo-engine-reporting "0.1.3" + apollo-server-caching "0.2.1" apollo-server-env "2.2.0" apollo-server-errors "2.2.0" - apollo-server-plugin-base "0.1.2" - apollo-tracing "0.3.2" - graphql-extensions "0.3.2" + apollo-server-plugin-base "0.1.5" + apollo-tracing "0.3.3" + graphql-extensions "0.3.5" graphql-subscriptions "^1.0.0" graphql-tag "^2.9.2" graphql-tools "^4.0.0" @@ -1095,19 +1074,19 @@ apollo-server-errors@2.2.0: resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== -apollo-server-express@2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.2.2.tgz#e6811024cac695351600c18985331b43ba24f556" - integrity sha512-DPxHOUd0Waztuix0r1ed6xfdlR7P7RzIXPmybhPXj1bZJtYHz5If0ngYNjtFqnXVrC8aSRtMz108SQUAnduYwA== +apollo-server-express@2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.2.5.tgz#9d27d68b3b1cf2f96a107a3091ecdea4012745a2" + integrity sha512-2SNlY8CNmYlbRJfn0iK4wesjqX3X9YIFhyok4sQ80n/gm24QMwZkFcPP+NLv+1lxvwyJYMwEFQPIBvkLRoUFXQ== dependencies: "@apollographql/apollo-upload-server" "^5.0.3" - "@apollographql/graphql-playground-html" "^1.6.4" + "@apollographql/graphql-playground-html" "^1.6.6" "@types/accepts" "^1.3.5" "@types/body-parser" "1.17.0" "@types/cors" "^2.8.4" "@types/express" "4.16.0" accepts "^1.3.5" - apollo-server-core "2.2.2" + apollo-server-core "2.2.5" body-parser "^1.18.3" cors "^2.8.4" graphql-subscriptions "^1.0.0" @@ -1135,29 +1114,29 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== -apollo-server-plugin-base@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.2.tgz#4c1ebb769b630a16ff8ade03f12759cde17a21dc" - integrity sha512-+uicMcNctlP6YwIhzLLEycZzao/810OSzcxgPYKItXr5lGa1GuHD7sRIWldT3YoSdpw6Gal2lBuw6/DmnoDsPg== +apollo-server-plugin-base@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.5.tgz#899c4d7bc0d9a6d9f1181cc83a791479409086f8" + integrity sha512-be77TaN9l16ZVG1tBl8Re3lJfUZ6B2T3DdEXnu6fjQwUuBdu3Y4MQR6B1TLhbuTb9DUkcSKZ3h5C55dIjvb2Vg== apollo-server@^2.0.4: - version "2.2.2" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.2.2.tgz#b17f91730ef399b42c2ba6ea366320ed0d6a9774" - integrity sha512-LiVId1s7o+4IqReyzqfqxVyNYr6BOGsaYyqUH4R5Vb0gRw5igmZEiYz4g+dqTrUT4Ktv2gDyFumM+MxNm+Gjqg== + version "2.2.5" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.2.5.tgz#412cf92a12939aac3890d4f0094a45dadfb89c79" + integrity sha512-Qf0FODtXzMJHhr6W8+NPu3ftxlL93o5s+aW9A35NZ305FuwgyriaQztaWILC+i4S/OxMTvuoCjNm9V+iVKackg== dependencies: - apollo-server-core "2.2.2" - apollo-server-express "2.2.2" + apollo-server-core "2.2.5" + apollo-server-express "2.2.5" express "^4.0.0" graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" -apollo-tracing@0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.2.tgz#1a6b695813791b8404b5adaa10925a7f2642f15d" - integrity sha512-YwN1m1k0JJsxGh0QWsEM3OLnyem0GT2tZnGeO2OogCr6dH5lE0SjKPc6UzpcI/3fPyxRrx5QvpUiP+DJeehhTA== +apollo-tracing@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.3.tgz#b819942180480c1c4d89e613cf2eff8f6d8b595a" + integrity sha512-gsTYgDVjtMlnomPq46aky7yk8XshCQfj9rxalCCismLlMomVW44fq+8GKQnZIkFOwiAsazRy4dzZ0cBbygA9sA== dependencies: apollo-server-env "2.2.0" - graphql-extensions "0.3.2" + graphql-extensions "0.3.3" apollo-tracing@^0.1.0: version "0.1.4" @@ -1175,10 +1154,10 @@ apollo-upload-server@^5.0.0: busboy "^0.2.14" object-path "^0.11.4" -apollo-utilities@1.0.25, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.25, apollo-utilities@^1.0.8: - version "1.0.25" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.25.tgz#899b00f5f990fb451675adf84cb3de82eb6372ea" - integrity sha512-AXvqkhni3Ir1ffm4SA1QzXn8k8I5BBl4PVKEyak734i4jFdp+xgfUyi2VCqF64TJlFTA/B73TRDUvO2D+tKtZg== +apollo-utilities@1.0.26, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.26: + version "1.0.26" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.26.tgz#589c66bf4d16223531351cf667a230c787def1da" + integrity sha512-URw7o3phymliqYCYatcird2YRPUU2eWCNvip64U9gQrX56mEfK4m99yBIDCMTpmcvOFsKLii1sIEZsHIs/bvnw== dependencies: fast-json-stable-stringify "^2.0.0" @@ -2482,13 +2461,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== -graphql-anywhere@^4.1.0-alpha.0: - version "4.1.22" - resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.22.tgz#1c831ba3c9e5664a0dd24d10d23a9e9512d92056" - integrity sha512-qm2/1cKM8nfotxDhm4J0r1znVlK0Yge/yEKt26EVVBgpIhvxjXYFALCGbr7cvfDlvzal1iSPpaYa+8YTtjsxQA== - dependencies: - apollo-utilities "^1.0.25" - graphql-config@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-2.0.0.tgz#daf69091055c6f675d63893a2d14c48f3fec3327" @@ -2515,10 +2487,17 @@ graphql-deduplicator@^2.0.1: resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3" integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA== -graphql-extensions@0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.2.tgz#a19dd62b62d769f4d1b9c4b4781cc353b2174998" - integrity sha512-eIAWwtZNlUAHtHF6uNP6+4M+GCksqUYfNBxW5rTAlCB4/ZcuIvchVtN1CgVM7MooW3akPM1Eci11WyeXvgOugQ== +graphql-extensions@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.3.tgz#277efe11976bbdfd59915551606a2d550247bb45" + integrity sha512-pudOaHq7Ok+rh1ElzlqFaoYZWGefUNsqn/jX6eKns7rl0VHuB4qZBfhpVLTpquJpM6Y19/hsCYZNPfnUVMFIiA== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" + +graphql-extensions@0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.5.tgz#95b742185d0016a9d65385a7a9e10753eadf0537" + integrity sha512-jpWSUIr27iOTR5JYu+dEMz74oZhOj8Xy+6lNopluiIu+ObEVSHW0czb2Jlcy3rOSTEPcibnpStO4F4/64IBqeQ== dependencies: "@apollographql/apollo-tools" "^0.2.6" @@ -2620,7 +2599,7 @@ graphql-subscriptions@^1.0.0: dependencies: iterall "^1.2.1" -graphql-tag@^2.4.2, graphql-tag@^2.9.2: +graphql-tag@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w== @@ -3479,7 +3458,7 @@ lowercase-keys@^1.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== -lru-cache@^4.0.1, lru-cache@^4.1.3: +lru-cache@^4.0.1: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== @@ -3487,6 +3466,13 @@ lru-cache@^4.0.1, lru-cache@^4.1.3: pseudomap "^1.0.2" yallist "^2.1.2" +lru-cache@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" @@ -3682,9 +3668,9 @@ negotiator@0.6.1: integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= neo4j-driver@^1.6.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.1.tgz#f21571d18e632ff03be7e84c06b38e1bc66fb111" - integrity sha512-erJPOF8gv22zd/T/8XwJQ2xdXspNtUquUfi1YFMZ2BYRDdXp/NGzmVEH4DeCEk4dF5GkGA91WPuQVBOEOfmTdw== + version "1.7.2" + resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.2.tgz#c72a6dfa6bd2106b00a42794dc52a82b227b48e0" + integrity sha512-0IvCFYhcP9hb5JveZk33epbReDKpFTn2u5vAa8zzGG344i6yFqZrBo0mtC114ciP9zFjAtfNOP72mRm8+NV0Fg== dependencies: babel-runtime "^6.26.0" text-encoding "^0.6.4" @@ -5424,10 +5410,10 @@ yargs@^12.0.1: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -zen-observable-ts@^0.8.10: - version "0.8.10" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz#18e2ce1c89fe026e9621fd83cc05168228fce829" - integrity sha512-5vqMtRggU/2GhePC9OU4sYEWOdvmayp2k3gjPf4F0mXwB3CSbbNznfDUvDJx9O2ZTa1EIXdJhPchQveFKwNXPQ== +zen-observable-ts@^0.8.10, zen-observable-ts@^0.8.11: + version "0.8.11" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.11.tgz#d54a27cd17dc4b4bb6bd008e5c096af7fcb068a9" + integrity sha512-8bs7rgGV4kz5iTb9isudkuQjtWwPnQ8lXq6/T76vrepYZVMsDEv6BXaEA+DHdJSK3KVLduagi9jSpSAJ5NgKHw== dependencies: zen-observable "^0.8.0" From 81605221a7f3c524226cbb2e16831f84a34e7236 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 30 Nov 2018 10:42:25 +0000 Subject: [PATCH 105/554] Bump neo4j from 3.4 to 3.5.0 Bumps neo4j from 3.4 to 3.5.0. Signed-off-by: dependabot[bot] --- Dockerfile.neo4j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.neo4j b/Dockerfile.neo4j index 66f996e68..831af4d34 100644 --- a/Dockerfile.neo4j +++ b/Dockerfile.neo4j @@ -1,2 +1,2 @@ -FROM neo4j:3.4 +FROM neo4j:3.5.0 RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.4.0.3/apoc-3.4.0.3-all.jar -P plugins/ From 8a79b4f7f7e15c5ab88b41bd28193701087e8b94 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 30 Nov 2018 14:41:56 +0100 Subject: [PATCH 106/554] Update Dockerfile.neo4j using correct APOC version matching Neo4J --- Dockerfile.neo4j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.neo4j b/Dockerfile.neo4j index 831af4d34..cb7fd228f 100644 --- a/Dockerfile.neo4j +++ b/Dockerfile.neo4j @@ -1,2 +1,2 @@ FROM neo4j:3.5.0 -RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.4.0.3/apoc-3.4.0.3-all.jar -P plugins/ +RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.1/apoc-3.5.0.1-all.jar -P plugins/ From b5ce0351c71b9cc9b28ea706b00db3af5a4af1fd Mon Sep 17 00:00:00 2001 From: Armin Kunkel Date: Mon, 3 Dec 2018 15:38:08 +0100 Subject: [PATCH 107/554] Add yarn db:reset script --- README.md | 10 +++++++++- package.json | 3 ++- src/graphql-schema.js | 2 +- src/seed/unseed-db.js | 23 +++++++++++++++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 src/seed/unseed-db.js diff --git a/README.md b/README.md index 653068a1d..ba14d4bc1 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ you build a frontend application without running a neo4j instance. Just set `MOCK=true` inside `.env` or pass it on application start. -## Seeding The Database +## Seeding and Unseeding The Database Optionally you can seed the GraphQL service by executing mutations that will write sample data to the database: @@ -110,6 +110,14 @@ yarn db:seed npm run db:seed ``` +For a reset you can use the reset script: + +```bash +yarn db:reset +# -or- +npm run db:reset +``` + ## Todo`s - [x] add jwt authentication diff --git a/package.json b/package.json index 3a7a5311d..66b15bb28 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "test": "echo \"Error: no test specified\" && exit 0", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "db:seed": "concurrently --kill-others --success first 'cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start' 'wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js'" + "db:seed": "concurrently --kill-others --success first 'cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start' 'wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js'", + "db:reset": "concurrently --kill-others --success first 'cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start' 'wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/unseed-db.js'" }, "author": "Human Connection gGmbH", "license": "MIT", diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 44ec8116d..119372fb6 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -10,7 +10,7 @@ export const typeDefs = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, "schema.graphql")) .toString('utf-8') -const query = (cypher, session) => { +export const query = (cypher, session) => { return new Promise((resolve, reject) => { let data = [] session diff --git a/src/seed/unseed-db.js b/src/seed/unseed-db.js new file mode 100644 index 000000000..615fbccf9 --- /dev/null +++ b/src/seed/unseed-db.js @@ -0,0 +1,23 @@ +import { query } from '../graphql-schema' +import dotenv from 'dotenv' +import neo4j from '../bootstrap/neo4j' + +dotenv.config() + +if (process.env.NODE_ENV === 'production') { + throw new Error('YOU CAN`T UNSEED IN PRODUCTION MODE') +} + +const driver = neo4j().getDriver() +const session = driver.session() + +query('MATCH (n) DETACH DELETE n', session).then(() => { + console.log('Successfully deleted all nodes and relations!') +}).catch((err) => { + console.log(`Error occurred deleting the nodes and relations (reset the db)\n\n${err}`) +}).finally(() => { + if (session) { + session.close() + } + process.exit(0) +}) \ No newline at end of file From 66b12f28b8b07b871d448dbcd9df97fed8f32b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 17:16:41 +0100 Subject: [PATCH 108/554] Wording: `unseed` does not exist but `clean` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ba14d4bc1..65fbbc4da 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ you build a frontend application without running a neo4j instance. Just set `MOCK=true` inside `.env` or pass it on application start. -## Seeding and Unseeding The Database +## Seeding and Cleaning The Database Optionally you can seed the GraphQL service by executing mutations that will write sample data to the database: From 0bfe880c2151acfcd23b946e24d60411be38a8ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 17:28:53 +0100 Subject: [PATCH 109/554] Use docker-compose for testing on Travis CI Currently running * seeds * eslint --- .travis.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index e9a1878ce..ae23f5112 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,27 @@ language: node_js node_js: - "10" -services: - - docker cache: yarn: true directories: - node_modules +services: + - docker +env: + - DOCKER_COMPOSE_VERSION=1.23.2 + +before_install: + - sudo rm /usr/local/bin/docker-compose + - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose + - chmod +x docker-compose + - sudo mv docker-compose /usr/local/bin install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend . script: - # TODO: re-add when testing is setup properly - # - docker run humanconnection/nitro-backend yarn run db:seed +- docker run humanconnection/backend:latest yarn run eslint +- docker-compose run --rm backend yarn run db:seed # seeding needs neo4j after_success: # - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh From 15d9178369bd29df40f3e2810f8e8eb184c7a5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 18:05:28 +0100 Subject: [PATCH 110/554] Install and configure eslint Fix all violations but one - there is a mock in our authentication. --- .eslintrc.js | 18 + package.json | 8 + src/bootstrap/directives.js | 2 +- src/bootstrap/neo4j.js | 2 +- src/bootstrap/scalars.js | 2 +- src/graphql-schema.js | 20 +- src/index.js | 4 +- src/jwt/generateToken.js | 2 +- src/middleware/index.js | 6 +- src/middleware/permissionsMiddleware.js | 11 +- src/middleware/xssMiddleware.js | 1 - src/seed/data/organizations.js | 2 - src/seed/data/posts.js | 4 +- src/seed/seed-db.js | 15 +- src/seed/seed-helpers.js | 2 +- src/seed/unseed-db.js | 16 +- yarn.lock | 556 +++++++++++++++++++++++- 17 files changed, 600 insertions(+), 71 deletions(-) create mode 100644 .eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..ae2dcb316 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,18 @@ +module.exports = { + "extends": "standard", + "parser": "babel-eslint", + "env": { + "es6": true, + "node": true, + }, + "rules": { + "indent": [ + "error", + 2 + ], + "quotes": [ + "error", + "single" + ] + } +}; diff --git a/package.json b/package.json index 66b15bb28..a191ee27c 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "GraphQL Backend for Human Connection", "main": "src/index.js", "scripts": { + "eslint": "eslint src --config .eslintrc.js", "test": "echo \"Error: no test specified\" && exit 0", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", @@ -46,8 +47,15 @@ "trunc-html": "^1.1.2" }, "devDependencies": { + "babel-eslint": "^10.0.1", "concurrently": "^4.1.0", "cross-env": "^5.2.0", + "eslint": "^5.9.0", + "eslint-config-standard": "^12.0.0", + "eslint-plugin-import": "^2.14.0", + "eslint-plugin-node": "^8.0.0", + "eslint-plugin-promise": "^4.0.1", + "eslint-plugin-standard": "^4.0.0", "faker": "^4.1.0", "nodemon": "^1.18.7", "wait-on": "^3.2.0" diff --git a/src/bootstrap/directives.js b/src/bootstrap/directives.js index 280713721..8c392ed46 100644 --- a/src/bootstrap/directives.js +++ b/src/bootstrap/directives.js @@ -4,7 +4,7 @@ import { GraphQLDefaultToDirective } from 'graphql-custom-directives' -export default function applyDirectives(augmentedSchema) { +export default function applyDirectives (augmentedSchema) { const directives = [ GraphQLLowerCaseDirective, GraphQLTrimDirective, diff --git a/src/bootstrap/neo4j.js b/src/bootstrap/neo4j.js index 9b17361fa..766c12065 100644 --- a/src/bootstrap/neo4j.js +++ b/src/bootstrap/neo4j.js @@ -4,7 +4,7 @@ let driver export default function () { return { - getDriver() { + getDriver () { if (!driver) { driver = neo4j.driver( process.env.NEO4J_URI || 'bolt://localhost:7687', diff --git a/src/bootstrap/scalars.js b/src/bootstrap/scalars.js index 2676f69ae..813bd5051 100644 --- a/src/bootstrap/scalars.js +++ b/src/bootstrap/scalars.js @@ -4,7 +4,7 @@ import { GraphQLDateTime } from 'graphql-iso-date' -export default function applyScalars(augmentedSchema) { +export default function applyScalars (augmentedSchema) { augmentedSchema._typeMap.Date = GraphQLDate augmentedSchema._typeMap.Time = GraphQLTime augmentedSchema._typeMap.DateTime = GraphQLDateTime diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 119372fb6..b52c9e232 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -7,7 +7,7 @@ import generateJwt from './jwt/generateToken' import { fixUrl } from './middleware/fixImageUrlsMiddleware' export const typeDefs = - fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, "schema.graphql")) + fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, 'schema.graphql')) .toString('utf-8') export const query = (cypher, session) => { @@ -54,15 +54,15 @@ export const resolvers = { return new Promise(async (resolve) => { const session = driver.session() const queries = { - countUsers: `MATCH (r:User) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countUsers`, - countPosts: `MATCH (r:Post) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countPosts`, - countComments: `MATCH (r:Comment) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countComments`, - countNotifications: `MATCH (r:Notification) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countNotifications`, - countOrganizations: `MATCH (r:Organization) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countOrganizations`, - countProjects: `MATCH (r:Project) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countProjects`, - countInvites: `MATCH (r:Invite) WHERE r.wasUsed <> true OR NOT exists(r.wasUsed) RETURN COUNT(r) AS countInvites`, - countFollows: `MATCH (:User)-[r:FOLLOWS]->(:User) RETURN COUNT(r) AS countFollows`, - countShouts: `MATCH (:User)-[r:SHOUTED]->(:Post) RETURN COUNT(r) AS countShouts` + countUsers: 'MATCH (r:User) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countUsers', + countPosts: 'MATCH (r:Post) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countPosts', + countComments: 'MATCH (r:Comment) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countComments', + countNotifications: 'MATCH (r:Notification) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countNotifications', + countOrganizations: 'MATCH (r:Organization) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countOrganizations', + countProjects: 'MATCH (r:Project) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countProjects', + countInvites: 'MATCH (r:Invite) WHERE r.wasUsed <> true OR NOT exists(r.wasUsed) RETURN COUNT(r) AS countInvites', + countFollows: 'MATCH (:User)-[r:FOLLOWS]->(:User) RETURN COUNT(r) AS countFollows', + countShouts: 'MATCH (:User)-[r:SHOUTED]->(:Post) RETURN COUNT(r) AS countShouts' } let data = { countUsers: (await queryOne(queries.countUsers, session)).countUsers, diff --git a/src/index.js b/src/index.js index 3fca43694..2a73a4e3c 100644 --- a/src/index.js +++ b/src/index.js @@ -68,6 +68,6 @@ const serverConfig = { // } } -server.start(serverConfig, options => { - console.log(`Server ready at ${process.env.GRAPHQL_URI} 🚀`); +server.start(serverConfig, options => { + console.log(`Server ready at ${process.env.GRAPHQL_URI} 🚀`) }) diff --git a/src/jwt/generateToken.js b/src/jwt/generateToken.js index d1daeaf33..7cbc70330 100644 --- a/src/jwt/generateToken.js +++ b/src/jwt/generateToken.js @@ -3,7 +3,7 @@ import jwt from 'jsonwebtoken' import ms from 'ms' // Generate an Access Token for the given User ID -export default function generateJwt(user) { +export default function generateJwt (user) { const token = jwt.sign(user, process.env.JWT_SECRET, { expiresIn: ms('1d'), issuer: process.env.GRAPHQL_URI, diff --git a/src/middleware/index.js b/src/middleware/index.js index 6b17eb5f6..56a0b5673 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -3,9 +3,9 @@ import softDeleteMiddleware from './softDeleteMiddleware' import sluggifyMiddleware from './sluggifyMiddleware' import fixImageUrlsMiddleware from './fixImageUrlsMiddleware' import excerptMiddleware from './excerptMiddleware' -import dateTimeMiddleware from './dateTimeMiddleware'; -import xssMiddleware from './xssMiddleware'; -import permissionsMiddleware from './permissionsMiddleware'; +import dateTimeMiddleware from './dateTimeMiddleware' +import xssMiddleware from './xssMiddleware' +import permissionsMiddleware from './permissionsMiddleware' export default schema => { let middleware = [ diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 3a77d1136..e95fd49d8 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -1,17 +1,8 @@ -import { rule, shield, and, or, not, allow } from 'graphql-shield' +import { rule, shield, allow } from 'graphql-shield' -const isAuthenticated = rule()(async (parent, args, ctx, info) => { - return ctx.user !== null -}) const isOwner = rule()(async (parent, args, ctx, info) => { return ctx.user.id === parent.id }) -const isAdmin = rule()(async (parent, args, ctx, info) => { - return ctx.user.role === 'ADMIN' -}) -const isModerator = rule()(async (parent, args, ctx, info) => { - return ctx.user.role === 'MODERATOR' -}) // Permissions const permissions = shield({ diff --git a/src/middleware/xssMiddleware.js b/src/middleware/xssMiddleware.js index 46d0c663d..ac71f3421 100644 --- a/src/middleware/xssMiddleware.js +++ b/src/middleware/xssMiddleware.js @@ -1,5 +1,4 @@ import walkRecursive from './helpers/walkRecursive' -import trunc from 'trunc-html' // import { getByDot, setByDot, getItems, replaceItems } from 'feathers-hooks-common' import sanitizeHtml from 'sanitize-html' // import { isEmpty, intersection } from 'lodash' diff --git a/src/seed/data/organizations.js b/src/seed/data/organizations.js index 26ca64b89..b8b9075d4 100644 --- a/src/seed/data/organizations.js +++ b/src/seed/data/organizations.js @@ -1,5 +1,3 @@ -import faker from 'faker' - export default () => { return `mutation { o1: CreateOrganization( diff --git a/src/seed/data/posts.js b/src/seed/data/posts.js index e94f63f69..8624c422d 100644 --- a/src/seed/data/posts.js +++ b/src/seed/data/posts.js @@ -6,7 +6,7 @@ export default function (data) { p1: CreatePost( id: "p1", title: "Gedanken eines Polizisten zum Einsatz im Hambacher Forst", - content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", + content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :)


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION❤️

", image: "https://picsum.photos/1280/1024?image=352", visibility: public, disabled: false, @@ -31,7 +31,7 @@ export default function (data) { p2: CreatePost( id: "p2", title: "Julian Assange", - content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben 


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :) 


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION ❤️

", + content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :)


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION❤️

", image: "https://picsum.photos/1280/1024?image=72", visibility: public, disabled: false, diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index df6999426..3e7e6e9c4 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,12 +1,11 @@ -import ApolloClient from "apollo-client"; -import dotenv from "dotenv"; -import gql from 'graphql-tag' -import fetch from "node-fetch"; -import { HttpLink } from "apollo-link-http"; -import { InMemoryCache } from "apollo-cache-inmemory"; +import ApolloClient from 'apollo-client' +import dotenv from 'dotenv' +import fetch from 'node-fetch' +import { HttpLink } from 'apollo-link-http' +import { InMemoryCache } from 'apollo-cache-inmemory' import Seed from './data/index' -dotenv.config(); +dotenv.config() if (process.env.NODE_ENV === 'production') { throw new Error('YOU CAN`T SEED IN PRODUCTION MODE') @@ -15,6 +14,6 @@ if (process.env.NODE_ENV === 'production') { const client = new ApolloClient({ link: new HttpLink({ uri: process.env.GRAPHQL_URI, fetch }), cache: new InMemoryCache() -}); +}) Seed(client) diff --git a/src/seed/seed-helpers.js b/src/seed/seed-helpers.js index 590b9c514..48b9ba01d 100644 --- a/src/seed/seed-helpers.js +++ b/src/seed/seed-helpers.js @@ -137,7 +137,7 @@ export default { const chars = '23456789abcdefghkmnpqrstuvwxyzABCDEFGHJKLMNPRSTUVWXYZ' let code = '' for (let i = 0; i < 8; i++) { - const n = _.random(0, chars.length-1) + const n = _.random(0, chars.length - 1) code += chars.substr(n, 1) } return code diff --git a/src/seed/unseed-db.js b/src/seed/unseed-db.js index 615fbccf9..e1336dc4b 100644 --- a/src/seed/unseed-db.js +++ b/src/seed/unseed-db.js @@ -5,19 +5,19 @@ import neo4j from '../bootstrap/neo4j' dotenv.config() if (process.env.NODE_ENV === 'production') { - throw new Error('YOU CAN`T UNSEED IN PRODUCTION MODE') + throw new Error('YOU CAN`T UNSEED IN PRODUCTION MODE') } const driver = neo4j().getDriver() const session = driver.session() query('MATCH (n) DETACH DELETE n', session).then(() => { - console.log('Successfully deleted all nodes and relations!') + console.log('Successfully deleted all nodes and relations!') }).catch((err) => { - console.log(`Error occurred deleting the nodes and relations (reset the db)\n\n${err}`) + console.log(`Error occurred deleting the nodes and relations (reset the db)\n\n${err}`) }).finally(() => { - if (session) { - session.close() - } - process.exit(0) -}) \ No newline at end of file + if (session) { + session.close() + } + process.exit(0) +}) diff --git a/yarn.lock b/yarn.lock index fc6cc1c35..5abc4e9ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -264,7 +264,7 @@ output-file-sync "^2.0.0" v8flags "^3.1.1" -"@babel/parser@^7.1.2", "@babel/parser@^7.1.6": +"@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.6.tgz#16e97aca1ec1062324a01c5a6a7d0df8dd189854" integrity sha512-dWP6LJm9nKT6ALaa+bnL247GHHMWir3vSlZ2+IHgHgktZQx0L3Uvq2uAWcuzIe+fujRsYWBW2q622C5UvGK9iQ== @@ -646,7 +646,7 @@ "@babel/parser" "^7.1.2" "@babel/types" "^7.1.2" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.1.6": +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.6.tgz#c8db9963ab4ce5b894222435482bd8ea854b7b5c" integrity sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ== @@ -849,6 +849,26 @@ accepts@^1.3.5, accepts@~1.3.5: mime-types "~2.1.18" negotiator "0.6.1" +acorn-jsx@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" + integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== + +acorn@^6.0.2: + version "6.0.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" + integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== + +ajv@^6.5.3, ajv@^6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.1.tgz#6360f5ed0d80f232cc2b294c362d5dc2e538dd61" + integrity sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ajv@^6.5.5: version "6.5.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" @@ -871,6 +891,11 @@ ansi-escapes@^1.1.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -881,12 +906,17 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-regex@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" + integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -1238,6 +1268,11 @@ assignment@2.2.0: resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.2.0.tgz#f5b5bc2d160d69986e8700cd38f567c0aabe101e" integrity sha1-9bW8LRYNaZhuhwDNOPVnwKq+EB4= +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" @@ -1299,6 +1334,18 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== +babel-eslint@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed" + integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + eslint-scope "3.7.1" + eslint-visitor-keys "^1.0.0" + babel-polyfill@6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" @@ -1487,6 +1534,18 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= + camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -1523,7 +1582,7 @@ chalk@1.1.3, chalk@^1.0.0: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== @@ -1537,6 +1596,11 @@ chardet@^0.4.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + cheerio@^1.0.0-rc.2: version "1.0.0-rc.2" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" @@ -1579,6 +1643,11 @@ ci-info@^1.5.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -1699,6 +1768,11 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" @@ -1834,7 +1908,7 @@ date-fns@^2.0.0-alpha.24: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.25.tgz#651a5d1f59a01af6cf0371e39b2ae29df5d521ee" integrity sha512-iQzJkHF0L4wah9Ae9PkvwemwFz6qmRLuNZcghmvf2t+ptLs1qXzONLiGtjmPQzL6+JpC01JjlTopY2AEy4NFAg== -debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -1848,7 +1922,7 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^4.1.0: +debug@^4.0.1, debug@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== @@ -1870,6 +1944,11 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + define-properties@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -1937,6 +2016,21 @@ dicer@0.2.5: readable-stream "1.1.x" streamsearch "0.1.2" +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + dom-serializer@0, dom-serializer@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" @@ -2047,7 +2141,7 @@ entities@^1.1.1, entities@~1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== -error-ex@^1.3.1: +error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -2084,11 +2178,176 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +eslint-config-standard@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9" + integrity sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ== + +eslint-import-resolver-node@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" + integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + +eslint-plugin-es@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz#475f65bb20c993fc10e8c8fe77d1d60068072da6" + integrity sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw== + dependencies: + eslint-utils "^1.3.0" + regexpp "^2.0.1" + +eslint-plugin-import@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" + integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== + dependencies: + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.2.0" + has "^1.0.1" + lodash "^4.17.4" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + resolve "^1.6.0" + +eslint-plugin-node@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.0.tgz#fb9e8911f4543514f154bb6a5924b599aa645568" + integrity sha512-Y+ln8iQ52scz9+rSPnSWRaAxeWaoJZ4wIveDR0vLHkuSZGe44Vk1J4HX7WvEP5Cm+iXPE8ixo7OM7gAO3/OKpQ== + dependencies: + eslint-plugin-es "^1.3.1" + eslint-utils "^1.3.1" + ignore "^5.0.2" + minimatch "^3.0.4" + resolve "^1.8.1" + semver "^5.5.0" + +eslint-plugin-promise@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" + integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg== + +eslint-plugin-standard@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz#f845b45109c99cd90e77796940a344546c8f6b5c" + integrity sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA== + +eslint-scope@3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.0, eslint-utils@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" + integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + +eslint@^5.9.0: + version "5.9.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" + integrity sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.5.3" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^2.1.0" + eslint-scope "^4.0.0" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^4.0.0" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + imurmurhash "^0.1.4" + inquirer "^6.1.0" + is-resolvable "^1.1.0" + js-yaml "^3.12.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.5" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^2.0.1" + require-uncached "^1.0.3" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.0.2" + text-table "^0.2.0" + +espree@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" + integrity sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w== + dependencies: + acorn "^6.0.2" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -2213,6 +2472,15 @@ external-editor@^2.0.1: iconv-lite "^0.4.17" tmp "^0.0.33" +external-editor@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -2252,6 +2520,11 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -2259,6 +2532,14 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -2291,7 +2572,15 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" -find-up@^2.1.0: +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= @@ -2305,6 +2594,16 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" +flat-cache@^1.2.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" + integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== + dependencies: + circular-json "^0.3.1" + graceful-fs "^4.1.2" + rimraf "~2.6.2" + write "^0.2.1" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -2371,6 +2670,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -2415,7 +2719,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.0, glob@^7.0.5: +glob@^7.0.0, glob@^7.0.5, glob@^7.1.2: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== @@ -2434,7 +2738,7 @@ global-dirs@^0.1.0: dependencies: ini "^1.3.4" -globals@^11.1.0: +globals@^11.1.0, globals@^11.7.0: version "11.9.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== @@ -2808,7 +3112,7 @@ iconv-lite@0.4.23: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -2837,6 +3141,16 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.0.2: + version "5.0.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.0.4.tgz#33168af4a21e99b00c5d41cbadb6a6cb49903a45" + integrity sha512-WLsTMEhsQuXpCiG173+f3aymI43SXa+fB1rSfbzyP4GkPP+ZFVuO0/3sFUGNBtifisPeDcl/uD/Y2NxZ7xFq4g== + immutable-tuple@^0.4.9: version "0.4.9" resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.9.tgz#473ebdd6c169c461913a454bf87ef8f601a20ff0" @@ -2889,6 +3203,25 @@ inquirer@3.0.6: strip-ansi "^3.0.0" through "^2.3.6" +inquirer@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52" + integrity sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.0" + figures "^2.0.0" + lodash "^4.17.10" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.1.0" + string-width "^2.1.0" + strip-ansi "^5.0.0" + through "^2.3.6" + insane@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/insane/-/insane-2.6.1.tgz#c7dcae7b51c20346883b71078fad6ce0483c198f" @@ -3105,6 +3438,11 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" +is-resolvable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" @@ -3205,7 +3543,7 @@ js-levenshtein@^1.1.3: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.10.0: +js-yaml@^3.10.0, js-yaml@^3.12.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== @@ -3243,6 +3581,11 @@ json-schema@0.2.3: resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" @@ -3347,6 +3690,14 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + libphonenumber-js@^1.6.4: version "1.6.7" resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.6.7.tgz#cb4501f6d1e5e0b4c8ccbd10ba489359f649dd73" @@ -3365,6 +3716,16 @@ linkifyjs@^2.1.7: react "^16.4.2" react-dom "^16.4.2" +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.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" @@ -3564,7 +3925,7 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -minimatch@^3.0.4: +minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -3653,6 +4014,11 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + needle@^2.2.1: version "2.2.4" resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" @@ -3935,6 +4301,18 @@ optimism@^0.6.6: dependencies: immutable-tuple "^0.4.9" +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -4034,6 +4412,13 @@ package-json@^4.0.0: registry-url "^3.0.3" semver "^5.1.0" +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + 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" @@ -4090,6 +4475,13 @@ path-dirname@^1.0.0: resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -4100,7 +4492,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= @@ -4120,6 +4512,13 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + pause@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" @@ -4130,6 +4529,11 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" @@ -4154,6 +4558,13 @@ pirates@^4.0.0: dependencies: node-modules-regexp "^1.0.0" +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= + dependencies: + find-up "^1.0.0" + pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -4161,6 +4572,11 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -4175,6 +4591,11 @@ postcss@^6.0.14: source-map "^0.6.1" supports-color "^5.4.0" +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" @@ -4190,6 +4611,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== +progress@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.2.tgz#db9476f916bcc9ebe8a04efb22b18b0740376c61" + integrity sha512-/OLz5F9beZUWwSHZDreXgap1XShX6W+DCHQCqwCF7uZ88s6uTlD2cR3JBE77SegCmNtb1Idst+NfmwcdU6KVhw== + prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" @@ -4310,6 +4736,23 @@ react@^16.4.2: prop-types "^15.6.2" scheduler "^0.11.2" +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + read-pkg@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" @@ -4402,6 +4845,11 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + regexpu-core@^4.1.3, regexpu-core@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.2.0.tgz#a3744fa03806cffe146dea4421a3e73bdcc47b1d" @@ -4492,12 +4940,25 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.3.2: +resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== @@ -4522,7 +4983,7 @@ retry@0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= -rimraf@^2.6.1: +rimraf@^2.6.1, rimraf@~2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== @@ -4541,7 +5002,7 @@ rx@^4.1.0: resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= -rxjs@^6.3.3: +rxjs@^6.1.0, rxjs@^6.3.3: version "6.3.3" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== @@ -4611,7 +5072,7 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== @@ -4697,6 +5158,15 @@ slash@^2.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== +slice-ansi@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.0.0.tgz#5373bdb8559b45676e8541c66916cdd6251612e7" + integrity sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + slug@^0.9.1: version "0.9.2" resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.2.tgz#e409e4dae3a4bd2fd283557e2806e0a8abb98242" @@ -4866,7 +5336,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -4900,12 +5370,24 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" + integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow== + dependencies: + ansi-regex "^4.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= -strip-json-comments@~2.0.1: +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= @@ -4945,6 +5427,16 @@ symbol-observable@^1.0.2, symbol-observable@^1.0.4: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== +table@^5.0.2: + version "5.1.1" + resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837" + integrity sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw== + dependencies: + ajv "^6.6.1" + lodash "^4.17.11" + slice-ansi "2.0.0" + string-width "^2.1.1" + tar@^4: version "4.4.8" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" @@ -4970,6 +5462,11 @@ text-encoding@^0.6.4: resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" integrity sha1-45mpgiV6J22uQou5KEXLcb3CbRk= +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -5080,6 +5577,13 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + type-is@^1.6.16, type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" @@ -5310,6 +5814,11 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -5332,6 +5841,13 @@ write-file-atomic@^2.0.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= + dependencies: + mkdirp "^0.5.1" + ws@^5.2.0: version "5.2.2" resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" From f00dbb67dfec192dd470483230fb862b62cbbe9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 18:06:08 +0100 Subject: [PATCH 111/554] Re-add success notification on Discord Why was it disabled in the first place @appinteractive? --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index ae23f5112..c5351a21a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,9 +24,9 @@ script: - docker-compose run --rm backend yarn run db:seed # seeding needs neo4j after_success: - # - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh - # - chmod +x send.sh - # - ./send.sh success $WEBHOOK_URL + - 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 docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; docker tag humanconnection/nitro-backend humanconnection/nitro-backend:latest; From 2ace3e5ce814ef38f55bbb316f33cf033af56a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 18:28:34 +0100 Subject: [PATCH 112/554] Disable eslint for the always-true if-condition See: https://github.com/Human-Connection/Nitro-Backend/issues/41 --- src/jwt/strategy.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/jwt/strategy.js b/src/jwt/strategy.js index 80774b65b..0807c3fd1 100644 --- a/src/jwt/strategy.js +++ b/src/jwt/strategy.js @@ -20,7 +20,10 @@ export default () => { (JWTPayload, next) => { // usually this would be a database call: // var user = users[_.findIndex(users, {id: JWTPayload.id})] + // TODO: fix https://github.com/Human-Connection/Nitro-Backend/issues/41 + /* eslint-disable */ if (true) { + /* eslint-enable */ next(null, {}) } else { next(null, false) From 333f1811618337d54dff88ab9cd6417d1ec21d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 18:31:46 +0100 Subject: [PATCH 113/554] Fix typo in .travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c5351a21a..eacbdc107 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,10 +17,10 @@ before_install: - sudo mv docker-compose /usr/local/bin install: - - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend . + - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend:latest . script: -- docker run humanconnection/backend:latest yarn run eslint +- docker run humanconnection/nitro-backend:latest yarn run eslint - docker-compose run --rm backend yarn run db:seed # seeding needs neo4j after_success: From a7b4b55b6c5b854feafdd9a937eb414476bee06a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 18:57:53 +0100 Subject: [PATCH 114/554] Follow up to @appinteractive's commit e2f7bc51 Next time: `git grep "backend"` :+1: --- docker-compose.override.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 22e16da73..70e2fe389 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -4,8 +4,8 @@ services: backend: container_name: backend.127.0.0.1.xip.io volumes: - - .:/backend - - /backend/node_modules + - .:/nitro-backend + - /nitro-backend/node_modules neo4j: ports: - 7687:7687 From 298db35546b8625debde942cdaa350774c083608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 19:04:45 +0100 Subject: [PATCH 115/554] Use simple past and consistend naming --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 65fbbc4da..7a02fb167 100644 --- a/README.md +++ b/README.md @@ -92,14 +92,14 @@ run Neo4j in one of the [many cloud options](https://neo4j.com/developer/guide-c [spin up Neo4j in a Docker container](https://neo4j.com/developer/docker/) or on Debian-based systems install [Neo4j from the Debian Repository](http://debian.neo4j.org/). Just be sure to update the Neo4j connection string and credentials accordingly in `.env`. -## Mocking API Results +## Mock API Results Alternatively you can just mock all responses from the api which let you build a frontend application without running a neo4j instance. Just set `MOCK=true` inside `.env` or pass it on application start. -## Seeding and Cleaning The Database +## Seed and Reset the Database Optionally you can seed the GraphQL service by executing mutations that will write sample data to the database: From d061348ec8d54ce76f3ab6cabbf3796539a89084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 19:28:25 +0100 Subject: [PATCH 116/554] Use npm: prefixes to DRY package.json @appinteractive and @Mastercuber have a look, I guess this feature of concurrently is new to you: https://www.npmjs.com/package/concurrently#usage For some reason, concurrently hangs when run with docker-compose. I haven't figured out how to fix this. Run locally, everything terminates as expected. --- package.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a191ee27c..7ed758717 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,11 @@ "test": "echo \"Error: no test specified\" && exit 0", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "db:seed": "concurrently --kill-others --success first 'cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start' 'wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js'", - "db:reset": "concurrently --kill-others --success first 'cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start' 'wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/unseed-db.js'" + "db:backdoor": "cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start", + "db:script:seed": "wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js", + "db:script:reset": "wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/unseed-db.js", + "db:seed": "concurrently --kill-others --success first -n backdoor,seed \"yarn run db:backdoor\" \"yarn run db:script:seed\"", + "db:reset": "concurrently --kill-others --success first -n backdoor,reset \"yarn run db:backdoor\" \"yarn run db:script:reset\"" }, "author": "Human Connection gGmbH", "license": "MIT", From f1c3c6bedede1bfa9a66e80ea59266031d0d02bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 20:43:16 +0100 Subject: [PATCH 117/554] Wording: no-auth-server instead of backdoor Suggested by @appinteractive --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 7ed758717..bdc2c0c80 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,11 @@ "test": "echo \"Error: no test specified\" && exit 0", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "db:backdoor": "cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start", + "db:no-auth-server": "cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start", "db:script:seed": "wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/unseed-db.js", - "db:seed": "concurrently --kill-others --success first -n backdoor,seed \"yarn run db:backdoor\" \"yarn run db:script:seed\"", - "db:reset": "concurrently --kill-others --success first -n backdoor,reset \"yarn run db:backdoor\" \"yarn run db:script:reset\"" + "db:seed": "concurrently --kill-others --success first -n no-auth-server,seed \"yarn run db:no-auth-server\" \"yarn run db:script:seed\"", + "db:reset": "concurrently --kill-others --success first -n no-auth-server,reset \"yarn run db:no-auth-server\" \"yarn run db:script:reset\"" }, "author": "Human Connection gGmbH", "license": "MIT", From d201d7367028b7757e6140eea1953830a05fe24c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 20:43:42 +0100 Subject: [PATCH 118/554] Run seeds without docker-compose I give up with running docker-compose on Travis CI. Using `bash` instead of Linux alpine's `sh` does **not** fix the issue as suggested here: https://github.com/kimmobrunfeldt/concurrently/issues/104 --- .travis.yml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index eacbdc107..63ce4a4e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,21 +7,16 @@ cache: - node_modules services: - docker -env: - - DOCKER_COMPOSE_VERSION=1.23.2 - -before_install: - - sudo rm /usr/local/bin/docker-compose - - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose - - chmod +x docker-compose - - sudo mv docker-compose /usr/local/bin + - neo4j install: + - yarn install - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend:latest . script: - docker run humanconnection/nitro-backend:latest yarn run eslint -- docker-compose run --rm backend yarn run db:seed # seeding needs neo4j +- yarn run db:reset +- yarn run db:seed after_success: - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh From fa8cbba421f59407308ab630dcfcd382292579dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 3 Dec 2018 20:49:23 +0100 Subject: [PATCH 119/554] Copy .env.template for dummy secrets on Travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 63ce4a4e1..322137700 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ services: install: - yarn install - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend:latest . + - cp .env.template .env script: - docker run humanconnection/nitro-backend:latest yarn run eslint From 5eae8a89785798519aec66fb708389f6e5ea0327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 4 Dec 2018 00:18:49 +0100 Subject: [PATCH 120/554] Configure Travis CI conditional builds and add placeholder deployment. This commit should deploy to * `production` if on branch master AND tagged * `staging` if on branch master * `custom` if tagged The custom deployment is inspired by https://zeit.co/now and should deploy features for demonstration purposes before merging into master. It will happen that we trigger multiple deployments with this workflow: If we deploy to production, that is going to deploy to a custom environment and to staging. But I think this is not too problematic. What do you think @appinteractive @mcwimpy? --- .travis.yml | 16 ++++++++++++++++ scripts/deploy.sh | 4 ++++ 2 files changed, 20 insertions(+) create mode 100755 scripts/deploy.sh diff --git a/.travis.yml b/.travis.yml index 322137700..adfd185f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,3 +33,19 @@ after_failure: - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh - chmod +x send.sh - ./send.sh failure $WEBHOOK_URL + +deploy: + - provider: script + script: scripts/deploy.sh nitro.human-connection.org + on: + branch: master + tag: true + - provider: script + script: scripts/deploy.sh nitro-staging.human-connection.org + on: + branch: master + - provider: script + script: scripts/deploy.sh "nitro-$(git rev-parse --short HEAD).human-connection.org" + on: + tag: true + all_branches: true diff --git a/scripts/deploy.sh b/scripts/deploy.sh new file mode 100755 index 000000000..b66b63a77 --- /dev/null +++ b/scripts/deploy.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +echo "See me deployed at $1 :)" + From 8e462e9cc66e694f981f29b56a2973fe9f0894c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 4 Dec 2018 00:50:00 +0100 Subject: [PATCH 121/554] Typo: `tagS` to deploy only if git tag exists --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index adfd185f5..3afc08703 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,7 @@ deploy: script: scripts/deploy.sh nitro.human-connection.org on: branch: master - tag: true + tags: true - provider: script script: scripts/deploy.sh nitro-staging.human-connection.org on: @@ -47,5 +47,5 @@ deploy: - provider: script script: scripts/deploy.sh "nitro-$(git rev-parse --short HEAD).human-connection.org" on: - tag: true + tags: true all_branches: true From 0fab314b13f4f0fef815e947d6c02930cea0baa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 4 Dec 2018 01:20:50 +0100 Subject: [PATCH 122/554] Wording: Use `reset-db` for the file name, too FYI: @Mastercuber --- package.json | 2 +- src/seed/{unseed-db.js => reset-db.js} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/seed/{unseed-db.js => reset-db.js} (100%) diff --git a/package.json b/package.json index bdc2c0c80..a5fe9e159 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "db:no-auth-server": "cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start", "db:script:seed": "wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js", - "db:script:reset": "wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/unseed-db.js", + "db:script:reset": "wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/reset-db.js", "db:seed": "concurrently --kill-others --success first -n no-auth-server,seed \"yarn run db:no-auth-server\" \"yarn run db:script:seed\"", "db:reset": "concurrently --kill-others --success first -n no-auth-server,reset \"yarn run db:no-auth-server\" \"yarn run db:script:reset\"" }, diff --git a/src/seed/unseed-db.js b/src/seed/reset-db.js similarity index 100% rename from src/seed/unseed-db.js rename to src/seed/reset-db.js From d355974b6e2aed27d7a495c4454b3aacf9c9c766 Mon Sep 17 00:00:00 2001 From: Armin Kunkel Date: Tue, 4 Dec 2018 03:52:33 +0100 Subject: [PATCH 123/554] Add troubleshoot to kubernetes README --- kubernetes/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index 81c6c4f88..5192f9a19 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -6,14 +6,15 @@ First of all start minikube on your machine: ```sh minikube start ``` -[troubleshoot] If you get an error message along th lines of 'The vboxdrv kernel module is not loaded.' - then you have the same issue i had. to solve this you need to install the propper linux kernel host modules package. Here an example for Manjaro: +**[troubleshoot]** If you get an error message along th lines of 'The vboxdrv kernel module is not loaded.' - then you have the same issue i had. to solve this you need to install the propper linux kernel host modules package. Here an example for Manjaro: https://forum.manjaro.org/t/installing-virtualbox-kernel-modules/6999 +**[troubleshoot]** When you can not start minikube, try also to remove the cluster with `minikube delete` and start again with `minikube start`. Sometimes this fix startup problems of the cluster. You can always get an overview and see what's going on with your minikube: ```sh minikube dashboard ``` -[troubleshoot] now again you might run into trouble with an error like 'kubectl could not be found on your path.' In this case run the following command: +**[troubleshoot]** now again you might run into trouble with an error like 'kubectl could not be found on your path.' In this case run the following command: ```sh curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.10.0/bin/linux/amd64/kubectl && chmod +x kubectl && sudo cp kubectl /usr/local/bin/ && rm kubectl ``` From 43b5d8eeb0b76b4d2b1917ba47b79ae2b2e71626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 4 Dec 2018 21:41:19 +0100 Subject: [PATCH 124/554] Follow @appinteractives review See: https://github.com/Human-Connection/Nitro-Backend/pull/40#pullrequestreview-180898363 https://github.com/Human-Connection/Nitro-Backend/pull/40#pullrequestreview-180950115 --- package.json | 12 +++++++----- src/middleware/permissionsMiddleware.js | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a5fe9e159..6986d1d93 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,18 @@ "version": "0.0.1", "description": "GraphQL Backend for Human Connection", "main": "src/index.js", + "config": { + "no_auth": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 PERMISSIONS=disabled" + }, "scripts": { "eslint": "eslint src --config .eslintrc.js", "test": "echo \"Error: no test specified\" && exit 0", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "db:no-auth-server": "cross-env GRAPHQL_URI=http://localhost:4001 PERMISSIONS=disabled GRAPHQL_PORT=4001 yarn run start", - "db:script:seed": "wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/seed-db.js", - "db:script:reset": "wait-on tcp:4001 && cross-env GRAPHQL_URI=http://localhost:4001 ./node_modules/.bin/babel-node src/seed/reset-db.js", - "db:seed": "concurrently --kill-others --success first -n no-auth-server,seed \"yarn run db:no-auth-server\" \"yarn run db:script:seed\"", - "db:reset": "concurrently --kill-others --success first -n no-auth-server,reset \"yarn run db:no-auth-server\" \"yarn run db:script:reset\"" + "db:script:seed": "wait-on tcp:4001 && $npm_package_config_no_auth ./node_modules/.bin/babel-node src/seed/seed-db.js", + "db:script:reset": "wait-on tcp:4001 && $npm_package_config_no_auth ./node_modules/.bin/babel-node src/seed/reset-db.js", + "db:seed": "concurrently --kill-others --success first -n no-auth-server,seed '$npm_package_config_no_auth yarn run start' 'yarn run db:script:seed'", + "db:reset": "concurrently --kill-others --success first -n no-auth-server,reset '$npm_package_config_no_auth yarn run start' 'yarn run db:script:reset'" }, "author": "Human Connection gGmbH", "license": "MIT", diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index e95fd49d8..5b0cb87d2 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -1,5 +1,19 @@ import { rule, shield, allow } from 'graphql-shield' +/* + * TODO: implement + * See: https://github.com/Human-Connection/Nitro-Backend/pull/40#pullrequestreview-180898363 +const isAuthenticated = rule()(async (parent, args, ctx, info) => { + return ctx.user !== null +}) +const isAdmin = rule()(async (parent, args, ctx, info) => { + return ctx.user.role === 'ADMIN' +}) +const isModerator = rule()(async (parent, args, ctx, info) => { + return ctx.user.role === 'MODERATOR' +}) +*/ + const isOwner = rule()(async (parent, args, ctx, info) => { return ctx.user.id === parent.id }) From 7623b4dc8512b44e5562ab72daa0945f08e753eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 4 Dec 2018 22:56:53 +0000 Subject: [PATCH 125/554] Bump sanitize-html from 1.19.1 to 1.19.2 Bumps [sanitize-html](https://github.com/punkave/sanitize-html) from 1.19.1 to 1.19.2. - [Release notes](https://github.com/punkave/sanitize-html/releases) - [Changelog](https://github.com/punkave/sanitize-html/blob/master/CHANGELOG.md) - [Commits](https://github.com/punkave/sanitize-html/compare/1.19.1...1.19.2) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 54 ++++++++++++++++++++++++++++------------------------ 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 6986d1d93..4b921809b 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "node-fetch": "^2.1.2", "passport": "^0.4.0", "passport-jwt": "^4.0.0", - "sanitize-html": "^1.19.1", + "sanitize-html": "^1.19.2", "slug": "^0.9.1", "trunc-html": "^1.1.2" }, diff --git a/yarn.lock b/yarn.lock index 5abc4e9ae..1c087217c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1582,7 +1582,7 @@ chalk@1.1.3, chalk@^1.0.0: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== @@ -1886,6 +1886,14 @@ css-select@~1.2.0: domutils "1.5.1" nth-check "~1.0.1" +css-tree@^1.0.0-alpha.29: + version "1.0.0-alpha.29" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39" + integrity sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg== + dependencies: + mdn-data "~1.1.0" + source-map "^0.5.3" + css-what@2.1: version "2.1.2" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" @@ -3074,7 +3082,7 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== -htmlparser2@^3.9.0, htmlparser2@^3.9.1: +htmlparser2@^3.10.0, htmlparser2@^3.9.1: version "3.10.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" integrity sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ== @@ -3787,7 +3795,7 @@ lodash.isstring@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= -lodash.mergewith@^4.6.0: +lodash.mergewith@^4.6.1: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== @@ -3860,6 +3868,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +mdn-data@~1.1.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01" + integrity sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA== + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -4582,15 +4595,6 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -postcss@^6.0.14: - version "6.0.23" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" - integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== - dependencies: - chalk "^2.4.1" - source-map "^0.6.1" - supports-color "^5.4.0" - prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -5026,21 +5030,21 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sanitize-html@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.1.tgz#e8b33c69578054d6ee4f57ea152d6497f3f6fb7d" - integrity sha512-zNYr6FvBn4bZukr9x2uny6od/9YdjCLwF+FqxivqI0YOt/m9GIxfX+tWhm52tBAPUXiTTb4bJTGVagRz5b06bw== +sanitize-html@^1.19.2: + version "1.19.2" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.2.tgz#c03fffe2bf96cd582968ece9792cbca32e64dde0" + integrity sha512-7fNb3/N0sZ/nkshMRBoxLz6K1dlMSVF/eQHX1Bof9sRT7cZJvmrDGfXEn544MXJnpY29vux1A599g9UrcHTBXA== dependencies: - chalk "^2.3.0" - htmlparser2 "^3.9.0" + chalk "^2.4.1" + css-tree "^1.0.0-alpha.29" + htmlparser2 "^3.10.0" lodash.clonedeep "^4.5.0" lodash.escaperegexp "^4.1.2" lodash.isplainobject "^4.0.6" lodash.isstring "^4.0.1" - lodash.mergewith "^4.6.0" - postcss "^6.0.14" + lodash.mergewith "^4.6.1" srcset "^1.0.0" - xtend "^4.0.0" + xtend "^4.0.1" sax@1.2.1: version "1.2.1" @@ -5228,12 +5232,12 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.0, source-map@^0.5.6: +source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1: +source-map@^0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -5415,7 +5419,7 @@ supports-color@^4.5.0: dependencies: has-flag "^2.0.0" -supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0: +supports-color@^5.2.0, supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -5880,7 +5884,7 @@ xmlbuilder@~9.0.1: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= -xtend@^4.0.0: +xtend@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= From ad62a8ebb324b32702c0776db7d2a7e36393586d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 5 Dec 2018 00:12:47 +0100 Subject: [PATCH 126/554] Set unimplemented mocha tests to pending --- package.json | 2 +- src/middleware/permissionsMiddleware.test.js | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 12a6124b7..09bfd85dc 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "no_auth": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 PERMISSIONS=disabled" }, "scripts": { - "test": "mocha --require @babel/register src/**/*.test.js", + "mocha": "./node_modules/.bin/mocha --require @babel/register src/**/*.test.js", "eslint": "eslint src --config .eslintrc.js", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", diff --git a/src/middleware/permissionsMiddleware.test.js b/src/middleware/permissionsMiddleware.test.js index 644eef35d..d48b35440 100644 --- a/src/middleware/permissionsMiddleware.test.js +++ b/src/middleware/permissionsMiddleware.test.js @@ -1,19 +1,16 @@ import { describe, it } from 'mocha' -import { expect } from 'chai' describe('query', () => { describe('statistics', () => { describe('authenticated user', () => { describe('read', () => { - it('is forbidden', () => { - }) + it('is forbidden') }) }) - context('admin', () => { + describe('admin', () => { describe('read', () => { - it('is permitted', () => { - }) + it('is permitted') }) }) }) From 03d71489584eef89af59e0d828489f98758530ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 5 Dec 2018 00:37:18 +0100 Subject: [PATCH 127/554] Run the tests in the docker image Travis lags behind with the current version of docker-compose --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6c98c8ba7..5f4314cbb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ install: script: - docker run humanconnection/nitro-backend:latest yarn run eslint -- docker-compose run --rm backend yarn run mocha +- docker run humanconnection/nitro-backend:latest yarn run mocha - yarn run db:reset - yarn run db:seed From c6cc46105738d8b17cd064be3b89d921d6b7a56e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 6 Dec 2018 04:48:26 +0000 Subject: [PATCH 128/554] Bump dotenv from 6.1.0 to 6.2.0 Bumps [dotenv](https://github.com/motdotla/dotenv) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/motdotla/dotenv/releases) - [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md) - [Commits](https://github.com/motdotla/dotenv/compare/v6.1.0...v6.2.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 4b921809b..8529a6d9f 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "bcryptjs": "^2.4.3", "cheerio": "^1.0.0-rc.2", "date-fns": "^2.0.0-alpha.24", - "dotenv": "^6.0.0", + "dotenv": "^6.2.0", "graphql-custom-directives": "^0.2.13", "graphql-iso-date": "^3.6.1", "graphql-middleware": "1.7.6", diff --git a/yarn.lock b/yarn.lock index 1c087217c..1ac67ea81 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2097,10 +2097,10 @@ dotenv@^0.4.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" integrity sha1-9vs1E2PC2SIHJFxzeALJq1rhSVo= -dotenv@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.1.0.tgz#9853b6ca98292acb7dec67a95018fa40bccff42c" - integrity sha512-/veDn2ztgRlB7gKmE3i9f6CmDIyXAy6d5nBq+whO9SLX+Zs1sXEgFLPi+aSuWqUuusMfbi84fT8j34fs1HaYUw== +dotenv@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" + integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w== duplexer3@^0.1.4: version "0.1.4" From 0d9322f601a80ea3d53633c4ff95ffc17dfc8b0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 6 Dec 2018 11:56:30 +0000 Subject: [PATCH 129/554] Bump sanitize-html from 1.19.2 to 1.19.3 Bumps [sanitize-html](https://github.com/punkave/sanitize-html) from 1.19.2 to 1.19.3. - [Release notes](https://github.com/punkave/sanitize-html/releases) - [Changelog](https://github.com/punkave/sanitize-html/blob/master/CHANGELOG.md) - [Commits](https://github.com/punkave/sanitize-html/compare/1.19.2...1.19.3) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 38 +++++++++++++++++--------------------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 8529a6d9f..d83a8475b 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "node-fetch": "^2.1.2", "passport": "^0.4.0", "passport-jwt": "^4.0.0", - "sanitize-html": "^1.19.2", + "sanitize-html": "^1.19.3", "slug": "^0.9.1", "trunc-html": "^1.1.2" }, diff --git a/yarn.lock b/yarn.lock index 1ac67ea81..84bc62a56 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1886,14 +1886,6 @@ css-select@~1.2.0: domutils "1.5.1" nth-check "~1.0.1" -css-tree@^1.0.0-alpha.29: - version "1.0.0-alpha.29" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39" - integrity sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg== - dependencies: - mdn-data "~1.1.0" - source-map "^0.5.3" - css-what@2.1: version "2.1.2" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" @@ -3868,11 +3860,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -mdn-data@~1.1.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01" - integrity sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA== - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -4595,6 +4582,15 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= +postcss@^7.0.5: + version "7.0.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.6.tgz#6dcaa1e999cdd4a255dcd7d4d9547f4ca010cdc2" + integrity sha512-Nq/rNjnHFcKgCDDZYO0lNsl6YWe6U7tTy+ESN+PnLxebL8uBtYX59HZqvrj7YLK5UCyll2hqDsJOo3ndzEW8Ug== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.5.0" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -5030,19 +5026,19 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sanitize-html@^1.19.2: - version "1.19.2" - resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.2.tgz#c03fffe2bf96cd582968ece9792cbca32e64dde0" - integrity sha512-7fNb3/N0sZ/nkshMRBoxLz6K1dlMSVF/eQHX1Bof9sRT7cZJvmrDGfXEn544MXJnpY29vux1A599g9UrcHTBXA== +sanitize-html@^1.19.3: + version "1.19.3" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.3.tgz#6a6562ec4a90e6b9139ca3c845a3c83512288519" + integrity sha512-QpIjbF1rhUSQj9V7Wey/gv4DPqOso8KTebaI4rC97p0WCLnTpmhf7BJZUhS83MTtqRvUo8MuXH316CW2Nzd48w== dependencies: chalk "^2.4.1" - css-tree "^1.0.0-alpha.29" htmlparser2 "^3.10.0" lodash.clonedeep "^4.5.0" lodash.escaperegexp "^4.1.2" lodash.isplainobject "^4.0.6" lodash.isstring "^4.0.1" lodash.mergewith "^4.6.1" + postcss "^7.0.5" srcset "^1.0.0" xtend "^4.0.1" @@ -5232,12 +5228,12 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0: +source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -5419,7 +5415,7 @@ supports-color@^4.5.0: dependencies: has-flag "^2.0.0" -supports-color@^5.2.0, supports-color@^5.3.0: +supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== From fc2fca031723322b9c26361d003259cf9a6e34d1 Mon Sep 17 00:00:00 2001 From: faithngetich Date: Thu, 6 Dec 2018 19:12:29 +0300 Subject: [PATCH 130/554] Use the right db seed name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a02fb167..9be587c51 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Run: docker-compose up # if you want seed data # open another terminal and run -docker-compose exec backend yarn run seedDb +docker-compose exec backend yarn run db:seed ``` App is [running on port 4000](http://localhost:4000/) From 3d65d09b3a15dda1e4b9c3f18e62283361f5f310 Mon Sep 17 00:00:00 2001 From: faithngetich Date: Thu, 6 Dec 2018 19:20:15 +0300 Subject: [PATCH 131/554] Add a missing discord link --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 7a02fb167..cd0cfe8be 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ > We still need to evaluate the drawbacks and estimate the development > cost of such an approach +## How to get in touch +Connect with other developers over [Discord](https://discord.gg/6ub73U3) + ## Quick Start ### Installation with Docker From b84a48f981953d84fc3991372585b1bf971c82ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 6 Dec 2018 16:26:10 +0000 Subject: [PATCH 132/554] Bump neo4j-graphql-js from 1.0.5 to 2.0.0 Bumps [neo4j-graphql-js](https://github.com/neo4j-graphql/neo4j-graphql-js) from 1.0.5 to 2.0.0. - [Release notes](https://github.com/neo4j-graphql/neo4j-graphql-js/releases) - [Changelog](https://github.com/neo4j-graphql/neo4j-graphql-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/neo4j-graphql/neo4j-graphql-js/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 27 +++++++++++++++++---------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index d83a8475b..547f6d2b1 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "lodash": "^4.17.11", "ms": "^2.1.1", "neo4j-driver": "^1.6.1", - "neo4j-graphql-js": "1.0.5", + "neo4j-graphql-js": "2.0.0", "node-fetch": "^2.1.2", "passport": "^0.4.0", "passport-jwt": "^4.0.0", diff --git a/yarn.lock b/yarn.lock index 84bc62a56..88add8583 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2957,13 +2957,20 @@ graphql-yoga@1.16.2: graphql-tools "^3.0.0" subscriptions-transport-ws "^0.9.8" -"graphql@^0.11.0 || ^0.12.0 || ^0.13.0", graphql@^0.13.2: +"graphql@^0.11.0 || ^0.12.0 || ^0.13.0": version "0.13.2" resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== dependencies: iterall "^1.2.1" +graphql@^14.0.2: + version "14.0.2" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.0.2.tgz#7dded337a4c3fd2d075692323384034b357f5650" + integrity sha512-gUC4YYsaiSJT1h40krG3J+USGlwhzNTXSb4IOZljn9ag5Tj+RkoXrWp+Kh7WyE3t1NCfab5kzCuxBIvOMERMXw== + dependencies: + iterall "^1.2.2" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -3509,7 +3516,7 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -iterall@^1.1.3, iterall@^1.2.1: +iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== @@ -4033,7 +4040,7 @@ negotiator@0.6.1: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= -neo4j-driver@^1.6.1: +neo4j-driver@^1.6.1, neo4j-driver@^1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.2.tgz#c72a6dfa6bd2106b00a42794dc52a82b227b48e0" integrity sha512-0IvCFYhcP9hb5JveZk33epbReDKpFTn2u5vAa8zzGG344i6yFqZrBo0mtC114ciP9zFjAtfNOP72mRm8+NV0Fg== @@ -4042,14 +4049,14 @@ neo4j-driver@^1.6.1: text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-graphql-js@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.5.tgz#ef5d59d2e7cf46971af49bceec2f4bcd2debc835" - integrity sha512-Fn+lsynWeUy6AT2Xnzpl4vuBWTroUtAyK38qbBVd26z8SeWuQrlxtJFUEifU4VrQxw7tMfbLUSKt7Av+eDQiPw== +neo4j-graphql-js@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.0.0.tgz#db89d21aeedca67edf6cc8ba34daef9c76933594" + integrity sha512-tcQhzgmX0/SEZWkV30U0R3nBILvjcSvf43KOTpf5wKGatwB+4jJ8sOwjzJme7Nr0JkaNnSSyIwQBq0bw84miaQ== dependencies: - graphql "^0.13.2" - lodash "^4.17.10" - neo4j-driver "^1.6.1" + graphql "^14.0.2" + lodash "^4.17.11" + neo4j-driver "^1.7.2" nice-try@^1.0.4: version "1.0.5" From 6dac30b8205a33251d6f0b445c67cabf9845d195 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 7 Dec 2018 04:25:58 +0000 Subject: [PATCH 133/554] Bump neo4j-graphql-js from 2.0.0 to 2.0.1 Bumps [neo4j-graphql-js](https://github.com/neo4j-graphql/neo4j-graphql-js) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/neo4j-graphql/neo4j-graphql-js/releases) - [Changelog](https://github.com/neo4j-graphql/neo4j-graphql-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/neo4j-graphql/neo4j-graphql-js/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 547f6d2b1..ab4323234 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "lodash": "^4.17.11", "ms": "^2.1.1", "neo4j-driver": "^1.6.1", - "neo4j-graphql-js": "2.0.0", + "neo4j-graphql-js": "2.0.1", "node-fetch": "^2.1.2", "passport": "^0.4.0", "passport-jwt": "^4.0.0", diff --git a/yarn.lock b/yarn.lock index 88add8583..5a90f6d74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4049,10 +4049,10 @@ neo4j-driver@^1.6.1, neo4j-driver@^1.7.2: text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-graphql-js@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.0.0.tgz#db89d21aeedca67edf6cc8ba34daef9c76933594" - integrity sha512-tcQhzgmX0/SEZWkV30U0R3nBILvjcSvf43KOTpf5wKGatwB+4jJ8sOwjzJme7Nr0JkaNnSSyIwQBq0bw84miaQ== +neo4j-graphql-js@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.0.1.tgz#76e10947873e1fde2e4f8427fe8d6a066aea2ce4" + integrity sha512-IadLuuQc4wo9DGqn8fhFoEp1wauTZlbYb975WXjIe5V3j6+Dd70LkgZjSg/BJb+ikv7td774ZsU7d6dQFo8Plw== dependencies: graphql "^14.0.2" lodash "^4.17.11" From 26d55043ed49dcf6f1b5351851ab3d9cc41cac06 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 7 Dec 2018 20:24:52 +0100 Subject: [PATCH 134/554] added testing coverage and codecov config --- .codecov.yml | 2 + .gitignore | 2 + .travis.yml | 3 +- package.json | 7 +- yarn.lock | 410 +++++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 409 insertions(+), 15 deletions(-) create mode 100644 .codecov.yml diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 000000000..97bec0084 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,2 @@ +coverage: + range: "60...100" diff --git a/.gitignore b/.gitignore index d927e1c27..b880d50ef 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ node_modules/ .env .vscode yarn-error.log +coverage.lcov +.nyc-output/ diff --git a/.travis.yml b/.travis.yml index 5f4314cbb..fc2326425 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,8 +15,7 @@ install: - cp .env.template .env script: -- docker run humanconnection/nitro-backend:latest yarn run eslint -- docker run humanconnection/nitro-backend:latest yarn run mocha +- docker run humanconnection/nitro-backend:latest yarn run ci - yarn run db:reset - yarn run db:seed diff --git a/package.json b/package.json index 126c79ff0..634cb501c 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,10 @@ "no_auth": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 PERMISSIONS=disabled" }, "scripts": { - "mocha": "./node_modules/.bin/mocha --require @babel/register src/**/*.test.js", - "eslint": "eslint src --config .eslintrc.js", + "ci": "yarn run lint && yarn run test && yarn run test:coverage", + "lint": "eslint src --config .eslintrc.js", + "test": "nyc --reporter=text-lcov mocha --require @babel/register src/**/*.test.js", + "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "db:script:seed": "wait-on tcp:4001 && $npm_package_config_no_auth ./node_modules/.bin/babel-node src/seed/seed-db.js", @@ -67,6 +69,7 @@ "faker": "^4.1.0", "mocha": "^5.2.0", "nodemon": "^1.18.7", + "nyc": "^13.1.0", "wait-on": "^3.2.0" } } diff --git a/yarn.lock b/yarn.lock index 34fa576e4..89f48b931 100644 --- a/yarn.lock +++ b/yarn.lock @@ -67,6 +67,17 @@ semver "^5.4.1" source-map "^0.5.0" +"@babel/generator@^7.0.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.0.tgz#eaf3821fa0301d9d4aef88e63d4bcc19b73ba16c" + integrity sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg== + dependencies: + "@babel/types" "^7.2.0" + jsesc "^2.5.1" + lodash "^4.17.10" + source-map "^0.5.0" + trim-right "^1.0.1" + "@babel/generator@^7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.6.tgz#001303cf87a5b9d093494a4bf251d7b5d03d3999" @@ -637,7 +648,7 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/template@^7.1.0", "@babel/template@^7.1.2": +"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2": version "7.1.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" integrity sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag== @@ -670,6 +681,15 @@ lodash "^4.17.10" to-fast-properties "^2.0.0" +"@babel/types@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.0.tgz#7941c5b2d8060e06f9601d6be7c223eef906d5d8" + integrity sha512-b4v7dyfApuKDvmPb+O488UlGuR1WbwMXFsO/cyqMrnfvRAChZKJAYeeglWTjUO1b9UghKKgepAQM5tsvBJca6A== + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" + to-fast-properties "^2.0.0" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -1229,11 +1249,23 @@ apollo-utilities@1.0.26, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apoll dependencies: fast-json-stable-stringify "^2.0.0" +append-transform@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" + integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== + dependencies: + default-require-extensions "^2.0.0" + aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + are-we-there-yet@~1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" @@ -1279,6 +1311,11 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -1333,6 +1370,13 @@ async-retry@^1.2.1: dependencies: retry "0.12.0" +async@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== + dependencies: + lodash "^4.17.10" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1582,6 +1626,16 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +caching-transform@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-2.0.0.tgz#e1292bd92d35b6e8b1ed7075726724b3bd64eea0" + integrity sha512-tTfemGmFWe7KZ3KN6VsSgQZbd9Bgo7A40wlp4PTsJJvFu4YAnEC5YnfdiKq6Vh2i9XJLnA9n8OXD46orVpnPMw== + dependencies: + make-dir "^1.0.0" + md5-hex "^2.0.0" + package-hash "^2.0.0" + write-file-atomic "^2.0.0" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -1594,7 +1648,7 @@ callsites@^0.2.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= -camelcase@^4.0.0: +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= @@ -1791,6 +1845,11 @@ commander@^2.5.0, commander@^2.8.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1853,7 +1912,7 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.1.0: +convert-source-map@^1.1.0, convert-source-map@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== @@ -1921,6 +1980,14 @@ cross-fetch@2.2.2: node-fetch "2.1.2" whatwg-fetch "2.0.4" +cross-spawn@^4: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -1986,6 +2053,11 @@ date-fns@^2.0.0-alpha.24: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.25.tgz#651a5d1f59a01af6cf0371e39b2ae29df5d521ee" integrity sha512-iQzJkHF0L4wah9Ae9PkvwemwFz6qmRLuNZcghmvf2t+ptLs1qXzONLiGtjmPQzL6+JpC01JjlTopY2AEy4NFAg== +debug-log@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" + integrity sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8= + debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2014,7 +2086,7 @@ debug@^4.0.1, debug@^4.1.0: dependencies: ms "^2.1.1" -decamelize@^1.2.0: +decamelize@^1.1.1, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -2041,6 +2113,13 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +default-require-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" + integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= + dependencies: + strip-bom "^3.0.0" + define-properties@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -2265,6 +2344,11 @@ es-to-primitive@^1.1.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-error@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2669,6 +2753,15 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" +find-cache-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d" + integrity sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA== + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^3.0.0" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -2706,6 +2799,14 @@ for-in@^1.0.2: resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +foreground-child@^1.5.6: + version "1.5.6" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" + integrity sha1-T9ca0t/elnibmApcCilZN8svXOk= + dependencies: + cross-spawn "^4" + signal-exit "^3.0.0" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -2833,7 +2934,7 @@ glob@7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.5, glob@^7.1.2: +glob@^7.0.0, glob@^7.0.5, glob@^7.1.2, glob@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== @@ -3090,6 +3191,17 @@ growl@1.10.5: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== +handlebars@^4.0.11: + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" + integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== + dependencies: + async "^2.5.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -3368,6 +3480,11 @@ invariant@^2.2.2: dependencies: loose-envify "^1.0.0" +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + invert-kv@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" @@ -3640,6 +3757,58 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +istanbul-lib-coverage@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda" + integrity sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA== + +istanbul-lib-hook@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.1.tgz#918a57b75a0f951d552a08487ca1fa5336433d72" + integrity sha512-ufiZoiJ8CxY577JJWEeFuxXZoMqiKpq/RqZtOAYuQLvlkbJWscq9n3gc4xrCGH9n4pW0qnTxOz1oyMmVtk8E1w== + dependencies: + append-transform "^1.0.0" + +istanbul-lib-instrument@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz#b5f066b2a161f75788be17a9d556f40a0cf2afc9" + integrity sha512-eQY9vN9elYjdgN9Iv6NS/00bptm02EBBk70lRMaVjeA6QYocQgenVrSgC28TJurdnZa80AGO3ASdFN+w/njGiQ== + dependencies: + "@babel/generator" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + istanbul-lib-coverage "^2.0.1" + semver "^5.5.0" + +istanbul-lib-report@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.2.tgz#430a2598519113e1da7af274ba861bd42dd97535" + integrity sha512-rJ8uR3peeIrwAxoDEbK4dJ7cqqtxBisZKCuwkMtMv0xYzaAnsAi3AHrHPAAtNXzG/bcCgZZ3OJVqm1DTi9ap2Q== + dependencies: + istanbul-lib-coverage "^2.0.1" + make-dir "^1.3.0" + supports-color "^5.4.0" + +istanbul-lib-source-maps@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-2.0.1.tgz#ce8b45131d8293fdeaa732f4faf1852d13d0a97e" + integrity sha512-30l40ySg+gvBLcxTrLzR4Z2XTRj3HgRCA/p2rnbs/3OiTaoj054gAbuP5DcLOtwqmy4XW8qXBHzrmP2/bQ9i3A== + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^2.0.1" + make-dir "^1.3.0" + rimraf "^2.6.2" + source-map "^0.6.1" + +istanbul-reports@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.0.1.tgz#fb8d6ea850701a3984350b977a969e9a556116a7" + integrity sha512-CT0QgMBJqs6NJLF678ZHcquUAZIoBIUNzdJrRJfpkI9OnzG6MkUfHxbJC3ln981dMswC7/B1mfX3LNkhgJxsuw== + dependencies: + handlebars "^4.0.11" + iterall@^1.1.3, iterall@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" @@ -3814,6 +3983,13 @@ latest-version@^3.0.0: dependencies: package-json "^4.0.0" +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + lcid@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" @@ -3857,6 +4033,16 @@ 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" @@ -3888,6 +4074,11 @@ lodash.escaperegexp@^4.1.2: resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" integrity sha1-ZHYsSGGAglGKw99Mz11YhtriA0c= +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= + lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" @@ -3965,7 +4156,7 @@ lru-cache@^5.0.0: dependencies: yallist "^3.0.2" -make-dir@^1.0.0: +make-dir@^1.0.0, make-dir@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== @@ -3991,6 +4182,18 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +md5-hex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" + integrity sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM= + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + integrity sha1-givM1l4RfFFPqxdrJZRdVBAKA8M= + mdn-data@~1.1.0: version "1.1.4" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01" @@ -4001,6 +4204,13 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= + dependencies: + mimic-fn "^1.0.0" + mem@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" @@ -4015,6 +4225,13 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== + dependencies: + source-map "^0.6.1" + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -4078,6 +4295,11 @@ minimist@1.2.0, minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + minipass@^2.2.1, minipass@^2.3.4: version "2.3.5" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" @@ -4350,6 +4572,37 @@ numeral@^2.0.6: resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" integrity sha1-StCAk21EPCVhrtnyGX7//iX05QY= +nyc@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-13.1.0.tgz#463665c7ff6b5798e322624a5eb449a678db90e3" + integrity sha512-3GyY6TpQ58z9Frpv4GMExE1SV2tAgYqC7HSy2omEhNiCT3mhT9NyiOvIE8zkbuJVFzmvvNTnE4h/7/wQae7xLg== + dependencies: + archy "^1.0.0" + arrify "^1.0.1" + caching-transform "^2.0.0" + convert-source-map "^1.6.0" + debug-log "^1.0.1" + find-cache-dir "^2.0.0" + find-up "^3.0.0" + foreground-child "^1.5.6" + glob "^7.1.3" + istanbul-lib-coverage "^2.0.1" + istanbul-lib-hook "^2.0.1" + istanbul-lib-instrument "^3.0.0" + istanbul-lib-report "^2.0.2" + istanbul-lib-source-maps "^2.0.1" + istanbul-reports "^2.0.1" + make-dir "^1.3.0" + merge-source-map "^1.1.0" + resolve-from "^4.0.0" + rimraf "^2.6.2" + signal-exit "^3.0.2" + spawn-wrap "^1.4.2" + test-exclude "^5.0.0" + uuid "^3.3.2" + yargs "11.1.0" + yargs-parser "^9.0.2" + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -4454,6 +4707,14 @@ optimism@^0.6.6: dependencies: immutable-tuple "^0.4.9" +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" @@ -4466,11 +4727,20 @@ optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" -os-homedir@^1.0.0: +os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + os-locale@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" @@ -4555,6 +4825,16 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== +package-hash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-2.0.0.tgz#78ae326c89e05a4d813b68601977af05c00d2a0d" + integrity sha1-eK4ybIngWk2BO2hgGXevBcANKg0= + dependencies: + graceful-fs "^4.1.11" + lodash.flattendeep "^4.4.0" + md5-hex "^2.0.0" + release-zalgo "^1.0.0" + package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -4672,6 +4952,13 @@ 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" + pathval@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" @@ -4730,6 +5017,13 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" @@ -4893,6 +5187,14 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" @@ -4902,6 +5204,15 @@ 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" + read-pkg@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" @@ -5038,6 +5349,13 @@ regjsparser@^0.3.0: dependencies: jsesc "~0.5.0" +release-zalgo@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" + integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= + dependencies: + es6-error "^4.0.1" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -5102,6 +5420,11 @@ resolve-from@^1.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -5132,7 +5455,7 @@ retry@0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= -rimraf@^2.6.1, rimraf@~2.6.2: +rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== @@ -5382,7 +5705,7 @@ source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -5392,6 +5715,18 @@ spawn-command@^0.0.2-1: resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A= +spawn-wrap@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" + integrity sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg== + dependencies: + foreground-child "^1.5.6" + mkdirp "^0.5.0" + os-homedir "^1.0.1" + rimraf "^2.6.2" + signal-exit "^3.0.2" + which "^1.3.0" + spdx-correct@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" @@ -5571,7 +5906,7 @@ supports-color@^4.5.0: dependencies: has-flag "^2.0.0" -supports-color@^5.2.0, supports-color@^5.3.0: +supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -5613,6 +5948,16 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" +test-exclude@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.0.0.tgz#cdce7cece785e0e829cd5c2b27baf18bc583cfb7" + integrity sha512-bO3Lj5+qFa9YLfYW2ZcXMOV1pmQvw+KS/DpjqhyX6Y6UZ8zstpZJ+mA2ERkXfpOqhxsJlQiLeVXD3Smsrs6oLw== + dependencies: + arrify "^1.0.1" + minimatch "^3.0.4" + read-pkg-up "^4.0.0" + require-main-filename "^1.0.1" + text-encoding@^0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" @@ -5753,6 +6098,14 @@ type-is@^1.6.16, type-is@~1.6.16: media-typer "0.3.0" mime-types "~2.1.18" +uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + undefsafe@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76" @@ -5954,7 +6307,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.9: +which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -5975,6 +6328,11 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -6046,6 +6404,11 @@ xtend@^4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + "y18n@^3.2.1 || ^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" @@ -6069,6 +6432,31 @@ yargs-parser@^11.1.1: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= + dependencies: + camelcase "^4.1.0" + +yargs@11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" + integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A== + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^9.0.2" + yargs@^12.0.1: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" From e22f950c4809818e1b6aceaf3b6d438ac3620a70 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 7 Dec 2018 20:27:29 +0100 Subject: [PATCH 135/554] use mocha from bin --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 634cb501c..70a509de0 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "scripts": { "ci": "yarn run lint && yarn run test && yarn run test:coverage", "lint": "eslint src --config .eslintrc.js", - "test": "nyc --reporter=text-lcov mocha --require @babel/register src/**/*.test.js", + "test": "nyc --reporter=text-lcov ./node_modules/.bin/mocha --require @babel/register src/**/*.test.js", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", From 034fea3f4702a37f3b96a50efad875560ee503c7 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 7 Dec 2018 20:30:40 +0100 Subject: [PATCH 136/554] fixing console log issues --- src/index.js | 1 + src/seed/data/index.js | 2 ++ src/seed/reset-db.js | 2 ++ src/server.js | 5 ++++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 4b09f5f65..fee7b06dd 100644 --- a/src/index.js +++ b/src/index.js @@ -9,5 +9,6 @@ const serverConfig = { } server.start(serverConfig, options => { + /* eslint-disable-next-line no-console */ console.log(`Server ready at ${process.env.GRAPHQL_URI} 🚀`) }) diff --git a/src/seed/data/index.js b/src/seed/data/index.js index 3692bec25..e66342fe3 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -31,8 +31,10 @@ export default async function (client) { }) data[key] = Object.assign(data[key] || {}, res.data) } catch (err) { + /* eslint-disable-next-line no-console */ console.error(err) } }) + /* eslint-disable-next-line no-console */ console.log('Seeded Data', data) } diff --git a/src/seed/reset-db.js b/src/seed/reset-db.js index e1336dc4b..616ff71e8 100644 --- a/src/seed/reset-db.js +++ b/src/seed/reset-db.js @@ -12,8 +12,10 @@ const driver = neo4j().getDriver() const session = driver.session() query('MATCH (n) DETACH DELETE n', session).then(() => { + /* eslint-disable-next-line no-console */ console.log('Successfully deleted all nodes and relations!') }).catch((err) => { + /* eslint-disable-next-line no-console */ console.log(`Error occurred deleting the nodes and relations (reset the db)\n\n${err}`) }).finally(() => { if (session) { diff --git a/src/server.js b/src/server.js index ee5fe66f2..bf3e07248 100644 --- a/src/server.js +++ b/src/server.js @@ -23,6 +23,7 @@ let schema = makeExecutableSchema({ const driver = neo4j().getDriver() const MOCK = (process.env.MOCK === 'true') +/* eslint-disable-next-line no-console */ console.log('MOCK:', MOCK) schema = augmentSchema(schema, { @@ -45,7 +46,9 @@ const server = new GraphQLServer({ try { const token = payload.req.headers.authorization.replace('Bearer ', '') payload.user = await jwt.verify(token, process.env.JWT_SECRET) - } catch (err) {} + } catch (err) { + // nothing + } return payload }, From 0ca5b0923a732b68f896df5d9428f517519c85bd Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 7 Dec 2018 20:30:50 +0100 Subject: [PATCH 137/554] ignoring .nyc_output --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b880d50ef..50ab0c8a4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ node_modules/ .vscode yarn-error.log coverage.lcov -.nyc-output/ +.nyc_output/ From ceca6477b2a3ba8f986ae7ee44daf302dbdd32a5 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 7 Dec 2018 20:42:37 +0100 Subject: [PATCH 138/554] added graphql 0.13.0 as its a needed peer dependency --- package.json | 83 +++++----- yarn.lock | 428 ++++++++++++++++++++++++--------------------------- 2 files changed, 244 insertions(+), 267 deletions(-) diff --git a/package.json b/package.json index ab4323234..3cc3f6816 100644 --- a/package.json +++ b/package.json @@ -13,56 +13,57 @@ "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "db:script:seed": "wait-on tcp:4001 && $npm_package_config_no_auth ./node_modules/.bin/babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && $npm_package_config_no_auth ./node_modules/.bin/babel-node src/seed/reset-db.js", - "db:seed": "concurrently --kill-others --success first -n no-auth-server,seed '$npm_package_config_no_auth yarn run start' 'yarn run db:script:seed'", + "db:seed": "concurrently --kill-others --success first -n no-auth-server,seed '$npm_package_config_no_auth yarn run start' 'yarn run db:script:seed'", "db:reset": "concurrently --kill-others --success first -n no-auth-server,reset '$npm_package_config_no_auth yarn run start' 'yarn run db:script:reset'" }, "author": "Human Connection gGmbH", "license": "MIT", "dependencies": { - "@babel/cli": "^7.1.5", - "@babel/core": "^7.1.6", - "@babel/node": "^7.0.0", - "@babel/preset-env": "^7.1.6", - "@babel/register": "^7.0.0", - "apollo-cache-inmemory": "^1.2.5", - "apollo-client": "^2.3.2", - "apollo-link-http": "^1.5.4", - "apollo-server": "^2.0.4", - "bcryptjs": "^2.4.3", - "cheerio": "^1.0.0-rc.2", - "date-fns": "^2.0.0-alpha.24", - "dotenv": "^6.2.0", - "graphql-custom-directives": "^0.2.13", - "graphql-iso-date": "^3.6.1", + "@babel/cli": "~7.1.5", + "@babel/core": "~7.1.6", + "@babel/node": "~7.0.0", + "@babel/preset-env": "~7.1.6", + "@babel/register": "~7.0.0", + "apollo-cache-inmemory": "~1.2.5", + "apollo-client": "~2.3.2", + "apollo-link-http": "~1.5.4", + "apollo-server": "~2.0.4", + "bcryptjs": "~2.4.3", + "cheerio": "~1.0.0-rc.2", + "date-fns": "~2.0.0-alpha.24", + "dotenv": "~6.2.0", + "graphql": "~0.13.0", + "graphql-custom-directives": "~0.2.13", + "graphql-iso-date": "~3.6.1", "graphql-middleware": "1.7.6", - "graphql-shield": "^4.0.1", - "graphql-tag": "^2.9.2", + "graphql-shield": "~4.0.1", + "graphql-tag": "~2.9.2", "graphql-yoga": "1.16.2", - "jsonwebtoken": "^8.3.0", - "linkifyjs": "^2.1.7", - "lodash": "^4.17.11", - "ms": "^2.1.1", - "neo4j-driver": "^1.6.1", + "jsonwebtoken": "~8.3.0", + "linkifyjs": "~2.1.7", + "lodash": "~4.17.11", + "ms": "~2.1.1", + "neo4j-driver": "~1.6.1", "neo4j-graphql-js": "2.0.1", - "node-fetch": "^2.1.2", - "passport": "^0.4.0", - "passport-jwt": "^4.0.0", - "sanitize-html": "^1.19.3", - "slug": "^0.9.1", - "trunc-html": "^1.1.2" + "node-fetch": "~2.1.2", + "passport": "~0.4.0", + "passport-jwt": "~4.0.0", + "sanitize-html": "~1.19.3", + "slug": "~0.9.1", + "trunc-html": "~1.1.2" }, "devDependencies": { - "babel-eslint": "^10.0.1", - "concurrently": "^4.1.0", - "cross-env": "^5.2.0", - "eslint": "^5.9.0", - "eslint-config-standard": "^12.0.0", - "eslint-plugin-import": "^2.14.0", - "eslint-plugin-node": "^8.0.0", - "eslint-plugin-promise": "^4.0.1", - "eslint-plugin-standard": "^4.0.0", - "faker": "^4.1.0", - "nodemon": "^1.18.7", - "wait-on": "^3.2.0" + "babel-eslint": "~10.0.1", + "concurrently": "~4.1.0", + "cross-env": "~5.2.0", + "eslint": "~5.9.0", + "eslint-config-standard": "~12.0.0", + "eslint-plugin-import": "~2.14.0", + "eslint-plugin-node": "~8.0.0", + "eslint-plugin-promise": "~4.0.1", + "eslint-plugin-standard": "~4.0.0", + "faker": "~4.1.0", + "nodemon": "~1.18.7", + "wait-on": "~3.2.0" } } diff --git a/yarn.lock b/yarn.lock index 5a90f6d74..0559fb6df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,13 +2,6 @@ # yarn lockfile v1 -"@apollographql/apollo-tools@^0.2.6": - version "0.2.8" - resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.2.8.tgz#f755baa3576eabdd93afa2782be61f5ae8a856dc" - integrity sha512-A7FTUigtpGCFBaLT1ILicdjM6pZ7LQNw7Vgos0t4aLYtvlKO/L1nMi/NO7bPypzZaJSToTgcxHJPRydP1Md+Kw== - dependencies: - apollo-env "0.2.5" - "@apollographql/apollo-upload-server@^5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" @@ -18,12 +11,12 @@ busboy "^0.2.14" object-path "^0.11.4" -"@apollographql/graphql-playground-html@^1.6.6": +"@apollographql/graphql-playground-html@^1.6.0": version "1.6.6" resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz#022209e28a2b547dcde15b219f0c50f47aa5beb3" integrity sha512-lqK94b+caNtmKFs5oUVXlSpN3sm5IXZ+KfhMxOtr0LR2SqErzkoJilitjDvJ1WbjHlxLI7WtCjRmOLdOGJqtMQ== -"@babel/cli@^7.1.5": +"@babel/cli@~7.1.5": version "7.1.5" resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.1.5.tgz#4ccf0a8cdabeefdd8ce955384530f050935bc4d7" integrity sha512-zbO/DtTnaDappBflIU3zYEgATLToRDmW5uN/EGH1GXaes7ydfjqmAoK++xmJIA+8HfDw7UyPZNdM8fhGhfmMhw== @@ -47,7 +40,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.1.6": +"@babel/core@~7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.6.tgz#3733cbee4317429bc87c62b29cf8587dba7baeb3" integrity sha512-Hz6PJT6e44iUNpAn8AoyAs6B3bl60g7MJQaI0rZEar6ECzh6+srYO1xlIdssio34mPaUtAb1y+XlkkSJzok3yw== @@ -251,7 +244,7 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/node@^7.0.0": +"@babel/node@~7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.0.0.tgz#20e55bb0e015700a0f6ff281c712de7619ad56f4" integrity sha512-mKbN8Bb1TzH9YnKMWMhBRX+o5MVJHtUSalNcsiGa4FRgVfY7ozqkbttuIDWqeXxZ3rwI9ZqmCUr9XsPV2VYlSw== @@ -562,7 +555,7 @@ core-js "^2.5.7" regenerator-runtime "^0.11.1" -"@babel/preset-env@^7.1.6": +"@babel/preset-env@~7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.1.6.tgz#a0bf4b96b6bfcf6e000afc5b72b4abe7cc13ae97" integrity sha512-YIBfpJNQMBkb6MCkjz/A9J76SNCSuGVamOVBgoUkLzpJD/z8ghHi9I42LQ4pulVX68N/MmImz6ZTixt7Azgexw== @@ -609,7 +602,7 @@ js-levenshtein "^1.1.3" semver "^5.3.0" -"@babel/register@^7.0.0": +"@babel/register@^7.0.0", "@babel/register@~7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.0.0.tgz#fa634bae1bfa429f60615b754fc1f1d745edd827" integrity sha512-f/+CRmaCe7rVEvcvPvxeA8j5aJhHC3aJie7YuqcMDhUOuyWLA7J/aNrTaHIzoWPEhpHA54mec4Mm8fv8KBlv3g== @@ -730,10 +723,10 @@ dependencies: "@types/node" "*" -"@types/async@2.0.50": - version "2.0.50" - resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.50.tgz#117540e026d64e1846093abbd5adc7e27fda7bcb" - integrity sha512-VMhZMMQgV1zsR+lX/0IBfAk+8Eb7dPVMWiQGFAt3qjo5x7Ml6b77jUo0e1C3ToD+XRDXqtrfw+6AB0uUsPEr3Q== +"@types/async@2.0.49": + version "2.0.49" + resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0" + integrity sha512-Benr3i5odUkvpFkOpzGqrltGdbSs+EVCkEBGXbuR7uT0VzhXKIkhem6PDzHdx5EonA+rfbB3QvP6aDOw5+zp5Q== "@types/body-parser@*", "@types/body-parser@1.17.0": version "1.17.0" @@ -818,10 +811,10 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" -"@types/ws@^6.0.0": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28" - integrity sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q== +"@types/ws@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-5.1.2.tgz#f02d3b1cd46db7686734f3ce83bdf46c49decd64" + integrity sha512-NkTXUKTYdXdnPE2aUUbGOXE1XfMK527SCvU/9bj86kyFF6kZ9ZnOQ3mK5jADn98Y2vEUD/7wKDgZa7Qst2wYOg== dependencies: "@types/events" "*" "@types/node" "*" @@ -931,13 +924,13 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -apollo-cache-control@0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.3.tgz#ad71d8f786e06f0275b2432004c15c2d37c48484" - integrity sha512-X6JhKfIaMLfl2jpsK/880BflXA+2lmm2sAsOZL4Bn2VrMsDtOssI1Ij9vNRbch9k9cA4WJvKed7Sql/wUIa1Eg== +apollo-cache-control@0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.2.4.tgz#af32b27cde9c86bda8e1ff2db3ab14951c26f92c" + integrity sha512-Duswm5utdKGaRPuGtUSe7+gjQPYdb9VscLmEFRWYcfyrNBF5tYtycliY3wOSF0zEUE1CersSAwBEWFTTiD50ug== dependencies: - apollo-server-env "2.2.0" - graphql-extensions "0.3.3" + apollo-server-env "2.0.3" + graphql-extensions "0.2.0" apollo-cache-control@^0.1.0: version "0.1.1" @@ -946,71 +939,63 @@ apollo-cache-control@^0.1.0: dependencies: graphql-extensions "^0.0.x" -apollo-cache-inmemory@^1.2.5: - version "1.3.11" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.11.tgz#6cb8f24ec812715169f9acbb0b67833f9a19ec90" - integrity sha512-fSoyjBV5RV57J3i/VHDDB74ZgXc0PFiogheNFHEhC0mL6rg5e/DjTx0Vg+csIBk23gvlzTvV+eypx7Q2NJ+dYg== +apollo-cache-inmemory@~1.2.5: + version "1.2.10" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.2.10.tgz#362d6c36cfd815a309b966f71e5d2b6c770c7989" + integrity sha512-eBusPFVtYIuo+PIfJdAwUCQ4cs7AJ4mB7sTdXxNQCXToYw8mzE6EfHnV37kdVfBXSaa82BzE2rb/YUq/duuamw== dependencies: - apollo-cache "^1.1.21" - apollo-utilities "^1.0.26" - optimism "^0.6.6" + apollo-cache "^1.1.17" + apollo-utilities "^1.0.21" + graphql-anywhere "^4.1.19" -apollo-cache@1.1.21, apollo-cache@^1.1.21: +apollo-cache@^1.1.14, apollo-cache@^1.1.17: version "1.1.21" resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.21.tgz#950025e2272741ba8e5064419906e3ac4072925d" integrity sha512-5ErNb78KHtrJNimkDBTEigcvHkIqUmS7QJIk4lpZZ+XLVVgvk2fD+GhD1PLP+s8vHfAKVbO6vdbRxCCjGGrh5w== dependencies: apollo-utilities "^1.0.26" -apollo-client@^2.3.2: - version "2.4.7" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.7.tgz#b6712fd4c9ba346e3c44cfec7e6868e532b6a957" - integrity sha512-6aAm+16AFBYZhJF8eKxrup6AbYni01InDiwTfZhMMTP2xaXQWjsQnfaHbI2oE+hd3+AZFy1drkse8RZKghR/WQ== +apollo-client@~2.3.2: + version "2.3.8" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.3.8.tgz#0384a7210eb601ab88b1c13750da076fc9255b95" + integrity sha512-X5wsBD1be1P/mScGsH5H+2hIE8d78WAfqOvFvBpP+C+jzJ9387uHLyFmYYMLRRqDQ3ihjI4iSID7KEOW2gyCcQ== dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.21" + apollo-cache "^1.1.14" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "1.0.26" + apollo-utilities "^1.0.18" symbol-observable "^1.0.2" zen-observable "^0.8.0" optionalDependencies: - "@types/async" "2.0.50" + "@types/async" "2.0.49" -apollo-datasource@0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.2.1.tgz#3ecef4efe64f7a04a43862f32027d38ac09e142c" - integrity sha512-r185+JTa5KuF1INeTAk7AEP76zwMN6c8Ph1lmpzJMNwBUEzTGnLClrccCskCBx4SxfnkdKbuQdwn9JwCJUWrdg== +apollo-datasource@0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.1.3.tgz#e7ae9d20f29a8a35f239b02f0c47169cfd78d70b" + integrity sha512-yEGEe5Cjzqqu5ml1VV3O8+C+thzdknZri9Ny0P3daTGNO+45J3vBOMcmaANeeI2+OOeWxdqUNa5aPOx/35kniw== dependencies: - apollo-server-caching "0.2.1" - apollo-server-env "2.2.0" + apollo-server-caching "0.1.2" + apollo-server-env "2.0.3" -apollo-engine-reporting-protobuf@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.1.0.tgz#fbc220cac2a3b7800ffc155d7e54c21c56b7848e" - integrity sha512-GReJtAYTmpwg0drb9VgFtqObYYTCHkJhlHEYCeXY8bJV4fOgXsAZ7CIXR9nPKO0mBaoHIHaGYvXGcyCLrZ36VA== +apollo-engine-reporting-protobuf@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz#cd394f0f769c6f97d8621c4a7839095c84efcdb0" + integrity sha512-AySoDgog2p1Nph44FyyqaU4AfRZOXx8XZxRsVHvYY4dHlrMmDDhhjfF3Jswa7Wr8X/ivvx3xA0jimRn6rsG8Ew== dependencies: protobufjs "^6.8.6" -apollo-engine-reporting@0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.3.tgz#85ad6ffd71db8f877202ce8b3d7dbfa7cabfbcf9" - integrity sha512-VkjiifHMHIAxydXecT+ck0WtqpFIsMlylKnKeuNAXfIfAXHX/JYtLhbArTTyhDunLrphMiUewfFv9P0K+aX2jw== +apollo-engine-reporting@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.0.5.tgz#2a52313e3df98a056294672fe7ad2a107ef54c15" + integrity sha512-543LtBSnekZWz9y9GHsXdBoIFmZKyXYlQeeRB9CAIbOUcDl8HQaWYRr/H91wvVqG1OgUhi2g6BVzNHXj17akVA== dependencies: - apollo-engine-reporting-protobuf "0.1.0" - apollo-server-env "2.2.0" + apollo-engine-reporting-protobuf "0.0.1" + apollo-server-env "2.0.3" async-retry "^1.2.1" - graphql-extensions "0.3.3" + graphql-extensions "0.2.0" lodash "^4.17.10" -apollo-env@0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.2.5.tgz#162c785bccd2aea69350a7600fab4b7147fc9da5" - integrity sha512-Gc7TEbwCl7jJVutnn8TWfzNSkrrqyoo0DP92BQJFU9pZbJhpidoXf2Sw1YwOJl82rRKH3ujM3C8vdZLOgpFcFA== - dependencies: - core-js "^3.0.0-beta.3" - node-fetch "^2.2.0" - apollo-link-dedup@^1.0.0: version "1.0.11" resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.11.tgz#6f34ea748d2834850329ad03111ef18445232b05" @@ -1025,7 +1010,7 @@ apollo-link-http-common@^0.2.6: dependencies: apollo-link "^1.2.4" -apollo-link-http@^1.5.4: +apollo-link-http@~1.5.4: version "1.5.7" resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.7.tgz#098615c427a910ec8c5817476bbabe68c586b339" integrity sha512-EZ9nynHjwYCpGYP5IsRrZGTWidUVpshk7MuSG4joqGtJMwpFCgMQz+y3BHdUhowHtfAd9z60XmeOTG9FJolb8A== @@ -1049,38 +1034,35 @@ apollo-link@^1.2.2: apollo-utilities "^1.0.0" zen-observable-ts "^0.8.10" -apollo-server-caching@0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.2.1.tgz#7e67f8c8cac829e622b394f0fb82579cabbeadfd" - integrity sha512-+U9F3X297LL8Gqy6ypfDNEv/DfV/tDht9Dr2z3AMaEkNW1bwO6rmdDL01zYxDuVDVq6Z3qSiNCSO2pXE2F0zmA== +apollo-server-caching@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.1.2.tgz#f5b85701945110a5fca1956450e8553576635936" + integrity sha512-jBRnsTgXN0m8yVpumoelaUq9mXR7YpJ3EE+y/alI7zgXY+0qFDqksRApU8dEfg3q6qUnO7rFxRhdG5eyc0+1ig== dependencies: - lru-cache "^5.0.0" + lru-cache "^4.1.3" -apollo-server-core@2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.5.tgz#bf1538c10213be38a37dd8e6461461f7b808c57e" - integrity sha512-obz6VSJI7vSR+pEAZFwqOe/HAOuF4l1fYU9WNtVcQvxaKhykDgcu+byO0sXrOf/iB7uUIyaFdhinwzuwkqB8XQ== +apollo-server-core@2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.0.7.tgz#ccde1dcb6bf00e915f1cb2b3e15a664f8825f9d3" + integrity sha512-1DLxAcYbBjYCpKbWVxYOihQrVsi+lJQdKgHSRtuvzx8ep5B6k6nHxhsoee2GzIfk7b2NY0R7zQBqamC+aooT9w== dependencies: - "@apollographql/apollo-tools" "^0.2.6" "@apollographql/apollo-upload-server" "^5.0.3" - "@apollographql/graphql-playground-html" "^1.6.6" - "@types/ws" "^6.0.0" - apollo-cache-control "0.3.3" - apollo-datasource "0.2.1" - apollo-engine-reporting "0.1.3" - apollo-server-caching "0.2.1" - apollo-server-env "2.2.0" - apollo-server-errors "2.2.0" - apollo-server-plugin-base "0.1.5" - apollo-tracing "0.3.3" - graphql-extensions "0.3.5" - graphql-subscriptions "^1.0.0" + "@types/ws" "^5.1.2" + apollo-cache-control "0.2.4" + apollo-datasource "0.1.3" + apollo-engine-reporting "0.0.5" + apollo-server-caching "0.1.2" + apollo-server-env "2.0.3" + apollo-server-errors "2.0.2" + apollo-tracing "0.2.4" + graphql-extensions "0.2.0" + graphql-subscriptions "^0.5.8" graphql-tag "^2.9.2" - graphql-tools "^4.0.0" - json-stable-stringify "^1.0.1" + graphql-tools "^3.0.4" + hash.js "^1.1.3" lodash "^4.17.10" subscriptions-transport-ws "^0.9.11" - ws "^6.0.0" + ws "^5.2.0" apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: version "1.4.0" @@ -1091,36 +1073,36 @@ apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: apollo-tracing "^0.1.0" graphql-extensions "^0.0.x" -apollo-server-env@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.2.0.tgz#5eec5dbf46581f663fd6692b2e05c7e8ae6d6034" - integrity sha512-wjJiI5nQWPBpNmpiLP389Ezpstp71szS6DHAeTgYLb/ulCw3CTuuA+0/E1bsThVWiQaDeHZE0sE3yI8q2zrYiA== +apollo-server-env@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.0.3.tgz#3c13552cd33f400160076cf8e1c9b24be4d27e13" + integrity sha512-uIfKFH8n8xKO0eLb9Fa79+s2DdMuVethgznvW6SrOYq5VzgkIIobqKEuZPKa5wObw9CkCyju/+Sr7b7WWMFxUQ== dependencies: node-fetch "^2.1.2" util.promisify "^1.0.0" -apollo-server-errors@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" - integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== +apollo-server-errors@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz#e9cbb1b74d2cd78aed23cd886ca2d0c186323b2b" + integrity sha512-zyWDqAVDCkj9espVsoUpZr9PwDznM8UW6fBfhV+i1br//s2AQb07N6ektZ9pRIEvkhykDZW+8tQbDwAO0vUROg== -apollo-server-express@2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.2.5.tgz#9d27d68b3b1cf2f96a107a3091ecdea4012745a2" - integrity sha512-2SNlY8CNmYlbRJfn0iK4wesjqX3X9YIFhyok4sQ80n/gm24QMwZkFcPP+NLv+1lxvwyJYMwEFQPIBvkLRoUFXQ== +apollo-server-express@2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.0.7.tgz#ed8840525c90eef2612e600976aaabfa86a86c9c" + integrity sha512-zzG0pkomT+aZEHztvU79Duk+aTOvUBprSN9teSCnqP1GAgSyLi52L4i0ttY4PSSGsbgkwwsa8GkOhH51c45K7g== dependencies: "@apollographql/apollo-upload-server" "^5.0.3" - "@apollographql/graphql-playground-html" "^1.6.6" + "@apollographql/graphql-playground-html" "^1.6.0" "@types/accepts" "^1.3.5" "@types/body-parser" "1.17.0" "@types/cors" "^2.8.4" "@types/express" "4.16.0" accepts "^1.3.5" - apollo-server-core "2.2.5" + apollo-server-core "2.0.7" body-parser "^1.18.3" cors "^2.8.4" - graphql-subscriptions "^1.0.0" - graphql-tools "^4.0.0" + graphql-subscriptions "^0.5.8" + graphql-tools "^3.0.4" type-is "^1.6.16" apollo-server-express@^1.3.6: @@ -1144,29 +1126,24 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== -apollo-server-plugin-base@0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.5.tgz#899c4d7bc0d9a6d9f1181cc83a791479409086f8" - integrity sha512-be77TaN9l16ZVG1tBl8Re3lJfUZ6B2T3DdEXnu6fjQwUuBdu3Y4MQR6B1TLhbuTb9DUkcSKZ3h5C55dIjvb2Vg== - -apollo-server@^2.0.4: - version "2.2.5" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.2.5.tgz#412cf92a12939aac3890d4f0094a45dadfb89c79" - integrity sha512-Qf0FODtXzMJHhr6W8+NPu3ftxlL93o5s+aW9A35NZ305FuwgyriaQztaWILC+i4S/OxMTvuoCjNm9V+iVKackg== +apollo-server@~2.0.4: + version "2.0.8" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.0.8.tgz#7012598c1f4a8126aba41614cfc0a05a736e9b45" + integrity sha512-6Q9wKobpDXMHzALZuCaRq7JyxZ7P1Jj3C6qaecx/ThZpxmdvj03qakGnk4AZx7G/VrYYxiUZZaXcgltLD7QidQ== dependencies: - apollo-server-core "2.2.5" - apollo-server-express "2.2.5" + apollo-server-core "2.0.7" + apollo-server-express "2.0.7" express "^4.0.0" - graphql-subscriptions "^1.0.0" - graphql-tools "^4.0.0" + graphql-subscriptions "^0.5.8" + graphql-tools "^3.0.4" -apollo-tracing@0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.3.tgz#b819942180480c1c4d89e613cf2eff8f6d8b595a" - integrity sha512-gsTYgDVjtMlnomPq46aky7yk8XshCQfj9rxalCCismLlMomVW44fq+8GKQnZIkFOwiAsazRy4dzZ0cBbygA9sA== +apollo-tracing@0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.2.4.tgz#5749fc4f4f0230e541606a9314314c5f341c1133" + integrity sha512-wfIgDpkRWDpSoQpuDN640cq3Gr3mY17EE4YvJ48H+onranz6bDMDSbGxNU5LA3Hv09erOEDmx72MkgipLxSYOA== dependencies: - apollo-server-env "2.2.0" - graphql-extensions "0.3.3" + apollo-server-env "2.0.3" + graphql-extensions "0.2.0" apollo-tracing@^0.1.0: version "0.1.4" @@ -1184,7 +1161,7 @@ apollo-upload-server@^5.0.0: busboy "^0.2.14" object-path "^0.11.4" -apollo-utilities@1.0.26, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.26: +apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.18, apollo-utilities@^1.0.21, apollo-utilities@^1.0.26: version "1.0.26" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.26.tgz#589c66bf4d16223531351cf667a230c787def1da" integrity sha512-URw7o3phymliqYCYatcird2YRPUU2eWCNvip64U9gQrX56mEfK4m99yBIDCMTpmcvOFsKLii1sIEZsHIs/bvnw== @@ -1334,7 +1311,7 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== -babel-eslint@^10.0.1: +babel-eslint@~10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed" integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ== @@ -1355,7 +1332,7 @@ babel-polyfill@6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-runtime@^6.22.0, babel-runtime@^6.26.0: +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= @@ -1398,7 +1375,7 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bcryptjs@^2.4.3: +bcryptjs@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= @@ -1601,7 +1578,7 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -cheerio@^1.0.0-rc.2: +cheerio@~1.0.0-rc.2: version "1.0.0-rc.2" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" integrity sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs= @@ -1736,7 +1713,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concurrently@^4.1.0: +concurrently@~4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-4.1.0.tgz#17fdf067da71210685d9ea554423ef239da30d33" integrity sha512-pwzXCE7qtOB346LyO9eFWpkFJVO3JQZ/qU/feGeaAHiX1M3Rw3zgXKc5cZ8vSH5DGygkjzLFDzA/pwoQDkRNGg== @@ -1810,11 +1787,6 @@ core-js@^2.4.0, core-js@^2.5.3, core-js@^2.5.7: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== -core-js@^3.0.0-beta.3: - version "3.0.0-beta.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.3.tgz#b0f22009972b8c6c04550ebf38513ca4b3cc9559" - integrity sha512-kM/OfrnMThP5PwGAj5HhQLdjUqzjrllqN2EVnk/X9qrLsfYjR2hzZ+E/8CzH0xuosexZtqMTLQrk//BULrBj9w== - core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1835,7 +1807,7 @@ create-error-class@^3.0.0: dependencies: capture-stack-trace "^1.0.0" -cross-env@^5.2.0: +cross-env@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2" integrity sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg== @@ -1903,7 +1875,7 @@ date-fns@^1.23.0: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" integrity sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw== -date-fns@^2.0.0-alpha.24: +date-fns@~2.0.0-alpha.24: version "2.0.0-alpha.25" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.25.tgz#651a5d1f59a01af6cf0371e39b2ae29df5d521ee" integrity sha512-iQzJkHF0L4wah9Ae9PkvwemwFz6qmRLuNZcghmvf2t+ptLs1qXzONLiGtjmPQzL6+JpC01JjlTopY2AEy4NFAg== @@ -2089,7 +2061,7 @@ dotenv@^0.4.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" integrity sha1-9vs1E2PC2SIHJFxzeALJq1rhSVo= -dotenv@^6.2.0: +dotenv@~6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w== @@ -2178,7 +2150,7 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -eslint-config-standard@^12.0.0: +eslint-config-standard@~12.0.0: version "12.0.0" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9" integrity sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ== @@ -2207,7 +2179,7 @@ eslint-plugin-es@^1.3.1: eslint-utils "^1.3.0" regexpp "^2.0.1" -eslint-plugin-import@^2.14.0: +eslint-plugin-import@~2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== @@ -2223,7 +2195,7 @@ eslint-plugin-import@^2.14.0: read-pkg-up "^2.0.0" resolve "^1.6.0" -eslint-plugin-node@^8.0.0: +eslint-plugin-node@~8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.0.tgz#fb9e8911f4543514f154bb6a5924b599aa645568" integrity sha512-Y+ln8iQ52scz9+rSPnSWRaAxeWaoJZ4wIveDR0vLHkuSZGe44Vk1J4HX7WvEP5Cm+iXPE8ixo7OM7gAO3/OKpQ== @@ -2235,12 +2207,12 @@ eslint-plugin-node@^8.0.0: resolve "^1.8.1" semver "^5.5.0" -eslint-plugin-promise@^4.0.1: +eslint-plugin-promise@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg== -eslint-plugin-standard@^4.0.0: +eslint-plugin-standard@~4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz#f845b45109c99cd90e77796940a344546c8f6b5c" integrity sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA== @@ -2271,7 +2243,7 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@^5.9.0: +eslint@~5.9.0: version "5.9.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" integrity sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w== @@ -2505,7 +2477,7 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= -faker@^4.1.0: +faker@~4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" integrity sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8= @@ -2765,6 +2737,13 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== +graphql-anywhere@^4.1.19: + version "4.1.23" + resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.23.tgz#4275b161432b7c60a36970a1d9840d8c5cc2516e" + integrity sha512-8wtmwxWmLzAy52Z4WAw9UiYZ4ViiNXM+2DMOSlg2F7WsVstD0v75uOjCLJQUvbld5kHrgzTxter/THFVkGL+Yw== + dependencies: + apollo-utilities "^1.0.26" + graphql-config@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-2.0.0.tgz#daf69091055c6f675d63893a2d14c48f3fec3327" @@ -2776,7 +2755,7 @@ graphql-config@2.0.0: lodash "^4.17.4" minimatch "^3.0.4" -graphql-custom-directives@^0.2.13: +graphql-custom-directives@~0.2.13: 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== @@ -2791,19 +2770,12 @@ graphql-deduplicator@^2.0.1: resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3" integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA== -graphql-extensions@0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.3.tgz#277efe11976bbdfd59915551606a2d550247bb45" - integrity sha512-pudOaHq7Ok+rh1ElzlqFaoYZWGefUNsqn/jX6eKns7rl0VHuB4qZBfhpVLTpquJpM6Y19/hsCYZNPfnUVMFIiA== +graphql-extensions@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.2.0.tgz#39baaf43a98de07378843317ce110592e6fcc943" + integrity sha512-dW2PdomN+IXzUDQALzpBk++sEXm2LamCP16hCOZ2B/go50I967R7/K+rr8qOxoNb7lvtLW1BjQg8kRoPqByrug== dependencies: - "@apollographql/apollo-tools" "^0.2.6" - -graphql-extensions@0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.5.tgz#95b742185d0016a9d65385a7a9e10753eadf0537" - integrity sha512-jpWSUIr27iOTR5JYu+dEMz74oZhOj8Xy+6lNopluiIu+ObEVSHW0czb2Jlcy3rOSTEPcibnpStO4F4/64IBqeQ== - dependencies: - "@apollographql/apollo-tools" "^0.2.6" + apollo-server-env "2.0.3" graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: version "0.0.10" @@ -2827,7 +2799,7 @@ graphql-import@^0.6.0: dependencies: lodash "^4.17.4" -graphql-iso-date@^3.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== @@ -2881,10 +2853,10 @@ graphql-request@^1.4.0: dependencies: cross-fetch "2.2.2" -graphql-shield@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.1.0.tgz#8bd55179fd28d00e64ca5a7dbd3cffe82e282e73" - integrity sha512-r3m5t7FpLDyJQIby0IKyNrtp8k62hP/syhPcrpdT67UVNKh0jjjl+zpjXh/3PXeNZHPEAiBQTHhFjnC7H2B4SA== +graphql-shield@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.0.1.tgz#731fca9a69a540ff446edf9e5bec610da295f5cb" + integrity sha512-JLKf1Le0NFZzSSEzBMbl+mbGBsydHejYtTZ7RO5Ks/+HYXxdkBbBs4Cc/R7zAY9UW5lgpJzVNyC02NXBL34/Sw== dependencies: object-hash "^1.3.0" opencollective "1.0.3" @@ -2896,19 +2868,17 @@ graphql-subscriptions@^0.5.8: dependencies: iterall "^1.2.1" -graphql-subscriptions@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-1.0.0.tgz#475267694b3bd465af6477dbab4263a3f62702b8" - integrity sha512-+ytmryoHF1LVf58NKEaNPRUzYyXplm120ntxfPcgOBC7TnK7Tv/4VRHeh4FAR9iL+O1bqhZs4nkibxQ+OA5cDQ== - dependencies: - iterall "^1.2.1" - graphql-tag@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w== -graphql-tools@^3.0.0, graphql-tools@^3.0.5: +graphql-tag@~2.9.2: + version "2.9.2" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.9.2.tgz#2f60a5a981375f430bf1e6e95992427dc18af686" + integrity sha512-qnNmof9pAqj/LUzs3lStP0Gw1qhdVCUS7Ab7+SUB6KD5aX1uqxWQRwMnOGTkhKuLvLNIs1TvNz+iS9kUGl1MhA== + +graphql-tools@^3.0.0, graphql-tools@^3.0.4, graphql-tools@^3.0.5: version "3.1.1" resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-3.1.1.tgz#d593358f01e7c8b1671a17b70ddb034dea9dbc50" integrity sha512-yHvPkweUB0+Q/GWH5wIG60bpt8CTwBklCSzQdEHmRUgAdEQKxw+9B7zB3dG7wB3Ym7M7lfrS4Ej+jtDZfA2UXg== @@ -2957,7 +2927,7 @@ graphql-yoga@1.16.2: graphql-tools "^3.0.0" subscriptions-transport-ws "^0.9.8" -"graphql@^0.11.0 || ^0.12.0 || ^0.13.0": +"graphql@^0.11.0 || ^0.12.0 || ^0.13.0", graphql@~0.13.0: version "0.13.2" resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== @@ -3049,6 +3019,14 @@ has@^1.0.1: dependencies: function-bind "^1.1.1" +hash.js@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + he@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" @@ -3158,11 +3136,6 @@ ignore@^5.0.2: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.0.4.tgz#33168af4a21e99b00c5d41cbadb6a6cb49903a45" integrity sha512-WLsTMEhsQuXpCiG173+f3aymI43SXa+fB1rSfbzyP4GkPP+ZFVuO0/3sFUGNBtifisPeDcl/uD/Y2NxZ7xFq4g== -immutable-tuple@^0.4.9: - version "0.4.9" - resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.9.tgz#473ebdd6c169c461913a454bf87ef8f601a20ff0" - integrity sha512-LWbJPZnidF8eczu7XmcnLBsumuyRBkpwIRPCZxlojouhBo5jEBO4toj6n7hMy6IxHU/c+MqDSWkvaTpPlMQcyA== - import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -3593,13 +3566,6 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -3612,12 +3578,7 @@ json5@^2.1.0: dependencies: minimist "^1.2.0" -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - -jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: +jsonwebtoken@^8.2.0: version "8.4.0" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz#8757f7b4cb7440d86d5e2f3becefa70536c8e46a" integrity sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg== @@ -3632,6 +3593,21 @@ jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: lodash.once "^4.0.0" ms "^2.1.1" +jsonwebtoken@~8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz#056c90eee9a65ed6e6c72ddb0a1d325109aaf643" + integrity sha512-oge/hvlmeJCH+iIz1DwcO7vKPkNGJHhgkspk8OH3VKlw+mbi42WtD4ig1+VXRln765vxptAv+xT26Fd3cteqag== + dependencies: + jws "^3.1.5" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -3714,7 +3690,7 @@ libphonenumber-js@^1.6.4: semver-compare "^1.0.0" xml2js "^0.4.17" -linkifyjs@^2.1.7: +linkifyjs@~2.1.7: version "2.1.7" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-2.1.7.tgz#e5d68d2ae30b9c055e1d74cc40f9a31d3abb4012" integrity sha512-Cbn77BnYEslpAObZZoP6GVQHF1j5T6RsDydNq5RVxIy4eiZAiADRx7qHfWzfEMQecc1PtZFog1AsCGGX2WjQLA== @@ -3804,7 +3780,7 @@ lodash.once@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= -lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: +lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.11: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -3834,12 +3810,13 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" -lru-cache@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== +lru-cache@^4.1.3: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== dependencies: - yallist "^3.0.2" + pseudomap "^1.0.2" + yallist "^2.1.2" make-dir@^1.0.0: version "1.3.0" @@ -3932,6 +3909,11 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== +minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -3989,7 +3971,7 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@^2.1.1: +ms@^2.1.1, ms@~2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== @@ -4040,7 +4022,7 @@ negotiator@0.6.1: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= -neo4j-driver@^1.6.1, neo4j-driver@^1.7.2: +neo4j-driver@^1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.2.tgz#c72a6dfa6bd2106b00a42794dc52a82b227b48e0" integrity sha512-0IvCFYhcP9hb5JveZk33epbReDKpFTn2u5vAa8zzGG344i6yFqZrBo0mtC114ciP9zFjAtfNOP72mRm8+NV0Fg== @@ -4049,6 +4031,14 @@ neo4j-driver@^1.6.1, neo4j-driver@^1.7.2: text-encoding "^0.6.4" uri-js "^4.2.1" +neo4j-driver@~1.6.1: + version "1.6.4" + resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.6.4.tgz#b190f28fdc3e91f02e9fcc32b3857ac2ce710f03" + integrity sha512-R3SU9EPmc5uHvFG/v1HJL+Oho63pKOms2KHKWh09mJDb3F3RigDNFKaqehu0t8ZhCY89e5QazK+pqQq78EDjVQ== + dependencies: + babel-runtime "^6.18.0" + uri-js "^4.2.1" + neo4j-graphql-js@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.0.1.tgz#76e10947873e1fde2e4f8427fe8d6a066aea2ce4" @@ -4071,12 +4061,12 @@ node-fetch@1.6.3: encoding "^0.1.11" is-stream "^1.0.1" -node-fetch@2.1.2: +node-fetch@2.1.2, node-fetch@~2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= -node-fetch@^2.1.2, node-fetch@^2.2.0: +node-fetch@^2.1.2: version "2.3.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== @@ -4109,7 +4099,7 @@ node-releases@^1.0.1: dependencies: semver "^5.3.0" -nodemon@^1.18.7: +nodemon@~1.18.7: version "1.18.7" resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.7.tgz#716b66bf3e89ac4fcfb38a9e61887a03fc82efbb" integrity sha512-xuC1V0F5EcEyKQ1VhHYD13owznQbUw29JKvZ8bVH7TmuvVNHvvbp9pLgE4PjTMRJVe0pJ8fGRvwR2nMiosIsPQ== @@ -4301,13 +4291,6 @@ opn@4.0.2: object-assign "^4.0.1" pinkie-promise "^2.0.0" -optimism@^0.6.6: - version "0.6.8" - resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.8.tgz#0780b546da8cd0a72e5207e0c3706c990c8673a6" - integrity sha512-bN5n1KCxSqwBDnmgDnzMtQTHdL+uea2HYFx1smvtE+w2AMl0Uy31g0aXnP/Nt85OINnMJPRpJyfRQLTCqn5Weg== - dependencies: - immutable-tuple "^0.4.9" - optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" @@ -4456,7 +4439,7 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -passport-jwt@^4.0.0: +passport-jwt@~4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg== @@ -4469,7 +4452,7 @@ passport-strategy@1.x.x, passport-strategy@^1.0.0: resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= -passport@^0.4.0: +passport@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" integrity sha1-xQlWkTR71a07XhgCOMORTRbwWBE= @@ -5033,7 +5016,7 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sanitize-html@^1.19.3: +sanitize-html@~1.19.3: version "1.19.3" resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.3.tgz#6a6562ec4a90e6b9139ca3c845a3c83512288519" integrity sha512-QpIjbF1rhUSQj9V7Wey/gv4DPqOso8KTebaI4rC97p0WCLnTpmhf7BJZUhS83MTtqRvUo8MuXH316CW2Nzd48w== @@ -5174,7 +5157,7 @@ slice-ansi@2.0.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -slug@^0.9.1: +slug@~0.9.1: version "0.9.2" resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.2.tgz#e409e4dae3a4bd2fd283557e2806e0a8abb98242" integrity sha512-WULwxWq6NBM/i24pV9st/WI9TwzjXYpNzxbWr9mRDj74Lqwb3ahsnWsWJtXHfBPpBqXb4m1hYt9S7eMyDkZsKA== @@ -5553,7 +5536,7 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= -trunc-html@^1.1.2: +trunc-html@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/trunc-html/-/trunc-html-1.1.2.tgz#1e97d51f67d470b67662b1a670e6d0ea7a8edafe" integrity sha1-HpfVH2fUcLZ2YrGmcObQ6nqO2v4= @@ -5779,7 +5762,7 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -wait-on@^3.2.0: +wait-on@~3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-3.2.0.tgz#c83924df0fc42a675c678324c49c769d378bcb85" integrity sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg== @@ -5862,13 +5845,6 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" -ws@^6.0.0: - version "6.1.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" - integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== - dependencies: - async-limiter "~1.0.0" - xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" From 80bc9be9ab7869c981f3cdac99d5c1da1c2afb81 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 7 Dec 2018 20:53:41 +0100 Subject: [PATCH 139/554] pinned and updated package for more stable installs --- package.json | 36 +- yarn.lock | 1008 +++++++++++++++++++++++++------------------------- 2 files changed, 532 insertions(+), 512 deletions(-) diff --git a/package.json b/package.json index 3cc3f6816..c008de412 100644 --- a/package.json +++ b/package.json @@ -19,37 +19,37 @@ "author": "Human Connection gGmbH", "license": "MIT", "dependencies": { - "@babel/cli": "~7.1.5", - "@babel/core": "~7.1.6", - "@babel/node": "~7.0.0", - "@babel/preset-env": "~7.1.6", + "@babel/cli": "~7.2.0", + "@babel/core": "~7.2.0", + "@babel/node": "~7.2.0", + "@babel/preset-env": "~7.2.0", "@babel/register": "~7.0.0", - "apollo-cache-inmemory": "~1.2.5", - "apollo-client": "~2.3.2", - "apollo-link-http": "~1.5.4", - "apollo-server": "~2.0.4", + "apollo-cache-inmemory": "~1.3.11", + "apollo-client": "~2.4.7", + "apollo-link-http": "~1.5.7", + "apollo-server": "~2.2.6", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", - "date-fns": "~2.0.0-alpha.24", + "date-fns": "^2.0.0-alpha.25", "dotenv": "~6.2.0", "graphql": "~0.13.0", - "graphql-custom-directives": "~0.2.13", + "graphql-custom-directives": "~0.2.14", "graphql-iso-date": "~3.6.1", - "graphql-middleware": "1.7.6", - "graphql-shield": "~4.0.1", - "graphql-tag": "~2.9.2", - "graphql-yoga": "1.16.2", - "jsonwebtoken": "~8.3.0", + "graphql-middleware": "2.0.2", + "graphql-shield": "~4.1.0", + "graphql-tag": "~2.10.0", + "graphql-yoga": "~1.16.7", + "jsonwebtoken": "~8.4.0", "linkifyjs": "~2.1.7", "lodash": "~4.17.11", "ms": "~2.1.1", - "neo4j-driver": "~1.6.1", + "neo4j-driver": "~1.7.2", "neo4j-graphql-js": "2.0.1", - "node-fetch": "~2.1.2", + "node-fetch": "~2.3.0", "passport": "~0.4.0", "passport-jwt": "~4.0.0", "sanitize-html": "~1.19.3", - "slug": "~0.9.1", + "slug": "~0.9.2", "trunc-html": "~1.1.2" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 0559fb6df..bcaa93b68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,13 @@ # yarn lockfile v1 +"@apollographql/apollo-tools@^0.2.6": + version "0.2.8" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.2.8.tgz#f755baa3576eabdd93afa2782be61f5ae8a856dc" + integrity sha512-A7FTUigtpGCFBaLT1ILicdjM6pZ7LQNw7Vgos0t4aLYtvlKO/L1nMi/NO7bPypzZaJSToTgcxHJPRydP1Md+Kw== + dependencies: + apollo-env "0.2.5" + "@apollographql/apollo-upload-server@^5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" @@ -11,15 +18,15 @@ busboy "^0.2.14" object-path "^0.11.4" -"@apollographql/graphql-playground-html@^1.6.0": +"@apollographql/graphql-playground-html@^1.6.6": version "1.6.6" resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz#022209e28a2b547dcde15b219f0c50f47aa5beb3" integrity sha512-lqK94b+caNtmKFs5oUVXlSpN3sm5IXZ+KfhMxOtr0LR2SqErzkoJilitjDvJ1WbjHlxLI7WtCjRmOLdOGJqtMQ== -"@babel/cli@~7.1.5": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.1.5.tgz#4ccf0a8cdabeefdd8ce955384530f050935bc4d7" - integrity sha512-zbO/DtTnaDappBflIU3zYEgATLToRDmW5uN/EGH1GXaes7ydfjqmAoK++xmJIA+8HfDw7UyPZNdM8fhGhfmMhw== +"@babel/cli@~7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.2.0.tgz#505ed8d351daee6a88918da02c046c18c8c5a24f" + integrity sha512-FLteTkEoony0DX8NbnT51CmwmLBzINdlXmiJCSqCLmqWCDA/xk8EITPWqwDnVLbuK0bsZONt/grqHnQzQ15j0Q== dependencies: commander "^2.8.1" convert-source-map "^1.1.0" @@ -40,18 +47,18 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@~7.1.6": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.6.tgz#3733cbee4317429bc87c62b29cf8587dba7baeb3" - integrity sha512-Hz6PJT6e44iUNpAn8AoyAs6B3bl60g7MJQaI0rZEar6ECzh6+srYO1xlIdssio34mPaUtAb1y+XlkkSJzok3yw== +"@babel/core@~7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.0.tgz#a4dd3814901998e93340f0086e9867fefa163ada" + integrity sha512-7pvAdC4B+iKjFFp9Ztj0QgBndJ++qaMeonT185wAqUnhipw8idm9Rv1UMyBuKtYjfl6ORNkgEgcsYLfHX/GpLw== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.1.6" - "@babel/helpers" "^7.1.5" - "@babel/parser" "^7.1.6" + "@babel/generator" "^7.2.0" + "@babel/helpers" "^7.2.0" + "@babel/parser" "^7.2.0" "@babel/template" "^7.1.2" "@babel/traverse" "^7.1.6" - "@babel/types" "^7.1.6" + "@babel/types" "^7.2.0" convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -71,6 +78,17 @@ source-map "^0.5.0" trim-right "^1.0.1" +"@babel/generator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.0.tgz#eaf3821fa0301d9d4aef88e63d4bcc19b73ba16c" + integrity sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg== + dependencies: + "@babel/types" "^7.2.0" + jsesc "^2.5.1" + lodash "^4.17.10" + source-map "^0.5.0" + trim-right "^1.0.1" + "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" @@ -226,14 +244,14 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helpers@^7.1.5": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.1.5.tgz#68bfc1895d685f2b8f1995e788dbfe1f6ccb1996" - integrity sha512-2jkcdL02ywNBry1YNFAH/fViq4fXG0vdckHqeJk+75fpQ2OH+Az6076tX/M0835zA45E0Cqa6pV5Kiv9YOqjEg== +"@babel/helpers@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.2.0.tgz#8335f3140f3144270dc63c4732a4f8b0a50b7a21" + integrity sha512-Fr07N+ea0dMcMN8nFpuK6dUIT7/ivt9yKQdEEnjVS83tG2pHwPi03gYmk/tyuwONnZ+sY+GFFPlWGgCtW1hF9A== dependencies: "@babel/template" "^7.1.2" "@babel/traverse" "^7.1.5" - "@babel/types" "^7.1.5" + "@babel/types" "^7.2.0" "@babel/highlight@^7.0.0": version "7.0.0" @@ -244,17 +262,15 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/node@~7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.0.0.tgz#20e55bb0e015700a0f6ff281c712de7619ad56f4" - integrity sha512-mKbN8Bb1TzH9YnKMWMhBRX+o5MVJHtUSalNcsiGa4FRgVfY7ozqkbttuIDWqeXxZ3rwI9ZqmCUr9XsPV2VYlSw== +"@babel/node@~7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.2.0.tgz#0b601be8ef03897923e3908dc18129836d44e6fa" + integrity sha512-RFwVH5xWpwd4SfkOI0WsK9AnF5o+C9iMTvUkkTb7jUNaiDieV8BGK38t74bTPjgc4FCxSAWNKqaqgDW4fenkyA== dependencies: "@babel/polyfill" "^7.0.0" "@babel/register" "^7.0.0" commander "^2.8.1" - fs-readdir-recursive "^1.0.0" lodash "^4.17.10" - output-file-sync "^2.0.0" v8flags "^3.1.1" "@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.6": @@ -262,111 +278,116 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.6.tgz#16e97aca1ec1062324a01c5a6a7d0df8dd189854" integrity sha512-dWP6LJm9nKT6ALaa+bnL247GHHMWir3vSlZ2+IHgHgktZQx0L3Uvq2uAWcuzIe+fujRsYWBW2q622C5UvGK9iQ== -"@babel/plugin-proposal-async-generator-functions@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce" - integrity sha512-Fq803F3Jcxo20MXUSDdmZZXrPe6BWyGcWBPPNB/M7WaUYESKDeKMOGIxEzQOjGSmW/NWb6UaPZrtTB2ekhB/ew== +"@babel/parser@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.2.0.tgz#02d01dbc330b6cbf36b76ac93c50752c69027065" + integrity sha512-M74+GvK4hn1eejD9lZ7967qAwvqTZayQa3g10ag4s9uewgR7TKjeaT0YMyoq+gVfKYABiWZ4MQD701/t5e1Jhg== + +"@babel/plugin-proposal-async-generator-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" + integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-remap-async-to-generator" "^7.1.0" - "@babel/plugin-syntax-async-generators" "^7.0.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" -"@babel/plugin-proposal-json-strings@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz#3b4d7b5cf51e1f2e70f52351d28d44fc2970d01e" - integrity sha512-kfVdUkIAGJIVmHmtS/40i/fg/AGnw/rsZBCaapY5yjeO5RA9m165Xbw9KMOu2nqXP5dTFjEjHdfNdoVcHv133Q== +"@babel/plugin-proposal-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" + integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" -"@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e" - integrity sha512-14fhfoPcNu7itSen7Py1iGN0gEm87hX/B+8nZPqkdmANyyYWYMY2pjA3r8WXbWVKMzfnSNS0xY8GVS0IjXi/iw== +"@babel/plugin-proposal-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.2.0.tgz#88f5fec3e7ad019014c97f7ee3c992f0adbf7fb8" + integrity sha512-1L5mWLSvR76XYUQJXkd/EEQgjq8HHRP6lQuZTTg0VA4tTGPpGemmCdAfQIz1rzEuWAm+ecP8PyyEm30jC1eQCg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" -"@babel/plugin-proposal-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425" - integrity sha512-JPqAvLG1s13B/AuoBjdBYvn38RqW6n1TzrQO839/sIpqLpbnXKacsAgpZHzLD83Sm8SDXMkkrAvEnJ25+0yIpw== +"@babel/plugin-proposal-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" + integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" -"@babel/plugin-proposal-unicode-property-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz#498b39cd72536cd7c4b26177d030226eba08cd33" - integrity sha512-tM3icA6GhC3ch2SkmSxv7J/hCWKISzwycub6eGsDrFDgukD4dZ/I+x81XgW0YslS6mzNuQ1Cbzh5osjIMgepPQ== +"@babel/plugin-proposal-unicode-property-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz#abe7281fe46c95ddc143a65e5358647792039520" + integrity sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" regexpu-core "^4.2.0" -"@babel/plugin-syntax-async-generators@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz#bf0891dcdbf59558359d0c626fdc9490e20bc13c" - integrity sha512-im7ged00ddGKAjcZgewXmp1vxSZQQywuQXe2B1A7kajjZmDeY/ekMPmWr9zJgveSaQH0k7BcGrojQhcK06l0zA== +"@babel/plugin-syntax-async-generators@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" + integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-json-strings@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz#0d259a68090e15b383ce3710e01d5b23f3770cbd" - integrity sha512-UlSfNydC+XLj4bw7ijpldc1uZ/HB84vw+U6BTuqMdIEmz/LDe63w/GHtpQMdXWdqQZFeAI9PjnHe/vDhwirhKA== +"@babel/plugin-syntax-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" + integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b" - integrity sha512-5A0n4p6bIiVe5OvQPxBnesezsgFJdHhSs3uFSvaPdMqtsovajLZ+G2vZyvNe10EzJBWWo3AcHGKhAFUxqwp2dw== +"@babel/plugin-syntax-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" + integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475" - integrity sha512-Wc+HVvwjcq5qBg1w5RG9o9RVzmCaAg/Vp0erHCKpAYV8La6I94o4GQAmFYNmkzoMO6gzoOSulpKeSSz6mPEoZw== +"@babel/plugin-syntax-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" + integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749" - integrity sha512-2EZDBl1WIO/q4DIkIp4s86sdp4ZifL51MoIviLY/gG/mLSuOIEg7J8o6mhbxOTvUJkaN50n+8u41FVsr5KLy/w== +"@babel/plugin-transform-arrow-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" + integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811" - integrity sha512-rNmcmoQ78IrvNCIt/R9U+cixUHeYAzgusTFgIAv+wQb9HJU4szhpDD6e5GCACmj/JP5KxuCwM96bX3L9v4ZN/g== +"@babel/plugin-transform-async-to-generator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz#68b8a438663e88519e65b776f8938f3445b1a2ff" + integrity sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-remap-async-to-generator" "^7.1.0" -"@babel/plugin-transform-block-scoped-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz#482b3f75103927e37288b3b67b65f848e2aa0d07" - integrity sha512-AOBiyUp7vYTqz2Jibe1UaAWL0Hl9JUXEgjFvvvcSc9MVDItv46ViXFw2F7SVt1B5k+KWjl44eeXOAk3UDEaJjQ== +"@babel/plugin-transform-block-scoped-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" + integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-block-scoping@^7.1.5": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.1.5.tgz#3e8e0bc9a5104519923302a24f748f72f2f61f37" - integrity sha512-jlYcDrz+5ayWC7mxgpn1Wj8zj0mmjCT2w0mPIMSwO926eXBRxpEgoN/uQVRBfjtr8ayjcmS+xk2G1jaP8JjMJQ== +"@babel/plugin-transform-block-scoping@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz#f17c49d91eedbcdf5dd50597d16f5f2f770132d4" + integrity sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.10" -"@babel/plugin-transform-classes@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249" - integrity sha512-rNaqoD+4OCBZjM7VaskladgqnZ1LO6o2UxuWSDzljzW21pN1KXkB7BstAVweZdxQkHAujps5QMNOTWesBciKFg== +"@babel/plugin-transform-classes@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.0.tgz#374f8876075d7d21fea55aeb5c53561259163f96" + integrity sha512-aPCEkrhJYebDXcGTAP+cdUENkH7zqOlgbKwLbghjjHpJRJBWM/FSlCjMoPGA8oUdiMfOrk3+8EFPLLb5r7zj2w== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-define-map" "^7.1.0" @@ -377,95 +398,95 @@ "@babel/helper-split-export-declaration" "^7.0.0" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31" - integrity sha512-ubouZdChNAv4AAWAgU7QKbB93NU5sHwInEWfp+/OzJKA02E6Woh9RVoX4sZrbRwtybky/d7baTUqwFx+HgbvMA== +"@babel/plugin-transform-computed-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" + integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-destructuring@^7.0.0": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.1.3.tgz#e69ff50ca01fac6cb72863c544e516c2b193012f" - integrity sha512-Mb9M4DGIOspH1ExHOUnn2UUXFOyVTiX84fXCd+6B5iWrQg/QMeeRmSwpZ9lnjYLSXtZwiw80ytVMr3zue0ucYw== +"@babel/plugin-transform-destructuring@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.2.0.tgz#e75269b4b7889ec3a332cd0d0c8cff8fed0dc6f3" + integrity sha512-coVO2Ayv7g0qdDbrNiadE4bU7lvCd9H539m2gMknyVjjMdwF/iCOM7R+E8PkntoqLkltO0rk+3axhpp/0v68VQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-dotall-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz#73a24da69bc3c370251f43a3d048198546115e58" - integrity sha512-00THs8eJxOJUFVx1w8i1MBF4XH4PsAjKjQ1eqN/uCH3YKwP21GCKfrn6YZFZswbOk9+0cw1zGQPHVc1KBlSxig== +"@babel/plugin-transform-dotall-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz#f0aabb93d120a8ac61e925ea0ba440812dbe0e49" + integrity sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" regexpu-core "^4.1.3" -"@babel/plugin-transform-duplicate-keys@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz#a0601e580991e7cace080e4cf919cfd58da74e86" - integrity sha512-w2vfPkMqRkdxx+C71ATLJG30PpwtTpW7DDdLqYt2acXU7YjztzeWW2Jk1T6hKqCLYCcEA5UQM/+xTAm+QCSnuQ== +"@babel/plugin-transform-duplicate-keys@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz#d952c4930f312a4dbfff18f0b2914e60c35530b3" + integrity sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-exponentiation-operator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73" - integrity sha512-uZt9kD1Pp/JubkukOGQml9tqAeI8NkE98oZnHZ2qHRElmeKCodbTZgOEUtujSCSLhHSBWbzNiFSDIMC4/RBTLQ== +"@babel/plugin-transform-exponentiation-operator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" + integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== dependencies: "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-for-of@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39" - integrity sha512-TlxKecN20X2tt2UEr2LNE6aqA0oPeMT1Y3cgz8k4Dn1j5ObT8M3nl9aA37LLklx0PBZKETC9ZAf9n/6SujTuXA== +"@babel/plugin-transform-for-of@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz#ab7468befa80f764bb03d3cb5eef8cc998e1cad9" + integrity sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-function-name@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb" - integrity sha512-VxOa1TMlFMtqPW2IDYZQaHsFrq/dDoIjgN098NowhexhZcz3UGlvPgZXuE1jEvNygyWyxRacqDpCZt+par1FNg== +"@babel/plugin-transform-function-name@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz#f7930362829ff99a3174c39f0afcc024ef59731a" + integrity sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86" - integrity sha512-1NTDBWkeNXgpUcyoVFxbr9hS57EpZYXpje92zv0SUzjdu3enaRwF/l3cmyRnXLtIdyJASyiS6PtybK+CgKf7jA== +"@babel/plugin-transform-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" + integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-amd@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.1.0.tgz#f9e0a7072c12e296079b5a59f408ff5b97bf86a8" - integrity sha512-wt8P+xQ85rrnGNr2x1iV3DW32W8zrB6ctuBkYBbf5/ZzJY99Ob4MFgsZDFgczNU76iy9PWsy4EuxOliDjdKw6A== +"@babel/plugin-transform-modules-amd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz#82a9bce45b95441f617a24011dc89d12da7f4ee6" + integrity sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-commonjs@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c" - integrity sha512-wtNwtMjn1XGwM0AXPspQgvmE6msSJP15CX2RVfpTSTNPLhKhaOjaIfBaVfj4iUZ/VrFSodcFedwtPg/NxwQlPA== +"@babel/plugin-transform-modules-commonjs@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz#c4f1933f5991d5145e9cfad1dfd848ea1727f404" + integrity sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" -"@babel/plugin-transform-modules-systemjs@^7.0.0": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.1.3.tgz#2119a3e3db612fd74a19d88652efbfe9613a5db0" - integrity sha512-PvTxgjxQAq4pvVUZF3mD5gEtVDuId8NtWkJsZLEJZMZAW3TvgQl1pmydLLN1bM8huHFVVU43lf0uvjQj9FRkKw== +"@babel/plugin-transform-modules-systemjs@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.2.0.tgz#912bfe9e5ff982924c81d0937c92d24994bb9068" + integrity sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ== dependencies: "@babel/helper-hoist-variables" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-umd@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.1.0.tgz#a29a7d85d6f28c3561c33964442257cc6a21f2a8" - integrity sha512-enrRtn5TfRhMmbRwm7F8qOj0qEYByqUvTttPEGimcBH4CJHphjyK1Vg7sdU7JjeEmgSpM890IT/efS2nMHwYig== +"@babel/plugin-transform-modules-umd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" + integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -477,18 +498,18 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-object-super@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.1.0.tgz#b1ae194a054b826d8d4ba7ca91486d4ada0f91bb" - integrity sha512-/O02Je1CRTSk2SSJaq0xjwQ8hG4zhZGNjE8psTsSNPXyLRCODv7/PBozqT5AmQMzp7MI3ndvMhGdqp9c96tTEw== +"@babel/plugin-transform-object-super@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" + integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-replace-supers" "^7.1.0" -"@babel/plugin-transform-parameters@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed" - integrity sha512-vHV7oxkEJ8IHxTfRr3hNGzV446GAb+0hgbA7o/0Jd76s+YzccdWuTU296FOCOl/xweU4t/Ya4g41yWz80RFCRw== +"@babel/plugin-transform-parameters@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz#0d5ad15dc805e2ea866df4dd6682bfe76d1408c2" + integrity sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA== dependencies: "@babel/helper-call-delegate" "^7.1.0" "@babel/helper-get-function-arity" "^7.0.0" @@ -501,47 +522,47 @@ dependencies: regenerator-transform "^0.13.3" -"@babel/plugin-transform-shorthand-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15" - integrity sha512-g/99LI4vm5iOf5r1Gdxq5Xmu91zvjhEG5+yZDJW268AZELAu4J1EiFLnkSG3yuUsZyOipVOVUKoGPYwfsTymhw== +"@babel/plugin-transform-shorthand-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" + integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b" - integrity sha512-L702YFy2EvirrR4shTj0g2xQp7aNwZoWNCkNu2mcoU0uyzMl0XRwDSwzB/xp6DSUFiBmEXuyAyEN16LsgVqGGQ== +"@babel/plugin-transform-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.0.tgz#0c76c12a3b5826130078ee8ec84a7a8e4afd79c4" + integrity sha512-7TtPIdwjS/i5ZBlNiQePQCovDh9pAhVbp/nGVRBZuUdBiVRThyyLend3OHobc0G+RLCPPAN70+z/MAMhsgJd/A== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-sticky-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366" - integrity sha512-LFUToxiyS/WD+XEWpkx/XJBrUXKewSZpzX68s+yEOtIbdnsRjpryDw9U06gYc6klYEij/+KQVRnD3nz3AoKmjw== +"@babel/plugin-transform-sticky-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" + integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" -"@babel/plugin-transform-template-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65" - integrity sha512-vA6rkTCabRZu7Nbl9DfLZE1imj4tzdWcg5vtdQGvj+OH9itNNB6hxuRMHuIY8SGnEt1T9g5foqs9LnrHzsqEFg== +"@babel/plugin-transform-template-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz#d87ed01b8eaac7a92473f608c97c089de2ba1e5b" + integrity sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-typeof-symbol@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz#4dcf1e52e943e5267b7313bff347fdbe0f81cec9" - integrity sha512-1r1X5DO78WnaAIvs5uC48t41LLckxsYklJrZjNKcevyz83sF2l4RHbw29qrCPr/6ksFsdfRpT/ZgxNWHXRnffg== +"@babel/plugin-transform-typeof-symbol@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" + integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc" - integrity sha512-uJBrJhBOEa3D033P95nPHu3nbFwFE9ZgXsfEitzoIXIwqAZWk7uXcg06yFKXz9FSxBH5ucgU/cYdX0IV8ldHKw== +"@babel/plugin-transform-unicode-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz#4eb8db16f972f8abb5062c161b8b115546ade08b" + integrity sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" @@ -555,49 +576,49 @@ core-js "^2.5.7" regenerator-runtime "^0.11.1" -"@babel/preset-env@~7.1.6": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.1.6.tgz#a0bf4b96b6bfcf6e000afc5b72b4abe7cc13ae97" - integrity sha512-YIBfpJNQMBkb6MCkjz/A9J76SNCSuGVamOVBgoUkLzpJD/z8ghHi9I42LQ4pulVX68N/MmImz6ZTixt7Azgexw== +"@babel/preset-env@~7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.2.0.tgz#a5030e7e4306af5a295dd5d7c78dc5464af3fee2" + integrity sha512-haGR38j5vOGVeBatrQPr3l0xHbs14505DcM57cbJy48kgMFvvHHoYEhHuRV+7vi559yyAUAVbTWzbK/B/pzJng== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.1.0" - "@babel/plugin-proposal-json-strings" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.0.0" - "@babel/plugin-syntax-async-generators" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.1.0" - "@babel/plugin-transform-block-scoped-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.1.5" - "@babel/plugin-transform-classes" "^7.1.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-dotall-regex" "^7.0.0" - "@babel/plugin-transform-duplicate-keys" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.1.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.1.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-amd" "^7.1.0" - "@babel/plugin-transform-modules-commonjs" "^7.1.0" - "@babel/plugin-transform-modules-systemjs" "^7.0.0" - "@babel/plugin-transform-modules-umd" "^7.1.0" + "@babel/plugin-proposal-async-generator-functions" "^7.2.0" + "@babel/plugin-proposal-json-strings" "^7.2.0" + "@babel/plugin-proposal-object-rest-spread" "^7.2.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.2.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/plugin-transform-arrow-functions" "^7.2.0" + "@babel/plugin-transform-async-to-generator" "^7.2.0" + "@babel/plugin-transform-block-scoped-functions" "^7.2.0" + "@babel/plugin-transform-block-scoping" "^7.2.0" + "@babel/plugin-transform-classes" "^7.2.0" + "@babel/plugin-transform-computed-properties" "^7.2.0" + "@babel/plugin-transform-destructuring" "^7.2.0" + "@babel/plugin-transform-dotall-regex" "^7.2.0" + "@babel/plugin-transform-duplicate-keys" "^7.2.0" + "@babel/plugin-transform-exponentiation-operator" "^7.2.0" + "@babel/plugin-transform-for-of" "^7.2.0" + "@babel/plugin-transform-function-name" "^7.2.0" + "@babel/plugin-transform-literals" "^7.2.0" + "@babel/plugin-transform-modules-amd" "^7.2.0" + "@babel/plugin-transform-modules-commonjs" "^7.2.0" + "@babel/plugin-transform-modules-systemjs" "^7.2.0" + "@babel/plugin-transform-modules-umd" "^7.2.0" "@babel/plugin-transform-new-target" "^7.0.0" - "@babel/plugin-transform-object-super" "^7.1.0" - "@babel/plugin-transform-parameters" "^7.1.0" + "@babel/plugin-transform-object-super" "^7.2.0" + "@babel/plugin-transform-parameters" "^7.2.0" "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typeof-symbol" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - browserslist "^4.1.0" + "@babel/plugin-transform-shorthand-properties" "^7.2.0" + "@babel/plugin-transform-spread" "^7.2.0" + "@babel/plugin-transform-sticky-regex" "^7.2.0" + "@babel/plugin-transform-template-literals" "^7.2.0" + "@babel/plugin-transform-typeof-symbol" "^7.2.0" + "@babel/plugin-transform-unicode-regex" "^7.2.0" + browserslist "^4.3.4" invariant "^2.2.2" js-levenshtein "^1.1.3" semver "^5.3.0" @@ -654,7 +675,7 @@ globals "^11.1.0" lodash "^4.17.10" -"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.5", "@babel/types@^7.1.6": +"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.6.tgz#0adb330c3a281348a190263aceb540e10f04bcce" integrity sha512-DMiUzlY9DSjVsOylJssxLHSgj6tWM9PRFJOGW/RaOglVOK9nzTxoOMfTfRQXGUCUQ/HmlG2efwC+XqUEJ5ay4w== @@ -663,6 +684,15 @@ lodash "^4.17.10" to-fast-properties "^2.0.0" +"@babel/types@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.0.tgz#7941c5b2d8060e06f9601d6be7c223eef906d5d8" + integrity sha512-b4v7dyfApuKDvmPb+O488UlGuR1WbwMXFsO/cyqMrnfvRAChZKJAYeeglWTjUO1b9UghKKgepAQM5tsvBJca6A== + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" + to-fast-properties "^2.0.0" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -723,10 +753,10 @@ dependencies: "@types/node" "*" -"@types/async@2.0.49": - version "2.0.49" - resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0" - integrity sha512-Benr3i5odUkvpFkOpzGqrltGdbSs+EVCkEBGXbuR7uT0VzhXKIkhem6PDzHdx5EonA+rfbB3QvP6aDOw5+zp5Q== +"@types/async@2.0.50": + version "2.0.50" + resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.50.tgz#117540e026d64e1846093abbd5adc7e27fda7bcb" + integrity sha512-VMhZMMQgV1zsR+lX/0IBfAk+8Eb7dPVMWiQGFAt3qjo5x7Ml6b77jUo0e1C3ToD+XRDXqtrfw+6AB0uUsPEr3Q== "@types/body-parser@*", "@types/body-parser@1.17.0": version "1.17.0" @@ -778,10 +808,10 @@ resolved "https://registry.yarnpkg.com/@types/graphql-deduplicator/-/graphql-deduplicator-2.0.0.tgz#9e577b8f3feb3d067b0ca756f4a1fb356d533922" integrity sha512-swUwj5hWF1yFzbUXStLJrUa0ksAt11B8+SwhsAjQAX0LYJ1LLioAyuDcJ9bovWbsNzIXJYXLvljSPQw8nR728w== -"@types/graphql@^0.13.0": - version "0.13.4" - resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.13.4.tgz#55ae9c29f0fd6b85ee536f5c72b4769d5c5e06b1" - integrity sha512-B4yel4ro2nTb3v0pYO8vO6SjgvFJSrwUY+IO6TUSLdOSB+gQFslylrhRCHxvXMIhxB71mv5PEE9dAX+24S8sew== +"@types/graphql@^14.0.0": + version "14.0.3" + resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-14.0.3.tgz#389e2e5b83ecdb376d9f98fae2094297bc112c1c" + integrity sha512-TcFkpEjcQK7w8OcrQcd7iIBPjU0rdyi3ldj6d0iJ4PPSzbWqPBvXj9KSwO14hTOX2dm9RoiH7VuxksJLNYdXUQ== "@types/long@^4.0.0": version "4.0.0" @@ -811,10 +841,10 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" -"@types/ws@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-5.1.2.tgz#f02d3b1cd46db7686734f3ce83bdf46c49decd64" - integrity sha512-NkTXUKTYdXdnPE2aUUbGOXE1XfMK527SCvU/9bj86kyFF6kZ9ZnOQ3mK5jADn98Y2vEUD/7wKDgZa7Qst2wYOg== +"@types/ws@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28" + integrity sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q== dependencies: "@types/events" "*" "@types/node" "*" @@ -924,13 +954,13 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -apollo-cache-control@0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.2.4.tgz#af32b27cde9c86bda8e1ff2db3ab14951c26f92c" - integrity sha512-Duswm5utdKGaRPuGtUSe7+gjQPYdb9VscLmEFRWYcfyrNBF5tYtycliY3wOSF0zEUE1CersSAwBEWFTTiD50ug== +apollo-cache-control@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.3.tgz#ad71d8f786e06f0275b2432004c15c2d37c48484" + integrity sha512-X6JhKfIaMLfl2jpsK/880BflXA+2lmm2sAsOZL4Bn2VrMsDtOssI1Ij9vNRbch9k9cA4WJvKed7Sql/wUIa1Eg== dependencies: - apollo-server-env "2.0.3" - graphql-extensions "0.2.0" + apollo-server-env "2.2.0" + graphql-extensions "0.3.3" apollo-cache-control@^0.1.0: version "0.1.1" @@ -939,63 +969,71 @@ apollo-cache-control@^0.1.0: dependencies: graphql-extensions "^0.0.x" -apollo-cache-inmemory@~1.2.5: - version "1.2.10" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.2.10.tgz#362d6c36cfd815a309b966f71e5d2b6c770c7989" - integrity sha512-eBusPFVtYIuo+PIfJdAwUCQ4cs7AJ4mB7sTdXxNQCXToYw8mzE6EfHnV37kdVfBXSaa82BzE2rb/YUq/duuamw== +apollo-cache-inmemory@~1.3.11: + version "1.3.11" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.11.tgz#6cb8f24ec812715169f9acbb0b67833f9a19ec90" + integrity sha512-fSoyjBV5RV57J3i/VHDDB74ZgXc0PFiogheNFHEhC0mL6rg5e/DjTx0Vg+csIBk23gvlzTvV+eypx7Q2NJ+dYg== dependencies: - apollo-cache "^1.1.17" - apollo-utilities "^1.0.21" - graphql-anywhere "^4.1.19" + apollo-cache "^1.1.21" + apollo-utilities "^1.0.26" + optimism "^0.6.6" -apollo-cache@^1.1.14, apollo-cache@^1.1.17: +apollo-cache@1.1.21, apollo-cache@^1.1.21: version "1.1.21" resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.21.tgz#950025e2272741ba8e5064419906e3ac4072925d" integrity sha512-5ErNb78KHtrJNimkDBTEigcvHkIqUmS7QJIk4lpZZ+XLVVgvk2fD+GhD1PLP+s8vHfAKVbO6vdbRxCCjGGrh5w== dependencies: apollo-utilities "^1.0.26" -apollo-client@~2.3.2: - version "2.3.8" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.3.8.tgz#0384a7210eb601ab88b1c13750da076fc9255b95" - integrity sha512-X5wsBD1be1P/mScGsH5H+2hIE8d78WAfqOvFvBpP+C+jzJ9387uHLyFmYYMLRRqDQ3ihjI4iSID7KEOW2gyCcQ== +apollo-client@~2.4.7: + version "2.4.7" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.7.tgz#b6712fd4c9ba346e3c44cfec7e6868e532b6a957" + integrity sha512-6aAm+16AFBYZhJF8eKxrup6AbYni01InDiwTfZhMMTP2xaXQWjsQnfaHbI2oE+hd3+AZFy1drkse8RZKghR/WQ== dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "^1.1.14" + apollo-cache "1.1.21" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "^1.0.18" + apollo-utilities "1.0.26" symbol-observable "^1.0.2" zen-observable "^0.8.0" optionalDependencies: - "@types/async" "2.0.49" + "@types/async" "2.0.50" -apollo-datasource@0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.1.3.tgz#e7ae9d20f29a8a35f239b02f0c47169cfd78d70b" - integrity sha512-yEGEe5Cjzqqu5ml1VV3O8+C+thzdknZri9Ny0P3daTGNO+45J3vBOMcmaANeeI2+OOeWxdqUNa5aPOx/35kniw== +apollo-datasource@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.2.1.tgz#3ecef4efe64f7a04a43862f32027d38ac09e142c" + integrity sha512-r185+JTa5KuF1INeTAk7AEP76zwMN6c8Ph1lmpzJMNwBUEzTGnLClrccCskCBx4SxfnkdKbuQdwn9JwCJUWrdg== dependencies: - apollo-server-caching "0.1.2" - apollo-server-env "2.0.3" + apollo-server-caching "0.2.1" + apollo-server-env "2.2.0" -apollo-engine-reporting-protobuf@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz#cd394f0f769c6f97d8621c4a7839095c84efcdb0" - integrity sha512-AySoDgog2p1Nph44FyyqaU4AfRZOXx8XZxRsVHvYY4dHlrMmDDhhjfF3Jswa7Wr8X/ivvx3xA0jimRn6rsG8Ew== +apollo-engine-reporting-protobuf@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.1.0.tgz#fbc220cac2a3b7800ffc155d7e54c21c56b7848e" + integrity sha512-GReJtAYTmpwg0drb9VgFtqObYYTCHkJhlHEYCeXY8bJV4fOgXsAZ7CIXR9nPKO0mBaoHIHaGYvXGcyCLrZ36VA== dependencies: protobufjs "^6.8.6" -apollo-engine-reporting@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.0.5.tgz#2a52313e3df98a056294672fe7ad2a107ef54c15" - integrity sha512-543LtBSnekZWz9y9GHsXdBoIFmZKyXYlQeeRB9CAIbOUcDl8HQaWYRr/H91wvVqG1OgUhi2g6BVzNHXj17akVA== +apollo-engine-reporting@0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.3.tgz#85ad6ffd71db8f877202ce8b3d7dbfa7cabfbcf9" + integrity sha512-VkjiifHMHIAxydXecT+ck0WtqpFIsMlylKnKeuNAXfIfAXHX/JYtLhbArTTyhDunLrphMiUewfFv9P0K+aX2jw== dependencies: - apollo-engine-reporting-protobuf "0.0.1" - apollo-server-env "2.0.3" + apollo-engine-reporting-protobuf "0.1.0" + apollo-server-env "2.2.0" async-retry "^1.2.1" - graphql-extensions "0.2.0" + graphql-extensions "0.3.3" lodash "^4.17.10" +apollo-env@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.2.5.tgz#162c785bccd2aea69350a7600fab4b7147fc9da5" + integrity sha512-Gc7TEbwCl7jJVutnn8TWfzNSkrrqyoo0DP92BQJFU9pZbJhpidoXf2Sw1YwOJl82rRKH3ujM3C8vdZLOgpFcFA== + dependencies: + core-js "^3.0.0-beta.3" + node-fetch "^2.2.0" + apollo-link-dedup@^1.0.0: version "1.0.11" resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.11.tgz#6f34ea748d2834850329ad03111ef18445232b05" @@ -1010,7 +1048,7 @@ apollo-link-http-common@^0.2.6: dependencies: apollo-link "^1.2.4" -apollo-link-http@~1.5.4: +apollo-link-http@~1.5.7: version "1.5.7" resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.7.tgz#098615c427a910ec8c5817476bbabe68c586b339" integrity sha512-EZ9nynHjwYCpGYP5IsRrZGTWidUVpshk7MuSG4joqGtJMwpFCgMQz+y3BHdUhowHtfAd9z60XmeOTG9FJolb8A== @@ -1026,43 +1064,38 @@ apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4: apollo-utilities "^1.0.0" zen-observable-ts "^0.8.11" -apollo-link@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.3.tgz#9bd8d5fe1d88d31dc91dae9ecc22474d451fb70d" - integrity sha512-iL9yS2OfxYhigme5bpTbmRyC+Htt6tyo2fRMHT3K1XRL/C5IQDDz37OjpPy4ndx7WInSvfSZaaOTKFja9VWqSw== +apollo-server-caching@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.2.1.tgz#7e67f8c8cac829e622b394f0fb82579cabbeadfd" + integrity sha512-+U9F3X297LL8Gqy6ypfDNEv/DfV/tDht9Dr2z3AMaEkNW1bwO6rmdDL01zYxDuVDVq6Z3qSiNCSO2pXE2F0zmA== dependencies: - apollo-utilities "^1.0.0" - zen-observable-ts "^0.8.10" + lru-cache "^5.0.0" -apollo-server-caching@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.1.2.tgz#f5b85701945110a5fca1956450e8553576635936" - integrity sha512-jBRnsTgXN0m8yVpumoelaUq9mXR7YpJ3EE+y/alI7zgXY+0qFDqksRApU8dEfg3q6qUnO7rFxRhdG5eyc0+1ig== - dependencies: - lru-cache "^4.1.3" - -apollo-server-core@2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.0.7.tgz#ccde1dcb6bf00e915f1cb2b3e15a664f8825f9d3" - integrity sha512-1DLxAcYbBjYCpKbWVxYOihQrVsi+lJQdKgHSRtuvzx8ep5B6k6nHxhsoee2GzIfk7b2NY0R7zQBqamC+aooT9w== +apollo-server-core@2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.6.tgz#33031a3e1156d4cd0ad3c5c49de263173f521b32" + integrity sha512-hC3+Y9A4rN4W2X2cWqjrWWHkjKaG/jUQjtAVpQteDW+7n3bLKHCrpDFiFad++lq0ymRVW8diAaYDS4myJwjmoA== dependencies: + "@apollographql/apollo-tools" "^0.2.6" "@apollographql/apollo-upload-server" "^5.0.3" - "@types/ws" "^5.1.2" - apollo-cache-control "0.2.4" - apollo-datasource "0.1.3" - apollo-engine-reporting "0.0.5" - apollo-server-caching "0.1.2" - apollo-server-env "2.0.3" - apollo-server-errors "2.0.2" - apollo-tracing "0.2.4" - graphql-extensions "0.2.0" - graphql-subscriptions "^0.5.8" + "@apollographql/graphql-playground-html" "^1.6.6" + "@types/ws" "^6.0.0" + apollo-cache-control "0.3.3" + apollo-datasource "0.2.1" + apollo-engine-reporting "0.1.3" + apollo-server-caching "0.2.1" + apollo-server-env "2.2.0" + apollo-server-errors "2.2.0" + apollo-server-plugin-base "0.1.6" + apollo-tracing "0.3.3" + graphql-extensions "0.3.6" + graphql-subscriptions "^1.0.0" graphql-tag "^2.9.2" - graphql-tools "^3.0.4" - hash.js "^1.1.3" + graphql-tools "^4.0.0" + json-stable-stringify "^1.0.1" lodash "^4.17.10" subscriptions-transport-ws "^0.9.11" - ws "^5.2.0" + ws "^6.0.0" apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: version "1.4.0" @@ -1073,36 +1106,36 @@ apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: apollo-tracing "^0.1.0" graphql-extensions "^0.0.x" -apollo-server-env@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.0.3.tgz#3c13552cd33f400160076cf8e1c9b24be4d27e13" - integrity sha512-uIfKFH8n8xKO0eLb9Fa79+s2DdMuVethgznvW6SrOYq5VzgkIIobqKEuZPKa5wObw9CkCyju/+Sr7b7WWMFxUQ== +apollo-server-env@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.2.0.tgz#5eec5dbf46581f663fd6692b2e05c7e8ae6d6034" + integrity sha512-wjJiI5nQWPBpNmpiLP389Ezpstp71szS6DHAeTgYLb/ulCw3CTuuA+0/E1bsThVWiQaDeHZE0sE3yI8q2zrYiA== dependencies: node-fetch "^2.1.2" util.promisify "^1.0.0" -apollo-server-errors@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz#e9cbb1b74d2cd78aed23cd886ca2d0c186323b2b" - integrity sha512-zyWDqAVDCkj9espVsoUpZr9PwDznM8UW6fBfhV+i1br//s2AQb07N6ektZ9pRIEvkhykDZW+8tQbDwAO0vUROg== +apollo-server-errors@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" + integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== -apollo-server-express@2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.0.7.tgz#ed8840525c90eef2612e600976aaabfa86a86c9c" - integrity sha512-zzG0pkomT+aZEHztvU79Duk+aTOvUBprSN9teSCnqP1GAgSyLi52L4i0ttY4PSSGsbgkwwsa8GkOhH51c45K7g== +apollo-server-express@2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.2.6.tgz#2c0c5bdab6eccf63ab138ad4b6d6836aeb723540" + integrity sha512-+zajJDcJLhWdkW8f0D5KQfDsaxgx7fQ3ULGDT1eZgL0UY5pazWBOnXqeRoVKRl+r1WcrwN1SMfBVnAKWv6CyVw== dependencies: "@apollographql/apollo-upload-server" "^5.0.3" - "@apollographql/graphql-playground-html" "^1.6.0" + "@apollographql/graphql-playground-html" "^1.6.6" "@types/accepts" "^1.3.5" "@types/body-parser" "1.17.0" "@types/cors" "^2.8.4" "@types/express" "4.16.0" accepts "^1.3.5" - apollo-server-core "2.0.7" + apollo-server-core "2.2.6" body-parser "^1.18.3" cors "^2.8.4" - graphql-subscriptions "^0.5.8" - graphql-tools "^3.0.4" + graphql-subscriptions "^1.0.0" + graphql-tools "^4.0.0" type-is "^1.6.16" apollo-server-express@^1.3.6: @@ -1126,24 +1159,29 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== -apollo-server@~2.0.4: - version "2.0.8" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.0.8.tgz#7012598c1f4a8126aba41614cfc0a05a736e9b45" - integrity sha512-6Q9wKobpDXMHzALZuCaRq7JyxZ7P1Jj3C6qaecx/ThZpxmdvj03qakGnk4AZx7G/VrYYxiUZZaXcgltLD7QidQ== - dependencies: - apollo-server-core "2.0.7" - apollo-server-express "2.0.7" - express "^4.0.0" - graphql-subscriptions "^0.5.8" - graphql-tools "^3.0.4" +apollo-server-plugin-base@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.6.tgz#56932c0e3a0366e03952a6e2805efe5fa2e046bf" + integrity sha512-nh6I2+mgSL5cYxqYXymAr8xBZ/ju8nunPjHp/21+/mgbF4Is0xtM9oDq5Qf0Q/cGh/djF6YcBuB1yUG+68gJXw== -apollo-tracing@0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.2.4.tgz#5749fc4f4f0230e541606a9314314c5f341c1133" - integrity sha512-wfIgDpkRWDpSoQpuDN640cq3Gr3mY17EE4YvJ48H+onranz6bDMDSbGxNU5LA3Hv09erOEDmx72MkgipLxSYOA== +apollo-server@~2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.2.6.tgz#7af396692ff06a6feb3429a7287bac5ee18b58eb" + integrity sha512-3fy9sm+w2hUVQNyy2gCVIFOD0DJD2IWpXTzHjpi2uned3JIE0mI4pP2JSBiBTjXVwgu4/2ql+f29Ex3VT8cHIg== dependencies: - apollo-server-env "2.0.3" - graphql-extensions "0.2.0" + apollo-server-core "2.2.6" + apollo-server-express "2.2.6" + express "^4.0.0" + graphql-subscriptions "^1.0.0" + graphql-tools "^4.0.0" + +apollo-tracing@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.3.tgz#b819942180480c1c4d89e613cf2eff8f6d8b595a" + integrity sha512-gsTYgDVjtMlnomPq46aky7yk8XshCQfj9rxalCCismLlMomVW44fq+8GKQnZIkFOwiAsazRy4dzZ0cBbygA9sA== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.3.3" apollo-tracing@^0.1.0: version "0.1.4" @@ -1161,7 +1199,7 @@ apollo-upload-server@^5.0.0: busboy "^0.2.14" object-path "^0.11.4" -apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.18, apollo-utilities@^1.0.21, apollo-utilities@^1.0.26: +apollo-utilities@1.0.26, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.26: version "1.0.26" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.26.tgz#589c66bf4d16223531351cf667a230c787def1da" integrity sha512-URw7o3phymliqYCYatcird2YRPUU2eWCNvip64U9gQrX56mEfK4m99yBIDCMTpmcvOFsKLii1sIEZsHIs/bvnw== @@ -1332,7 +1370,7 @@ babel-polyfill@6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: +babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= @@ -1450,14 +1488,14 @@ braces@^2.3.0, braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -browserslist@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.4.tgz#4477b737db6a1b07077275b24791e680d4300425" - integrity sha512-u5iz+ijIMUlmV8blX82VGFrB9ecnUg5qEt55CMZ/YJEhha+d8qpBfOFuutJ6F/VKRXjZoD33b6uvarpPxcl3RA== +browserslist@^4.3.4: + version "4.3.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.5.tgz#1a917678acc07b55606748ea1adf9846ea8920f7" + integrity sha512-z9ZhGc3d9e/sJ9dIx5NFXkKoaiQTnrvrMsN3R1fGb1tkWWNSz12UewJn9TNxGo1l7J23h0MRaPmk7jfeTZYs1w== dependencies: - caniuse-lite "^1.0.30000899" - electron-to-chromium "^1.3.82" - node-releases "^1.0.1" + caniuse-lite "^1.0.30000912" + electron-to-chromium "^1.3.86" + node-releases "^1.0.5" buffer-equal-constant-time@1.0.1: version "1.0.1" @@ -1533,10 +1571,10 @@ camelcase@^5.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== -caniuse-lite@^1.0.30000899: - version "1.0.30000909" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000909.tgz#697e8f447ca5f758e7c6cef39ec429ce18b908d3" - integrity sha512-4Ix9ArKpo3s/dLGVn/el9SAk6Vn2kGhg8XeE4eRTsGEsmm9RnTkwnBsVZs7p4wA8gB+nsgP36vZWYbG8a4nYrg== +caniuse-lite@^1.0.30000912: + version "1.0.30000916" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000916.tgz#3428d3f529f0a7b2bfaaec65e796037bdd433aab" + integrity sha512-D6J9jloPm2MPkg0PXcODLMQAJKkeixKO9xhqTUMvtd44MtTYMyyDXPQ2Lk9IgBq5FH0frwiPa/N/w8ncQf7kIQ== capture-stack-trace@^1.0.0: version "1.0.1" @@ -1787,6 +1825,11 @@ core-js@^2.4.0, core-js@^2.5.3, core-js@^2.5.7: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== +core-js@^3.0.0-beta.3: + version "3.0.0-beta.4" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.4.tgz#7443c32990d21198d23de18acb061a5e5bc9f549" + integrity sha512-yz4iJCkkSQLQSLHPGUln6r5ZBkLPzZSvHG0g1nfvcdnmpIe+KE9WOb1ZEEf6EEaEmjp9Ol0Kw5J5vnoIWc5eWw== + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1875,7 +1918,7 @@ date-fns@^1.23.0: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" integrity sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw== -date-fns@~2.0.0-alpha.24: +date-fns@^2.0.0-alpha.25: version "2.0.0-alpha.25" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.25.tgz#651a5d1f59a01af6cf0371e39b2ae29df5d521ee" integrity sha512-iQzJkHF0L4wah9Ae9PkvwemwFz6qmRLuNZcghmvf2t+ptLs1qXzONLiGtjmPQzL6+JpC01JjlTopY2AEy4NFAg== @@ -2091,10 +2134,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.82: - version "1.3.84" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.84.tgz#2e55df59e818f150a9f61b53471ebf4f0feecc65" - integrity sha512-IYhbzJYOopiTaNWMBp7RjbecUBsbnbDneOP86f3qvS0G0xfzwNSvMJpTrvi5/Y1gU7tg2NAgeg8a8rCYvW9Whw== +electron-to-chromium@^1.3.86: + version "1.3.88" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.88.tgz#f36ab32634f49ef2b0fdc1e82e2d1cc17feb29e7" + integrity sha512-UPV4NuQMKeUh1S0OWRvwg0PI8ASHN9kBC8yDTk1ROXLC85W5GnhTRu/MZu3Teqx3JjlQYuckuHYXSUSgtb3J+A== encodeurl@~1.0.2: version "1.0.2" @@ -2619,7 +2662,7 @@ fs-minipass@^1.2.5: dependencies: minipass "^2.2.1" -fs-readdir-recursive@^1.0.0, fs-readdir-recursive@^1.1.0: +fs-readdir-recursive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== @@ -2737,25 +2780,18 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== -graphql-anywhere@^4.1.19: - version "4.1.23" - resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-4.1.23.tgz#4275b161432b7c60a36970a1d9840d8c5cc2516e" - integrity sha512-8wtmwxWmLzAy52Z4WAw9UiYZ4ViiNXM+2DMOSlg2F7WsVstD0v75uOjCLJQUvbld5kHrgzTxter/THFVkGL+Yw== +graphql-config@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-2.2.1.tgz#5fd0ec77ac7428ca5fb2026cf131be10151a0cb2" + integrity sha512-U8+1IAhw9m6WkZRRcyj8ZarK96R6lQBQ0an4lp76Ps9FyhOXENC5YQOxOFGm5CxPrX2rD0g3Je4zG5xdNJjwzQ== dependencies: - apollo-utilities "^1.0.26" - -graphql-config@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-2.0.0.tgz#daf69091055c6f675d63893a2d14c48f3fec3327" - integrity sha512-//hZmROEk79zzPlH6SVTQeXd8NVV65rquz1zxZeO6oEuX5KNnii8+oznLu7d897EfJ+NShTZtsY9FMmxxkWmJw== - dependencies: - graphql-import "^0.4.0" - graphql-request "^1.4.0" + graphql-import "^0.7.1" + graphql-request "^1.5.0" js-yaml "^3.10.0" lodash "^4.17.4" minimatch "^3.0.4" -graphql-custom-directives@~0.2.13: +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== @@ -2770,12 +2806,19 @@ graphql-deduplicator@^2.0.1: resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3" integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA== -graphql-extensions@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.2.0.tgz#39baaf43a98de07378843317ce110592e6fcc943" - integrity sha512-dW2PdomN+IXzUDQALzpBk++sEXm2LamCP16hCOZ2B/go50I967R7/K+rr8qOxoNb7lvtLW1BjQg8kRoPqByrug== +graphql-extensions@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.3.tgz#277efe11976bbdfd59915551606a2d550247bb45" + integrity sha512-pudOaHq7Ok+rh1ElzlqFaoYZWGefUNsqn/jX6eKns7rl0VHuB4qZBfhpVLTpquJpM6Y19/hsCYZNPfnUVMFIiA== dependencies: - apollo-server-env "2.0.3" + "@apollographql/apollo-tools" "^0.2.6" + +graphql-extensions@0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.6.tgz#9ddb294b4b3303df4bbfd8258f10ad402e290dba" + integrity sha512-QGnDQ0TkF1YpVE/ZvKVl3bZ1PfwSbynVBcNU5U1DPU56pLkltETORiFL4TQ/Tt7RzagBX/xVaI3q0xJC6h9M5w== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: version "0.0.10" @@ -2785,78 +2828,65 @@ graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: core-js "^2.5.3" source-map-support "^0.5.1" -graphql-import@^0.4.0: - version "0.4.5" - resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.4.5.tgz#e2f18c28d335733f46df8e0733d8deb1c6e2a645" - integrity sha512-G/+I08Qp6/QGTb9qapknCm3yPHV0ZL7wbaalWFpxsfR8ZhZoTBe//LsbsCKlbALQpcMegchpJhpTSKiJjhaVqQ== - dependencies: - lodash "^4.17.4" - -graphql-import@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.6.0.tgz#c00cb8a269ceea263e062922c8c81a2272d1ffcb" - integrity sha512-S6Aj4pTzehCwyh7hKUKlWLgE6soDdW/T6JPePC16exzFDNdZHXRj7lqv75yMWJCkBY0pBtWicMLinb4ni6QRyg== +graphql-import@^0.7.0, graphql-import@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.7.1.tgz#4add8d91a5f752d764b0a4a7a461fcd93136f223" + integrity sha512-YpwpaPjRUVlw2SN3OPljpWbVRWAhMAyfSba5U47qGMOSsPLi2gYeJtngGpymjm9nk57RFWEpjqwh4+dpYuFAPw== dependencies: lodash "^4.17.4" + resolve-from "^4.0.0" 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@1.6.6: - version "1.6.6" - resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.6.6.tgz#f40f4e836ced479df718dbc1869ea4cd3b64027b" - integrity sha512-1rSSPEJOhBMwNCBCp5CCh3YZFvo8qN/pzQM8k50pd/w2hBsBvOx0AVU9Or6JQbTXxYrKFXvKFUxC5Lp+2oeUtw== +graphql-middleware@1.7.7: + version "1.7.7" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.7.tgz#0a7a7193a873c4769401df2aef4ffb9c6ca97f43" + integrity sha512-Y4aXFMVLaGiZ19ukibZ4x/RejuUPhsJteijQFRlvmkGpF+XBHG/xozeDTWt0M1aJRjJWmwjna0nko6/o/DJQRQ== dependencies: - graphql-tools "^3.0.5" + graphql-tools "^4.0.1" -graphql-middleware@1.7.6: +graphql-middleware@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-2.0.2.tgz#99a3b0ff3f3e3fa66c6ddc8608e6e4eb1d2bb99c" + integrity sha512-qDmot+DU2XTRnWS3SJGRUUPQ9jhma9AtUR1GtWnqq3JkzoqzT/dprxS7eszIj0c1gD5UrySpm4yM1fNbQcazwA== + dependencies: + graphql-tools "^4.0.3" + +graphql-playground-html@1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.4.tgz#be7c5a6213d67aeedf03d90b7e7d55fec4d42212" + integrity sha512-mnpAVYSR3TesYsJ5OLJVJMA0muTCw4npsCI1cKMtW35lbA6KljZkLkz3ZWXhEIYPnHKIeUHEtbn1ZGkEXtAxLg== + dependencies: + graphql-config "2.2.1" + +graphql-playground-middleware-express@1.7.6: version "1.7.6" - resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.6.tgz#f226bf6671f3d82a9378f8b335804c8e44d21733" - integrity sha512-nKWd6BVgsh6S2eDRIcm3TjJPmXEEmqK6DY2a8/nK11NrNAFpZCq+esSSPG1F0HZShsDdE/h3M+/jLcD/zKlMvA== + resolved "https://registry.yarnpkg.com/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.6.tgz#aca38d2b8e5147914fc8fa613d151edd4ed0bc44" + integrity sha512-fICPxYGIdhCxtFlwCnP3uZ2uRWeQ9wj7OkcWUiHNwaFma2TbRD5nNKaPA2u21YWha9xv26qIDxxcdW27F/lcbQ== dependencies: - graphql-tools "^4.0.0" + graphql-playground-html "1.6.4" -graphql-playground-html@1.5.5: - version "1.5.5" - resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.5.5.tgz#e2aca543eb66b435ead495b45244b2604d6b2d48" - integrity sha512-PzSywpEKcjbDUkV6e3ivEixvAuUJGyYmBUvuittzySe/RgwHRo0xKLD7HouUCTbpFfWMw8kRKhAUVtt7Ys97uw== +graphql-playground-middleware-lambda@1.7.6: + version "1.7.6" + resolved "https://registry.yarnpkg.com/graphql-playground-middleware-lambda/-/graphql-playground-middleware-lambda-1.7.6.tgz#03aa4e3592144f4eb390a216f09b39f6b29f12d2" + integrity sha512-C4XYi32UTwP4YpHBgK9hiuxGBULiNFTu7qeFjHGWoXQIg/lioydyKnd3hVWB06QRUoHWLQj/pAI9ay3bdzCx3w== dependencies: - graphql-config "2.0.0" + graphql-playground-html "1.6.4" -graphql-playground-html@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz#6ec4d54325ab2e5352506fdb89eb37c3fc718bf8" - integrity sha512-et3huQFEuAZgAiUfs9a+1Wo/JDX94k7XqNRc8LhpGT8k2NwIhMAbZKqudVF/Ww4+XDoEB4LUTSFGRPBYvKrcKQ== - dependencies: - graphql-config "2.0.0" - -graphql-playground-middleware-express@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.2.tgz#5f7bf3683494fe17893d1b54bbecee5e222c2e78" - integrity sha512-JvKsVOR/U5QguBtEvTt0ozQ49uh1C6cW8O1xR6krQpJZIxjLYqpgusLUddTiVkka6Q/A4/AXBohY85jPudxYDg== - dependencies: - graphql-playground-html "1.6.0" - -graphql-playground-middleware-lambda@1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/graphql-playground-middleware-lambda/-/graphql-playground-middleware-lambda-1.6.1.tgz#e0f1944558136dd3975570c92c702d6009cc779c" - integrity sha512-FO6XG9QRs+0AkwfAnL80u8A02xTg1rPUH+Ay13ASTs0nEePav5GkrWfL59ZY+sK4ZzFvz72aImuXAs3Ajn8VtA== - dependencies: - graphql-playground-html "1.5.5" - -graphql-request@^1.4.0: +graphql-request@^1.5.0: version "1.8.2" resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" integrity sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg== dependencies: cross-fetch "2.2.2" -graphql-shield@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.0.1.tgz#731fca9a69a540ff446edf9e5bec610da295f5cb" - integrity sha512-JLKf1Le0NFZzSSEzBMbl+mbGBsydHejYtTZ7RO5Ks/+HYXxdkBbBs4Cc/R7zAY9UW5lgpJzVNyC02NXBL34/Sw== +graphql-shield@~4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.1.0.tgz#8bd55179fd28d00e64ca5a7dbd3cffe82e282e73" + integrity sha512-r3m5t7FpLDyJQIby0IKyNrtp8k62hP/syhPcrpdT67UVNKh0jjjl+zpjXh/3PXeNZHPEAiBQTHhFjnC7H2B4SA== dependencies: object-hash "^1.3.0" opencollective "1.0.3" @@ -2868,28 +2898,19 @@ graphql-subscriptions@^0.5.8: dependencies: iterall "^1.2.1" -graphql-tag@^2.9.2: +graphql-subscriptions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-1.0.0.tgz#475267694b3bd465af6477dbab4263a3f62702b8" + integrity sha512-+ytmryoHF1LVf58NKEaNPRUzYyXplm120ntxfPcgOBC7TnK7Tv/4VRHeh4FAR9iL+O1bqhZs4nkibxQ+OA5cDQ== + dependencies: + iterall "^1.2.1" + +graphql-tag@^2.9.2, graphql-tag@~2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w== -graphql-tag@~2.9.2: - version "2.9.2" - resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.9.2.tgz#2f60a5a981375f430bf1e6e95992427dc18af686" - integrity sha512-qnNmof9pAqj/LUzs3lStP0Gw1qhdVCUS7Ab7+SUB6KD5aX1uqxWQRwMnOGTkhKuLvLNIs1TvNz+iS9kUGl1MhA== - -graphql-tools@^3.0.0, graphql-tools@^3.0.4, graphql-tools@^3.0.5: - version "3.1.1" - resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-3.1.1.tgz#d593358f01e7c8b1671a17b70ddb034dea9dbc50" - integrity sha512-yHvPkweUB0+Q/GWH5wIG60bpt8CTwBklCSzQdEHmRUgAdEQKxw+9B7zB3dG7wB3Ym7M7lfrS4Ej+jtDZfA2UXg== - dependencies: - apollo-link "^1.2.2" - apollo-utilities "^1.0.1" - deprecated-decorator "^0.1.6" - iterall "^1.1.3" - uuid "^3.1.0" - -graphql-tools@^4.0.0: +graphql-tools@^4.0.0, graphql-tools@^4.0.1, graphql-tools@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.3.tgz#23b5cb52c519212b1b2e4630a361464396ad264b" integrity sha512-NNZM0WSnVLX1zIMUxu7SjzLZ4prCp15N5L2T2ro02OVyydZ0fuCnZYRnx/yK9xjGWbZA0Q58yEO//Bv/psJWrg== @@ -2900,14 +2921,14 @@ graphql-tools@^4.0.0: iterall "^1.1.3" uuid "^3.1.0" -graphql-yoga@1.16.2: - version "1.16.2" - resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.16.2.tgz#083293a9cecab6283e883c5a482c5c920fa66585" - integrity sha512-dV7uEUm/tzl3K/gkHPBt718N+F0gmhZKsg8HJpj35SEniGyXVI3VjDWd7Na3bWdue4p8Sxb+/JguuK8jpe8dWg== +graphql-yoga@~1.16.7: + version "1.16.7" + resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.16.7.tgz#05bdfadf9a4623b0409bee3c5b75b7b3f7249e6f" + integrity sha512-N82SmBpKyDD7GXXo2NbVBMPffbxFWD+YOf/Vqx3Kujj/hNOX+0s/7G+EPp4TgJZqHQjcOw5TqQ0kOANO8w6Kmg== dependencies: "@types/cors" "^2.8.4" "@types/express" "^4.11.1" - "@types/graphql" "^0.13.0" + "@types/graphql" "^14.0.0" "@types/graphql-deduplicator" "^2.0.0" "@types/zen-observable" "^0.5.3" apollo-server-express "^1.3.6" @@ -2917,30 +2938,30 @@ graphql-yoga@1.16.2: body-parser-graphql "1.1.0" cors "^2.8.4" express "^4.16.3" - graphql "^0.11.0 || ^0.12.0 || ^0.13.0" + graphql "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0" graphql-deduplicator "^2.0.1" - graphql-import "^0.6.0" - graphql-middleware "1.6.6" - graphql-playground-middleware-express "1.7.2" - graphql-playground-middleware-lambda "1.6.1" + graphql-import "^0.7.0" + graphql-middleware "1.7.7" + graphql-playground-middleware-express "1.7.6" + graphql-playground-middleware-lambda "1.7.6" graphql-subscriptions "^0.5.8" - graphql-tools "^3.0.0" + graphql-tools "^4.0.0" subscriptions-transport-ws "^0.9.8" -"graphql@^0.11.0 || ^0.12.0 || ^0.13.0", graphql@~0.13.0: - version "0.13.2" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" - integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== - dependencies: - iterall "^1.2.1" - -graphql@^14.0.2: +"graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0", graphql@^14.0.2: version "14.0.2" resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.0.2.tgz#7dded337a4c3fd2d075692323384034b357f5650" integrity sha512-gUC4YYsaiSJT1h40krG3J+USGlwhzNTXSb4IOZljn9ag5Tj+RkoXrWp+Kh7WyE3t1NCfab5kzCuxBIvOMERMXw== dependencies: iterall "^1.2.2" +graphql@~0.13.0: + version "0.13.2" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" + integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== + dependencies: + iterall "^1.2.1" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -3019,14 +3040,6 @@ has@^1.0.1: dependencies: function-bind "^1.1.1" -hash.js@^1.1.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - he@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" @@ -3136,6 +3149,11 @@ ignore@^5.0.2: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.0.4.tgz#33168af4a21e99b00c5d41cbadb6a6cb49903a45" integrity sha512-WLsTMEhsQuXpCiG173+f3aymI43SXa+fB1rSfbzyP4GkPP+ZFVuO0/3sFUGNBtifisPeDcl/uD/Y2NxZ7xFq4g== +immutable-tuple@^0.4.9: + version "0.4.9" + resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.9.tgz#473ebdd6c169c461913a454bf87ef8f601a20ff0" + integrity sha512-LWbJPZnidF8eczu7XmcnLBsumuyRBkpwIRPCZxlojouhBo5jEBO4toj6n7hMy6IxHU/c+MqDSWkvaTpPlMQcyA== + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -3566,6 +3584,13 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -3578,7 +3603,12 @@ json5@^2.1.0: dependencies: minimist "^1.2.0" -jsonwebtoken@^8.2.0: +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonwebtoken@^8.2.0, jsonwebtoken@~8.4.0: version "8.4.0" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz#8757f7b4cb7440d86d5e2f3becefa70536c8e46a" integrity sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg== @@ -3593,21 +3623,6 @@ jsonwebtoken@^8.2.0: lodash.once "^4.0.0" ms "^2.1.1" -jsonwebtoken@~8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz#056c90eee9a65ed6e6c72ddb0a1d325109aaf643" - integrity sha512-oge/hvlmeJCH+iIz1DwcO7vKPkNGJHhgkspk8OH3VKlw+mbi42WtD4ig1+VXRln765vxptAv+xT26Fd3cteqag== - dependencies: - jws "^3.1.5" - lodash.includes "^4.3.0" - lodash.isboolean "^3.0.3" - lodash.isinteger "^4.0.4" - lodash.isnumber "^3.0.3" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.once "^4.0.0" - ms "^2.1.1" - jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -3810,13 +3825,12 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" -lru-cache@^4.1.3: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== +lru-cache@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" + yallist "^3.0.2" make-dir@^1.0.0: version "1.3.0" @@ -3909,11 +3923,6 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -4022,7 +4031,7 @@ negotiator@0.6.1: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= -neo4j-driver@^1.7.2: +neo4j-driver@^1.7.2, neo4j-driver@~1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.2.tgz#c72a6dfa6bd2106b00a42794dc52a82b227b48e0" integrity sha512-0IvCFYhcP9hb5JveZk33epbReDKpFTn2u5vAa8zzGG344i6yFqZrBo0mtC114ciP9zFjAtfNOP72mRm8+NV0Fg== @@ -4031,14 +4040,6 @@ neo4j-driver@^1.7.2: text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-driver@~1.6.1: - version "1.6.4" - resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.6.4.tgz#b190f28fdc3e91f02e9fcc32b3857ac2ce710f03" - integrity sha512-R3SU9EPmc5uHvFG/v1HJL+Oho63pKOms2KHKWh09mJDb3F3RigDNFKaqehu0t8ZhCY89e5QazK+pqQq78EDjVQ== - dependencies: - babel-runtime "^6.18.0" - uri-js "^4.2.1" - neo4j-graphql-js@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.0.1.tgz#76e10947873e1fde2e4f8427fe8d6a066aea2ce4" @@ -4061,12 +4062,12 @@ node-fetch@1.6.3: encoding "^0.1.11" is-stream "^1.0.1" -node-fetch@2.1.2, node-fetch@~2.1.2: +node-fetch@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= -node-fetch@^2.1.2: +node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== @@ -4092,10 +4093,10 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -node-releases@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.4.tgz#2d585de8c6c81d00017e063e7810a63889aa6756" - integrity sha512-GqRV9GcHw8JCRDaP/JoeNMNzEGzHAknMvIHqMb2VeTOmg1Cf9+ej8bkV12tHfzWHQMCkQ5zUFgwFUkfraynNCw== +node-releases@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.0.tgz#be7464fa8d877808237520fd49436d5e79191c3d" + integrity sha512-+qV91QMDBvARuPxUEfI/mRF/BY+UAkTIn3pvmvM2iOLIRvv6RNYklFXBgrkky6P1wXUqQW1P3qKlWxxy4JZbfg== dependencies: semver "^5.3.0" @@ -4291,6 +4292,13 @@ opn@4.0.2: object-assign "^4.0.1" pinkie-promise "^2.0.0" +optimism@^0.6.6: + version "0.6.8" + resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.8.tgz#0780b546da8cd0a72e5207e0c3706c990c8673a6" + integrity sha512-bN5n1KCxSqwBDnmgDnzMtQTHdL+uea2HYFx1smvtE+w2AMl0Uy31g0aXnP/Nt85OINnMJPRpJyfRQLTCqn5Weg== + dependencies: + immutable-tuple "^0.4.9" + optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" @@ -4943,6 +4951,11 @@ resolve-from@^1.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -5157,7 +5170,7 @@ slice-ansi@2.0.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -slug@~0.9.1: +slug@~0.9.2: version "0.9.2" resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.2.tgz#e409e4dae3a4bd2fd283557e2806e0a8abb98242" integrity sha512-WULwxWq6NBM/i24pV9st/WI9TwzjXYpNzxbWr9mRDj74Lqwb3ahsnWsWJtXHfBPpBqXb4m1hYt9S7eMyDkZsKA== @@ -5845,6 +5858,13 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" +ws@^6.0.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" + integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== + dependencies: + async-limiter "~1.0.0" + xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" @@ -5909,7 +5929,7 @@ yargs@^12.0.1: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -zen-observable-ts@^0.8.10, zen-observable-ts@^0.8.11: +zen-observable-ts@^0.8.11: version "0.8.11" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.11.tgz#d54a27cd17dc4b4bb6bd008e5c096af7fcb068a9" integrity sha512-8bs7rgGV4kz5iTb9isudkuQjtWwPnQ8lXq6/T76vrepYZVMsDEv6BXaEA+DHdJSK3KVLduagi9jSpSAJ5NgKHw== From 1d92f0ad24f3c1e460a6aecafab537382eb2f910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sat, 8 Dec 2018 01:22:35 +0100 Subject: [PATCH 140/554] Replace concurrently with npm-run-all Package npm-run-all is specialized on npm scripts and does not hang with docker-compose. --- package.json | 10 +- yarn.lock | 1093 ++++---------------------------------------------- 2 files changed, 81 insertions(+), 1022 deletions(-) diff --git a/package.json b/package.json index 8529a6d9f..468ae69f4 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,10 @@ "test": "echo \"Error: no test specified\" && exit 0", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "db:script:seed": "wait-on tcp:4001 && $npm_package_config_no_auth ./node_modules/.bin/babel-node src/seed/seed-db.js", - "db:script:reset": "wait-on tcp:4001 && $npm_package_config_no_auth ./node_modules/.bin/babel-node src/seed/reset-db.js", - "db:seed": "concurrently --kill-others --success first -n no-auth-server,seed '$npm_package_config_no_auth yarn run start' 'yarn run db:script:seed'", - "db:reset": "concurrently --kill-others --success first -n no-auth-server,reset '$npm_package_config_no_auth yarn run start' 'yarn run db:script:reset'" + "db:script:seed": "wait-on tcp:4001 && ./node_modules/.bin/babel-node src/seed/seed-db.js", + "db:script:reset": "wait-on tcp:4001 && ./node_modules/.bin/babel-node src/seed/reset-db.js", + "db:seed": "$npm_package_config_no_auth run-p --race start db:script:seed", + "db:reset": "$npm_package_config_no_auth run-p --race start db:script:reset" }, "author": "Human Connection gGmbH", "license": "MIT", @@ -53,7 +53,6 @@ }, "devDependencies": { "babel-eslint": "^10.0.1", - "concurrently": "^4.1.0", "cross-env": "^5.2.0", "eslint": "^5.9.0", "eslint-config-standard": "^12.0.0", @@ -63,6 +62,7 @@ "eslint-plugin-standard": "^4.0.0", "faker": "^4.1.0", "nodemon": "^1.18.7", + "npm-run-all": "^4.1.5", "wait-on": "^3.2.0" } } diff --git a/yarn.lock b/yarn.lock index 1ac67ea81..356903cdb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,14 +5,12 @@ "@apollographql/apollo-tools@^0.2.6": version "0.2.8" resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.2.8.tgz#f755baa3576eabdd93afa2782be61f5ae8a856dc" - integrity sha512-A7FTUigtpGCFBaLT1ILicdjM6pZ7LQNw7Vgos0t4aLYtvlKO/L1nMi/NO7bPypzZaJSToTgcxHJPRydP1Md+Kw== dependencies: apollo-env "0.2.5" "@apollographql/apollo-upload-server@^5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" - integrity sha512-tGAp3ULNyoA8b5o9LsU2Lq6SwgVPUOKAqKywu2liEtTvrFSGPrObwanhYwArq3GPeOqp2bi+JknSJCIU3oQN1Q== dependencies: "@babel/runtime-corejs2" "^7.0.0-rc.1" busboy "^0.2.14" @@ -21,12 +19,10 @@ "@apollographql/graphql-playground-html@^1.6.6": version "1.6.6" resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz#022209e28a2b547dcde15b219f0c50f47aa5beb3" - integrity sha512-lqK94b+caNtmKFs5oUVXlSpN3sm5IXZ+KfhMxOtr0LR2SqErzkoJilitjDvJ1WbjHlxLI7WtCjRmOLdOGJqtMQ== "@babel/cli@^7.1.5": version "7.1.5" resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.1.5.tgz#4ccf0a8cdabeefdd8ce955384530f050935bc4d7" - integrity sha512-zbO/DtTnaDappBflIU3zYEgATLToRDmW5uN/EGH1GXaes7ydfjqmAoK++xmJIA+8HfDw7UyPZNdM8fhGhfmMhw== dependencies: commander "^2.8.1" convert-source-map "^1.1.0" @@ -43,14 +39,12 @@ "@babel/code-frame@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== dependencies: "@babel/highlight" "^7.0.0" "@babel/core@^7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.6.tgz#3733cbee4317429bc87c62b29cf8587dba7baeb3" - integrity sha512-Hz6PJT6e44iUNpAn8AoyAs6B3bl60g7MJQaI0rZEar6ECzh6+srYO1xlIdssio34mPaUtAb1y+XlkkSJzok3yw== dependencies: "@babel/code-frame" "^7.0.0" "@babel/generator" "^7.1.6" @@ -70,7 +64,6 @@ "@babel/generator@^7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.6.tgz#001303cf87a5b9d093494a4bf251d7b5d03d3999" - integrity sha512-brwPBtVvdYdGxtenbQgfCdDPmtkmUBZPjUoK5SXJEBuHaA5BCubh9ly65fzXz7R6o5rA76Rs22ES8Z+HCc0YIQ== dependencies: "@babel/types" "^7.1.6" jsesc "^2.5.1" @@ -81,14 +74,12 @@ "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" - integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== dependencies: "@babel/types" "^7.0.0" "@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" - integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== dependencies: "@babel/helper-explode-assignable-expression" "^7.1.0" "@babel/types" "^7.0.0" @@ -96,7 +87,6 @@ "@babel/helper-call-delegate@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz#6a957f105f37755e8645343d3038a22e1449cc4a" - integrity sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ== dependencies: "@babel/helper-hoist-variables" "^7.0.0" "@babel/traverse" "^7.1.0" @@ -105,7 +95,6 @@ "@babel/helper-define-map@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c" - integrity sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/types" "^7.0.0" @@ -114,7 +103,6 @@ "@babel/helper-explode-assignable-expression@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" - integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== dependencies: "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" @@ -122,7 +110,6 @@ "@babel/helper-function-name@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" - integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== dependencies: "@babel/helper-get-function-arity" "^7.0.0" "@babel/template" "^7.1.0" @@ -131,35 +118,30 @@ "@babel/helper-get-function-arity@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" - integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== dependencies: "@babel/types" "^7.0.0" "@babel/helper-hoist-variables@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz#46adc4c5e758645ae7a45deb92bab0918c23bb88" - integrity sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w== dependencies: "@babel/types" "^7.0.0" "@babel/helper-member-expression-to-functions@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" - integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg== dependencies: "@babel/types" "^7.0.0" "@babel/helper-module-imports@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" - integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== dependencies: "@babel/types" "^7.0.0" "@babel/helper-module-transforms@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.1.0.tgz#470d4f9676d9fad50b324cdcce5fbabbc3da5787" - integrity sha512-0JZRd2yhawo79Rcm4w0LwSMILFmFXjugG3yqf+P/UsKsRS1mJCmMwwlHDlMg7Avr9LrvSpp4ZSULO9r8jpCzcw== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" @@ -171,26 +153,22 @@ "@babel/helper-optimise-call-expression@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" - integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== dependencies: "@babel/types" "^7.0.0" "@babel/helper-plugin-utils@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" - integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== "@babel/helper-regex@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27" - integrity sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg== dependencies: lodash "^4.17.10" "@babel/helper-remap-async-to-generator@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" - integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-wrap-function" "^7.1.0" @@ -201,7 +179,6 @@ "@babel/helper-replace-supers@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz#5fc31de522ec0ef0899dc9b3e7cf6a5dd655f362" - integrity sha512-BvcDWYZRWVuDeXTYZWxekQNO5D4kO55aArwZOTFXw6rlLQA8ZaDicJR1sO47h+HrnCiDFiww0fSPV0d713KBGQ== dependencies: "@babel/helper-member-expression-to-functions" "^7.0.0" "@babel/helper-optimise-call-expression" "^7.0.0" @@ -211,7 +188,6 @@ "@babel/helper-simple-access@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" - integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== dependencies: "@babel/template" "^7.1.0" "@babel/types" "^7.0.0" @@ -219,14 +195,12 @@ "@babel/helper-split-export-declaration@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" - integrity sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag== dependencies: "@babel/types" "^7.0.0" "@babel/helper-wrap-function@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.1.0.tgz#8cf54e9190706067f016af8f75cb3df829cc8c66" - integrity sha512-R6HU3dete+rwsdAfrOzTlE9Mcpk4RjU3aX3gi9grtmugQY0u79X7eogUvfXA5sI81Mfq1cn6AgxihfN33STjJA== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/template" "^7.1.0" @@ -236,7 +210,6 @@ "@babel/helpers@^7.1.5": version "7.1.5" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.1.5.tgz#68bfc1895d685f2b8f1995e788dbfe1f6ccb1996" - integrity sha512-2jkcdL02ywNBry1YNFAH/fViq4fXG0vdckHqeJk+75fpQ2OH+Az6076tX/M0835zA45E0Cqa6pV5Kiv9YOqjEg== dependencies: "@babel/template" "^7.1.2" "@babel/traverse" "^7.1.5" @@ -245,7 +218,6 @@ "@babel/highlight@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" - integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== dependencies: chalk "^2.0.0" esutils "^2.0.2" @@ -254,7 +226,6 @@ "@babel/node@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.0.0.tgz#20e55bb0e015700a0f6ff281c712de7619ad56f4" - integrity sha512-mKbN8Bb1TzH9YnKMWMhBRX+o5MVJHtUSalNcsiGa4FRgVfY7ozqkbttuIDWqeXxZ3rwI9ZqmCUr9XsPV2VYlSw== dependencies: "@babel/polyfill" "^7.0.0" "@babel/register" "^7.0.0" @@ -267,12 +238,10 @@ "@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.6.tgz#16e97aca1ec1062324a01c5a6a7d0df8dd189854" - integrity sha512-dWP6LJm9nKT6ALaa+bnL247GHHMWir3vSlZ2+IHgHgktZQx0L3Uvq2uAWcuzIe+fujRsYWBW2q622C5UvGK9iQ== "@babel/plugin-proposal-async-generator-functions@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce" - integrity sha512-Fq803F3Jcxo20MXUSDdmZZXrPe6BWyGcWBPPNB/M7WaUYESKDeKMOGIxEzQOjGSmW/NWb6UaPZrtTB2ekhB/ew== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-remap-async-to-generator" "^7.1.0" @@ -281,7 +250,6 @@ "@babel/plugin-proposal-json-strings@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz#3b4d7b5cf51e1f2e70f52351d28d44fc2970d01e" - integrity sha512-kfVdUkIAGJIVmHmtS/40i/fg/AGnw/rsZBCaapY5yjeO5RA9m165Xbw9KMOu2nqXP5dTFjEjHdfNdoVcHv133Q== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-json-strings" "^7.0.0" @@ -289,7 +257,6 @@ "@babel/plugin-proposal-object-rest-spread@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e" - integrity sha512-14fhfoPcNu7itSen7Py1iGN0gEm87hX/B+8nZPqkdmANyyYWYMY2pjA3r8WXbWVKMzfnSNS0xY8GVS0IjXi/iw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.0.0" @@ -297,7 +264,6 @@ "@babel/plugin-proposal-optional-catch-binding@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425" - integrity sha512-JPqAvLG1s13B/AuoBjdBYvn38RqW6n1TzrQO839/sIpqLpbnXKacsAgpZHzLD83Sm8SDXMkkrAvEnJ25+0yIpw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" @@ -305,7 +271,6 @@ "@babel/plugin-proposal-unicode-property-regex@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz#498b39cd72536cd7c4b26177d030226eba08cd33" - integrity sha512-tM3icA6GhC3ch2SkmSxv7J/hCWKISzwycub6eGsDrFDgukD4dZ/I+x81XgW0YslS6mzNuQ1Cbzh5osjIMgepPQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" @@ -314,42 +279,36 @@ "@babel/plugin-syntax-async-generators@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz#bf0891dcdbf59558359d0c626fdc9490e20bc13c" - integrity sha512-im7ged00ddGKAjcZgewXmp1vxSZQQywuQXe2B1A7kajjZmDeY/ekMPmWr9zJgveSaQH0k7BcGrojQhcK06l0zA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-json-strings@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz#0d259a68090e15b383ce3710e01d5b23f3770cbd" - integrity sha512-UlSfNydC+XLj4bw7ijpldc1uZ/HB84vw+U6BTuqMdIEmz/LDe63w/GHtpQMdXWdqQZFeAI9PjnHe/vDhwirhKA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b" - integrity sha512-5A0n4p6bIiVe5OvQPxBnesezsgFJdHhSs3uFSvaPdMqtsovajLZ+G2vZyvNe10EzJBWWo3AcHGKhAFUxqwp2dw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-optional-catch-binding@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475" - integrity sha512-Wc+HVvwjcq5qBg1w5RG9o9RVzmCaAg/Vp0erHCKpAYV8La6I94o4GQAmFYNmkzoMO6gzoOSulpKeSSz6mPEoZw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-arrow-functions@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749" - integrity sha512-2EZDBl1WIO/q4DIkIp4s86sdp4ZifL51MoIviLY/gG/mLSuOIEg7J8o6mhbxOTvUJkaN50n+8u41FVsr5KLy/w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-async-to-generator@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811" - integrity sha512-rNmcmoQ78IrvNCIt/R9U+cixUHeYAzgusTFgIAv+wQb9HJU4szhpDD6e5GCACmj/JP5KxuCwM96bX3L9v4ZN/g== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -358,14 +317,12 @@ "@babel/plugin-transform-block-scoped-functions@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz#482b3f75103927e37288b3b67b65f848e2aa0d07" - integrity sha512-AOBiyUp7vYTqz2Jibe1UaAWL0Hl9JUXEgjFvvvcSc9MVDItv46ViXFw2F7SVt1B5k+KWjl44eeXOAk3UDEaJjQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-block-scoping@^7.1.5": version "7.1.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.1.5.tgz#3e8e0bc9a5104519923302a24f748f72f2f61f37" - integrity sha512-jlYcDrz+5ayWC7mxgpn1Wj8zj0mmjCT2w0mPIMSwO926eXBRxpEgoN/uQVRBfjtr8ayjcmS+xk2G1jaP8JjMJQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.10" @@ -373,7 +330,6 @@ "@babel/plugin-transform-classes@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249" - integrity sha512-rNaqoD+4OCBZjM7VaskladgqnZ1LO6o2UxuWSDzljzW21pN1KXkB7BstAVweZdxQkHAujps5QMNOTWesBciKFg== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-define-map" "^7.1.0" @@ -387,21 +343,18 @@ "@babel/plugin-transform-computed-properties@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31" - integrity sha512-ubouZdChNAv4AAWAgU7QKbB93NU5sHwInEWfp+/OzJKA02E6Woh9RVoX4sZrbRwtybky/d7baTUqwFx+HgbvMA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-destructuring@^7.0.0": version "7.1.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.1.3.tgz#e69ff50ca01fac6cb72863c544e516c2b193012f" - integrity sha512-Mb9M4DGIOspH1ExHOUnn2UUXFOyVTiX84fXCd+6B5iWrQg/QMeeRmSwpZ9lnjYLSXtZwiw80ytVMr3zue0ucYw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-dotall-regex@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz#73a24da69bc3c370251f43a3d048198546115e58" - integrity sha512-00THs8eJxOJUFVx1w8i1MBF4XH4PsAjKjQ1eqN/uCH3YKwP21GCKfrn6YZFZswbOk9+0cw1zGQPHVc1KBlSxig== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" @@ -410,14 +363,12 @@ "@babel/plugin-transform-duplicate-keys@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz#a0601e580991e7cace080e4cf919cfd58da74e86" - integrity sha512-w2vfPkMqRkdxx+C71ATLJG30PpwtTpW7DDdLqYt2acXU7YjztzeWW2Jk1T6hKqCLYCcEA5UQM/+xTAm+QCSnuQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-exponentiation-operator@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73" - integrity sha512-uZt9kD1Pp/JubkukOGQml9tqAeI8NkE98oZnHZ2qHRElmeKCodbTZgOEUtujSCSLhHSBWbzNiFSDIMC4/RBTLQ== dependencies: "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -425,14 +376,12 @@ "@babel/plugin-transform-for-of@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39" - integrity sha512-TlxKecN20X2tt2UEr2LNE6aqA0oPeMT1Y3cgz8k4Dn1j5ObT8M3nl9aA37LLklx0PBZKETC9ZAf9n/6SujTuXA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-function-name@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb" - integrity sha512-VxOa1TMlFMtqPW2IDYZQaHsFrq/dDoIjgN098NowhexhZcz3UGlvPgZXuE1jEvNygyWyxRacqDpCZt+par1FNg== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -440,14 +389,12 @@ "@babel/plugin-transform-literals@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86" - integrity sha512-1NTDBWkeNXgpUcyoVFxbr9hS57EpZYXpje92zv0SUzjdu3enaRwF/l3cmyRnXLtIdyJASyiS6PtybK+CgKf7jA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-modules-amd@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.1.0.tgz#f9e0a7072c12e296079b5a59f408ff5b97bf86a8" - integrity sha512-wt8P+xQ85rrnGNr2x1iV3DW32W8zrB6ctuBkYBbf5/ZzJY99Ob4MFgsZDFgczNU76iy9PWsy4EuxOliDjdKw6A== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -455,7 +402,6 @@ "@babel/plugin-transform-modules-commonjs@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c" - integrity sha512-wtNwtMjn1XGwM0AXPspQgvmE6msSJP15CX2RVfpTSTNPLhKhaOjaIfBaVfj4iUZ/VrFSodcFedwtPg/NxwQlPA== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -464,7 +410,6 @@ "@babel/plugin-transform-modules-systemjs@^7.0.0": version "7.1.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.1.3.tgz#2119a3e3db612fd74a19d88652efbfe9613a5db0" - integrity sha512-PvTxgjxQAq4pvVUZF3mD5gEtVDuId8NtWkJsZLEJZMZAW3TvgQl1pmydLLN1bM8huHFVVU43lf0uvjQj9FRkKw== dependencies: "@babel/helper-hoist-variables" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -472,7 +417,6 @@ "@babel/plugin-transform-modules-umd@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.1.0.tgz#a29a7d85d6f28c3561c33964442257cc6a21f2a8" - integrity sha512-enrRtn5TfRhMmbRwm7F8qOj0qEYByqUvTttPEGimcBH4CJHphjyK1Vg7sdU7JjeEmgSpM890IT/efS2nMHwYig== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -480,14 +424,12 @@ "@babel/plugin-transform-new-target@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz#ae8fbd89517fa7892d20e6564e641e8770c3aa4a" - integrity sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-object-super@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.1.0.tgz#b1ae194a054b826d8d4ba7ca91486d4ada0f91bb" - integrity sha512-/O02Je1CRTSk2SSJaq0xjwQ8hG4zhZGNjE8psTsSNPXyLRCODv7/PBozqT5AmQMzp7MI3ndvMhGdqp9c96tTEw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-replace-supers" "^7.1.0" @@ -495,7 +437,6 @@ "@babel/plugin-transform-parameters@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed" - integrity sha512-vHV7oxkEJ8IHxTfRr3hNGzV446GAb+0hgbA7o/0Jd76s+YzccdWuTU296FOCOl/xweU4t/Ya4g41yWz80RFCRw== dependencies: "@babel/helper-call-delegate" "^7.1.0" "@babel/helper-get-function-arity" "^7.0.0" @@ -504,28 +445,24 @@ "@babel/plugin-transform-regenerator@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz#5b41686b4ed40bef874d7ed6a84bdd849c13e0c1" - integrity sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw== dependencies: regenerator-transform "^0.13.3" "@babel/plugin-transform-shorthand-properties@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15" - integrity sha512-g/99LI4vm5iOf5r1Gdxq5Xmu91zvjhEG5+yZDJW268AZELAu4J1EiFLnkSG3yuUsZyOipVOVUKoGPYwfsTymhw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-spread@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b" - integrity sha512-L702YFy2EvirrR4shTj0g2xQp7aNwZoWNCkNu2mcoU0uyzMl0XRwDSwzB/xp6DSUFiBmEXuyAyEN16LsgVqGGQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-sticky-regex@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366" - integrity sha512-LFUToxiyS/WD+XEWpkx/XJBrUXKewSZpzX68s+yEOtIbdnsRjpryDw9U06gYc6klYEij/+KQVRnD3nz3AoKmjw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" @@ -533,7 +470,6 @@ "@babel/plugin-transform-template-literals@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65" - integrity sha512-vA6rkTCabRZu7Nbl9DfLZE1imj4tzdWcg5vtdQGvj+OH9itNNB6hxuRMHuIY8SGnEt1T9g5foqs9LnrHzsqEFg== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -541,14 +477,12 @@ "@babel/plugin-transform-typeof-symbol@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz#4dcf1e52e943e5267b7313bff347fdbe0f81cec9" - integrity sha512-1r1X5DO78WnaAIvs5uC48t41LLckxsYklJrZjNKcevyz83sF2l4RHbw29qrCPr/6ksFsdfRpT/ZgxNWHXRnffg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-unicode-regex@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc" - integrity sha512-uJBrJhBOEa3D033P95nPHu3nbFwFE9ZgXsfEitzoIXIwqAZWk7uXcg06yFKXz9FSxBH5ucgU/cYdX0IV8ldHKw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" @@ -557,7 +491,6 @@ "@babel/polyfill@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.0.0.tgz#c8ff65c9ec3be6a1ba10113ebd40e8750fb90bff" - integrity sha512-dnrMRkyyr74CRelJwvgnnSUDh2ge2NCTyHVwpOdvRMHtJUyxLtMAfhBN3s64pY41zdw0kgiLPh6S20eb1NcX6Q== dependencies: core-js "^2.5.7" regenerator-runtime "^0.11.1" @@ -565,7 +498,6 @@ "@babel/preset-env@^7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.1.6.tgz#a0bf4b96b6bfcf6e000afc5b72b4abe7cc13ae97" - integrity sha512-YIBfpJNQMBkb6MCkjz/A9J76SNCSuGVamOVBgoUkLzpJD/z8ghHi9I42LQ4pulVX68N/MmImz6ZTixt7Azgexw== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -612,7 +544,6 @@ "@babel/register@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.0.0.tgz#fa634bae1bfa429f60615b754fc1f1d745edd827" - integrity sha512-f/+CRmaCe7rVEvcvPvxeA8j5aJhHC3aJie7YuqcMDhUOuyWLA7J/aNrTaHIzoWPEhpHA54mec4Mm8fv8KBlv3g== dependencies: core-js "^2.5.7" find-cache-dir "^1.0.0" @@ -625,7 +556,6 @@ "@babel/runtime-corejs2@^7.0.0-rc.1": version "7.1.5" resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.1.5.tgz#ec8341c9aec71d1139c985327314739d66b204a0" - integrity sha512-WsYRwQsFhVmxkAqwypPTZyV9GpkqMEaAr2zOItOmqSX2GBFaI+eq98CN81e13o0zaUKJOQGYyjhNVqj56nnkYg== dependencies: core-js "^2.5.7" regenerator-runtime "^0.12.0" @@ -633,14 +563,12 @@ "@babel/runtime@^7.0.0-beta.40": version "7.1.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.5.tgz#4170907641cf1f61508f563ece3725150cc6fe39" - integrity sha512-xKnPpXG/pvK1B90JkwwxSGii90rQGKtzcMt2gI5G6+M0REXaq6rOHsGC2ay6/d0Uje7zzvSzjEzfR3ENhFlrfA== dependencies: regenerator-runtime "^0.12.0" "@babel/template@^7.1.0", "@babel/template@^7.1.2": version "7.1.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" - integrity sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag== dependencies: "@babel/code-frame" "^7.0.0" "@babel/parser" "^7.1.2" @@ -649,7 +577,6 @@ "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.6.tgz#c8db9963ab4ce5b894222435482bd8ea854b7b5c" - integrity sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ== dependencies: "@babel/code-frame" "^7.0.0" "@babel/generator" "^7.1.6" @@ -664,7 +591,6 @@ "@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.5", "@babel/types@^7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.6.tgz#0adb330c3a281348a190263aceb540e10f04bcce" - integrity sha512-DMiUzlY9DSjVsOylJssxLHSgj6tWM9PRFJOGW/RaOglVOK9nzTxoOMfTfRQXGUCUQ/HmlG2efwC+XqUEJ5ay4w== dependencies: esutils "^2.0.2" lodash "^4.17.10" @@ -673,27 +599,22 @@ "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= "@protobufjs/base64@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== "@protobufjs/codegen@^2.0.4": version "2.0.4" resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== "@protobufjs/eventemitter@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= "@protobufjs/fetch@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= dependencies: "@protobufjs/aspromise" "^1.1.1" "@protobufjs/inquire" "^1.1.0" @@ -701,44 +622,36 @@ "@protobufjs/float@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= "@protobufjs/inquire@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= "@protobufjs/path@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= "@protobufjs/pool@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= "@protobufjs/utf8@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= "@types/accepts@^1.3.5": version "1.3.5" resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" - integrity sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ== dependencies: "@types/node" "*" "@types/async@2.0.50": version "2.0.50" resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.50.tgz#117540e026d64e1846093abbd5adc7e27fda7bcb" - integrity sha512-VMhZMMQgV1zsR+lX/0IBfAk+8Eb7dPVMWiQGFAt3qjo5x7Ml6b77jUo0e1C3ToD+XRDXqtrfw+6AB0uUsPEr3Q== "@types/body-parser@*", "@types/body-parser@1.17.0": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" - integrity sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w== dependencies: "@types/connect" "*" "@types/node" "*" @@ -746,26 +659,22 @@ "@types/connect@*": version "3.4.32" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" - integrity sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg== dependencies: "@types/node" "*" "@types/cors@^2.8.4": version "2.8.4" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.4.tgz#50991a759a29c0b89492751008c6af7a7c8267b0" - integrity sha512-ipZjBVsm2tF/n8qFGOuGBkUij9X9ZswVi9G3bx/6dz7POpVa6gVHcj1wsX/LVEn9MMF41fxK/PnZPPoTD1UFPw== dependencies: "@types/express" "*" "@types/events@*": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" - integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== "@types/express-serve-static-core@*": version "4.16.0" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz#fdfe777594ddc1fe8eb8eccce52e261b496e43e7" - integrity sha512-lTeoCu5NxJU4OD9moCgm0ESZzweAx0YqsAcab6OB0EB3+As1OaHtKnaGJvcngQxYsi9UNv0abn4/DRavrRxt4w== dependencies: "@types/events" "*" "@types/node" "*" @@ -774,7 +683,6 @@ "@types/express@*", "@types/express@4.16.0", "@types/express@^4.11.1": version "4.16.0" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.0.tgz#6d8bc42ccaa6f35cf29a2b7c3333cb47b5a32a19" - integrity sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "*" @@ -783,37 +691,30 @@ "@types/graphql-deduplicator@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/graphql-deduplicator/-/graphql-deduplicator-2.0.0.tgz#9e577b8f3feb3d067b0ca756f4a1fb356d533922" - integrity sha512-swUwj5hWF1yFzbUXStLJrUa0ksAt11B8+SwhsAjQAX0LYJ1LLioAyuDcJ9bovWbsNzIXJYXLvljSPQw8nR728w== "@types/graphql@^0.13.0": version "0.13.4" resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.13.4.tgz#55ae9c29f0fd6b85ee536f5c72b4769d5c5e06b1" - integrity sha512-B4yel4ro2nTb3v0pYO8vO6SjgvFJSrwUY+IO6TUSLdOSB+gQFslylrhRCHxvXMIhxB71mv5PEE9dAX+24S8sew== "@types/long@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" - integrity sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q== "@types/mime@*": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" - integrity sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA== "@types/node@*", "@types/node@^10.1.0": version "10.12.10" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.10.tgz#4fa76e6598b7de3f0cb6ec3abacc4f59e5b3a2ce" - integrity sha512-8xZEYckCbUVgK8Eg7lf5Iy4COKJ5uXlnIOnePN0WUwSQggy9tolM+tDJf7wMOnT/JT/W9xDYIaYggt3mRV2O5w== "@types/range-parser@*": version "1.2.2" resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.2.tgz#fa8e1ad1d474688a757140c91de6dace6f4abc8d" - integrity sha512-HtKGu+qG1NPvYe1z7ezLsyIaXYyi8SoAVqWDZgDQ8dLrsZvSzUNCwZyfX33uhWxL/SU0ZDQZ3nwZ0nimt507Kw== "@types/serve-static@*": version "1.13.2" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48" - integrity sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q== dependencies: "@types/express-serve-static-core" "*" "@types/mime" "*" @@ -821,7 +722,6 @@ "@types/ws@^6.0.0": version "6.0.1" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28" - integrity sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q== dependencies: "@types/events" "*" "@types/node" "*" @@ -829,22 +729,18 @@ "@types/zen-observable@^0.5.3": version "0.5.4" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.4.tgz#b863a4191e525206819e008097ebf0fb2e3a1cdc" - integrity sha512-sW6xN96wUak4tgc89d0tbTg7QDGYhGv5hvQIS6h4mRCd8h2btiZ80loPU8cyLwsBbA4ZeQt0FjvUhJ4rNhdsGg== "@types/zen-observable@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" - integrity sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg== abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== accepts@^1.3.5, accepts@~1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" - integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= dependencies: mime-types "~2.1.18" negotiator "0.6.1" @@ -852,17 +748,14 @@ accepts@^1.3.5, accepts@~1.3.5: acorn-jsx@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" - integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== acorn@^6.0.2: version "6.0.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" - integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== ajv@^6.5.3, ajv@^6.6.1: version "6.6.1" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.1.tgz#6360f5ed0d80f232cc2b294c362d5dc2e538dd61" - integrity sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -872,7 +765,6 @@ ajv@^6.5.3, ajv@^6.6.1: ajv@^6.5.5: version "6.5.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" - integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -882,51 +774,42 @@ ajv@^6.5.5: ansi-align@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" - integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= dependencies: string-width "^2.0.0" ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" - integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= ansi-regex@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" - integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== dependencies: micromatch "^3.1.4" normalize-path "^2.1.1" @@ -934,7 +817,6 @@ anymatch@^2.0.0: apollo-cache-control@0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.3.tgz#ad71d8f786e06f0275b2432004c15c2d37c48484" - integrity sha512-X6JhKfIaMLfl2jpsK/880BflXA+2lmm2sAsOZL4Bn2VrMsDtOssI1Ij9vNRbch9k9cA4WJvKed7Sql/wUIa1Eg== dependencies: apollo-server-env "2.2.0" graphql-extensions "0.3.3" @@ -942,14 +824,12 @@ apollo-cache-control@0.3.3: apollo-cache-control@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz#173d14ceb3eb9e7cb53de7eb8b61bee6159d4171" - integrity sha512-XJQs167e9u+e5ybSi51nGYr70NPBbswdvTEHtbtXbwkZ+n9t0SLPvUcoqceayOSwjK1XYOdU/EKPawNdb3rLQA== dependencies: graphql-extensions "^0.0.x" apollo-cache-inmemory@^1.2.5: version "1.3.11" resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.11.tgz#6cb8f24ec812715169f9acbb0b67833f9a19ec90" - integrity sha512-fSoyjBV5RV57J3i/VHDDB74ZgXc0PFiogheNFHEhC0mL6rg5e/DjTx0Vg+csIBk23gvlzTvV+eypx7Q2NJ+dYg== dependencies: apollo-cache "^1.1.21" apollo-utilities "^1.0.26" @@ -958,14 +838,12 @@ apollo-cache-inmemory@^1.2.5: apollo-cache@1.1.21, apollo-cache@^1.1.21: version "1.1.21" resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.21.tgz#950025e2272741ba8e5064419906e3ac4072925d" - integrity sha512-5ErNb78KHtrJNimkDBTEigcvHkIqUmS7QJIk4lpZZ+XLVVgvk2fD+GhD1PLP+s8vHfAKVbO6vdbRxCCjGGrh5w== dependencies: apollo-utilities "^1.0.26" apollo-client@^2.3.2: version "2.4.7" resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.7.tgz#b6712fd4c9ba346e3c44cfec7e6868e532b6a957" - integrity sha512-6aAm+16AFBYZhJF8eKxrup6AbYni01InDiwTfZhMMTP2xaXQWjsQnfaHbI2oE+hd3+AZFy1drkse8RZKghR/WQ== dependencies: "@types/zen-observable" "^0.8.0" apollo-cache "1.1.21" @@ -980,7 +858,6 @@ apollo-client@^2.3.2: apollo-datasource@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.2.1.tgz#3ecef4efe64f7a04a43862f32027d38ac09e142c" - integrity sha512-r185+JTa5KuF1INeTAk7AEP76zwMN6c8Ph1lmpzJMNwBUEzTGnLClrccCskCBx4SxfnkdKbuQdwn9JwCJUWrdg== dependencies: apollo-server-caching "0.2.1" apollo-server-env "2.2.0" @@ -988,14 +865,12 @@ apollo-datasource@0.2.1: apollo-engine-reporting-protobuf@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.1.0.tgz#fbc220cac2a3b7800ffc155d7e54c21c56b7848e" - integrity sha512-GReJtAYTmpwg0drb9VgFtqObYYTCHkJhlHEYCeXY8bJV4fOgXsAZ7CIXR9nPKO0mBaoHIHaGYvXGcyCLrZ36VA== dependencies: protobufjs "^6.8.6" apollo-engine-reporting@0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.3.tgz#85ad6ffd71db8f877202ce8b3d7dbfa7cabfbcf9" - integrity sha512-VkjiifHMHIAxydXecT+ck0WtqpFIsMlylKnKeuNAXfIfAXHX/JYtLhbArTTyhDunLrphMiUewfFv9P0K+aX2jw== dependencies: apollo-engine-reporting-protobuf "0.1.0" apollo-server-env "2.2.0" @@ -1006,7 +881,6 @@ apollo-engine-reporting@0.1.3: apollo-env@0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.2.5.tgz#162c785bccd2aea69350a7600fab4b7147fc9da5" - integrity sha512-Gc7TEbwCl7jJVutnn8TWfzNSkrrqyoo0DP92BQJFU9pZbJhpidoXf2Sw1YwOJl82rRKH3ujM3C8vdZLOgpFcFA== dependencies: core-js "^3.0.0-beta.3" node-fetch "^2.2.0" @@ -1014,21 +888,18 @@ apollo-env@0.2.5: apollo-link-dedup@^1.0.0: version "1.0.11" resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.11.tgz#6f34ea748d2834850329ad03111ef18445232b05" - integrity sha512-RcvkXR0CNbQcsw6LdrPksGa+9YjZ1ghk0k2PKal6rSBCyyqzokcBawXOtoMN8q+0FLR1dGs5GnAQVeucQuY28g== dependencies: apollo-link "^1.2.4" apollo-link-http-common@^0.2.6: version "0.2.6" resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.6.tgz#47b9012500599fe343e2e87378026384b4fc8c1f" - integrity sha512-LUOMWvrZuBP1hyWLBXyaW0KyFeKo79j+k3N+Q4HSkXKbLibnllXQ+JxxoSKGhm0bhREygiLtJAG9JnGlhxGO/Q== dependencies: apollo-link "^1.2.4" apollo-link-http@^1.5.4: version "1.5.7" resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.7.tgz#098615c427a910ec8c5817476bbabe68c586b339" - integrity sha512-EZ9nynHjwYCpGYP5IsRrZGTWidUVpshk7MuSG4joqGtJMwpFCgMQz+y3BHdUhowHtfAd9z60XmeOTG9FJolb8A== dependencies: apollo-link "^1.2.4" apollo-link-http-common "^0.2.6" @@ -1036,7 +907,6 @@ apollo-link-http@^1.5.4: apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.4.tgz#ab4d21d2e428db848e88b5e8f4adc717b19c954b" - integrity sha512-B1z+9H2nTyWEhMXRFSnoZ1vSuAYP+V/EdUJvRx9uZ8yuIBZMm6reyVtr1n0BWlKeSFyPieKJy2RLzmITAAQAMQ== dependencies: apollo-utilities "^1.0.0" zen-observable-ts "^0.8.11" @@ -1044,7 +914,6 @@ apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4: apollo-link@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.3.tgz#9bd8d5fe1d88d31dc91dae9ecc22474d451fb70d" - integrity sha512-iL9yS2OfxYhigme5bpTbmRyC+Htt6tyo2fRMHT3K1XRL/C5IQDDz37OjpPy4ndx7WInSvfSZaaOTKFja9VWqSw== dependencies: apollo-utilities "^1.0.0" zen-observable-ts "^0.8.10" @@ -1052,14 +921,12 @@ apollo-link@^1.2.2: apollo-server-caching@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.2.1.tgz#7e67f8c8cac829e622b394f0fb82579cabbeadfd" - integrity sha512-+U9F3X297LL8Gqy6ypfDNEv/DfV/tDht9Dr2z3AMaEkNW1bwO6rmdDL01zYxDuVDVq6Z3qSiNCSO2pXE2F0zmA== dependencies: lru-cache "^5.0.0" apollo-server-core@2.2.5: version "2.2.5" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.5.tgz#bf1538c10213be38a37dd8e6461461f7b808c57e" - integrity sha512-obz6VSJI7vSR+pEAZFwqOe/HAOuF4l1fYU9WNtVcQvxaKhykDgcu+byO0sXrOf/iB7uUIyaFdhinwzuwkqB8XQ== dependencies: "@apollographql/apollo-tools" "^0.2.6" "@apollographql/apollo-upload-server" "^5.0.3" @@ -1085,7 +952,6 @@ apollo-server-core@2.2.5: apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592" - integrity sha512-BP1Vh39krgEjkQxbjTdBURUjLHbFq1zeOChDJgaRsMxGtlhzuLWwwC6lLdPatN8jEPbeHq8Tndp9QZ3iQZOKKA== dependencies: apollo-cache-control "^0.1.0" apollo-tracing "^0.1.0" @@ -1094,7 +960,6 @@ apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: apollo-server-env@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.2.0.tgz#5eec5dbf46581f663fd6692b2e05c7e8ae6d6034" - integrity sha512-wjJiI5nQWPBpNmpiLP389Ezpstp71szS6DHAeTgYLb/ulCw3CTuuA+0/E1bsThVWiQaDeHZE0sE3yI8q2zrYiA== dependencies: node-fetch "^2.1.2" util.promisify "^1.0.0" @@ -1102,12 +967,10 @@ apollo-server-env@2.2.0: apollo-server-errors@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" - integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== apollo-server-express@2.2.5: version "2.2.5" resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.2.5.tgz#9d27d68b3b1cf2f96a107a3091ecdea4012745a2" - integrity sha512-2SNlY8CNmYlbRJfn0iK4wesjqX3X9YIFhyok4sQ80n/gm24QMwZkFcPP+NLv+1lxvwyJYMwEFQPIBvkLRoUFXQ== dependencies: "@apollographql/apollo-upload-server" "^5.0.3" "@apollographql/graphql-playground-html" "^1.6.6" @@ -1126,7 +989,6 @@ apollo-server-express@2.2.5: apollo-server-express@^1.3.6: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-1.4.0.tgz#7d7c58d6d6f9892b83fe575669093bb66738b125" - integrity sha512-zkH00nxhLnJfO0HgnNPBTfZw8qI5ILaPZ5TecMCI9+Y9Ssr2b0bFr9pBRsXy9eudPhI+/O4yqegSUsnLdF/CPw== dependencies: apollo-server-core "^1.4.0" apollo-server-module-graphiql "^1.4.0" @@ -1134,7 +996,6 @@ apollo-server-express@^1.3.6: apollo-server-lambda@1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/apollo-server-lambda/-/apollo-server-lambda-1.3.6.tgz#bdaac37f143c6798e40b8ae75580ba673cea260e" - integrity sha1-varDfxQ8Z5jkC4rnVYC6ZzzqJg4= dependencies: apollo-server-core "^1.3.6" apollo-server-module-graphiql "^1.3.4" @@ -1142,17 +1003,14 @@ apollo-server-lambda@1.3.6: apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" - integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== apollo-server-plugin-base@0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.5.tgz#899c4d7bc0d9a6d9f1181cc83a791479409086f8" - integrity sha512-be77TaN9l16ZVG1tBl8Re3lJfUZ6B2T3DdEXnu6fjQwUuBdu3Y4MQR6B1TLhbuTb9DUkcSKZ3h5C55dIjvb2Vg== apollo-server@^2.0.4: version "2.2.5" resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.2.5.tgz#412cf92a12939aac3890d4f0094a45dadfb89c79" - integrity sha512-Qf0FODtXzMJHhr6W8+NPu3ftxlL93o5s+aW9A35NZ305FuwgyriaQztaWILC+i4S/OxMTvuoCjNm9V+iVKackg== dependencies: apollo-server-core "2.2.5" apollo-server-express "2.2.5" @@ -1163,7 +1021,6 @@ apollo-server@^2.0.4: apollo-tracing@0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.3.tgz#b819942180480c1c4d89e613cf2eff8f6d8b595a" - integrity sha512-gsTYgDVjtMlnomPq46aky7yk8XshCQfj9rxalCCismLlMomVW44fq+8GKQnZIkFOwiAsazRy4dzZ0cBbygA9sA== dependencies: apollo-server-env "2.2.0" graphql-extensions "0.3.3" @@ -1171,14 +1028,12 @@ apollo-tracing@0.3.3: apollo-tracing@^0.1.0: version "0.1.4" resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" - integrity sha512-Uv+1nh5AsNmC3m130i2u3IqbS+nrxyVV3KYimH5QKsdPjxxIQB3JAT+jJmpeDxBel8gDVstNmCh82QSLxLSIdQ== dependencies: graphql-extensions "~0.0.9" apollo-upload-server@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/apollo-upload-server/-/apollo-upload-server-5.0.0.tgz#c953b523608313966e0c8444637f4ae8ef77d5bc" - integrity sha512-CzbHvMo/6TO5XrovzmV/ojTft17s9Cd+vKLGngChpB0UW1ObxKlNLlcXRLD+yt6Nec32/Kt209HmA31hnwxB/g== dependencies: "@babel/runtime" "^7.0.0-beta.40" busboy "^0.2.14" @@ -1187,19 +1042,16 @@ apollo-upload-server@^5.0.0: apollo-utilities@1.0.26, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.26: version "1.0.26" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.26.tgz#589c66bf4d16223531351cf667a230c787def1da" - integrity sha512-URw7o3phymliqYCYatcird2YRPUU2eWCNvip64U9gQrX56mEfK4m99yBIDCMTpmcvOFsKLii1sIEZsHIs/bvnw== dependencies: fast-json-stable-stringify "^2.0.0" aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== are-we-there-yet@~1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== dependencies: delegates "^1.0.0" readable-stream "^2.0.6" @@ -1207,103 +1059,96 @@ are-we-there-yet@~1.1.2: argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" array-uniq@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== dependencies: safer-buffer "~2.1.0" assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= assignment@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.0.0.tgz#ffd17b21bf5d6b22e777b989681a815456a3dd3e" - integrity sha1-/9F7Ib9dayLnd7mJaBqBVFaj3T4= assignment@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.2.0.tgz#f5b5bc2d160d69986e8700cd38f567c0aabe101e" - integrity sha1-9bW8LRYNaZhuhwDNOPVnwKq+EB4= astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - integrity sha1-GdOGodntxufByF04iu28xW0zYC0= async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== async-retry@^1.2.1: version "1.2.3" resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.2.3.tgz#a6521f338358d322b1a0012b79030c6f411d1ce0" - integrity sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q== dependencies: retry "0.12.0" asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== aws-lambda@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/aws-lambda/-/aws-lambda-0.1.2.tgz#19b1585075df31679597b976a5f1def61f12ccee" - integrity sha1-GbFYUHXfMWeVl7l2pfHe9h8SzO4= dependencies: aws-sdk "^*" commander "^2.5.0" @@ -1312,7 +1157,6 @@ aws-lambda@^0.1.2: aws-sdk@^*: version "2.360.0" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.360.0.tgz#f640acbc7de07aa7a381a31b110fc3502fe90288" - integrity sha512-bzr2j6s1LNlkWDTgnFszr2r7eJ2/DfWx4GJbGV17LKnxC9ZHkHKtX50sEa1g4Yzb1RveSXlC3Hfyus92gPQ4BQ== dependencies: buffer "4.9.1" events "1.1.1" @@ -1327,17 +1171,14 @@ aws-sdk@^*: aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" - integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== babel-eslint@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed" - integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ== dependencies: "@babel/code-frame" "^7.0.0" "@babel/parser" "^7.0.0" @@ -1349,7 +1190,6 @@ babel-eslint@^10.0.1: babel-polyfill@6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" - integrity sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0= dependencies: babel-runtime "^6.22.0" core-js "^2.4.0" @@ -1358,7 +1198,6 @@ babel-polyfill@6.23.0: babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= dependencies: core-js "^2.4.0" regenerator-runtime "^0.11.0" @@ -1366,22 +1205,18 @@ babel-runtime@^6.22.0, babel-runtime@^6.26.0: backo2@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" - integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2: version "1.3.0" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: cache-base "^1.0.1" class-utils "^0.3.5" @@ -1394,31 +1229,26 @@ base@^0.11.1: bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= dependencies: tweetnacl "^0.14.3" bcryptjs@^2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" - integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= binary-extensions@^1.0.0: version "1.12.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" - integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== body-parser-graphql@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/body-parser-graphql/-/body-parser-graphql-1.1.0.tgz#80a80353c7cb623562fd375750dfe018d75f0f7c" - integrity sha512-bOBF4n1AnUjcY1SzLeibeIx4XOuYqEkjn/Lm4yKhnN6KedoXMv4hVqgcKHGRnxOMJP64tErqrQU+4cihhpbJXg== dependencies: body-parser "^1.18.2" body-parser@1.18.3, body-parser@^1.18.2, body-parser@^1.18.3: version "1.18.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" - integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= dependencies: bytes "3.0.0" content-type "~1.0.4" @@ -1434,12 +1264,10 @@ body-parser@1.18.3, body-parser@^1.18.2, body-parser@^1.18.3: boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= boxen@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" - integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== dependencies: ansi-align "^2.0.0" camelcase "^4.0.0" @@ -1452,7 +1280,6 @@ boxen@^1.2.1: brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -1460,7 +1287,6 @@ brace-expansion@^1.1.7: braces@^2.3.0, braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: arr-flatten "^1.1.0" array-unique "^0.3.2" @@ -1476,7 +1302,6 @@ braces@^2.3.0, braces@^2.3.1: browserslist@^4.1.0: version "4.3.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.4.tgz#4477b737db6a1b07077275b24791e680d4300425" - integrity sha512-u5iz+ijIMUlmV8blX82VGFrB9ecnUg5qEt55CMZ/YJEhha+d8qpBfOFuutJ6F/VKRXjZoD33b6uvarpPxcl3RA== dependencies: caniuse-lite "^1.0.30000899" electron-to-chromium "^1.3.82" @@ -1485,17 +1310,14 @@ browserslist@^4.1.0: buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== buffer@4.9.1: version "4.9.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -1504,12 +1326,10 @@ buffer@4.9.1: builtin-modules@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= busboy@^0.2.14: version "0.2.14" resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" - integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= dependencies: dicer "0.2.5" readable-stream "1.1.x" @@ -1517,12 +1337,10 @@ busboy@^0.2.14: bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: collection-visit "^1.0.0" component-emitter "^1.2.1" @@ -1537,44 +1355,32 @@ cache-base@^1.0.1: caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= dependencies: callsites "^0.2.0" callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" - integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= - -camelcase@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" - integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== caniuse-lite@^1.0.30000899: version "1.0.30000909" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000909.tgz#697e8f447ca5f758e7c6cef39ec429ce18b908d3" - integrity sha512-4Ix9ArKpo3s/dLGVn/el9SAk6Vn2kGhg8XeE4eRTsGEsmm9RnTkwnBsVZs7p4wA8gB+nsgP36vZWYbG8a4nYrg== capture-stack-trace@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" - integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= chalk@1.1.3, chalk@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -1585,7 +1391,6 @@ chalk@1.1.3, chalk@^1.0.0: chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" @@ -1594,17 +1399,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1: chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" - integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== cheerio@^1.0.0-rc.2: version "1.0.0-rc.2" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" - integrity sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs= dependencies: css-select "~1.2.0" dom-serializer "~0.1.0" @@ -1616,7 +1418,6 @@ cheerio@^1.0.0-rc.2: chokidar@^2.0.3, chokidar@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" - integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== dependencies: anymatch "^2.0.0" async-each "^1.0.0" @@ -1636,22 +1437,18 @@ chokidar@^2.0.3, chokidar@^2.0.4: chownr@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" - integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== ci-info@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" - integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== dependencies: arr-union "^3.1.0" define-property "^0.2.5" @@ -1661,38 +1458,24 @@ class-utils@^0.3.5: cli-boxes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: restore-cursor "^2.0.0" cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= - -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= dependencies: map-visit "^1.0.0" object-visit "^1.0.0" @@ -1700,61 +1483,38 @@ collection-visit@^1.0.0: color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" - integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== dependencies: delayed-stream "~1.0.0" commander@^2.5.0, commander@^2.8.1: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concurrently@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-4.1.0.tgz#17fdf067da71210685d9ea554423ef239da30d33" - integrity sha512-pwzXCE7qtOB346LyO9eFWpkFJVO3JQZ/qU/feGeaAHiX1M3Rw3zgXKc5cZ8vSH5DGygkjzLFDzA/pwoQDkRNGg== - dependencies: - chalk "^2.4.1" - date-fns "^1.23.0" - lodash "^4.17.10" - read-pkg "^4.0.1" - rxjs "^6.3.3" - spawn-command "^0.0.2-1" - supports-color "^4.5.0" - tree-kill "^1.1.0" - yargs "^12.0.1" configstore@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" - integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== dependencies: dot-prop "^4.1.0" graceful-fs "^4.1.2" @@ -1766,64 +1526,52 @@ configstore@^3.0.0: console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" - integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== convert-source-map@^1.1.0: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== dependencies: safe-buffer "~5.1.1" cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js@^2.4.0, core-js@^2.5.3, core-js@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" - integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== core-js@^3.0.0-beta.3: version "3.0.0-beta.3" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.3.tgz#b0f22009972b8c6c04550ebf38513ca4b3cc9559" - integrity sha512-kM/OfrnMThP5PwGAj5HhQLdjUqzjrllqN2EVnk/X9qrLsfYjR2hzZ+E/8CzH0xuosexZtqMTLQrk//BULrBj9w== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= cors@^2.8.4: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== dependencies: object-assign "^4" vary "^1" @@ -1831,14 +1579,12 @@ cors@^2.8.4: create-error-class@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= dependencies: capture-stack-trace "^1.0.0" cross-env@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2" - integrity sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg== dependencies: cross-spawn "^6.0.5" is-windows "^1.0.0" @@ -1846,7 +1592,6 @@ cross-env@^5.2.0: cross-fetch@2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.2.tgz#a47ff4f7fc712daba8f6a695a11c948440d45723" - integrity sha1-pH/09/xxLauo9qaVoRyUhEDUVyM= dependencies: node-fetch "2.1.2" whatwg-fetch "2.0.4" @@ -1854,16 +1599,14 @@ cross-fetch@2.2.2: cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= dependencies: lru-cache "^4.0.1" shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== dependencies: nice-try "^1.0.4" path-key "^2.0.1" @@ -1874,12 +1617,10 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= css-select@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= dependencies: boolbase "~1.0.0" css-what "2.1" @@ -1889,7 +1630,6 @@ css-select@~1.2.0: css-tree@^1.0.0-alpha.29: version "1.0.0-alpha.29" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39" - integrity sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg== dependencies: mdn-data "~1.1.0" source-map "^0.5.3" @@ -1897,91 +1637,68 @@ css-tree@^1.0.0-alpha.29: css-what@2.1: version "2.1.2" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" - integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ== dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= dependencies: assert-plus "^1.0.0" -date-fns@^1.23.0: - version "1.29.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" - integrity sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw== - date-fns@^2.0.0-alpha.24: version "2.0.0-alpha.25" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.25.tgz#651a5d1f59a01af6cf0371e39b2ae29df5d521ee" - integrity sha512-iQzJkHF0L4wah9Ae9PkvwemwFz6qmRLuNZcghmvf2t+ptLs1qXzONLiGtjmPQzL6+JpC01JjlTopY2AEy4NFAg== debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== dependencies: ms "^2.1.1" debug@^4.0.1, debug@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" - integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== dependencies: ms "^2.1.1" -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= define-properties@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== dependencies: object-keys "^1.0.12" define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= dependencies: is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== dependencies: is-descriptor "^1.0.2" isobject "^3.0.1" @@ -1989,37 +1706,30 @@ define-property@^2.0.2: delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= deprecated-decorator@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" - integrity sha1-AJZjF7ehL+kvPMgx91g68ym4bDc= destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= dicer@0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" - integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= dependencies: readable-stream "1.1.x" streamsearch "0.1.2" @@ -2027,7 +1737,6 @@ dicer@0.2.5: doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= dependencies: esutils "^2.0.2" isarray "^1.0.0" @@ -2035,14 +1744,12 @@ doctrine@1.5.0: doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" dom-serializer@0, dom-serializer@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" - integrity sha1-BzxpdUbOB4DOI75KKOKT5AvDDII= dependencies: domelementtype "~1.1.1" entities "~1.1.1" @@ -2050,29 +1757,24 @@ dom-serializer@0, dom-serializer@~0.1.0: domelementtype@1: version "1.2.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.2.1.tgz#578558ef23befac043a1abb0db07635509393479" - integrity sha512-SQVCLFS2E7G5CRCMdn6K9bIhRj1bS6QBWZfF0TUPh4V/BbqrQ619IdSS3/izn0FZ+9l+uODzaZjb08fjOfablA== domelementtype@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" - integrity sha1-sXrtguirWeUt2cGbF1bg/BhyBMI= domelementtype@~1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" - integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs= domhandler@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== dependencies: domelementtype "1" domutils@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= dependencies: dom-serializer "0" domelementtype "1" @@ -2080,7 +1782,6 @@ domutils@1.5.1: domutils@^1.5.1: version "1.7.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== dependencies: dom-serializer "0" domelementtype "1" @@ -2088,29 +1789,24 @@ domutils@^1.5.1: dot-prop@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" - integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== dependencies: is-obj "^1.0.0" dotenv@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" - integrity sha1-9vs1E2PC2SIHJFxzeALJq1rhSVo= dotenv@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" - integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w== duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= dependencies: jsbn "~0.1.0" safer-buffer "^2.1.0" @@ -2118,48 +1814,40 @@ ecc-jsbn@~0.1.1: ecdsa-sig-formatter@1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz#1c595000f04a8897dfb85000892a0f4c33af86c3" - integrity sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM= dependencies: safe-buffer "^5.0.1" ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.82: version "1.3.84" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.84.tgz#2e55df59e818f150a9f61b53471ebf4f0feecc65" - integrity sha512-IYhbzJYOopiTaNWMBp7RjbecUBsbnbDneOP86f3qvS0G0xfzwNSvMJpTrvi5/Y1gU7tg2NAgeg8a8rCYvW9Whw== encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= encoding@^0.1.11: version "0.1.12" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= dependencies: iconv-lite "~0.4.13" entities@^1.1.1, entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" -es-abstract@^1.5.1: +es-abstract@^1.4.3, es-abstract@^1.5.1: version "1.12.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" - integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== dependencies: es-to-primitive "^1.1.1" function-bind "^1.1.1" @@ -2170,7 +1858,6 @@ es-abstract@^1.5.1: es-to-primitive@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== dependencies: is-callable "^1.1.4" is-date-object "^1.0.1" @@ -2179,22 +1866,18 @@ es-to-primitive@^1.1.1: escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= eslint-config-standard@^12.0.0: version "12.0.0" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9" - integrity sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ== eslint-import-resolver-node@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" - integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== dependencies: debug "^2.6.9" resolve "^1.5.0" @@ -2202,7 +1885,6 @@ eslint-import-resolver-node@^0.3.1: eslint-module-utils@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" - integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= dependencies: debug "^2.6.8" pkg-dir "^1.0.0" @@ -2210,7 +1892,6 @@ eslint-module-utils@^2.2.0: eslint-plugin-es@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz#475f65bb20c993fc10e8c8fe77d1d60068072da6" - integrity sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw== dependencies: eslint-utils "^1.3.0" regexpp "^2.0.1" @@ -2218,7 +1899,6 @@ eslint-plugin-es@^1.3.1: eslint-plugin-import@^2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" - integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== dependencies: contains-path "^0.1.0" debug "^2.6.8" @@ -2234,7 +1914,6 @@ eslint-plugin-import@^2.14.0: eslint-plugin-node@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.0.tgz#fb9e8911f4543514f154bb6a5924b599aa645568" - integrity sha512-Y+ln8iQ52scz9+rSPnSWRaAxeWaoJZ4wIveDR0vLHkuSZGe44Vk1J4HX7WvEP5Cm+iXPE8ixo7OM7gAO3/OKpQ== dependencies: eslint-plugin-es "^1.3.1" eslint-utils "^1.3.1" @@ -2246,17 +1925,14 @@ eslint-plugin-node@^8.0.0: eslint-plugin-promise@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" - integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg== eslint-plugin-standard@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz#f845b45109c99cd90e77796940a344546c8f6b5c" - integrity sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA== eslint-scope@3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" - integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" @@ -2264,7 +1940,6 @@ eslint-scope@3.7.1: eslint-scope@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" - integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" @@ -2272,17 +1947,14 @@ eslint-scope@^4.0.0: eslint-utils@^1.3.0, eslint-utils@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" - integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" - integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== eslint@^5.9.0: version "5.9.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" - integrity sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.5.3" @@ -2326,7 +1998,6 @@ eslint@^5.9.0: espree@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" - integrity sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w== dependencies: acorn "^6.0.2" acorn-jsx "^5.0.0" @@ -2335,64 +2006,42 @@ espree@^4.0.0: esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" - integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== dependencies: estraverse "^4.0.0" esrecurse@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== dependencies: estraverse "^4.1.0" estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eventemitter3@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" - integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== events@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= - -execa@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" - integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== - dependencies: - cross-spawn "^6.0.0" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -2405,7 +2054,6 @@ execa@^0.7.0: expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= dependencies: debug "^2.3.3" define-property "^0.2.5" @@ -2418,7 +2066,6 @@ expand-brackets@^2.1.4: express@^4.0.0, express@^4.16.3: version "4.16.4" resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" - integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== dependencies: accepts "~1.3.5" array-flatten "1.1.1" @@ -2454,14 +2101,12 @@ express@^4.0.0, express@^4.16.3: extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= dependencies: assign-symbols "^1.0.0" is-extendable "^1.0.1" @@ -2469,12 +2114,10 @@ extend-shallow@^3.0.0, extend-shallow@^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== external-editor@^2.0.1: version "2.2.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" - integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== dependencies: chardet "^0.4.0" iconv-lite "^0.4.17" @@ -2483,7 +2126,6 @@ external-editor@^2.0.1: external-editor@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" - integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== dependencies: chardet "^0.7.0" iconv-lite "^0.4.24" @@ -2492,7 +2134,6 @@ external-editor@^3.0.0: extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: array-unique "^0.3.2" define-property "^1.0.0" @@ -2506,44 +2147,36 @@ extglob@^2.0.4: extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= extsprintf@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= faker@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" - integrity sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8= fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= dependencies: escape-string-regexp "^1.0.5" file-entry-cache@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= dependencies: flat-cache "^1.2.1" object-assign "^4.0.1" @@ -2551,7 +2184,6 @@ file-entry-cache@^2.0.0: fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= dependencies: extend-shallow "^2.0.1" is-number "^3.0.0" @@ -2561,7 +2193,6 @@ fill-range@^4.0.0: finalhandler@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" - integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== dependencies: debug "2.6.9" encodeurl "~1.0.2" @@ -2574,7 +2205,6 @@ finalhandler@1.1.1: find-cache-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" - integrity sha1-kojj6ePMN0hxfTnq3hfPcfww7m8= dependencies: commondir "^1.0.1" make-dir "^1.0.0" @@ -2583,7 +2213,6 @@ find-cache-dir@^1.0.0: find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= dependencies: path-exists "^2.0.0" pinkie-promise "^2.0.0" @@ -2591,21 +2220,12 @@ find-up@^1.0.0: find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= dependencies: locate-path "^2.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - flat-cache@^1.2.1: version "1.3.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" - integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== dependencies: circular-json "^0.3.1" graceful-fs "^4.1.2" @@ -2615,17 +2235,14 @@ flat-cache@^1.2.1: for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== dependencies: asynckit "^0.4.0" combined-stream "^1.0.6" @@ -2634,59 +2251,49 @@ form-data@~2.3.2: forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: map-cache "^0.2.2" fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== dependencies: minipass "^2.2.1" fs-readdir-recursive@^1.0.0, fs-readdir-recursive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" - integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.2: version "1.2.4" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== dependencies: nan "^2.9.2" node-pre-gyp "^0.10.0" -function-bind@^1.1.1: +function-bind@^1.0.2, 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== functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= dependencies: aproba "^1.0.3" console-control-strings "^1.0.0" @@ -2697,32 +2304,23 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= dependencies: assert-plus "^1.0.0" glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= dependencies: is-glob "^3.1.0" path-dirname "^1.0.0" @@ -2730,7 +2328,6 @@ glob-parent@^3.1.0: glob@^7.0.0, glob@^7.0.5, glob@^7.1.2: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -2742,19 +2339,16 @@ glob@^7.0.0, glob@^7.0.5, glob@^7.1.2: global-dirs@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" - integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= dependencies: ini "^1.3.4" globals@^11.1.0, globals@^11.7.0: version "11.9.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" - integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" - integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= dependencies: create-error-class "^3.0.0" duplexer3 "^0.1.4" @@ -2771,12 +2365,10 @@ got@^6.7.1: graceful-fs@^4.1.11, graceful-fs@^4.1.2: version "4.1.15" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" - integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== graphql-config@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-2.0.0.tgz#daf69091055c6f675d63893a2d14c48f3fec3327" - integrity sha512-//hZmROEk79zzPlH6SVTQeXd8NVV65rquz1zxZeO6oEuX5KNnii8+oznLu7d897EfJ+NShTZtsY9FMmxxkWmJw== dependencies: graphql-import "^0.4.0" graphql-request "^1.4.0" @@ -2787,7 +2379,6 @@ graphql-config@2.0.0: graphql-custom-directives@^0.2.13: 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" @@ -2797,26 +2388,22 @@ graphql-custom-directives@^0.2.13: graphql-deduplicator@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3" - integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA== graphql-extensions@0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.3.tgz#277efe11976bbdfd59915551606a2d550247bb45" - integrity sha512-pudOaHq7Ok+rh1ElzlqFaoYZWGefUNsqn/jX6eKns7rl0VHuB4qZBfhpVLTpquJpM6Y19/hsCYZNPfnUVMFIiA== dependencies: "@apollographql/apollo-tools" "^0.2.6" graphql-extensions@0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.5.tgz#95b742185d0016a9d65385a7a9e10753eadf0537" - integrity sha512-jpWSUIr27iOTR5JYu+dEMz74oZhOj8Xy+6lNopluiIu+ObEVSHW0czb2Jlcy3rOSTEPcibnpStO4F4/64IBqeQ== dependencies: "@apollographql/apollo-tools" "^0.2.6" graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: version "0.0.10" resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" - integrity sha512-TnQueqUDCYzOSrpQb3q1ngDSP2otJSF+9yNLrQGPzkMsvnQ+v6e2d5tl+B35D4y+XpmvVnAn4T3ZK28mkILveA== dependencies: core-js "^2.5.3" source-map-support "^0.5.1" @@ -2824,75 +2411,64 @@ graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: graphql-import@^0.4.0: version "0.4.5" resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.4.5.tgz#e2f18c28d335733f46df8e0733d8deb1c6e2a645" - integrity sha512-G/+I08Qp6/QGTb9qapknCm3yPHV0ZL7wbaalWFpxsfR8ZhZoTBe//LsbsCKlbALQpcMegchpJhpTSKiJjhaVqQ== dependencies: lodash "^4.17.4" graphql-import@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.6.0.tgz#c00cb8a269ceea263e062922c8c81a2272d1ffcb" - integrity sha512-S6Aj4pTzehCwyh7hKUKlWLgE6soDdW/T6JPePC16exzFDNdZHXRj7lqv75yMWJCkBY0pBtWicMLinb4ni6QRyg== dependencies: lodash "^4.17.4" 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@1.6.6: version "1.6.6" resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.6.6.tgz#f40f4e836ced479df718dbc1869ea4cd3b64027b" - integrity sha512-1rSSPEJOhBMwNCBCp5CCh3YZFvo8qN/pzQM8k50pd/w2hBsBvOx0AVU9Or6JQbTXxYrKFXvKFUxC5Lp+2oeUtw== dependencies: graphql-tools "^3.0.5" graphql-middleware@1.7.6: version "1.7.6" resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.6.tgz#f226bf6671f3d82a9378f8b335804c8e44d21733" - integrity sha512-nKWd6BVgsh6S2eDRIcm3TjJPmXEEmqK6DY2a8/nK11NrNAFpZCq+esSSPG1F0HZShsDdE/h3M+/jLcD/zKlMvA== dependencies: graphql-tools "^4.0.0" graphql-playground-html@1.5.5: version "1.5.5" resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.5.5.tgz#e2aca543eb66b435ead495b45244b2604d6b2d48" - integrity sha512-PzSywpEKcjbDUkV6e3ivEixvAuUJGyYmBUvuittzySe/RgwHRo0xKLD7HouUCTbpFfWMw8kRKhAUVtt7Ys97uw== dependencies: graphql-config "2.0.0" graphql-playground-html@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz#6ec4d54325ab2e5352506fdb89eb37c3fc718bf8" - integrity sha512-et3huQFEuAZgAiUfs9a+1Wo/JDX94k7XqNRc8LhpGT8k2NwIhMAbZKqudVF/Ww4+XDoEB4LUTSFGRPBYvKrcKQ== dependencies: graphql-config "2.0.0" graphql-playground-middleware-express@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.2.tgz#5f7bf3683494fe17893d1b54bbecee5e222c2e78" - integrity sha512-JvKsVOR/U5QguBtEvTt0ozQ49uh1C6cW8O1xR6krQpJZIxjLYqpgusLUddTiVkka6Q/A4/AXBohY85jPudxYDg== dependencies: graphql-playground-html "1.6.0" graphql-playground-middleware-lambda@1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/graphql-playground-middleware-lambda/-/graphql-playground-middleware-lambda-1.6.1.tgz#e0f1944558136dd3975570c92c702d6009cc779c" - integrity sha512-FO6XG9QRs+0AkwfAnL80u8A02xTg1rPUH+Ay13ASTs0nEePav5GkrWfL59ZY+sK4ZzFvz72aImuXAs3Ajn8VtA== dependencies: graphql-playground-html "1.5.5" graphql-request@^1.4.0: version "1.8.2" resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" - integrity sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg== dependencies: cross-fetch "2.2.2" graphql-shield@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.1.0.tgz#8bd55179fd28d00e64ca5a7dbd3cffe82e282e73" - integrity sha512-r3m5t7FpLDyJQIby0IKyNrtp8k62hP/syhPcrpdT67UVNKh0jjjl+zpjXh/3PXeNZHPEAiBQTHhFjnC7H2B4SA== dependencies: object-hash "^1.3.0" opencollective "1.0.3" @@ -2900,26 +2476,22 @@ graphql-shield@^4.0.1: graphql-subscriptions@^0.5.8: version "0.5.8" resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7" - integrity sha512-0CaZnXKBw2pwnIbvmVckby5Ge5e2ecmjofhYCdyeACbCly2j3WXDP/pl+s+Dqd2GQFC7y99NB+53jrt55CKxYQ== dependencies: iterall "^1.2.1" graphql-subscriptions@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-1.0.0.tgz#475267694b3bd465af6477dbab4263a3f62702b8" - integrity sha512-+ytmryoHF1LVf58NKEaNPRUzYyXplm120ntxfPcgOBC7TnK7Tv/4VRHeh4FAR9iL+O1bqhZs4nkibxQ+OA5cDQ== dependencies: iterall "^1.2.1" graphql-tag@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" - integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w== graphql-tools@^3.0.0, graphql-tools@^3.0.5: version "3.1.1" resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-3.1.1.tgz#d593358f01e7c8b1671a17b70ddb034dea9dbc50" - integrity sha512-yHvPkweUB0+Q/GWH5wIG60bpt8CTwBklCSzQdEHmRUgAdEQKxw+9B7zB3dG7wB3Ym7M7lfrS4Ej+jtDZfA2UXg== dependencies: apollo-link "^1.2.2" apollo-utilities "^1.0.1" @@ -2930,7 +2502,6 @@ graphql-tools@^3.0.0, graphql-tools@^3.0.5: graphql-tools@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.3.tgz#23b5cb52c519212b1b2e4630a361464396ad264b" - integrity sha512-NNZM0WSnVLX1zIMUxu7SjzLZ4prCp15N5L2T2ro02OVyydZ0fuCnZYRnx/yK9xjGWbZA0Q58yEO//Bv/psJWrg== dependencies: apollo-link "^1.2.3" apollo-utilities "^1.0.1" @@ -2941,7 +2512,6 @@ graphql-tools@^4.0.0: graphql-yoga@1.16.2: version "1.16.2" resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.16.2.tgz#083293a9cecab6283e883c5a482c5c920fa66585" - integrity sha512-dV7uEUm/tzl3K/gkHPBt718N+F0gmhZKsg8HJpj35SEniGyXVI3VjDWd7Na3bWdue4p8Sxb+/JguuK8jpe8dWg== dependencies: "@types/cors" "^2.8.4" "@types/express" "^4.11.1" @@ -2968,19 +2538,16 @@ graphql-yoga@1.16.2: "graphql@^0.11.0 || ^0.12.0 || ^0.13.0", graphql@^0.13.2: version "0.13.2" resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" - integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== dependencies: iterall "^1.2.1" har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= har-validator@~5.1.0: version "5.1.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== dependencies: ajv "^6.5.5" har-schema "^2.0.0" @@ -2988,34 +2555,24 @@ har-validator@~5.1.0: has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= dependencies: ansi-regex "^2.0.0" -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: get-value "^2.0.3" has-values "^0.1.4" @@ -3024,7 +2581,6 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= dependencies: get-value "^2.0.6" has-values "^1.0.0" @@ -3033,12 +2589,10 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= has-values@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= dependencies: is-number "^3.0.0" kind-of "^4.0.0" @@ -3046,46 +2600,38 @@ has-values@^1.0.0: has@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" he@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" - integrity sha1-LAX/rvkLaOhg8/0rVO9YCYknfuI= hoek@5.x.x: version "5.0.4" resolved "https://registry.yarnpkg.com/hoek/-/hoek-5.0.4.tgz#0f7fa270a1cafeb364a4b2ddfaa33f864e4157da" - integrity sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w== hoek@6.x.x: version "6.0.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.0.3.tgz#7884360426d927865a0a1251fc9c59313af5b798" - integrity sha512-TU6RyZ/XaQCTWRLrdqZZtZqwxUVr6PDMfi6MlWNURZ7A6czanQqX4pFE1mdOUQR9FdPCsZ0UzL8jI/izZ+eBSQ== home-or-tmp@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-3.0.0.tgz#57a8fe24cf33cdd524860a15821ddc25c86671fb" - integrity sha1-V6j+JM8zzdUkhgoVgh3cJchmcfs= homedir-polyfill@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" - integrity sha1-TCu8inWJmP7r9e1oWA921GdotLw= dependencies: parse-passwd "^1.0.0" hosted-git-info@^2.1.4: version "2.7.1" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" - integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== htmlparser2@^3.10.0, htmlparser2@^3.9.1: version "3.10.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" - integrity sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ== dependencies: domelementtype "^1.3.0" domhandler "^2.3.0" @@ -3097,7 +2643,6 @@ htmlparser2@^3.10.0, htmlparser2@^3.9.1: http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: version "1.6.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= dependencies: depd "~1.1.2" inherits "2.0.3" @@ -3107,7 +2652,6 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= dependencies: assert-plus "^1.0.0" jsprim "^1.2.2" @@ -3116,68 +2660,56 @@ http-signature@~1.2.0: iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" - integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== dependencies: safer-buffer ">= 2.1.2 < 3" iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" ieee754@1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" - integrity sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q= ieee754@^1.1.4: version "1.1.12" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" - integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" - integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= ignore-walk@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== dependencies: minimatch "^3.0.4" ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.0.2: version "5.0.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.0.4.tgz#33168af4a21e99b00c5d41cbadb6a6cb49903a45" - integrity sha512-WLsTMEhsQuXpCiG173+f3aymI43SXa+fB1rSfbzyP4GkPP+ZFVuO0/3sFUGNBtifisPeDcl/uD/Y2NxZ7xFq4g== immutable-tuple@^0.4.9: version "0.4.9" resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.9.tgz#473ebdd6c169c461913a454bf87ef8f601a20ff0" - integrity sha512-LWbJPZnidF8eczu7XmcnLBsumuyRBkpwIRPCZxlojouhBo5jEBO4toj6n7hMy6IxHU/c+MqDSWkvaTpPlMQcyA== import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" wrappy "1" @@ -3185,17 +2717,14 @@ inflight@^1.0.4: inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== inquirer@3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" - integrity sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c= dependencies: ansi-escapes "^1.1.0" chalk "^1.0.0" @@ -3214,7 +2743,6 @@ inquirer@3.0.6: inquirer@^6.1.0: version "6.2.1" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52" - integrity sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg== dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" @@ -3233,7 +2761,6 @@ inquirer@^6.1.0: insane@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/insane/-/insane-2.6.1.tgz#c7dcae7b51c20346883b71078fad6ce0483c198f" - integrity sha1-x9yue1HCA0aIO3EHj61s4Eg8GY8= dependencies: assignment "2.0.0" he "0.5.0" @@ -3241,93 +2768,74 @@ insane@2.6.1: invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== dependencies: loose-envify "^1.0.0" -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - ipaddr.js@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" - integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= dependencies: kind-of "^3.0.2" is-accessor-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== dependencies: kind-of "^6.0.0" is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= dependencies: binary-extensions "^1.0.0" is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-builtin-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= dependencies: builtin-modules "^1.0.0" is-callable@^1.1.3, is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== is-ci@^1.0.10: version "1.2.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== dependencies: ci-info "^1.5.0" is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= dependencies: kind-of "^3.0.2" is-data-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== dependencies: kind-of "^6.0.0" is-date-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== dependencies: is-accessor-descriptor "^0.1.6" is-data-descriptor "^0.1.4" @@ -3336,7 +2844,6 @@ is-descriptor@^0.1.0: is-descriptor@^1.0.0, is-descriptor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== dependencies: is-accessor-descriptor "^1.0.0" is-data-descriptor "^1.0.0" @@ -3345,50 +2852,42 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= is-extendable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= dependencies: is-extglob "^2.1.0" is-glob@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" - integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= dependencies: is-extglob "^2.1.1" is-installed-globally@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= dependencies: global-dirs "^0.1.0" is-path-inside "^1.0.0" @@ -3396,141 +2895,116 @@ is-installed-globally@^0.1.0: is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= dependencies: kind-of "^3.0.2" is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= is-path-inside@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= dependencies: path-is-inside "^1.0.1" is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= is-regex@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= dependencies: has "^1.0.1" is-resolvable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" - integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== dependencies: has-symbols "^1.0.0" is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= is-windows@^1.0.0, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isemail@3.x.x: version "3.2.0" resolved "https://registry.yarnpkg.com/isemail/-/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c" - integrity sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg== dependencies: punycode "2.x.x" isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= iterall@^1.1.3, iterall@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" - integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== jmespath@0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" - integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= joi@^13.0.0: version "13.7.0" resolved "https://registry.yarnpkg.com/joi/-/joi-13.7.0.tgz#cfd85ebfe67e8a1900432400b4d03bbd93fb879f" - integrity sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q== dependencies: hoek "5.x.x" isemail "3.x.x" @@ -3539,22 +3013,18 @@ joi@^13.0.0: jquery@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca" - integrity sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg== js-levenshtein@^1.1.3: version "1.1.4" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.4.tgz#3a56e3cbf589ca0081eb22cd9ba0b1290a16d26e" - integrity sha512-PxfGzSs0ztShKrUYPIn5r0MtyAhYcCwmndozzpz8YObbPnD1jFxzlBGbRnX2mIu6Z13xN6+PTu05TQFnZFlzow== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.10.0, js-yaml@^3.12.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" - integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -3562,66 +3032,54 @@ js-yaml@^3.10.0, js-yaml@^3.12.0: jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= 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-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= dependencies: jsonify "~0.0.0" json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= json5@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" - integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== dependencies: minimist "^1.2.0" jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: version "8.4.0" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz#8757f7b4cb7440d86d5e2f3becefa70536c8e46a" - integrity sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg== dependencies: jws "^3.1.5" lodash.includes "^4.3.0" @@ -3636,7 +3094,6 @@ jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0: jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= dependencies: assert-plus "1.0.0" extsprintf "1.3.0" @@ -3646,7 +3103,6 @@ jsprim@^1.2.2: jwa@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.6.tgz#87240e76c9808dbde18783cf2264ef4929ee50e6" - integrity sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw== dependencies: buffer-equal-constant-time "1.0.1" ecdsa-sig-formatter "1.0.10" @@ -3655,7 +3111,6 @@ jwa@^1.1.5: jws@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.5.tgz#80d12d05b293d1e841e7cb8b4e69e561adcf834f" - integrity sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ== dependencies: jwa "^1.1.5" safe-buffer "^5.0.1" @@ -3663,45 +3118,32 @@ jws@^3.1.5: kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= dependencies: is-buffer "^1.1.5" kind-of@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== latest-version@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" - integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= dependencies: package-json "^4.0.0" -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= dependencies: prelude-ls "~1.1.2" type-check "~0.3.2" @@ -3709,7 +3151,6 @@ levn@^0.3.0, levn@~0.3.0: libphonenumber-js@^1.6.4: version "1.6.7" resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.6.7.tgz#cb4501f6d1e5e0b4c8ccbd10ba489359f649dd73" - integrity sha512-vdt8x1ILa7pjpkQilAuS58xgFPBrgGLBoAQV4jEusIwvjqUV+tgr5po1sifP2RmAcmKaM1NdyIDXgmpyb4V8bg== dependencies: minimist "^1.2.0" semver-compare "^1.0.0" @@ -3718,7 +3159,6 @@ libphonenumber-js@^1.6.4: linkifyjs@^2.1.7: version "2.1.7" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-2.1.7.tgz#e5d68d2ae30b9c055e1d74cc40f9a31d3abb4012" - integrity sha512-Cbn77BnYEslpAObZZoP6GVQHF1j5T6RsDydNq5RVxIy4eiZAiADRx7qHfWzfEMQecc1PtZFog1AsCGGX2WjQLA== optionalDependencies: jquery "^3.3.1" react "^16.4.2" @@ -3727,110 +3167,93 @@ linkifyjs@^2.1.7: load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= dependencies: graceful-fs "^4.1.2" parse-json "^2.2.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" + 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" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= dependencies: p-locate "^2.0.0" path-exists "^3.0.0" -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= lodash.escaperegexp@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" - integrity sha1-ZHYsSGGAglGKw99Mz11YhtriA0c= lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" - integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= lodash.isboolean@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= lodash.isinteger@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= lodash.isnumber@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= lodash.isstring@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= lodash.mergewith@^4.6.1: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" - integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" - integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" 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== lru-cache@^4.0.1: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" - integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== dependencies: pseudomap "^1.0.2" yallist "^2.1.2" @@ -3838,69 +3261,48 @@ lru-cache@^4.0.1: lru-cache@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: yallist "^3.0.2" make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== dependencies: pify "^3.0.0" -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: object-visit "^1.0.0" mdn-data@~1.1.0: version "1.1.4" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01" - integrity sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA== media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -mem@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" - integrity sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^1.0.0" - p-is-promise "^1.1.0" +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -3919,46 +3321,38 @@ micromatch@^3.1.10, micromatch@^3.1.4: mime-db@~1.37.0: version "1.37.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" - integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.19: version "2.1.21" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" - integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== dependencies: mime-db "~1.37.0" mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" - integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= minimist@1.2.0, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= minipass@^2.2.1, minipass@^2.3.4: version "2.3.5" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" @@ -3966,14 +3360,12 @@ minipass@^2.2.1, minipass@^2.3.4: minizlib@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" - integrity sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg== dependencies: minipass "^2.2.1" mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" @@ -3981,39 +3373,32 @@ mixin-deep@^1.2.0: mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" moment@^2.22.2: version "2.22.2" resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" - integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y= ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= nan@^2.9.2: version "2.11.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" - integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -4030,12 +3415,10 @@ nanomatch@^1.2.9: natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= needle@^2.2.1: version "2.2.4" resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" - integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== dependencies: debug "^2.1.2" iconv-lite "^0.4.4" @@ -4044,12 +3427,10 @@ needle@^2.2.1: negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" - integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= neo4j-driver@^1.6.1: version "1.7.2" resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.2.tgz#c72a6dfa6bd2106b00a42794dc52a82b227b48e0" - integrity sha512-0IvCFYhcP9hb5JveZk33epbReDKpFTn2u5vAa8zzGG344i6yFqZrBo0mtC114ciP9zFjAtfNOP72mRm8+NV0Fg== dependencies: babel-runtime "^6.26.0" text-encoding "^0.6.4" @@ -4058,7 +3439,6 @@ neo4j-driver@^1.6.1: neo4j-graphql-js@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-1.0.5.tgz#ef5d59d2e7cf46971af49bceec2f4bcd2debc835" - integrity sha512-Fn+lsynWeUy6AT2Xnzpl4vuBWTroUtAyK38qbBVd26z8SeWuQrlxtJFUEifU4VrQxw7tMfbLUSKt7Av+eDQiPw== dependencies: graphql "^0.13.2" lodash "^4.17.10" @@ -4067,12 +3447,10 @@ neo4j-graphql-js@1.0.5: nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== node-fetch@1.6.3: version "1.6.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" - integrity sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ= dependencies: encoding "^0.1.11" is-stream "^1.0.1" @@ -4080,22 +3458,18 @@ node-fetch@1.6.3: node-fetch@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" - integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= node-fetch@^2.1.2, node-fetch@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" - integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== node-modules-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= node-pre-gyp@^0.10.0: version "0.10.3" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" - integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== dependencies: detect-libc "^1.0.2" mkdirp "^0.5.1" @@ -4111,14 +3485,12 @@ node-pre-gyp@^0.10.0: node-releases@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.4.tgz#2d585de8c6c81d00017e063e7810a63889aa6756" - integrity sha512-GqRV9GcHw8JCRDaP/JoeNMNzEGzHAknMvIHqMb2VeTOmg1Cf9+ej8bkV12tHfzWHQMCkQ5zUFgwFUkfraynNCw== dependencies: semver "^5.3.0" nodemon@^1.18.7: version "1.18.7" resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.7.tgz#716b66bf3e89ac4fcfb38a9e61887a03fc82efbb" - integrity sha512-xuC1V0F5EcEyKQ1VhHYD13owznQbUw29JKvZ8bVH7TmuvVNHvvbp9pLgE4PjTMRJVe0pJ8fGRvwR2nMiosIsPQ== dependencies: chokidar "^2.0.4" debug "^3.1.0" @@ -4134,7 +3506,6 @@ nodemon@^1.18.7: nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= dependencies: abbrev "1" osenv "^0.1.4" @@ -4142,14 +3513,12 @@ nopt@^4.0.1: nopt@~1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= dependencies: abbrev "1" normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" - integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== dependencies: hosted-git-info "^2.1.4" is-builtin-module "^1.0.0" @@ -4159,34 +3528,44 @@ normalize-package-data@^2.3.2: normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= dependencies: remove-trailing-separator "^1.0.1" npm-bundled@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" - integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== npm-packlist@^1.1.6: version "1.1.12" resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" - integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== dependencies: 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" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= dependencies: path-key "^2.0.0" npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: are-we-there-yet "~1.1.2" console-control-strings "~1.1.0" @@ -4196,34 +3575,28 @@ npmlog@^4.0.2: nth-check@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== dependencies: boolbase "~1.0.0" number-is-nan@^1.0.0: version "1.0.1" 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= oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= dependencies: copy-descriptor "^0.1.0" define-property "^0.2.5" @@ -4232,29 +3605,24 @@ object-copy@^0.1.0: object-hash@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" - integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== object-keys@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" - integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== object-path@^0.11.4: version "0.11.4" resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" - integrity sha1-NwrnUvvzfePqcKhhwju6iRVpGUk= object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= dependencies: isobject "^3.0.0" object.getownpropertydescriptors@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= dependencies: define-properties "^1.1.2" es-abstract "^1.5.1" @@ -4262,35 +3630,30 @@ object.getownpropertydescriptors@^2.0.3: object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= dependencies: isobject "^3.0.1" on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= dependencies: ee-first "1.1.1" once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= dependencies: mimic-fn "^1.0.0" opencollective@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/opencollective/-/opencollective-1.0.3.tgz#aee6372bc28144583690c3ca8daecfc120dd0ef1" - integrity sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE= dependencies: babel-polyfill "6.23.0" chalk "1.1.3" @@ -4302,7 +3665,6 @@ opencollective@1.0.3: opn@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" - integrity sha1-erwi5kTf9jsKltWrfyeQwPAavJU= dependencies: object-assign "^4.0.1" pinkie-promise "^2.0.0" @@ -4310,14 +3672,12 @@ opn@4.0.2: optimism@^0.6.6: version "0.6.8" resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.8.tgz#0780b546da8cd0a72e5207e0c3706c990c8673a6" - integrity sha512-bN5n1KCxSqwBDnmgDnzMtQTHdL+uea2HYFx1smvtE+w2AMl0Uy31g0aXnP/Nt85OINnMJPRpJyfRQLTCqn5Weg== dependencies: immutable-tuple "^0.4.9" optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= dependencies: deep-is "~0.1.3" fast-levenshtein "~2.0.4" @@ -4329,26 +3689,14 @@ optionator@^0.8.2: os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" - integrity sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw== - dependencies: - execa "^0.10.0" - lcid "^2.0.0" - mem "^4.0.0" os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= osenv@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.0" @@ -4356,69 +3704,34 @@ osenv@^0.1.4: output-file-sync@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-2.0.1.tgz#f53118282f5f553c2799541792b723a4c71430c0" - integrity sha512-mDho4qm7WgIXIGf4eYU1RHN2UU5tPfVYVSRwDJw0uTmj35DQUt/eNp19N7v6T3SrR0ESTEf2up2CGO73qI35zQ== dependencies: graceful-fs "^4.1.11" is-plain-obj "^1.1.0" mkdirp "^0.5.1" -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" - integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== dependencies: p-try "^1.0.0" -p-limit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" - integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== - dependencies: - p-try "^2.0.0" - p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= dependencies: p-limit "^1.1.0" -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" - integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= dependencies: got "^6.7.1" registry-auth-token "^3.0.1" @@ -4428,14 +3741,12 @@ package-json@^4.0.0: parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= 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" @@ -4443,29 +3754,24 @@ parse-json@^4.0.0: parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= parse5@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" - integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== dependencies: "@types/node" "*" parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= passport-jwt@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" - integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg== dependencies: jsonwebtoken "^8.2.0" passport-strategy "^1.0.0" @@ -4473,12 +3779,10 @@ passport-jwt@^4.0.0: passport-strategy@1.x.x, passport-strategy@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" - integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= passport@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" - integrity sha1-xQlWkTR71a07XhgCOMORTRbwWBE= dependencies: passport-strategy "1.x.x" pause "0.0.1" @@ -4486,144 +3790,128 @@ passport@^0.4.0: path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= dependencies: pinkie-promise "^2.0.0" path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= path-parse@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= 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" + dependencies: + pify "^3.0.0" + pause@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" - integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pidtree@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.0.tgz#f6fada10fccc9f99bf50e90d0b23d72c9ebc2e6b" pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= pirates@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.0.tgz#850b18781b4ac6ec58a43c9ed9ec5fe6796addbd" - integrity sha512-8t5BsXy1LUIjn3WWOlOuFDuKswhQb/tkak641lvBgmPOBUQHXveORtlMCp6OdPV1dtuTaEahKA8VNz6uLfKBtA== dependencies: node-modules-regexp "^1.0.0" pkg-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= dependencies: find-up "^1.0.0" pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= dependencies: find-up "^2.1.0" pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= private@^0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== progress@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.2.tgz#db9476f916bcc9ebe8a04efb22b18b0740376c61" - integrity sha512-/OLz5F9beZUWwSHZDreXgap1XShX6W+DCHQCqwCF7uZ88s6uTlD2cR3JBE77SegCmNtb1Idst+NfmwcdU6KVhw== prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" - integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== dependencies: loose-envify "^1.3.1" object-assign "^4.1.1" @@ -4631,7 +3919,6 @@ prop-types@^15.6.2: protobufjs@^6.8.6: version "6.8.8" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" - integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -4650,7 +3937,6 @@ protobufjs@^6.8.6: proxy-addr@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" - integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== dependencies: forwarded "~0.1.2" ipaddr.js "1.8.0" @@ -4658,52 +3944,42 @@ proxy-addr@~2.0.4: pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24: version "1.1.29" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" - integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== pstree.remy@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.2.tgz#4448bbeb4b2af1fed242afc8dc7416a6f504951a" - integrity sha512-vL6NLxNHzkNTjGJUpMm5PLC+94/0tTlC1vkP9bdU0pOHih+EujMjgMTwfZopZvHWRFbqJ5Y73OMoau50PewDDA== punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= punycode@2.x.x, punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= qs@6.5.2, qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" - integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= raw-body@2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" - integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== dependencies: bytes "3.0.0" http-errors "1.6.3" @@ -4713,7 +3989,6 @@ raw-body@2.3.3: rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== dependencies: deep-extend "^0.6.0" ini "~1.3.0" @@ -4723,7 +3998,6 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: react-dom@^16.4.2: version "16.6.3" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.3.tgz#8fa7ba6883c85211b8da2d0efeffc9d3825cccc0" - integrity sha512-8ugJWRCWLGXy+7PmNh8WJz3g1TaTUt1XyoIcFN+x0Zbkoz+KKdUyx1AQLYJdbFXjuF41Nmjn5+j//rxvhFjgSQ== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -4733,7 +4007,6 @@ react-dom@^16.4.2: react@^16.4.2: version "16.6.3" resolved "https://registry.yarnpkg.com/react/-/react-16.6.3.tgz#25d77c91911d6bbdd23db41e70fb094cc1e0871c" - integrity sha512-zCvmH2vbEolgKxtqXL2wmGCUxUyNheYn/C+PD1YAjfxHC54+MhdruyhO7QieQrYsYeTxrn93PM2y0jRH1zEExw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -4743,7 +4016,6 @@ react@^16.4.2: read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= dependencies: find-up "^2.0.0" read-pkg "^2.0.0" @@ -4751,25 +4023,22 @@ read-pkg-up@^2.0.0: read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= dependencies: load-json-file "^2.0.0" normalize-package-data "^2.3.2" path-type "^2.0.0" -read-pkg@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" - integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" dependencies: + load-json-file "^4.0.0" normalize-package-data "^2.3.2" - parse-json "^4.0.0" - pify "^3.0.0" + path-type "^3.0.0" readable-stream@1.1.x: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= dependencies: core-util-is "~1.0.0" inherits "~2.0.1" @@ -4779,7 +4048,6 @@ readable-stream@1.1.x: 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== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -4792,7 +4060,6 @@ readable-stream@^2.0.2, readable-stream@^2.0.6: readable-stream@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.0.6.tgz#351302e4c68b5abd6a2ed55376a7f9a25be3057a" - integrity sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" @@ -4801,7 +4068,6 @@ readable-stream@^3.0.6: readdirp@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: graceful-fs "^4.1.11" micromatch "^3.1.10" @@ -4810,41 +4076,34 @@ readdirp@^2.0.0: regenerate-unicode-properties@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" - integrity sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw== dependencies: regenerate "^1.4.0" regenerate@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== regenerator-runtime@^0.10.0: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" - integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== regenerator-runtime@^0.12.0: version "0.12.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" - integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== regenerator-transform@^0.13.3: version "0.13.3" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb" - integrity sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA== dependencies: private "^0.1.6" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: extend-shallow "^3.0.2" safe-regex "^1.1.0" @@ -4852,12 +4111,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== regexpu-core@^4.1.3, regexpu-core@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.2.0.tgz#a3744fa03806cffe146dea4421a3e73bdcc47b1d" - integrity sha512-Z835VSnJJ46CNBttalHD/dB+Sj2ezmY6Xp38npwU87peK6mqOzOpV8eYktdkLTEkzzD+JsTcxd84ozd8I14+rw== dependencies: regenerate "^1.4.0" regenerate-unicode-properties "^7.0.0" @@ -4869,7 +4126,6 @@ regexpu-core@^4.1.3, regexpu-core@^4.2.0: registry-auth-token@^3.0.1: version "3.3.2" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" - integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== dependencies: rc "^1.1.6" safe-buffer "^5.0.1" @@ -4877,41 +4133,34 @@ registry-auth-token@^3.0.1: registry-url@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= dependencies: rc "^1.0.1" regjsgen@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.4.0.tgz#c1eb4c89a209263f8717c782591523913ede2561" - integrity sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA== regjsparser@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.3.0.tgz#3c326da7fcfd69fa0d332575a41c8c0cdf588c96" - integrity sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA== dependencies: jsesc "~0.5.0" remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== dependencies: aws-sign2 "~0.7.0" aws4 "^1.8.0" @@ -4934,20 +4183,9 @@ request@^2.88.0: tunnel-agent "^0.6.0" uuid "^3.3.2" -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= dependencies: caller-path "^0.1.0" resolve-from "^1.0.0" @@ -4955,24 +4193,20 @@ require-uncached@^1.0.3: resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" - integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== dependencies: path-parse "^1.0.5" restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= dependencies: onetime "^2.0.0" signal-exit "^3.0.2" @@ -4980,60 +4214,50 @@ restore-cursor@^2.0.0: ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== retry@0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= rimraf@^2.6.1, rimraf@~2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== dependencies: glob "^7.0.5" run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= dependencies: is-promise "^2.1.0" rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" - integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= -rxjs@^6.1.0, rxjs@^6.3.3: +rxjs@^6.1.0: version "6.3.3" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" - integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== dependencies: tslib "^1.9.0" safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= dependencies: ret "~0.1.10" "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sanitize-html@^1.19.2: version "1.19.2" resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.2.tgz#c03fffe2bf96cd582968ece9792cbca32e64dde0" - integrity sha512-7fNb3/N0sZ/nkshMRBoxLz6K1dlMSVF/eQHX1Bof9sRT7cZJvmrDGfXEn544MXJnpY29vux1A599g9UrcHTBXA== dependencies: chalk "^2.4.1" css-tree "^1.0.0-alpha.29" @@ -5049,17 +4273,14 @@ sanitize-html@^1.19.2: sax@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" - integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= sax@>=0.6.0, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== scheduler@^0.11.2: version "0.11.2" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.2.tgz#a8db5399d06eba5abac51b705b7151d2319d33d3" - integrity sha512-+WCP3s3wOaW4S7C1tl3TEXp4l9lJn0ZK8G3W3WKRWmw77Z2cIFUW2MiNTMHn5sCjxN+t7N43HAOOgMjyAg5hlg== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -5067,24 +4288,20 @@ scheduler@^0.11.2: semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" - integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" - integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= dependencies: semver "^5.0.3" "semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== send@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" - integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== dependencies: debug "2.6.9" depd "~1.1.2" @@ -5103,22 +4320,19 @@ send@0.16.2: serve-static@1.13.2: version "1.13.2" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" - integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" parseurl "~1.3.2" send "0.16.2" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= set-value@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -5128,7 +4342,6 @@ set-value@^0.4.3: set-value@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -5138,34 +4351,37 @@ set-value@^2.0.0: setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= dependencies: shebang-regex "^1.0.0" shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shell-quote@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== slice-ansi@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.0.0.tgz#5373bdb8559b45676e8541c66916cdd6251612e7" - integrity sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ== dependencies: ansi-styles "^3.2.0" astral-regex "^1.0.0" @@ -5174,14 +4390,12 @@ slice-ansi@2.0.0: slug@^0.9.1: version "0.9.2" resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.2.tgz#e409e4dae3a4bd2fd283557e2806e0a8abb98242" - integrity sha512-WULwxWq6NBM/i24pV9st/WI9TwzjXYpNzxbWr9mRDj74Lqwb3ahsnWsWJtXHfBPpBqXb4m1hYt9S7eMyDkZsKA== dependencies: unicode ">= 0.3.1" snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: define-property "^1.0.0" isobject "^3.0.0" @@ -5190,14 +4404,12 @@ snapdragon-node@^2.0.1: snapdragon-util@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: kind-of "^3.2.0" snapdragon@^0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== dependencies: base "^0.11.1" debug "^2.2.0" @@ -5211,7 +4423,6 @@ snapdragon@^0.8.1: source-map-resolve@^0.5.0: version "0.5.2" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== dependencies: atob "^2.1.1" decode-uri-component "^0.2.0" @@ -5222,7 +4433,6 @@ source-map-resolve@^0.5.0: source-map-support@^0.5.1, source-map-support@^0.5.9: version "0.5.9" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" - integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -5230,27 +4440,18 @@ source-map-support@^0.5.1, source-map-support@^0.5.9: source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= source-map@^0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spawn-command@^0.0.2-1: - version "0.0.2-1" - resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" - integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A= spdx-correct@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" - integrity sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" @@ -5258,12 +4459,10 @@ spdx-correct@^3.0.0: spdx-exceptions@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== spdx-expression-parse@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" @@ -5271,24 +4470,20 @@ spdx-expression-parse@^3.0.0: spdx-license-ids@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2" - integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: extend-shallow "^3.0.0" sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= srcset@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/srcset/-/srcset-1.0.0.tgz#a5669de12b42f3b1d5e83ed03c71046fc48f41ef" - integrity sha1-pWad4StC87HV6D7QPHEEb8SPQe8= dependencies: array-uniq "^1.0.2" number-is-nan "^1.0.0" @@ -5296,7 +4491,6 @@ srcset@^1.0.0: sshpk@^1.7.0: version "1.15.2" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.2.tgz#c946d6bd9b1a39d0e8635763f5242d6ed6dcb629" - integrity sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -5311,7 +4505,6 @@ sshpk@^1.7.0: static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= dependencies: define-property "^0.2.5" object-copy "^0.1.0" @@ -5319,22 +4512,18 @@ static-extend@^0.1.1: "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= statuses@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== streamsearch@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" - integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" @@ -5343,63 +4532,61 @@ string-width@^1.0.1: "string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.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" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.4.3" + function-bind "^1.0.2" + string_decoder@^1.1.1, string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= dependencies: ansi-regex "^3.0.0" strip-ansi@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" - integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow== dependencies: ansi-regex "^4.0.0" strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: version "0.9.15" resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz#68a8b7ba0037d8c489fb2f5a102d1494db297d0d" - integrity sha512-f9eBfWdHsePQV67QIX+VRhf++dn1adyC/PZHP6XI5AfKnZ4n0FW+v5omxwdHVpd4xq2ZijaHEcmlQrhBY79ZWQ== dependencies: backo2 "^1.0.2" eventemitter3 "^3.1.0" @@ -5410,31 +4597,20 @@ subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -supports-color@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" - integrity sha1-vnoN5ITexcXN34s9WRJQRJEvY1s= - dependencies: - has-flag "^2.0.0" supports-color@^5.2.0, supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" symbol-observable@^1.0.2, symbol-observable@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" - integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== table@^5.0.2: version "5.1.1" resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837" - integrity sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw== dependencies: ajv "^6.6.1" lodash "^4.17.11" @@ -5444,7 +4620,6 @@ table@^5.0.2: tar@^4: version "4.4.8" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" - integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== dependencies: chownr "^1.1.1" fs-minipass "^1.2.5" @@ -5457,53 +4632,44 @@ tar@^4: term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" - integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= dependencies: execa "^0.7.0" text-encoding@^0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" - integrity sha1-45mpgiV6J22uQou5KEXLcb3CbRk= text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= timed-out@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: kind-of "^3.0.2" 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" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: is-number "^3.0.0" repeat-string "^1.6.1" @@ -5511,7 +4677,6 @@ to-regex-range@^2.1.0: to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: define-property "^2.0.2" extend-shallow "^3.0.2" @@ -5521,39 +4686,29 @@ to-regex@^3.0.1, to-regex@^3.0.2: topo@3.x.x: version "3.0.3" resolved "https://registry.yarnpkg.com/topo/-/topo-3.0.3.tgz#d5a67fb2e69307ebeeb08402ec2a2a6f5f7ad95c" - integrity sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ== dependencies: hoek "6.x.x" touch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== dependencies: nopt "~1.0.10" tough-cookie@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== dependencies: psl "^1.1.24" punycode "^1.4.1" -tree-kill@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.1.tgz#5398f374e2f292b9dcc7b2e71e30a5c3bb6c743a" - integrity sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q== - trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= trunc-html@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/trunc-html/-/trunc-html-1.1.2.tgz#1e97d51f67d470b67662b1a670e6d0ea7a8edafe" - integrity sha1-HpfVH2fUcLZ2YrGmcObQ6nqO2v4= dependencies: assignment "2.2.0" insane "2.6.1" @@ -5562,36 +4717,30 @@ trunc-html@^1.1.2: trunc-text@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" - integrity sha1-WPh22KxZsiS3mDS7R4uGVuaWIrU= tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" - integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= dependencies: safe-buffer "^5.0.1" tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= dependencies: prelude-ls "~1.1.2" type-is@^1.6.16, type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" - integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== dependencies: media-typer "0.3.0" mime-types "~2.1.18" @@ -5599,19 +4748,16 @@ type-is@^1.6.16, type-is@~1.6.16: undefsafe@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76" - integrity sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY= dependencies: debug "^2.2.0" unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== unicode-match-property-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== dependencies: unicode-canonical-property-names-ecmascript "^1.0.4" unicode-property-aliases-ecmascript "^1.0.4" @@ -5619,22 +4765,18 @@ unicode-match-property-ecmascript@^1.0.4: unicode-match-property-value-ecmascript@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz#9f1dc76926d6ccf452310564fd834ace059663d4" - integrity sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ== unicode-property-aliases-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz#5a533f31b4317ea76f17d807fa0d116546111dd0" - integrity sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg== "unicode@>= 0.3.1": version "11.0.1" resolved "https://registry.yarnpkg.com/unicode/-/unicode-11.0.1.tgz#735bd422ec75cf28d396eb224d535d168d5f1db6" - integrity sha512-+cHtykLb+eF1yrSLWTwcYBrqJkTfX7Quoyg7Juhe6uylF43ZbMdxMuSHNYlnyLT8T7POAvavgBthzUF9AIaQvQ== union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= dependencies: arr-union "^3.1.0" get-value "^2.0.6" @@ -5644,19 +4786,16 @@ union-value@^1.0.0: unique-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= dependencies: crypto-random-string "^1.0.0" unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= dependencies: has-value "^0.3.1" isobject "^3.0.0" @@ -5664,17 +4803,14 @@ unset-value@^1.0.0: unzip-response@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= upath@^1.0.5: version "1.1.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" - integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== update-notifier@^2.3.0: version "2.5.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" - integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== dependencies: boxen "^1.2.1" chalk "^2.0.1" @@ -5690,26 +4826,22 @@ update-notifier@^2.3.0: uri-js@^4.2.1, uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== dependencies: punycode "^2.1.0" urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= url-parse-lax@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= dependencies: prepend-http "^1.0.1" url@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" - integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ= dependencies: punycode "1.3.2" querystring "0.2.0" @@ -5717,17 +4849,14 @@ url@0.10.3: use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= util.promisify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== dependencies: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" @@ -5735,29 +4864,24 @@ util.promisify@^1.0.0: utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= uuid@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== uuid@^3.1.0, uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== v8flags@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.1.tgz#42259a1461c08397e37fe1d4f1cfb59cad85a053" - integrity sha512-iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ== dependencies: homedir-polyfill "^1.0.1" validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" @@ -5765,12 +4889,10 @@ validate-npm-package-license@^3.0.1: vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= dependencies: assert-plus "^1.0.0" core-util-is "1.0.2" @@ -5779,7 +4901,6 @@ verror@1.10.0: wait-on@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-3.2.0.tgz#c83924df0fc42a675c678324c49c769d378bcb85" - integrity sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg== dependencies: core-js "^2.5.7" joi "^13.0.0" @@ -5790,56 +4911,36 @@ wait-on@^3.2.0: whatwg-fetch@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" - integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: string-width "^1.0.2 || 2" widest-line@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" - integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== dependencies: string-width "^2.1.1" wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= write-file-atomic@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" - integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== dependencies: graceful-fs "^4.1.11" imurmurhash "^0.1.4" @@ -5848,33 +4949,28 @@ write-file-atomic@^2.0.0: write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= dependencies: mkdirp "^0.5.1" ws@^5.2.0: version "5.2.2" resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== dependencies: async-limiter "~1.0.0" ws@^6.0.0: version "6.1.2" resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" - integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== dependencies: async-limiter "~1.0.0" xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= xml2js@0.4.19, xml2js@^0.4.17: version "0.4.19" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" - integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== dependencies: sax ">=0.6.0" xmlbuilder "~9.0.1" @@ -5882,62 +4978,25 @@ xml2js@0.4.19, xml2js@^0.4.17: xmlbuilder@~9.0.1: version "9.0.7" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= xtend@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= - -"y18n@^3.2.1 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= yallist@^3.0.0, yallist@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" - integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= - -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs@^12.0.1: - version "12.0.5" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== - dependencies: - cliui "^4.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" zen-observable-ts@^0.8.10, zen-observable-ts@^0.8.11: version "0.8.11" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.11.tgz#d54a27cd17dc4b4bb6bd008e5c096af7fcb068a9" - integrity sha512-8bs7rgGV4kz5iTb9isudkuQjtWwPnQ8lXq6/T76vrepYZVMsDEv6BXaEA+DHdJSK3KVLduagi9jSpSAJ5NgKHw== dependencies: zen-observable "^0.8.0" zen-observable@^0.8.0: version "0.8.11" resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.11.tgz#d3415885eeeb42ee5abb9821c95bb518fcd6d199" - integrity sha512-N3xXQVr4L61rZvGMpWe8XoCGX8vhU35dPyQ4fm5CY/KDlG0F75un14hjbckPXTDuKUY6V0dqR2giT6xN8Y4GEQ== From d9a707939202f2691fdd581683693875e484b6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sat, 8 Dec 2018 01:26:13 +0100 Subject: [PATCH 141/554] Run seeds and lint in docker-compose --- .travis.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 322137700..bbcb19c6e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,17 +7,23 @@ cache: - node_modules services: - docker - - neo4j + +env: + - DOCKER_COMPOSE_VERSION=1.23.2 + +before_install: + - sudo rm /usr/local/bin/docker-compose + - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose + - chmod +x docker-compose + - sudo mv docker-compose /usr/local/bin install: - - yarn install - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend:latest . - - cp .env.template .env script: -- docker run humanconnection/nitro-backend:latest yarn run eslint -- yarn run db:reset -- yarn run db:seed + - docker-compose exec backend yarn run eslint + - docker-compose exec backend yarn run db:reset + - docker-compose exec backend yarn run db:seed after_success: - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh From 46080fff98d5faae49d73beb1e19f0889a415642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sat, 8 Dec 2018 01:58:51 +0100 Subject: [PATCH 142/554] Fix build --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index bbcb19c6e..daaa1b43f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,7 @@ before_install: install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend:latest . + - docker-compose up -d script: - docker-compose exec backend yarn run eslint From b4c92ec29afb551d80f747300e3bcc4972803c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sat, 8 Dec 2018 13:17:43 +0100 Subject: [PATCH 143/554] Remove xip.io hack After we proxy API requests through the server-side-rendered frontend there is no need to use xip.io anymore. However, if you "join" services to a named network at arbitrary times, the DNS of docker-compose only works if you assign a name to the container. Thus I left `backend` as a container name. --- docker-compose.override.yml | 1 - docker-compose.yml | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 70e2fe389..ef8ce7706 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -2,7 +2,6 @@ version: "3.7" services: backend: - container_name: backend.127.0.0.1.xip.io volumes: - .:/nitro-backend - /nitro-backend/node_modules diff --git a/docker-compose.yml b/docker-compose.yml index 71ea7355c..311a34acc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,6 +2,7 @@ version: "3.7" services: backend: + container_name: backend image: humanconnection/nitro-backend:latest build: . networks: From ad66dd1b852aeba89a5d8f8602a019292c1e3d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sat, 8 Dec 2018 13:33:38 +0100 Subject: [PATCH 144/554] Give hc-network a name I was wrong. It's not the container name but I forgot simply to give the network the very same name as specified in the docker-compose.yml of the frontend --- docker-compose.override.yml | 4 ---- docker-compose.yml | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/docker-compose.override.yml b/docker-compose.override.yml index ef8ce7706..3be950735 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -9,7 +9,3 @@ services: ports: - 7687:7687 - 7474:7474 - -networks: - hc-network: - name: hc-network diff --git a/docker-compose.yml b/docker-compose.yml index 311a34acc..0b070c98e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,6 @@ version: "3.7" services: backend: - container_name: backend image: humanconnection/nitro-backend:latest build: . networks: @@ -33,6 +32,7 @@ services: networks: hc-network: + name: hc-network volumes: neo4j-data: From 141e1cc7fd795afd18bffd920ba45b8481e33c25 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sat, 8 Dec 2018 14:27:46 +0100 Subject: [PATCH 145/554] fix nyc testing on build --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 509d3bc70..23fa2f812 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "scripts": { "ci": "yarn run lint && yarn run test && yarn run test:coverage", "lint": "eslint src --config .eslintrc.js", - "test": "nyc --reporter=text-lcov ./node_modules/.bin/mocha --require @babel/register src/**/*.test.js", - "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", + "test": "./node_modules/.bin/nyc --reporter=text-lcov ./node_modules/.bin/mocha --require @babel/register src/**/*.test.js", + "test:coverage": "./node_modules/.bin/nyc report --reporter=text-lcov > coverage.lcov", "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "db:script:seed": "wait-on tcp:4001 && ./node_modules/.bin/babel-node src/seed/seed-db.js", From 499c6851a79aec532012565aa9e35d6d00ff8449 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 10 Dec 2018 11:35:16 +0000 Subject: [PATCH 146/554] Bump eslint from 5.9.0 to 5.10.0 Bumps [eslint](https://github.com/eslint/eslint) from 5.9.0 to 5.10.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v5.9.0...v5.10.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 21 +++++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index cdb672bfe..4fdf69783 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "apollo-server-testing": "~2.2.6", "babel-eslint": "~10.0.1", "chai": "~4.2.0", - "eslint": "~5.9.0", + "eslint": "~5.10.0", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.14.0", "eslint-plugin-node": "~8.0.0", diff --git a/yarn.lock b/yarn.lock index 0d28a8f5b..4825c4bc0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2086,9 +2086,10 @@ eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" -eslint@~5.9.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" +eslint@~5.10.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.10.0.tgz#24adcbe92bf5eb1fc2d2f2b1eebe0c5e0713903a" + integrity sha512-HpqzC+BHULKlnPwWae9MaVZ5AXJKpkxCVXQHrFaRw3hbDj26V/9ArYM4Rr/SQ8pi6qUPLXSSXC4RBJlyq2Z2OQ== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.5.3" @@ -2099,7 +2100,7 @@ eslint@~5.9.0: eslint-scope "^4.0.0" eslint-utils "^1.3.1" eslint-visitor-keys "^1.0.0" - espree "^4.0.0" + espree "^5.0.0" esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^2.0.0" @@ -2109,7 +2110,6 @@ eslint@~5.9.0: ignore "^4.0.6" imurmurhash "^0.1.4" inquirer "^6.1.0" - is-resolvable "^1.1.0" js-yaml "^3.12.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" @@ -2129,9 +2129,10 @@ eslint@~5.9.0: table "^5.0.2" text-table "^0.2.0" -espree@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" +espree@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.0.tgz#fc7f984b62b36a0f543b13fb9cd7b9f4a7f5b65c" + integrity sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA== dependencies: acorn "^6.0.2" acorn-jsx "^5.0.0" @@ -3099,10 +3100,6 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" -is-resolvable@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" From afa143a62725d390fe5300ab08aedee41ba0de5f Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 10 Dec 2018 12:41:19 +0100 Subject: [PATCH 147/554] added missing nyc dependency --- package.json | 1 + yarn.lock | 437 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 426 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 5594a0118..60219a12a 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "mocha": "^5.2.0", "nodemon": "~1.18.7", "npm-run-all": "~4.1.5", + "nyc": "^13.1.0", "wait-on": "~3.2.0" } } diff --git a/yarn.lock b/yarn.lock index ff6dd7390..0290b7091 100644 --- a/yarn.lock +++ b/yarn.lock @@ -67,7 +67,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.1.6", "@babel/generator@^7.2.0": +"@babel/generator@^7.0.0", "@babel/generator@^7.1.6", "@babel/generator@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.0.tgz#eaf3821fa0301d9d4aef88e63d4bcc19b73ba16c" integrity sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg== @@ -635,7 +635,7 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/template@^7.1.0", "@babel/template@^7.1.2": +"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2": version "7.1.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" integrity sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag== @@ -1178,11 +1178,23 @@ apollo-utilities@1.0.26, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apoll dependencies: fast-json-stable-stringify "^2.0.0" +append-transform@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" + integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== + dependencies: + default-require-extensions "^2.0.0" + aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + are-we-there-yet@~1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" @@ -1243,6 +1255,11 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -1297,6 +1314,13 @@ async-retry@^1.2.1: dependencies: retry "0.12.0" +async@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== + dependencies: + lodash "^4.17.10" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1546,6 +1570,16 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +caching-transform@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-2.0.0.tgz#e1292bd92d35b6e8b1ed7075726724b3bd64eea0" + integrity sha512-tTfemGmFWe7KZ3KN6VsSgQZbd9Bgo7A40wlp4PTsJJvFu4YAnEC5YnfdiKq6Vh2i9XJLnA9n8OXD46orVpnPMw== + dependencies: + make-dir "^1.0.0" + md5-hex "^2.0.0" + package-hash "^2.0.0" + write-file-atomic "^2.0.0" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -1558,7 +1592,7 @@ callsites@^0.2.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= -camelcase@^4.0.0: +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= @@ -1698,6 +1732,15 @@ cli-width@^2.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -1740,6 +1783,11 @@ commander@^2.5.0, commander@^2.8.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1787,7 +1835,7 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.1.0: +convert-source-map@^1.1.0, convert-source-map@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== @@ -1859,6 +1907,14 @@ cross-fetch@2.2.2: node-fetch "2.1.2" whatwg-fetch "2.0.4" +cross-spawn@^4: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -1911,6 +1967,11 @@ date-fns@^2.0.0-alpha.25: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.25.tgz#651a5d1f59a01af6cf0371e39b2ae29df5d521ee" integrity sha512-iQzJkHF0L4wah9Ae9PkvwemwFz6qmRLuNZcghmvf2t+ptLs1qXzONLiGtjmPQzL6+JpC01JjlTopY2AEy4NFAg== +debug-log@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" + integrity sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8= + debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -1939,6 +2000,11 @@ debug@^4.0.1, debug@^4.1.0: dependencies: ms "^2.1.1" +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -1961,6 +2027,13 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +default-require-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" + integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= + dependencies: + strip-bom "^3.0.0" + define-properties@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -2180,6 +2253,11 @@ es-to-primitive@^1.1.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-error@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2571,6 +2649,15 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" +find-cache-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d" + integrity sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA== + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^3.0.0" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -2586,6 +2673,13 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + flat-cache@^1.2.1: version "1.3.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" @@ -2601,6 +2695,14 @@ for-in@^1.0.2: resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +foreground-child@^1.5.6: + version "1.5.6" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" + integrity sha1-T9ca0t/elnibmApcCilZN8svXOk= + dependencies: + cross-spawn "^4" + signal-exit "^3.0.0" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -2681,6 +2783,11 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + get-func-name@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" @@ -2723,7 +2830,7 @@ glob@7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.5, glob@^7.1.2: +glob@^7.0.0, glob@^7.0.5, glob@^7.1.2, glob@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== @@ -2956,6 +3063,17 @@ growl@1.10.5: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== +handlebars@^4.0.11: + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" + integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== + dependencies: + async "^2.5.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -3229,6 +3347,11 @@ invariant@^2.2.2: dependencies: loose-envify "^1.0.0" +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + ipaddr.js@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" @@ -3496,6 +3619,58 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +istanbul-lib-coverage@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda" + integrity sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA== + +istanbul-lib-hook@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.1.tgz#918a57b75a0f951d552a08487ca1fa5336433d72" + integrity sha512-ufiZoiJ8CxY577JJWEeFuxXZoMqiKpq/RqZtOAYuQLvlkbJWscq9n3gc4xrCGH9n4pW0qnTxOz1oyMmVtk8E1w== + dependencies: + append-transform "^1.0.0" + +istanbul-lib-instrument@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz#b5f066b2a161f75788be17a9d556f40a0cf2afc9" + integrity sha512-eQY9vN9elYjdgN9Iv6NS/00bptm02EBBk70lRMaVjeA6QYocQgenVrSgC28TJurdnZa80AGO3ASdFN+w/njGiQ== + dependencies: + "@babel/generator" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + istanbul-lib-coverage "^2.0.1" + semver "^5.5.0" + +istanbul-lib-report@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.2.tgz#430a2598519113e1da7af274ba861bd42dd97535" + integrity sha512-rJ8uR3peeIrwAxoDEbK4dJ7cqqtxBisZKCuwkMtMv0xYzaAnsAi3AHrHPAAtNXzG/bcCgZZ3OJVqm1DTi9ap2Q== + dependencies: + istanbul-lib-coverage "^2.0.1" + make-dir "^1.3.0" + supports-color "^5.4.0" + +istanbul-lib-source-maps@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-2.0.1.tgz#ce8b45131d8293fdeaa732f4faf1852d13d0a97e" + integrity sha512-30l40ySg+gvBLcxTrLzR4Z2XTRj3HgRCA/p2rnbs/3OiTaoj054gAbuP5DcLOtwqmy4XW8qXBHzrmP2/bQ9i3A== + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^2.0.1" + make-dir "^1.3.0" + rimraf "^2.6.2" + source-map "^0.6.1" + +istanbul-reports@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.0.1.tgz#fb8d6ea850701a3984350b977a969e9a556116a7" + integrity sha512-CT0QgMBJqs6NJLF678ZHcquUAZIoBIUNzdJrRJfpkI9OnzG6MkUfHxbJC3ln981dMswC7/B1mfX3LNkhgJxsuw== + dependencies: + handlebars "^4.0.11" + iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" @@ -3670,6 +3845,13 @@ latest-version@^3.0.0: dependencies: package-json "^4.0.0" +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -3724,6 +3906,14 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" @@ -3739,6 +3929,11 @@ lodash.escaperegexp@^4.1.2: resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" integrity sha1-ZHYsSGGAglGKw99Mz11YhtriA0c= +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= + lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" @@ -3816,7 +4011,7 @@ lru-cache@^5.0.0: dependencies: yallist "^3.0.2" -make-dir@^1.0.0: +make-dir@^1.0.0, make-dir@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== @@ -3835,11 +4030,30 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +md5-hex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" + integrity sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM= + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + integrity sha1-givM1l4RfFFPqxdrJZRdVBAKA8M= + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= + dependencies: + mimic-fn "^1.0.0" + memorystream@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" @@ -3850,6 +4064,13 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== + dependencies: + source-map "^0.6.1" + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -3913,6 +4134,11 @@ minimist@1.2.0, minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + minipass@^2.2.1, minipass@^2.3.4: version "2.3.5" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" @@ -4200,6 +4426,37 @@ numeral@^2.0.6: resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" integrity sha1-StCAk21EPCVhrtnyGX7//iX05QY= +nyc@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-13.1.0.tgz#463665c7ff6b5798e322624a5eb449a678db90e3" + integrity sha512-3GyY6TpQ58z9Frpv4GMExE1SV2tAgYqC7HSy2omEhNiCT3mhT9NyiOvIE8zkbuJVFzmvvNTnE4h/7/wQae7xLg== + dependencies: + archy "^1.0.0" + arrify "^1.0.1" + caching-transform "^2.0.0" + convert-source-map "^1.6.0" + debug-log "^1.0.1" + find-cache-dir "^2.0.0" + find-up "^3.0.0" + foreground-child "^1.5.6" + glob "^7.1.3" + istanbul-lib-coverage "^2.0.1" + istanbul-lib-hook "^2.0.1" + istanbul-lib-instrument "^3.0.0" + istanbul-lib-report "^2.0.2" + istanbul-lib-source-maps "^2.0.1" + istanbul-reports "^2.0.1" + make-dir "^1.3.0" + merge-source-map "^1.1.0" + resolve-from "^4.0.0" + rimraf "^2.6.2" + signal-exit "^3.0.2" + spawn-wrap "^1.4.2" + test-exclude "^5.0.0" + uuid "^3.3.2" + yargs "11.1.0" + yargs-parser "^9.0.2" + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -4304,6 +4561,14 @@ optimism@^0.6.6: dependencies: immutable-tuple "^0.4.9" +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" @@ -4316,11 +4581,20 @@ optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" -os-homedir@^1.0.0: +os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -4355,6 +4629,13 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" +p-limit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" + integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== + dependencies: + p-try "^2.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -4362,11 +4643,33 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== + +package-hash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-2.0.0.tgz#78ae326c89e05a4d813b68601977af05c00d2a0d" + integrity sha1-eK4ybIngWk2BO2hgGXevBcANKg0= + dependencies: + graceful-fs "^4.1.11" + lodash.flattendeep "^4.4.0" + md5-hex "^2.0.0" + release-zalgo "^1.0.0" + package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -4554,6 +4857,13 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" @@ -4726,6 +5036,14 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" @@ -4871,6 +5189,13 @@ regjsparser@^0.6.0: dependencies: jsesc "~0.5.0" +release-zalgo@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" + integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= + dependencies: + es6-error "^4.0.1" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -4912,6 +5237,16 @@ request@^2.88.0: tunnel-agent "^0.6.0" uuid "^3.3.2" +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" @@ -4960,7 +5295,7 @@ retry@0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= -rimraf@^2.6.1, rimraf@~2.6.2: +rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== @@ -5083,7 +5418,7 @@ serve-static@1.13.2: parseurl "~1.3.2" send "0.16.2" -set-blocking@~2.0.0: +set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -5220,11 +5555,23 @@ source-map@^0.5.0, source-map@^0.5.6: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +spawn-wrap@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" + integrity sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg== + dependencies: + foreground-child "^1.5.6" + mkdirp "^0.5.0" + os-homedir "^1.0.1" + rimraf "^2.6.2" + signal-exit "^3.0.2" + which "^1.3.0" + spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" @@ -5413,7 +5760,7 @@ supports-color@^2.0.0: resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= -supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.5.0: +supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -5455,6 +5802,16 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" +test-exclude@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.0.0.tgz#cdce7cece785e0e829cd5c2b27baf18bc583cfb7" + integrity sha512-bO3Lj5+qFa9YLfYW2ZcXMOV1pmQvw+KS/DpjqhyX6Y6UZ8zstpZJ+mA2ERkXfpOqhxsJlQiLeVXD3Smsrs6oLw== + dependencies: + arrify "^1.0.1" + minimatch "^3.0.4" + read-pkg-up "^4.0.0" + require-main-filename "^1.0.1" + text-encoding@^0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" @@ -5590,6 +5947,14 @@ type-is@^1.6.16, type-is@~1.6.16: media-typer "0.3.0" mime-types "~2.1.18" +uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + undefsafe@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76" @@ -5786,7 +6151,12 @@ whatwg-fetch@2.0.4: resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== -which@^1.2.9: +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -5807,11 +6177,24 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -5870,6 +6253,11 @@ xtend@^4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" @@ -5880,6 +6268,31 @@ yallist@^3.0.0, yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= + dependencies: + camelcase "^4.1.0" + +yargs@11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" + integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A== + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^9.0.2" + zen-observable-ts@^0.8.11: version "0.8.11" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.11.tgz#d54a27cd17dc4b4bb6bd008e5c096af7fcb068a9" From 4ba03d18817bbb5a91591ad27924e64116394b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 10 Dec 2018 15:44:09 +0100 Subject: [PATCH 148/554] Trigger a build in our meta repository For full stack testing. --- .travis.yml | 1 + scripts/deploy.sh | 2 +- scripts/run_fullstack_tests.sh | 9 +++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100755 scripts/run_fullstack_tests.sh diff --git a/.travis.yml b/.travis.yml index 4b9c4827e..8b5c9449b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ env: - DOCKER_COMPOSE_VERSION=1.23.2 before_install: + - scripts/run_fullstack_tests.sh # trigger full stack testing in a different repository - sudo rm /usr/local/bin/docker-compose - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose - chmod +x docker-compose diff --git a/scripts/deploy.sh b/scripts/deploy.sh index b66b63a77..d4aadf2b3 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "See me deployed at $1 :)" diff --git a/scripts/run_fullstack_tests.sh b/scripts/run_fullstack_tests.sh new file mode 100755 index 000000000..c99bd84a2 --- /dev/null +++ b/scripts/run_fullstack_tests.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +if [[ -v TRAVIS_TOKEN ]]; then + # You need a Travis token to trigger the build on our meta repository. + # This token will not be available on forks of this repo. + curl -L https://raw.githubusercontent.com/Human-Connection/Human-Connection/master/scripts/trigger_build.sh > trigger_build.sh + chmod +x trigger_build.sh + ./trigger_build.sh +fi From bd26f738a59066deae87426cab12b44db8d82d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 10 Dec 2018 17:42:12 +0100 Subject: [PATCH 149/554] Same as this commit: https://github.com/Human-Connection/Nitro-Web/pull/84/commits/8b324fc8dd0860c864838546b53cdd92a684b441 --- .dockerignore | 1 + scripts/run_fullstack_tests.sh | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.dockerignore b/.dockerignore index ccb6f6091..f0f6fe315 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,5 +5,6 @@ npm-debug.log Dockerfile docker-compose*.yml +scripts/ .env diff --git a/scripts/run_fullstack_tests.sh b/scripts/run_fullstack_tests.sh index c99bd84a2..5176c493c 100755 --- a/scripts/run_fullstack_tests.sh +++ b/scripts/run_fullstack_tests.sh @@ -3,7 +3,7 @@ if [[ -v TRAVIS_TOKEN ]]; then # You need a Travis token to trigger the build on our meta repository. # This token will not be available on forks of this repo. - curl -L https://raw.githubusercontent.com/Human-Connection/Human-Connection/master/scripts/trigger_build.sh > trigger_build.sh - chmod +x trigger_build.sh - ./trigger_build.sh + curl -L https://raw.githubusercontent.com/Human-Connection/Human-Connection/master/scripts/trigger_build.sh > scripts/trigger_build.sh + chmod +x scripts/trigger_build.sh + ./scripts/trigger_build.sh fi From 35e7fd0cca3c5d0a6d93d3a89be7690d2f064632 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 11 Dec 2018 04:25:55 +0000 Subject: [PATCH 150/554] Bump slug from 0.9.2 to 0.9.3 Bumps [slug](https://github.com/Trott/node-slug) from 0.9.2 to 0.9.3. - [Release notes](https://github.com/Trott/node-slug/releases) - [Commits](https://github.com/Trott/node-slug/compare/q0.9.2...v0.9.3) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index cdb672bfe..0ed5a16c6 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "passport": "~0.4.0", "passport-jwt": "~4.0.0", "sanitize-html": "~1.19.3", - "slug": "~0.9.2", + "slug": "~0.9.3", "trunc-html": "~1.1.2" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 0d28a8f5b..647f69928 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4600,9 +4600,10 @@ slice-ansi@2.0.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -slug@~0.9.2: - version "0.9.2" - resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.2.tgz#e409e4dae3a4bd2fd283557e2806e0a8abb98242" +slug@~0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.3.tgz#8c9c773d79367c0188733316cf49fd2b8db40f6a" + integrity sha512-DddSQQnUdAofjFOKRT+zsMNrdzdte04G5DUA+NeaUJlPAqR1bWQ22qVfayRxHFiRGR3bUV0wt5VSj4849pGKSw== dependencies: unicode ">= 0.3.1" From 9cee0e7883b592373eea79d100383a667c135278 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 11 Dec 2018 04:26:07 +0000 Subject: [PATCH 151/554] Bump graphql-shield from 4.1.1 to 4.1.2 Bumps [graphql-shield](https://github.com/maticzav/graphql-shield) from 4.1.1 to 4.1.2. - [Release notes](https://github.com/maticzav/graphql-shield/releases) - [Commits](https://github.com/maticzav/graphql-shield/compare/v4.1.1...v4.1.2) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index cdb672bfe..0e26ae469 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "graphql-custom-directives": "~0.2.14", "graphql-iso-date": "~3.6.1", "graphql-middleware": "2.0.2", - "graphql-shield": "~4.1.0", + "graphql-shield": "~4.1.2", "graphql-tag": "~2.10.0", "graphql-yoga": "~1.16.7", "jsonwebtoken": "~8.4.0", diff --git a/yarn.lock b/yarn.lock index 0d28a8f5b..df116c3b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2616,10 +2616,10 @@ graphql-request@^1.5.0: dependencies: cross-fetch "2.2.2" -graphql-shield@~4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.1.1.tgz#177f9ec768d9d232b35d8c1406e39c81c5582481" - integrity sha512-0bxWc091MiG1UBjFqYbEcgs/CcrzPfRpoBoviz2PoZpBJAyWaN3EDLW2/Trjx9s0nGQTEhEeJDUI24Q6F1j/yg== +graphql-shield@~4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.1.2.tgz#dee5f9118c160cae1b793c443e3550ad7e81e1cb" + integrity sha512-hVzAMtb2dWeCv72A5DypAVHaFVXmA2NNH97wTNXtex4zFIhxWXauOF8WuoAXhWdlzxKF/s5NLthvl31AUxsRyQ== dependencies: object-hash "^1.3.0" opencollective "1.0.3" From 91f60439f41ed919d7e527ebac87053691d40e6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 11 Dec 2018 04:26:24 +0000 Subject: [PATCH 152/554] Bump nodemon from 1.18.7 to 1.18.8 Bumps [nodemon](https://github.com/remy/nodemon) from 1.18.7 to 1.18.8. - [Release notes](https://github.com/remy/nodemon/releases) - [Commits](https://github.com/remy/nodemon/compare/v1.18.7...v1.18.8) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index cdb672bfe..78371fc4e 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "eslint-plugin-standard": "~4.0.0", "faker": "~4.1.0", "mocha": "^5.2.0", - "nodemon": "~1.18.7", + "nodemon": "~1.18.8", "npm-run-all": "~4.1.5", "wait-on": "~3.2.0" } diff --git a/yarn.lock b/yarn.lock index 0d28a8f5b..6123280a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3669,20 +3669,21 @@ node-releases@^1.0.5: dependencies: semver "^5.3.0" -nodemon@~1.18.7: - version "1.18.7" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.7.tgz#716b66bf3e89ac4fcfb38a9e61887a03fc82efbb" +nodemon@~1.18.8: + version "1.18.8" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.8.tgz#eb4c0052dc81395bdc503f3c8ae3cba86ca7146a" + integrity sha512-CgC/JdCf+CT7Z+K6wWaV30t8GU1DPtXpr/6PuXC1/LboXCmUQNKOaz0AEMjoWDTt2AdHOBFxgv41dyC0i79SbA== dependencies: chokidar "^2.0.4" debug "^3.1.0" ignore-by-default "^1.0.1" minimatch "^3.0.4" - pstree.remy "^1.1.2" + pstree.remy "^1.1.3" semver "^5.5.0" supports-color "^5.2.0" touch "^3.1.0" undefsafe "^2.0.2" - update-notifier "^2.3.0" + update-notifier "^2.5.0" nopt@^4.0.1: version "4.0.1" @@ -4150,9 +4151,10 @@ psl@^1.1.24: version "1.1.29" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" -pstree.remy@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.2.tgz#4448bbeb4b2af1fed242afc8dc7416a6f504951a" +pstree.remy@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.4.tgz#a03d5dbc06ba639fb6dd4874644c4bad9882ec21" + integrity sha512-3kSyTN/iTJMxtL87idnFgTyOp2vQ6B/49QcHUO26kh2M2qahlUivFI1zWJ9FRFPoB+KgcP820JMOuIhkBJAP3Q== punycode@1.3.2: version "1.3.2" @@ -5037,9 +5039,10 @@ upath@^1.0.5: version "1.1.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" -update-notifier@^2.3.0: +update-notifier@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== dependencies: boxen "^1.2.1" chalk "^2.0.1" From 0d396712bd3f18d43bc9c83ade8547c706169d75 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 11 Dec 2018 11:37:53 +0100 Subject: [PATCH 153/554] downgrade graphql-middleware --- package.json | 2 +- yarn.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 60219a12a..5965bba4a 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "graphql": "~0.13.0", "graphql-custom-directives": "~0.2.14", "graphql-iso-date": "~3.6.1", - "graphql-middleware": "2.0.2", + "graphql-middleware": "~1.7.8", "graphql-shield": "~4.1.0", "graphql-tag": "~2.10.0", "graphql-yoga": "~1.16.7", diff --git a/yarn.lock b/yarn.lock index 0290b7091..10ba8bdc7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2944,12 +2944,12 @@ graphql-middleware@1.7.7: dependencies: graphql-tools "^4.0.1" -graphql-middleware@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-2.0.2.tgz#99a3b0ff3f3e3fa66c6ddc8608e6e4eb1d2bb99c" - integrity sha512-qDmot+DU2XTRnWS3SJGRUUPQ9jhma9AtUR1GtWnqq3JkzoqzT/dprxS7eszIj0c1gD5UrySpm4yM1fNbQcazwA== +graphql-middleware@~1.7.8: + version "1.7.8" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.8.tgz#617940d3cd462e9553e582d2b6ce86cb0e95a3dd" + integrity sha512-FNl427I9fCZ9ZwuywPHPbpVJCgDiMS+7dbtaEZu7zJiMP8il2+2T0KRKCiXkfLDKefiGkZnl4qVIFbncCDaduA== dependencies: - graphql-tools "^4.0.3" + graphql-tools "^4.0.2" graphql-playground-html@1.6.4: version "1.6.4" @@ -3006,7 +3006,7 @@ graphql-tag@^2.9.2, graphql-tag@~2.10.0: resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w== -graphql-tools@^4.0.0, graphql-tools@^4.0.1, graphql-tools@^4.0.3: +graphql-tools@^4.0.0, graphql-tools@^4.0.1, graphql-tools@^4.0.2: version "4.0.3" resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.3.tgz#23b5cb52c519212b1b2e4630a361464396ad264b" integrity sha512-NNZM0WSnVLX1zIMUxu7SjzLZ4prCp15N5L2T2ro02OVyydZ0fuCnZYRnx/yK9xjGWbZA0Q58yEO//Bv/psJWrg== From 0fd65793da8622c753fa9261a1b957b8d624b52c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 12 Dec 2018 04:35:55 +0000 Subject: [PATCH 154/554] Bump date-fns from 2.0.0-alpha.25 to 2.0.0-alpha.26 Bumps [date-fns](https://github.com/date-fns/date-fns) from 2.0.0-alpha.25 to 2.0.0-alpha.26. - [Release notes](https://github.com/date-fns/date-fns/releases) - [Changelog](https://github.com/date-fns/date-fns/blob/master/CHANGELOG.md) - [Commits](https://github.com/date-fns/date-fns/compare/v2.0.0-alpha.25...v2.0.0-alpha.26) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index cdb672bfe..e7debf530 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", "cross-env": "~5.2.0", - "date-fns": "^2.0.0-alpha.25", + "date-fns": "^2.0.0-alpha.26", "dotenv": "~6.2.0", "graphql": "~0.13.0", "graphql-custom-directives": "~0.2.14", diff --git a/yarn.lock b/yarn.lock index 0d28a8f5b..c8424aa9c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1756,9 +1756,10 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -date-fns@^2.0.0-alpha.25: - version "2.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.25.tgz#651a5d1f59a01af6cf0371e39b2ae29df5d521ee" +date-fns@^2.0.0-alpha.26: + version "2.0.0-alpha.26" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.26.tgz#e46afd73a2b50e0359446309ee7cb631d7467227" + integrity sha512-UAptCZ53MVimUFR8MXTyHED51AVGIqFlBfWgiS/KIoSYiJGrWScx4PYQVNSWfK2Js+43OlokCW1ttnexBTJ5Bg== debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" From 66f7265b150818b335cf0feaae833aa4ef8a02a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 12 Dec 2018 16:32:50 +0100 Subject: [PATCH 155/554] Remove the script to trigger full stack tests This will be handled by the frontend repo --- .travis.yml | 1 - scripts/run_fullstack_tests.sh | 9 --------- 2 files changed, 10 deletions(-) delete mode 100755 scripts/run_fullstack_tests.sh diff --git a/.travis.yml b/.travis.yml index 8b5c9449b..4b9c4827e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ env: - DOCKER_COMPOSE_VERSION=1.23.2 before_install: - - scripts/run_fullstack_tests.sh # trigger full stack testing in a different repository - sudo rm /usr/local/bin/docker-compose - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose - chmod +x docker-compose diff --git a/scripts/run_fullstack_tests.sh b/scripts/run_fullstack_tests.sh deleted file mode 100755 index 5176c493c..000000000 --- a/scripts/run_fullstack_tests.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -if [[ -v TRAVIS_TOKEN ]]; then - # You need a Travis token to trigger the build on our meta repository. - # This token will not be available on forks of this repo. - curl -L https://raw.githubusercontent.com/Human-Connection/Human-Connection/master/scripts/trigger_build.sh > scripts/trigger_build.sh - chmod +x scripts/trigger_build.sh - ./scripts/trigger_build.sh -fi From 2088d4e495352835bde05b3402503523cf6b160f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 14 Dec 2018 18:01:40 +0100 Subject: [PATCH 156/554] Use deployment script for docker images +Fix deprecation warning of docker login --- .travis.yml | 9 ++++----- scripts/docker_push.sh | 3 +++ 2 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 scripts/docker_push.sh diff --git a/.travis.yml b/.travis.yml index c65ef601b..8bfe76dcf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,11 +30,6 @@ 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 - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - docker tag humanconnection/nitro-backend humanconnection/nitro-backend:latest; - docker push humanconnection/nitro-backend:latest; - fi after_failure: - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh @@ -42,6 +37,10 @@ after_failure: - ./send.sh failure $WEBHOOK_URL deploy: + - provider: script + script: scripts/docker_push.sh + on: + branch: master - provider: script script: scripts/deploy.sh nitro.human-connection.org on: diff --git a/scripts/docker_push.sh b/scripts/docker_push.sh new file mode 100644 index 000000000..09a2d87e8 --- /dev/null +++ b/scripts/docker_push.sh @@ -0,0 +1,3 @@ +#!/bin/bash +echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin +docker push humanconnection/nitro-backend:latest From 957bb4cea2428e6a2fcd3fa9a3a817981e1d38b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 14 Dec 2018 18:24:12 +0100 Subject: [PATCH 157/554] Add Travis build status to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c7103742b..252f2405b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Human-Connection - NITRO Backend +[![Build Status](https://travis-ci.com/Human-Connection/Nitro-Backend.svg?branch=master)](https://travis-ci.com/Human-Connection/Nitro-Backend) > This Prototype tries to resolve the biggest hurdle of connecting > our services together. This is not possible in a sane way using From bdcadcb433e727fe83b1d2397eaafb15ac734d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 14 Dec 2018 18:25:30 +0100 Subject: [PATCH 158/554] Update .dockerignore and .gitignore --- .dockerignore | 18 ++++++++++++------ .gitignore | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.dockerignore b/.dockerignore index f0f6fe315..84b5adc92 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,10 +1,16 @@ .vscode/ - -node_modules/ -npm-debug.log +.nyc_output/ +.github/ +.travis.yml +.graphqlconfig +.env Dockerfile -docker-compose*.yml -scripts/ -.env +./*.png +./*.log + +kubernetes/ +node_modules/ +scripts/ +dist/ diff --git a/.gitignore b/.gitignore index 50ab0c8a4..a5e987954 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ node_modules/ .env .vscode yarn-error.log +dist/* coverage.lcov .nyc_output/ From fca0a67bfdffb774f1cbd8af1335690f6edd8ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 14 Dec 2018 18:30:10 +0100 Subject: [PATCH 159/554] Don't user docker-compose.override.yml on Travis It creates volumes and these volumns will change ownership and linux file permissions. That in turn will prevent Travis from removing those files and eventually crash the deployment. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8bfe76dcf..5a5dc960f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ before_install: install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend:latest . - - docker-compose up -d + - docker-compose -f docker-compose.yml up -d script: - docker-compose exec backend yarn run ci From f2eca183cc9b04f7cff295a21bb15dcec68016eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 14 Dec 2018 19:48:23 +0100 Subject: [PATCH 160/554] Fix commit hash in deploy URL Executable deploy scripts --- .travis.yml | 22 +++++++++++----------- scripts/docker_push.sh | 0 2 files changed, 11 insertions(+), 11 deletions(-) mode change 100644 => 100755 scripts/docker_push.sh diff --git a/.travis.yml b/.travis.yml index 5a5dc960f..5902c6031 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,16 +26,6 @@ script: - docker-compose exec backend yarn run db:reset - docker-compose exec backend yarn run db:seed -after_success: - - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh - - chmod +x send.sh - - ./send.sh success $WEBHOOK_URL - -after_failure: - - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh - - chmod +x send.sh - - ./send.sh failure $WEBHOOK_URL - deploy: - provider: script script: scripts/docker_push.sh @@ -51,7 +41,17 @@ deploy: on: branch: master - provider: script - script: scripts/deploy.sh "nitro-$(git rev-parse --short HEAD).human-connection.org" + script: scripts/deploy.sh "nitro-$TRAVIS_COMMIT.human-connection.org" on: tags: true all_branches: true + +after_success: + - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh + - chmod +x send.sh + - ./send.sh success $WEBHOOK_URL + +after_failure: + - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh + - chmod +x send.sh + - ./send.sh failure $WEBHOOK_URL diff --git a/scripts/docker_push.sh b/scripts/docker_push.sh old mode 100644 new mode 100755 From 212725e44d17dec531dd4118400d349d3dff4fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 14 Dec 2018 20:13:15 +0100 Subject: [PATCH 161/554] Minor changes --- .travis.yml | 20 ++++++++++---------- scripts/docker_push.sh | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5902c6031..b510062b9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,16 @@ script: - docker-compose exec backend yarn run db:reset - docker-compose exec backend yarn run db:seed +after_success: + - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh + - chmod +x send.sh + - ./send.sh success $WEBHOOK_URL + +after_failure: + - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh + - chmod +x send.sh + - ./send.sh failure $WEBHOOK_URL + deploy: - provider: script script: scripts/docker_push.sh @@ -45,13 +55,3 @@ deploy: on: tags: true all_branches: true - -after_success: - - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh - - chmod +x send.sh - - ./send.sh success $WEBHOOK_URL - -after_failure: - - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh - - chmod +x send.sh - - ./send.sh failure $WEBHOOK_URL diff --git a/scripts/docker_push.sh b/scripts/docker_push.sh index 09a2d87e8..a0d46ffd3 100755 --- a/scripts/docker_push.sh +++ b/scripts/docker_push.sh @@ -1,3 +1,3 @@ -#!/bin/bash +#!/usr/bin/env bash echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin docker push humanconnection/nitro-backend:latest From 9f78a96de2daa947fa2f2987d83c3ec7663bc6a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 14 Dec 2018 22:04:02 +0100 Subject: [PATCH 162/554] Run babel node instead of nodemon Quote of @appinteractive: ``` Currently we are running nodemon on production which watches for filechanges and consumes much more memory then just node. As nodemon is only for development, I added a build step to compile the application for production and then only run the dist folder with pure node. ``` --- .babelrc | 13 ++++++++++++- .travis.yml | 4 +++- Dockerfile | 1 + README.md | 8 ++++++++ dist/.gitkeep | 0 package.json | 30 ++++++++++++++++-------------- yarn.lock | 2 +- 7 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 dist/.gitkeep diff --git a/.babelrc b/.babelrc index b7191e76e..2d91b3635 100644 --- a/.babelrc +++ b/.babelrc @@ -1 +1,12 @@ -{ "presets": ["@babel/preset-env"] } +{ + "presets": [ + [ + "@babel/preset-env", + { + "targets": { + "node": "10" + } + } + ] + ] +} diff --git a/.travis.yml b/.travis.yml index b510062b9..1e832a04d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,9 @@ install: - docker-compose -f docker-compose.yml up -d script: - - docker-compose exec backend yarn run ci + - docker-compose exec backend yarn run lint + - docker-compose exec backend yarn run test + - docker-compose exec backend yarn run test:coverage - docker-compose exec backend yarn run db:reset - docker-compose exec backend yarn run db:seed diff --git a/Dockerfile b/Dockerfile index 269b74ea5..ad0ce1094 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,4 +16,5 @@ RUN yarn install --production=false --frozen-lockfile --non-interactive COPY . . COPY .env.template .env +RUN yarn run build CMD ["yarn", "run", "start"] diff --git a/README.md b/README.md index 252f2405b..1eb8cc528 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,14 @@ Configure the file `.env` according to your needs and your local setup. Start the GraphQL service: +```bash +yarn dev +# -or- +npm dev +``` + +And on the production machine run following: + ```bash yarn start # -or- diff --git a/dist/.gitkeep b/dist/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/package.json b/package.json index 422f3e975..f94b720ae 100644 --- a/package.json +++ b/package.json @@ -7,25 +7,22 @@ "no_auth": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 PERMISSIONS=disabled" }, "scripts": { - "ci": "yarn run lint && yarn run test && yarn run test:coverage", + "build": "babel src/ -d dist/ --copy-files", + "start": "node dist/", + "dev": "nodemon --exec babel-node src/index.js", + "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", + "mocha": "mocha --require @babel/register src/**/*.test.js", "lint": "eslint src --config .eslintrc.js", - "test": "./node_modules/.bin/nyc --reporter=text-lcov ./node_modules/.bin/mocha --require @babel/register src/**/*.test.js", - "test:coverage": "./node_modules/.bin/nyc report --reporter=text-lcov > coverage.lcov", - "start": "./node_modules/.bin/nodemon --exec babel-node src/index.js", - "start:debug": "./node_modules/.bin/nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "db:script:seed": "wait-on tcp:4001 && ./node_modules/.bin/babel-node src/seed/seed-db.js", - "db:script:reset": "wait-on tcp:4001 && ./node_modules/.bin/babel-node src/seed/reset-db.js", + "test": "nyc --reporter=text-lcov mocha --require @babel/register src/**/*.test.js", + "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", + "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", + "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", "db:seed": "$npm_package_config_no_auth run-p --race start db:script:seed", "db:reset": "$npm_package_config_no_auth run-p --race start db:script:reset" }, "author": "Human Connection gGmbH", "license": "MIT", "dependencies": { - "@babel/cli": "~7.2.0", - "@babel/core": "~7.2.0", - "@babel/node": "~7.2.0", - "@babel/preset-env": "~7.2.0", - "@babel/register": "~7.0.0", "apollo-cache-inmemory": "~1.3.11", "apollo-client": "~2.4.7", "apollo-link-http": "~1.5.7", @@ -52,10 +49,16 @@ "passport": "~0.4.0", "passport-jwt": "~4.0.0", "sanitize-html": "~1.19.3", + "faker": "~4.1.0", "slug": "~0.9.3", "trunc-html": "~1.1.2" }, "devDependencies": { + "@babel/cli": "~7.2.0", + "@babel/core": "~7.2.0", + "@babel/node": "~7.2.0", + "@babel/preset-env": "~7.2.0", + "@babel/register": "~7.0.0", "apollo-server-testing": "~2.2.6", "babel-eslint": "~10.0.1", "chai": "~4.2.0", @@ -65,8 +68,7 @@ "eslint-plugin-node": "~8.0.0", "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", - "faker": "~4.1.0", - "mocha": "^5.2.0", + "mocha": "~5.2.0", "nodemon": "~1.18.8", "npm-run-all": "~4.1.5", "nyc": "^13.1.0", diff --git a/yarn.lock b/yarn.lock index d67876365..bef258242 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4163,7 +4163,7 @@ mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: dependencies: minimist "0.0.8" -mocha@^5.2.0: +mocha@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== From bef8aa1d6ab8121b2c4bf78ef4d198350c309a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 14 Dec 2018 22:41:13 +0100 Subject: [PATCH 163/554] Reduce docker image size with multistage build We don't need development dependencies in production. I also added the BUILD_COMMIT environment variable to the image for convenience. --- .travis.yml | 2 +- Dockerfile | 13 +++++++++++-- docker-compose.override.yml | 3 +++ docker-compose.yml | 4 +++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1e832a04d..2de21f27b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ before_install: - sudo mv docker-compose /usr/local/bin install: - - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/nitro-backend:latest . + - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-backend:latest . - docker-compose -f docker-compose.yml up -d script: diff --git a/Dockerfile b/Dockerfile index ad0ce1094..d0080e3c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,11 @@ -FROM node:10-alpine +FROM node:10-alpine as builder LABEL Description="Backend of the Social Network Human-Connection.org" Vendor="Human Connection gGmbH" Version="0.0.1" Maintainer="Human Connection gGmbH (developer@human-connection.org)" # Expose the app port EXPOSE 4000 +ARG BUILD_COMMIT +ENV BUILD_COMMIT=$BUILD_COMMIT ARG WORKDIR=/nitro-backend RUN mkdir -p $WORKDIR WORKDIR $WORKDIR @@ -11,10 +13,17 @@ WORKDIR $WORKDIR # Install the Application Dependencies COPY package.json . COPY yarn.lock . -RUN yarn install --production=false --frozen-lockfile --non-interactive +RUN yarn install --frozen-lockfile --non-interactive COPY . . COPY .env.template .env RUN yarn run build CMD ["yarn", "run", "start"] + +# reduce image size with a multistage build +FROM node:10-alpine as production +ENV NODE_ENV=production +COPY --from=builder /nitro-backend/dist ./dist +COPY package.json yarn.lock ./ +RUN yarn install --frozen-lockfile --non-interactive diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 3be950735..2a5deb170 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -2,6 +2,9 @@ version: "3.7" services: backend: + build: + context: . + target: builder volumes: - .:/nitro-backend - /nitro-backend/node_modules diff --git a/docker-compose.yml b/docker-compose.yml index 0b070c98e..459496173 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,9 @@ version: "3.7" services: backend: image: humanconnection/nitro-backend:latest - build: . + build: + context: . + target: production networks: - hc-network depends_on: From 6d0f69eb7554f35d772ebeb3a8af06d71f5eb4ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 14 Dec 2018 21:44:40 +0000 Subject: [PATCH 164/554] Bump apollo-link-http from 1.5.7 to 1.5.8 Bumps [apollo-link-http](https://github.com/apollographql/apollo-link) from 1.5.7 to 1.5.8. - [Release notes](https://github.com/apollographql/apollo-link/releases) - [Changelog](https://github.com/apollographql/apollo-link/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-link/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 40 ++++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index f94b720ae..2031f6b6a 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "dependencies": { "apollo-cache-inmemory": "~1.3.11", "apollo-client": "~2.4.7", - "apollo-link-http": "~1.5.7", + "apollo-link-http": "~1.5.8", "apollo-server": "~2.2.6", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", diff --git a/yarn.lock b/yarn.lock index bef258242..29d83f280 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1006,28 +1006,28 @@ apollo-link-dedup@^1.0.0: dependencies: apollo-link "^1.2.4" -apollo-link-http-common@^0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.6.tgz#47b9012500599fe343e2e87378026384b4fc8c1f" - integrity sha512-LUOMWvrZuBP1hyWLBXyaW0KyFeKo79j+k3N+Q4HSkXKbLibnllXQ+JxxoSKGhm0bhREygiLtJAG9JnGlhxGO/Q== +apollo-link-http-common@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.7.tgz#cd8718f7db2178fb80600014fe9f14c4a8394985" + integrity sha512-rnn6BWDnd7DR8Xskpicw2dPV2bkXN4cD6VhikdWK982ovmLi7gP67ZXA+Hclox4aEUEhRLJnuprBwzSU3bRtEQ== dependencies: - apollo-link "^1.2.4" + apollo-link "^1.2.5" -apollo-link-http@~1.5.7: - version "1.5.7" - resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.7.tgz#098615c427a910ec8c5817476bbabe68c586b339" - integrity sha512-EZ9nynHjwYCpGYP5IsRrZGTWidUVpshk7MuSG4joqGtJMwpFCgMQz+y3BHdUhowHtfAd9z60XmeOTG9FJolb8A== +apollo-link-http@~1.5.8: + version "1.5.8" + resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.8.tgz#1be551338ca00db4082114221b409e0470fcc7e6" + integrity sha512-wkmj9fL5B4QYjw7q7w0GyetfqQKnA0QXGoh+/UK+LXJ+jLEz6JP2eLxrwgpX7o4ID6Og7l1JfeVxJE5fV1j2bg== dependencies: - apollo-link "^1.2.4" - apollo-link-http-common "^0.2.6" + apollo-link "^1.2.5" + apollo-link-http-common "^0.2.7" -apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.4.tgz#ab4d21d2e428db848e88b5e8f4adc717b19c954b" - integrity sha512-B1z+9H2nTyWEhMXRFSnoZ1vSuAYP+V/EdUJvRx9uZ8yuIBZMm6reyVtr1n0BWlKeSFyPieKJy2RLzmITAAQAMQ== +apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.5.tgz#f54932d6b8f1412a35e088bc199a116bce3f1f16" + integrity sha512-GJHEE4B06oEB58mpRRwW6ISyvgX2aCqCLjpcE3M/6/4e+ZVeX7fRGpMJJDq2zZ8n7qWdrEuY315JfxzpsJmUhA== dependencies: apollo-utilities "^1.0.0" - zen-observable-ts "^0.8.11" + zen-observable-ts "^0.8.12" apollo-server-caching@0.2.1: version "0.2.1" @@ -6287,10 +6287,10 @@ yargs@11.1.0: y18n "^3.2.1" yargs-parser "^9.0.2" -zen-observable-ts@^0.8.11: - version "0.8.11" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.11.tgz#d54a27cd17dc4b4bb6bd008e5c096af7fcb068a9" - integrity sha512-8bs7rgGV4kz5iTb9isudkuQjtWwPnQ8lXq6/T76vrepYZVMsDEv6BXaEA+DHdJSK3KVLduagi9jSpSAJ5NgKHw== +zen-observable-ts@^0.8.12: + version "0.8.12" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.12.tgz#38810d98645285c074775ab26b69992cc847c830" + integrity sha512-wwqbD6K6CqDd1T67UFg4hgDqnu2YAnFJDCPYmwN/N6Yfa+2QgoSp+nJomh+FWUdOc1A+553/ElvfoW8Vc/vsLg== dependencies: zen-observable "^0.8.0" From 4e816d902050421bd83064e05f4c62b0d4913a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 14 Dec 2018 23:10:48 +0100 Subject: [PATCH 165/554] Fix (?) the build with an image tag for builder Also I added a base stage so we can have a common working directory. --- Dockerfile | 22 ++++++++-------------- docker-compose.override.yml | 1 + 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/Dockerfile b/Dockerfile index d0080e3c4..ed6c274ce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,29 +1,23 @@ -FROM node:10-alpine as builder +FROM node:10-alpine as base LABEL Description="Backend of the Social Network Human-Connection.org" Vendor="Human Connection gGmbH" Version="0.0.1" Maintainer="Human Connection gGmbH (developer@human-connection.org)" -# Expose the app port EXPOSE 4000 - ARG BUILD_COMMIT ENV BUILD_COMMIT=$BUILD_COMMIT ARG WORKDIR=/nitro-backend RUN mkdir -p $WORKDIR WORKDIR $WORKDIR - -# Install the Application Dependencies -COPY package.json . -COPY yarn.lock . -RUN yarn install --frozen-lockfile --non-interactive - -COPY . . +COPY package.json yarn.lock ./ COPY .env.template .env - -RUN yarn run build CMD ["yarn", "run", "start"] +FROM base as builder +RUN yarn install --frozen-lockfile --non-interactive +COPY . . +RUN yarn run build + # reduce image size with a multistage build -FROM node:10-alpine as production +FROM base as production ENV NODE_ENV=production COPY --from=builder /nitro-backend/dist ./dist -COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile --non-interactive diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 2a5deb170..bed30c3eb 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -2,6 +2,7 @@ version: "3.7" services: backend: + image: humanconnection/nitro-backend:builder build: context: . target: builder From 94eea091de8c0fc4f97a4fbd51a1e939fe37285c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 14 Dec 2018 23:20:44 +0100 Subject: [PATCH 166/554] Ensure stage `builder` is used for testing But avoid synced volumes, otherwise the deployment will crash because Travis cannot clean up files just before entering the deployment. --- .travis.yml | 2 +- docker-compose.travis.yml | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 docker-compose.travis.yml diff --git a/.travis.yml b/.travis.yml index 2de21f27b..eaba8dba3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ before_install: install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-backend:latest . - - docker-compose -f docker-compose.yml up -d + - docker-compose -f docker-compose.yml -f docker-compose.travis.yml up -d script: - docker-compose exec backend yarn run lint diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml new file mode 100644 index 000000000..761a2aa64 --- /dev/null +++ b/docker-compose.travis.yml @@ -0,0 +1,8 @@ +version: "3.7" + +services: + backend: + image: humanconnection/nitro-backend:builder + build: + context: . + target: builder From 779190f711a28885cefc30d954e6b217e3e8dc4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 14 Dec 2018 23:41:11 +0100 Subject: [PATCH 167/554] Run `yarn run dev` in development --- docker-compose.override.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.override.yml b/docker-compose.override.yml index bed30c3eb..ef7d52c7e 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -9,6 +9,7 @@ services: volumes: - .:/nitro-backend - /nitro-backend/node_modules + command: yarn run dev neo4j: ports: - 7687:7687 From 3fc704467697ebf77cbf25647f571d160d0a813a Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sat, 15 Dec 2018 13:40:17 +0100 Subject: [PATCH 168/554] moved npm-run-all and wait-on from dev to prod dependencies as they are needed for seeding --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f94b720ae..be8b95743 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,9 @@ "sanitize-html": "~1.19.3", "faker": "~4.1.0", "slug": "~0.9.3", - "trunc-html": "~1.1.2" + "trunc-html": "~1.1.2", + "npm-run-all": "~4.1.5", + "wait-on": "~3.2.0" }, "devDependencies": { "@babel/cli": "~7.2.0", @@ -70,8 +72,6 @@ "eslint-plugin-standard": "~4.0.0", "mocha": "~5.2.0", "nodemon": "~1.18.8", - "npm-run-all": "~4.1.5", - "nyc": "^13.1.0", - "wait-on": "~3.2.0" + "nyc": "^13.1.0" } } From f992a136321d3237c892c7c086922baf97974aaa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Sun, 16 Dec 2018 17:17:38 +0000 Subject: [PATCH 169/554] Bump apollo-server from 2.2.6 to 2.3.1 Bumps [apollo-server](https://github.com/apollographql/apollo-server) from 2.2.6 to 2.3.1. - [Release notes](https://github.com/apollographql/apollo-server/releases) - [Changelog](https://github.com/apollographql/apollo-server/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-server/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 135 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 123 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index acff89389..223178bb2 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "apollo-cache-inmemory": "~1.3.11", "apollo-client": "~2.4.7", "apollo-link-http": "~1.5.8", - "apollo-server": "~2.2.6", + "apollo-server": "~2.3.1", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", "cross-env": "~5.2.0", diff --git a/yarn.lock b/yarn.lock index 29d83f280..65f0f0909 100644 --- a/yarn.lock +++ b/yarn.lock @@ -927,6 +927,14 @@ apollo-cache-control@0.3.3: apollo-server-env "2.2.0" graphql-extensions "0.3.3" +apollo-cache-control@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.4.0.tgz#fec343e6ec95aa4f1b88e07e62f067bee0c48397" + integrity sha512-WuriaNQIugTE8gYwfBWWCbbQTSKul/cV4JMi5UgqNIUvjHvnKZQLKbt5uYWow6QQNMkLT9hey8QPYkWpogkeSA== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.4.0" + apollo-cache-control@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz#173d14ceb3eb9e7cb53de7eb8b61bee6159d4171" @@ -980,6 +988,13 @@ apollo-engine-reporting-protobuf@0.1.0: dependencies: protobufjs "^6.8.6" +apollo-engine-reporting-protobuf@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.2.0.tgz#2aaf4d2eddefe7924d469cf1135267bc0deadf73" + integrity sha512-qI+GJKN78UMJ9Aq/ORdiM2qymZ5yswem+/VDdVFocq+/e1QqxjnpKjQWISkswci5+WtpJl9SpHBNxG98uHDKkA== + dependencies: + protobufjs "^6.8.6" + apollo-engine-reporting@0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.3.tgz#85ad6ffd71db8f877202ce8b3d7dbfa7cabfbcf9" @@ -991,6 +1006,17 @@ apollo-engine-reporting@0.1.3: graphql-extensions "0.3.3" lodash "^4.17.10" +apollo-engine-reporting@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.2.0.tgz#e71816b1f46e782f8538c5a118148d4c0e628e25" + integrity sha512-Q6FfVb10v/nrv8FaFsPjIYlWh62jaYav3LuMgM9PsHWGK/zRQFXOEwLxcY2UCvG7O1moxF3XGmfBhMgo54py+Q== + dependencies: + apollo-engine-reporting-protobuf "0.2.0" + apollo-server-env "2.2.0" + async-retry "^1.2.1" + graphql-extensions "0.4.0" + lodash "^4.17.10" + apollo-env@0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.2.5.tgz#162c785bccd2aea69350a7600fab4b7147fc9da5" @@ -1062,6 +1088,32 @@ apollo-server-core@2.2.6: subscriptions-transport-ws "^0.9.11" ws "^6.0.0" +apollo-server-core@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.3.1.tgz#cbdc0020a0dfecf2220cf5062dbb304fdf56edf2" + integrity sha512-8jMWYOQIZi9mDJlHe2rXg8Cp4xKYogeRu23jkcNy+k5UjZL+eO+kHXbNFiTaP4HLYYEpe2XE3asxp6q5YUEQeQ== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" + "@apollographql/graphql-playground-html" "^1.6.6" + "@types/ws" "^6.0.0" + apollo-cache-control "0.4.0" + apollo-datasource "0.2.1" + apollo-engine-reporting "0.2.0" + apollo-server-caching "0.2.1" + apollo-server-env "2.2.0" + apollo-server-errors "2.2.0" + apollo-server-plugin-base "0.2.1" + apollo-tracing "0.4.0" + graphql-extensions "0.4.1" + graphql-subscriptions "^1.0.0" + graphql-tag "^2.9.2" + graphql-tools "^4.0.0" + graphql-upload "^8.0.2" + json-stable-stringify "^1.0.1" + lodash "^4.17.10" + subscriptions-transport-ws "^0.9.11" + ws "^6.0.0" + apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592" @@ -1084,19 +1136,18 @@ apollo-server-errors@2.2.0: resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== -apollo-server-express@2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.2.6.tgz#2c0c5bdab6eccf63ab138ad4b6d6836aeb723540" - integrity sha512-+zajJDcJLhWdkW8f0D5KQfDsaxgx7fQ3ULGDT1eZgL0UY5pazWBOnXqeRoVKRl+r1WcrwN1SMfBVnAKWv6CyVw== +apollo-server-express@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.3.1.tgz#0598e2fa0a0d9e6eb570c0bb6ce65c31810a9c09" + integrity sha512-J+rObr4GdT/5j6qTByUJoSvZSjTAX/7VqIkr2t+GxwcVUFGet2MdOHuV6rtWKc8CRgvVKfKN6iBrb2EOFcp2LQ== dependencies: - "@apollographql/apollo-upload-server" "^5.0.3" "@apollographql/graphql-playground-html" "^1.6.6" "@types/accepts" "^1.3.5" "@types/body-parser" "1.17.0" "@types/cors" "^2.8.4" "@types/express" "4.16.0" accepts "^1.3.5" - apollo-server-core "2.2.6" + apollo-server-core "2.3.1" body-parser "^1.18.3" cors "^2.8.4" graphql-subscriptions "^1.0.0" @@ -1129,6 +1180,11 @@ apollo-server-plugin-base@0.1.6: resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.6.tgz#56932c0e3a0366e03952a6e2805efe5fa2e046bf" integrity sha512-nh6I2+mgSL5cYxqYXymAr8xBZ/ju8nunPjHp/21+/mgbF4Is0xtM9oDq5Qf0Q/cGh/djF6YcBuB1yUG+68gJXw== +apollo-server-plugin-base@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.2.1.tgz#d08c9576f7f11ab6e212f352d482faaa4059a31e" + integrity sha512-497NIY9VWRYCrMSkgR11IrIUO4Fsy6aGgnpOJoTdLQAnkDD9SJDSRzwKj4gypUoTT2unfKDng4eMxXVZlHvjOw== + apollo-server-testing@~2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.2.6.tgz#3ec60b6f099c2c55bd313cdbb8c177d8c86cda6d" @@ -1136,13 +1192,13 @@ apollo-server-testing@~2.2.6: dependencies: apollo-server-core "2.2.6" -apollo-server@~2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.2.6.tgz#7af396692ff06a6feb3429a7287bac5ee18b58eb" - integrity sha512-3fy9sm+w2hUVQNyy2gCVIFOD0DJD2IWpXTzHjpi2uned3JIE0mI4pP2JSBiBTjXVwgu4/2ql+f29Ex3VT8cHIg== +apollo-server@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.3.1.tgz#4d2b6bbb48b44d86076680304705b8b7ae952d37" + integrity sha512-+S+/BhLJF9Ms99OK9HpC4P6rcVWTobWWKeLSVdgxqG487i/kwMrCAw/ICrDVJGeOGJRi6PndVu9XdHWHuX1lvQ== dependencies: - apollo-server-core "2.2.6" - apollo-server-express "2.2.6" + apollo-server-core "2.3.1" + apollo-server-express "2.3.1" express "^4.0.0" graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" @@ -1155,6 +1211,14 @@ apollo-tracing@0.3.3: apollo-server-env "2.2.0" graphql-extensions "0.3.3" +apollo-tracing@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.4.0.tgz#4b939063f4292422ac5a3564b76d1d88dec0a916" + integrity sha512-BlM8iQUQva4fm0xD/pLwkcz0degfB9a/aAn4k4cK36eLVD8XUkl7ptEB0c+cwcj7tOYpV1r5QX1XwdayBzlHSg== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.4.0" + apollo-tracing@^0.1.0: version "0.1.4" resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" @@ -2733,6 +2797,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +fs-capacitor@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fs-capacitor/-/fs-capacitor-1.0.1.tgz#ff9dbfa14dfaf4472537720f19c3088ed9278df0" + integrity sha512-XdZK0Q78WP29Vm3FGgJRhRhrBm51PagovzWtW2kJ3Q6cYJbGtZqWSGTSPwvtEkyjIirFd7b8Yes/dpOYjt4RRQ== + fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" @@ -2915,6 +2984,20 @@ graphql-extensions@0.3.6: dependencies: "@apollographql/apollo-tools" "^0.2.6" +graphql-extensions@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.4.0.tgz#5857c7b7b9f20dbccbfd88730fffa5963b3c61ee" + integrity sha512-8TUgIIUVpXWOcqq9RdmTSHUrhc3a/s+saKv9cCl8TYWHK9vyJIdea7ZaSKHGDthZNcsN+C3LulZYRL3Ah8ukoA== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" + +graphql-extensions@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.4.1.tgz#92c49a8409ffbfb24559d7661ab60cc90d6086e4" + integrity sha512-Xei4rBxbsTHU6dYiq9y1xxbpRMU3+Os7yD3vXV5W4HbTaxRMizDmu6LAvV4oBEi0ttwICHARQjYTjDTDhHnxrQ== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" + graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: version "0.0.10" resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" @@ -3016,6 +3099,16 @@ graphql-tools@^4.0.0, graphql-tools@^4.0.1, graphql-tools@^4.0.2: iterall "^1.1.3" uuid "^3.1.0" +graphql-upload@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/graphql-upload/-/graphql-upload-8.0.2.tgz#1c1f116f15b7f8485cf40ff593a21368f0f58856" + integrity sha512-u8a5tKPfJ0rU4MY+B3skabL8pEjMkm3tUzq25KBx6nT0yEWmqUO7Z5tdwvwYLFpkLwew94Gue0ARbZtar3gLTw== + dependencies: + busboy "^0.2.14" + fs-capacitor "^1.0.0" + http-errors "^1.7.1" + object-path "^0.11.4" + graphql-yoga@~1.16.7: version "1.16.7" resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.16.7.tgz#05bdfadf9a4623b0409bee3c5b75b7b3f7249e6f" @@ -3205,6 +3298,17 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +http-errors@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.1.tgz#6a4ffe5d35188e1c39f872534690585852e1f027" + integrity sha512-jWEUgtZWGSMba9I1N3gc1HmvpBUaNC9vDdA46yScAdp+C5rdEuKWUBLWTQpW9FwSWSbYYs++b6SDCxf9UEJzfw== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -5635,7 +5739,7 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.4.0 < 2": +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= @@ -5863,6 +5967,11 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + topo@3.x.x: version "3.0.3" resolved "https://registry.yarnpkg.com/topo/-/topo-3.0.3.tgz#d5a67fb2e69307ebeeb08402ec2a2a6f5f7ad95c" From cdda79fd2e348b9fc8b6310ec041bbb99d031d5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 17 Dec 2018 04:39:16 +0000 Subject: [PATCH 170/554] Bump nodemon from 1.18.8 to 1.18.9 Bumps [nodemon](https://github.com/remy/nodemon) from 1.18.8 to 1.18.9. - [Release notes](https://github.com/remy/nodemon/releases) - [Commits](https://github.com/remy/nodemon/compare/v1.18.8...v1.18.9) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 223178bb2..99235eae7 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", "mocha": "~5.2.0", - "nodemon": "~1.18.8", + "nodemon": "~1.18.9", "nyc": "^13.1.0" } } diff --git a/yarn.lock b/yarn.lock index 65f0f0909..d8d225f18 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4414,16 +4414,16 @@ node-releases@^1.0.5: dependencies: semver "^5.3.0" -nodemon@~1.18.8: - version "1.18.8" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.8.tgz#eb4c0052dc81395bdc503f3c8ae3cba86ca7146a" - integrity sha512-CgC/JdCf+CT7Z+K6wWaV30t8GU1DPtXpr/6PuXC1/LboXCmUQNKOaz0AEMjoWDTt2AdHOBFxgv41dyC0i79SbA== +nodemon@~1.18.9: + version "1.18.9" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.9.tgz#90b467efd3b3c81b9453380aeb2a2cba535d0ead" + integrity sha512-oj/eEVTEI47pzYAjGkpcNw0xYwTl4XSTUQv2NPQI6PpN3b75PhpuYk3Vb3U80xHCyM2Jm+1j68ULHXl4OR3Afw== dependencies: chokidar "^2.0.4" debug "^3.1.0" ignore-by-default "^1.0.1" minimatch "^3.0.4" - pstree.remy "^1.1.3" + pstree.remy "^1.1.6" semver "^5.5.0" supports-color "^5.2.0" touch "^3.1.0" @@ -5051,10 +5051,10 @@ psl@^1.1.24: resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== -pstree.remy@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.4.tgz#a03d5dbc06ba639fb6dd4874644c4bad9882ec21" - integrity sha512-3kSyTN/iTJMxtL87idnFgTyOp2vQ6B/49QcHUO26kh2M2qahlUivFI1zWJ9FRFPoB+KgcP820JMOuIhkBJAP3Q== +pstree.remy@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.6.tgz#73a55aad9e2d95814927131fbf4dc1b62d259f47" + integrity sha512-NdF35+QsqD7EgNEI5mkI/X+UwaxVEbQaz9f4IooEmMUv6ZPmlTQYGjBPJGgrlzNdjSvIy4MWMg6Q6vCgBO2K+w== punycode@1.3.2: version "1.3.2" From b8a89c9fac11428f719fe6cc9f89c891c7bd78f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 17 Dec 2018 04:41:28 +0000 Subject: [PATCH 171/554] Bump apollo-link-http from 1.5.8 to 1.5.9 Bumps [apollo-link-http](https://github.com/apollographql/apollo-link) from 1.5.8 to 1.5.9. - [Release notes](https://github.com/apollographql/apollo-link/releases) - [Changelog](https://github.com/apollographql/apollo-link/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-link/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 40 ++++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 223178bb2..e9aa8ff55 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "dependencies": { "apollo-cache-inmemory": "~1.3.11", "apollo-client": "~2.4.7", - "apollo-link-http": "~1.5.8", + "apollo-link-http": "~1.5.9", "apollo-server": "~2.3.1", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", diff --git a/yarn.lock b/yarn.lock index 65f0f0909..5eef61131 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1032,28 +1032,28 @@ apollo-link-dedup@^1.0.0: dependencies: apollo-link "^1.2.4" -apollo-link-http-common@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.7.tgz#cd8718f7db2178fb80600014fe9f14c4a8394985" - integrity sha512-rnn6BWDnd7DR8Xskpicw2dPV2bkXN4cD6VhikdWK982ovmLi7gP67ZXA+Hclox4aEUEhRLJnuprBwzSU3bRtEQ== +apollo-link-http-common@^0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.8.tgz#c6deedfc2739db8b11013c3c2d2ccd657152941f" + integrity sha512-gGmXZN8mr7e9zjopzKQfZ7IKnh8H12NxBDzvp9nXI3U82aCVb72p+plgoYLcpMY8w6krvoYjgicFmf8LO20TCQ== dependencies: - apollo-link "^1.2.5" + apollo-link "^1.2.6" -apollo-link-http@~1.5.8: - version "1.5.8" - resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.8.tgz#1be551338ca00db4082114221b409e0470fcc7e6" - integrity sha512-wkmj9fL5B4QYjw7q7w0GyetfqQKnA0QXGoh+/UK+LXJ+jLEz6JP2eLxrwgpX7o4ID6Og7l1JfeVxJE5fV1j2bg== +apollo-link-http@~1.5.9: + version "1.5.9" + resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.9.tgz#9046f5640a94c8a8b508a39e0f2c628b781baecc" + integrity sha512-9tJy2zGm4Cm/1ycScDNZJe51dgnTSfKx7pKIgPZmcxkdDpgUY2DZitDH6ZBv4yp9z8MC9Xr9wgwc29s6hcadUQ== dependencies: - apollo-link "^1.2.5" - apollo-link-http-common "^0.2.7" + apollo-link "^1.2.6" + apollo-link-http-common "^0.2.8" -apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.5.tgz#f54932d6b8f1412a35e088bc199a116bce3f1f16" - integrity sha512-GJHEE4B06oEB58mpRRwW6ISyvgX2aCqCLjpcE3M/6/4e+ZVeX7fRGpMJJDq2zZ8n7qWdrEuY315JfxzpsJmUhA== +apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.6.tgz#d9b5676d79c01eb4e424b95c7171697f6ad2b8da" + integrity sha512-sUNlA20nqIF3gG3F8eyMD+mO80fmf3dPZX+GUOs3MI9oZR8ug09H3F0UsWJMcpEg6h55Yy5wZ+BMmAjrbenF/Q== dependencies: apollo-utilities "^1.0.0" - zen-observable-ts "^0.8.12" + zen-observable-ts "^0.8.13" apollo-server-caching@0.2.1: version "0.2.1" @@ -6396,10 +6396,10 @@ yargs@11.1.0: y18n "^3.2.1" yargs-parser "^9.0.2" -zen-observable-ts@^0.8.12: - version "0.8.12" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.12.tgz#38810d98645285c074775ab26b69992cc847c830" - integrity sha512-wwqbD6K6CqDd1T67UFg4hgDqnu2YAnFJDCPYmwN/N6Yfa+2QgoSp+nJomh+FWUdOc1A+553/ElvfoW8Vc/vsLg== +zen-observable-ts@^0.8.13: + version "0.8.13" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.13.tgz#ae1fd77c84ef95510188b1f8bca579d7a5448fc2" + integrity sha512-WDb8SM0tHCb6c0l1k60qXWlm1ok3zN9U4VkLdnBKQwIYwUoB9psH7LIFgR+JVCCMmBxUgOjskIid8/N02k/2Bg== dependencies: zen-observable "^0.8.0" From acd1197ca16dc3d389a75d93e6ef0c40116c539b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 18 Dec 2018 04:20:24 +0000 Subject: [PATCH 172/554] Bump sanitize-html from 1.19.3 to 1.20.0 Bumps [sanitize-html](https://github.com/punkave/sanitize-html) from 1.19.3 to 1.20.0. - [Release notes](https://github.com/punkave/sanitize-html/releases) - [Changelog](https://github.com/punkave/sanitize-html/blob/master/CHANGELOG.md) - [Commits](https://github.com/punkave/sanitize-html/compare/1.19.3...1.20.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 15e8a6524..3dcf5db74 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "node-fetch": "~2.3.0", "passport": "~0.4.0", "passport-jwt": "~4.0.0", - "sanitize-html": "~1.19.3", + "sanitize-html": "~1.20.0", "faker": "~4.1.0", "slug": "~0.9.3", "trunc-html": "~1.1.2", diff --git a/yarn.lock b/yarn.lock index 58f2b88fe..f9d341118 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5436,10 +5436,10 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sanitize-html@~1.19.3: - version "1.19.3" - resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.3.tgz#6a6562ec4a90e6b9139ca3c845a3c83512288519" - integrity sha512-QpIjbF1rhUSQj9V7Wey/gv4DPqOso8KTebaI4rC97p0WCLnTpmhf7BJZUhS83MTtqRvUo8MuXH316CW2Nzd48w== +sanitize-html@~1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.20.0.tgz#9a602beb1c9faf960fb31f9890f61911cc4d9156" + integrity sha512-BpxXkBoAG+uKCHjoXFmox6kCSYpnulABoGcZ/R3QyY9ndXbIM5S94eOr1IqnzTG8TnbmXaxWoDDzKC5eJv7fEQ== dependencies: chalk "^2.4.1" htmlparser2 "^3.10.0" From 9eef9bc81ceb29ac1fca3fcbe960b6d2fa9ff74d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 19 Dec 2018 10:06:00 +0100 Subject: [PATCH 173/554] Fix 'audience must be a string or array' I ran into this issue after setting up the installation locally. --- .env.template | 1 + 1 file changed, 1 insertion(+) diff --git a/.env.template b/.env.template index 59ae471c9..3ec0cbce9 100644 --- a/.env.template +++ b/.env.template @@ -3,6 +3,7 @@ NEO4J_USER=neo4j NEO4J_PASSWORD=letmein GRAPHQL_PORT=4000 GRAPHQL_URI=http://localhost:4000 +CLIENT_URI=http://localhost:3000 MOCK=false JWT_SECRET=b/&&7b78BF&fv/Vd From eaef67fad3c99e0c2c26dc1ee5244fc825dbc4ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 20 Dec 2018 17:55:03 +0100 Subject: [PATCH 174/554] Replace mocha with jest To have a consisten test runner in both repos (Nitro-Web and Nitro-Backend) --- package.json | 14 +- src/middleware/permissionsMiddleware.test.js | 6 +- yarn.lock | 1578 ++++++++++++++++-- 3 files changed, 1478 insertions(+), 120 deletions(-) diff --git a/package.json b/package.json index 3dcf5db74..f536720c8 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,9 @@ "start": "node dist/", "dev": "nodemon --exec babel-node src/index.js", "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "mocha": "mocha --require @babel/register src/**/*.test.js", + "jest": "jest", "lint": "eslint src --config .eslintrc.js", - "test": "nyc --reporter=text-lcov mocha --require @babel/register src/**/*.test.js", + "test": "nyc --reporter=text-lcov jest", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", @@ -32,6 +32,7 @@ "cross-env": "~5.2.0", "date-fns": "^2.0.0-alpha.26", "dotenv": "~6.2.0", + "faker": "~4.1.0", "graphql": "~0.13.0", "graphql-custom-directives": "~0.2.14", "graphql-iso-date": "~3.6.1", @@ -46,23 +47,24 @@ "neo4j-driver": "~1.7.2", "neo4j-graphql-js": "~2.0.1", "node-fetch": "~2.3.0", + "npm-run-all": "~4.1.5", "passport": "~0.4.0", "passport-jwt": "~4.0.0", "sanitize-html": "~1.20.0", - "faker": "~4.1.0", "slug": "~0.9.3", "trunc-html": "~1.1.2", - "npm-run-all": "~4.1.5", "wait-on": "~3.2.0" }, "devDependencies": { "@babel/cli": "~7.2.0", - "@babel/core": "~7.2.0", + "@babel/core": "^7.2.2", "@babel/node": "~7.2.0", "@babel/preset-env": "~7.2.0", "@babel/register": "~7.0.0", "apollo-server-testing": "~2.2.6", + "babel-core": "^7.0.0-0", "babel-eslint": "~10.0.1", + "babel-jest": "^23.6.0", "chai": "~4.2.0", "eslint": "~5.10.0", "eslint-config-standard": "~12.0.0", @@ -70,7 +72,7 @@ "eslint-plugin-node": "~8.0.0", "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", - "mocha": "~5.2.0", + "jest": "^23.6.0", "nodemon": "~1.18.9", "nyc": "^13.1.0" } diff --git a/src/middleware/permissionsMiddleware.test.js b/src/middleware/permissionsMiddleware.test.js index d48b35440..3cf808e39 100644 --- a/src/middleware/permissionsMiddleware.test.js +++ b/src/middleware/permissionsMiddleware.test.js @@ -1,16 +1,14 @@ -import { describe, it } from 'mocha' - describe('query', () => { describe('statistics', () => { describe('authenticated user', () => { describe('read', () => { - it('is forbidden') + xit('is forbidden', () => {}) }) }) describe('admin', () => { describe('read', () => { - it('is permitted') + xit('is permitted', () => {}) }) }) }) diff --git a/yarn.lock b/yarn.lock index f9d341118..95f261fdf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -40,25 +40,25 @@ optionalDependencies: chokidar "^2.0.3" -"@babel/code-frame@^7.0.0": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@~7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.0.tgz#a4dd3814901998e93340f0086e9867fefa163ada" - integrity sha512-7pvAdC4B+iKjFFp9Ztj0QgBndJ++qaMeonT185wAqUnhipw8idm9Rv1UMyBuKtYjfl6ORNkgEgcsYLfHX/GpLw== +"@babel/core@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687" + integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.2.0" + "@babel/generator" "^7.2.2" "@babel/helpers" "^7.2.0" - "@babel/parser" "^7.2.0" - "@babel/template" "^7.1.2" - "@babel/traverse" "^7.1.6" - "@babel/types" "^7.2.0" + "@babel/parser" "^7.2.2" + "@babel/template" "^7.2.2" + "@babel/traverse" "^7.2.2" + "@babel/types" "^7.2.2" convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -67,7 +67,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.1.6", "@babel/generator@^7.2.0": +"@babel/generator@^7.0.0", "@babel/generator@^7.1.6": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.0.tgz#eaf3821fa0301d9d4aef88e63d4bcc19b73ba16c" integrity sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg== @@ -78,6 +78,17 @@ source-map "^0.5.0" trim-right "^1.0.1" +"@babel/generator@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.2.tgz#18c816c70962640eab42fe8cae5f3947a5c65ccc" + integrity sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg== + dependencies: + "@babel/types" "^7.2.2" + jsesc "^2.5.1" + lodash "^4.17.10" + source-map "^0.5.0" + trim-right "^1.0.1" + "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" @@ -262,11 +273,16 @@ lodash "^4.17.10" v8flags "^3.1.1" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.6", "@babel/parser@^7.2.0": +"@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.6": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.2.0.tgz#02d01dbc330b6cbf36b76ac93c50752c69027065" integrity sha512-M74+GvK4hn1eejD9lZ7967qAwvqTZayQa3g10ag4s9uewgR7TKjeaT0YMyoq+gVfKYABiWZ4MQD701/t5e1Jhg== +"@babel/parser@^7.2.2", "@babel/parser@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.2.3.tgz#32f5df65744b70888d17872ec106b02434ba1489" + integrity sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA== + "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" @@ -644,7 +660,16 @@ "@babel/parser" "^7.1.2" "@babel/types" "^7.1.2" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.1.6": +"@babel/template@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" + integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.2.2" + "@babel/types" "^7.2.2" + +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5": version "7.1.6" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.6.tgz#c8db9963ab4ce5b894222435482bd8ea854b7b5c" integrity sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ== @@ -659,6 +684,21 @@ globals "^11.1.0" lodash "^4.17.10" +"@babel/traverse@^7.2.2": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8" + integrity sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.2.2" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/parser" "^7.2.3" + "@babel/types" "^7.2.2" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.10" + "@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.6", "@babel/types@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.0.tgz#7941c5b2d8060e06f9601d6be7c223eef906d5d8" @@ -668,6 +708,15 @@ lodash "^4.17.10" to-fast-properties "^2.0.0" +"@babel/types@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.2.tgz#44e10fc24e33af524488b716cdaee5360ea8ed1e" + integrity sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg== + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" + to-fast-properties "^2.0.0" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -834,6 +883,11 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" integrity sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg== +abab@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" + integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w== + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -847,12 +901,30 @@ accepts@^1.3.5, accepts@~1.3.5: mime-types "~2.1.18" negotiator "0.6.1" +acorn-globals@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.0.tgz#e3b6f8da3c1552a95ae627571f7dd6923bb54103" + integrity sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw== + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + acorn-jsx@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== -acorn@^6.0.2: +acorn-walk@^6.0.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913" + integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw== + +acorn@^5.5.3: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + +acorn@^6.0.1, acorn@^6.0.2: version "6.0.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== @@ -1242,6 +1314,13 @@ apollo-utilities@1.0.26, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apoll dependencies: fast-json-stable-stringify "^2.0.0" +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + integrity sha1-126/jKlNJ24keja61EpLdKthGZE= + dependencies: + default-require-extensions "^1.0.0" + append-transform@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" @@ -1274,12 +1353,19 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= -arr-flatten@^1.1.0: +arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== @@ -1289,6 +1375,11 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" @@ -1314,6 +1405,11 @@ array-uniq@^1.0.2: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" @@ -1378,7 +1474,7 @@ async-retry@^1.2.1: dependencies: retry "0.12.0" -async@^2.5.0: +async@^2.1.4, async@^2.5.0: version "2.6.1" resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== @@ -1429,6 +1525,45 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.0.0, babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-core@^7.0.0-0: + version "7.0.0-bridge.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" + integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== + babel-eslint@~10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed" @@ -1441,6 +1576,63 @@ babel-eslint@~10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" +babel-generator@^6.18.0, babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-jest@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.6.0.tgz#a644232366557a2240a0c083da6b25786185a2f1" + integrity sha512-lqKGG6LYXYu+DQh/slrQ8nxXQkEkhugdXsU6St7GmhVS7Ilc/22ArwqXNJrf0QaOBjZB0360qZMwXqDYQHXaew== + dependencies: + babel-plugin-istanbul "^4.1.6" + babel-preset-jest "^23.2.0" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-istanbul@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" + integrity sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ== + dependencies: + babel-plugin-syntax-object-rest-spread "^6.13.0" + find-up "^2.1.0" + istanbul-lib-instrument "^1.10.1" + test-exclude "^4.2.1" + +babel-plugin-jest-hoist@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167" + integrity sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc= + +babel-plugin-syntax-object-rest-spread@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= + babel-polyfill@6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" @@ -1450,6 +1642,27 @@ babel-polyfill@6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" +babel-preset-jest@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46" + integrity sha1-jsegOhOPABoaj7HoETZSvxpV2kY= + dependencies: + babel-plugin-jest-hoist "^23.2.0" + babel-plugin-syntax-object-rest-spread "^6.13.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" @@ -1458,6 +1671,47 @@ babel-runtime@^6.22.0, babel-runtime@^6.26.0: core-js "^2.4.0" regenerator-runtime "^0.11.0" +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.0.0, babel-traverse@^6.18.0, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + backo2@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" @@ -1552,6 +1806,15 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + braces@^2.3.0, braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -1568,10 +1831,17 @@ braces@^2.3.0, braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== +browser-process-hrtime@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" + integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== + +browser-resolve@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== + dependencies: + resolve "1.1.7" browserslist@^4.3.4: version "4.3.5" @@ -1582,6 +1852,13 @@ browserslist@^4.3.4: electron-to-chromium "^1.3.86" node-releases "^1.0.5" +bser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" + integrity sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk= + dependencies: + node-int64 "^0.4.0" + buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" @@ -1656,6 +1933,11 @@ callsites@^0.2.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -1666,6 +1948,13 @@ caniuse-lite@^1.0.30000912: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000916.tgz#3428d3f529f0a7b2bfaaec65e796037bdd433aab" integrity sha512-D6J9jloPm2MPkg0PXcODLMQAJKkeixKO9xhqTUMvtd44MtTYMyyDXPQ2Lk9IgBq5FH0frwiPa/N/w8ncQf7kIQ== +capture-exit@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" + integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28= + dependencies: + rsvp "^3.3.3" + capture-stack-trace@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" @@ -1687,7 +1976,7 @@ chai@~4.2.0: pathval "^1.1.0" type-detect "^4.0.5" -chalk@1.1.3, chalk@^1.0.0: +chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -1805,6 +2094,11 @@ cliui@^4.0.0: strip-ansi "^4.0.0" wrap-ansi "^2.0.0" +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -1837,11 +2131,6 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@2.15.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== - commander@^2.5.0, commander@^2.8.1: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" @@ -1899,7 +2188,7 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.1.0, convert-source-map@^1.6.0: +convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1, convert-source-map@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== @@ -1926,6 +2215,11 @@ core-js@^2.4.0: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.0.tgz#1e30793e9ee5782b307e37ffa22da0eacddd84d4" integrity sha512-kLRC6ncVpuEW/1kwrOXYX6KQASCVtrh1gQr/UiaVgFlf9WE5Vp+lNe5+h3LuMr5PAucWnnEXwH0nQHRH/gpGtw== +core-js@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042" + integrity sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg== + core-js@^2.5.3, core-js@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -2019,6 +2313,18 @@ css-what@2.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ== +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797" + integrity sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog== + +cssstyle@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.1.1.tgz#18b038a9c44d65f7a8e428a653b9f6fe42faf5fb" + integrity sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog== + dependencies: + cssom "0.3.x" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -2026,6 +2332,15 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +data-urls@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + date-fns@^2.0.0-alpha.26: version "2.0.0-alpha.26" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.26.tgz#e46afd73a2b50e0359446309ee7cb631d7467227" @@ -2043,13 +2358,6 @@ debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6. dependencies: ms "2.0.0" -debug@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -2091,6 +2399,13 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + integrity sha1-836hXT4T/9m0N9M+GnW1+5eHTLg= + dependencies: + strip-bom "^2.0.0" + default-require-extensions@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" @@ -2152,11 +2467,23 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= + dicer@0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" @@ -2165,7 +2492,7 @@ dicer@0.2.5: readable-stream "1.1.x" streamsearch "0.1.2" -diff@3.5.0: +diff@^3.2.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== @@ -2203,6 +2530,13 @@ domelementtype@~1.1.1: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs= +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + domhandler@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" @@ -2327,11 +2661,23 @@ escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escodegen@^1.9.1: + version "1.11.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589" + integrity sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw== + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + eslint-config-standard@~12.0.0: version "12.0.0" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9" @@ -2477,6 +2823,11 @@ espree@^5.0.0: acorn-jsx "^5.0.0" eslint-visitor-keys "^1.0.0" +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -2496,7 +2847,7 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= @@ -2521,6 +2872,13 @@ events@1.1.1: resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= +exec-sh@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" + integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== + dependencies: + merge "^1.2.0" + execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -2534,6 +2892,18 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -2547,6 +2917,25 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +expect@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98" + integrity sha512-dgSoOHgmtn/aDGRVFWclQyPDKl2CQRq0hmIEoUAuQs/2rn2NcvCWcSCovm6BLeuB/7EZuLGu2QfnR+qRt5OM4w== + dependencies: + ansi-styles "^3.2.0" + jest-diff "^23.6.0" + jest-get-type "^22.1.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + express@^4.0.0, express@^4.16.3: version "4.16.4" resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" @@ -2621,6 +3010,13 @@ external-editor@^3.0.0: iconv-lite "^0.4.24" tmp "^0.0.33" +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -2665,6 +3061,13 @@ fast-levenshtein@~2.0.4: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fb-watchman@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" + integrity sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg= + dependencies: + bser "^2.0.0" + figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -2680,6 +3083,30 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fileset@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA= + dependencies: + glob "^7.0.3" + minimatch "^3.0.3" + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -2753,11 +3180,18 @@ flat-cache@^1.2.1: rimraf "~2.6.2" write "^0.2.1" -for-in@^1.0.2: +for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + foreground-child@^1.5.6: version "1.5.6" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" @@ -2819,7 +3253,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.2: +fsevents@^1.2.2, fsevents@^1.2.3: version "1.2.4" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== @@ -2878,6 +3312,21 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -2886,19 +3335,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.0.5, glob@^7.1.2, glob@^7.1.3: +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== @@ -2922,6 +3359,11 @@ globals@^11.1.0, globals@^11.7.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" @@ -3150,12 +3592,12 @@ graphql@~0.13.0: dependencies: iterall "^1.2.1" -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= -handlebars@^4.0.11: +handlebars@^4.0.11, handlebars@^4.0.3: version "4.0.12" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== @@ -3186,6 +3628,11 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3244,11 +3691,6 @@ he@0.5.0: resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" integrity sha1-LAX/rvkLaOhg8/0rVO9YCYknfuI= -he@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" - integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= - hoek@5.x.x: version "5.0.4" resolved "https://registry.yarnpkg.com/hoek/-/hoek-5.0.4.tgz#0f7fa270a1cafeb364a4b2ddfaa33f864e4157da" @@ -3259,6 +3701,14 @@ hoek@6.x.x: resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.1.2.tgz#99e6d070561839de74ee427b61aa476bd6bddfd6" integrity sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q== +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + home-or-tmp@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-3.0.0.tgz#57a8fe24cf33cdd524860a15821ddc25c86671fb" @@ -3276,6 +3726,13 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + htmlparser2@^3.10.0, htmlparser2@^3.9.1: version "3.10.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" @@ -3325,7 +3782,7 @@ iconv-lite@0.4.23: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -3374,6 +3831,14 @@ import-lazy@^2.1.0: resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + integrity sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ== + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -3443,7 +3908,7 @@ insane@2.6.1: assignment "2.0.0" he "0.5.0" -invariant@^2.2.2: +invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -3547,6 +4012,18 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -3559,11 +4036,23 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -3576,6 +4065,18 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + integrity sha1-lp1J4bszKfa7fwkIm+JleLLd1Go= + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -3603,6 +4104,13 @@ is-npm@^1.0.0: resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -3610,6 +4118,11 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -3634,6 +4147,16 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -3673,6 +4196,11 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + is-windows@^1.0.0, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -3717,11 +4245,40 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +istanbul-api@^1.3.1: + version "1.3.7" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa" + integrity sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA== + dependencies: + async "^2.1.4" + fileset "^2.0.2" + istanbul-lib-coverage "^1.2.1" + istanbul-lib-hook "^1.2.2" + istanbul-lib-instrument "^1.10.2" + istanbul-lib-report "^1.1.5" + istanbul-lib-source-maps "^1.2.6" + istanbul-reports "^1.5.1" + js-yaml "^3.7.0" + mkdirp "^0.5.1" + once "^1.4.0" + +istanbul-lib-coverage@^1.2.0, istanbul-lib-coverage@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" + integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== + istanbul-lib-coverage@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda" integrity sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA== +istanbul-lib-hook@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86" + integrity sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw== + dependencies: + append-transform "^0.4.0" + istanbul-lib-hook@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.1.tgz#918a57b75a0f951d552a08487ca1fa5336433d72" @@ -3729,6 +4286,19 @@ istanbul-lib-hook@^2.0.1: dependencies: append-transform "^1.0.0" +istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" + integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A== + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.2.1" + semver "^5.3.0" + istanbul-lib-instrument@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz#b5f066b2a161f75788be17a9d556f40a0cf2afc9" @@ -3742,6 +4312,16 @@ istanbul-lib-instrument@^3.0.0: istanbul-lib-coverage "^2.0.1" semver "^5.5.0" +istanbul-lib-report@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c" + integrity sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw== + dependencies: + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + istanbul-lib-report@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.2.tgz#430a2598519113e1da7af274ba861bd42dd97535" @@ -3751,6 +4331,17 @@ istanbul-lib-report@^2.0.2: make-dir "^1.3.0" supports-color "^5.4.0" +istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f" + integrity sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg== + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + istanbul-lib-source-maps@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-2.0.1.tgz#ce8b45131d8293fdeaa732f4faf1852d13d0a97e" @@ -3762,6 +4353,13 @@ istanbul-lib-source-maps@^2.0.1: rimraf "^2.6.2" source-map "^0.6.1" +istanbul-reports@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a" + integrity sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw== + dependencies: + handlebars "^4.0.3" + istanbul-reports@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.0.1.tgz#fb8d6ea850701a3984350b977a969e9a556116a7" @@ -3774,6 +4372,323 @@ iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2: resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== +jest-changed-files@^23.4.2: + version "23.4.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.2.tgz#1eed688370cd5eebafe4ae93d34bb3b64968fe83" + integrity sha512-EyNhTAUWEfwnK0Is/09LxoqNDOn7mU7S3EHskG52djOFS/z+IT0jT3h3Ql61+dklcG7bJJitIWEMB4Sp1piHmA== + dependencies: + throat "^4.0.0" + +jest-cli@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.6.0.tgz#61ab917744338f443ef2baa282ddffdd658a5da4" + integrity sha512-hgeD1zRUp1E1zsiyOXjEn4LzRLWdJBV//ukAHGlx6s5mfCNJTbhbHjgxnDUXA8fsKWN/HqFFF6X5XcCwC/IvYQ== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.1.11" + import-local "^1.0.0" + is-ci "^1.0.10" + istanbul-api "^1.3.1" + istanbul-lib-coverage "^1.2.0" + istanbul-lib-instrument "^1.10.1" + istanbul-lib-source-maps "^1.2.4" + jest-changed-files "^23.4.2" + jest-config "^23.6.0" + jest-environment-jsdom "^23.4.0" + jest-get-type "^22.1.0" + jest-haste-map "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve-dependencies "^23.6.0" + jest-runner "^23.6.0" + jest-runtime "^23.6.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + jest-watcher "^23.4.0" + jest-worker "^23.2.0" + micromatch "^2.3.11" + node-notifier "^5.2.1" + prompts "^0.1.9" + realpath-native "^1.0.0" + rimraf "^2.5.4" + slash "^1.0.0" + string-length "^2.0.0" + strip-ansi "^4.0.0" + which "^1.2.12" + yargs "^11.0.0" + +jest-config@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.6.0.tgz#f82546a90ade2d8c7026fbf6ac5207fc22f8eb1d" + integrity sha512-i8V7z9BeDXab1+VNo78WM0AtWpBRXJLnkT+lyT+Slx/cbP5sZJ0+NDuLcmBE5hXAoK0aUp7vI+MOxR+R4d8SRQ== + dependencies: + babel-core "^6.0.0" + babel-jest "^23.6.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^23.4.0" + jest-environment-node "^23.4.0" + jest-get-type "^22.1.0" + jest-jasmine2 "^23.6.0" + jest-regex-util "^23.3.0" + jest-resolve "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + micromatch "^2.3.11" + pretty-format "^23.6.0" + +jest-diff@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d" + integrity sha512-Gz9l5Ov+X3aL5L37IT+8hoCUsof1CVYBb2QEkOupK64XyRR3h+uRpYIm97K7sY8diFxowR8pIGEdyfMKTixo3g== + dependencies: + chalk "^2.0.1" + diff "^3.2.0" + jest-get-type "^22.1.0" + pretty-format "^23.6.0" + +jest-docblock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7" + integrity sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c= + dependencies: + detect-newline "^2.1.0" + +jest-each@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.6.0.tgz#ba0c3a82a8054387016139c733a05242d3d71575" + integrity sha512-x7V6M/WGJo6/kLoissORuvLIeAoyo2YqLOoCDkohgJ4XOXSqOtyvr8FbInlAWS77ojBsZrafbozWoKVRdtxFCg== + dependencies: + chalk "^2.0.1" + pretty-format "^23.6.0" + +jest-environment-jsdom@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023" + integrity sha1-BWp5UrP+pROsYqFAosNox52eYCM= + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" + jsdom "^11.5.1" + +jest-environment-node@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10" + integrity sha1-V+gO0IQd6jAxZ8zozXlSHeuv3hA= + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" + +jest-get-type@^22.1.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== + +jest-haste-map@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.6.0.tgz#2e3eb997814ca696d62afdb3f2529f5bbc935e16" + integrity sha512-uyNhMyl6dr6HaXGHp8VF7cK6KpC6G9z9LiMNsst+rJIZ8l7wY0tk8qwjPmEghczojZ2/ZhtEdIabZ0OQRJSGGg== + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + invariant "^2.2.4" + jest-docblock "^23.2.0" + jest-serializer "^23.0.1" + jest-worker "^23.2.0" + micromatch "^2.3.11" + sane "^2.0.0" + +jest-jasmine2@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz#840e937f848a6c8638df24360ab869cc718592e0" + integrity sha512-pe2Ytgs1nyCs8IvsEJRiRTPC0eVYd8L/dXJGU08GFuBwZ4sYH/lmFDdOL3ZmvJR8QKqV9MFuwlsAi/EWkFUbsQ== + dependencies: + babel-traverse "^6.0.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^23.6.0" + is-generator-fn "^1.0.0" + jest-diff "^23.6.0" + jest-each "^23.6.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + pretty-format "^23.6.0" + +jest-leak-detector@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz#e4230fd42cf381a1a1971237ad56897de7e171de" + integrity sha512-f/8zA04rsl1Nzj10HIyEsXvYlMpMPcy0QkQilVZDFOaPbv2ur71X5u2+C4ZQJGyV/xvVXtCCZ3wQ99IgQxftCg== + dependencies: + pretty-format "^23.6.0" + +jest-matcher-utils@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80" + integrity sha512-rosyCHQfBcol4NsckTn01cdelzWLU9Cq7aaigDf8VwwpIRvWE/9zLgX2bON+FkEW69/0UuYslUe22SOdEf2nog== + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + pretty-format "^23.6.0" + +jest-message-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f" + integrity sha1-F2EMUJQjSVCNAaPR4L2iwHkIap8= + dependencies: + "@babel/code-frame" "^7.0.0-beta.35" + chalk "^2.0.1" + micromatch "^2.3.11" + slash "^1.0.0" + stack-utils "^1.0.1" + +jest-mock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134" + integrity sha1-rRxg8p6HGdR8JuETgJi20YsmETQ= + +jest-regex-util@^23.3.0: + version "23.3.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5" + integrity sha1-X4ZylUfCeFxAAs6qj4Sf6MpHG8U= + +jest-resolve-dependencies@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz#b4526af24c8540d9a3fab102c15081cf509b723d" + integrity sha512-EkQWkFWjGKwRtRyIwRwI6rtPAEyPWlUC2MpzHissYnzJeHcyCn1Hc8j7Nn1xUVrS5C6W5+ZL37XTem4D4pLZdA== + dependencies: + jest-regex-util "^23.3.0" + jest-snapshot "^23.6.0" + +jest-resolve@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.6.0.tgz#cf1d1a24ce7ee7b23d661c33ba2150f3aebfa0ae" + integrity sha512-XyoRxNtO7YGpQDmtQCmZjum1MljDqUCob7XlZ6jy9gsMugHdN2hY4+Acz9Qvjz2mSsOnPSH7skBmDYCHXVZqkA== + dependencies: + browser-resolve "^1.11.3" + chalk "^2.0.1" + realpath-native "^1.0.0" + +jest-runner@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.6.0.tgz#3894bd219ffc3f3cb94dc48a4170a2e6f23a5a38" + integrity sha512-kw0+uj710dzSJKU6ygri851CObtCD9cN8aNkg8jWJf4ewFyEa6kwmiH/r/M1Ec5IL/6VFa0wnAk6w+gzUtjJzA== + dependencies: + exit "^0.1.2" + graceful-fs "^4.1.11" + jest-config "^23.6.0" + jest-docblock "^23.2.0" + jest-haste-map "^23.6.0" + jest-jasmine2 "^23.6.0" + jest-leak-detector "^23.6.0" + jest-message-util "^23.4.0" + jest-runtime "^23.6.0" + jest-util "^23.4.0" + jest-worker "^23.2.0" + source-map-support "^0.5.6" + throat "^4.0.0" + +jest-runtime@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.6.0.tgz#059e58c8ab445917cd0e0d84ac2ba68de8f23082" + integrity sha512-ycnLTNPT2Gv+TRhnAYAQ0B3SryEXhhRj1kA6hBPSeZaNQkJ7GbZsxOLUkwg6YmvWGdX3BB3PYKFLDQCAE1zNOw== + dependencies: + babel-core "^6.0.0" + babel-plugin-istanbul "^4.1.6" + chalk "^2.0.1" + convert-source-map "^1.4.0" + exit "^0.1.2" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.11" + jest-config "^23.6.0" + jest-haste-map "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve "^23.6.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + micromatch "^2.3.11" + realpath-native "^1.0.0" + slash "^1.0.0" + strip-bom "3.0.0" + write-file-atomic "^2.1.0" + yargs "^11.0.0" + +jest-serializer@^23.0.1: + version "23.0.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165" + integrity sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU= + +jest-snapshot@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.6.0.tgz#f9c2625d1b18acda01ec2d2b826c0ce58a5aa17a" + integrity sha512-tM7/Bprftun6Cvj2Awh/ikS7zV3pVwjRYU2qNYS51VZHgaAMBs5l4o/69AiDHhQrj5+LA2Lq4VIvK7zYk/bswg== + dependencies: + babel-types "^6.0.0" + chalk "^2.0.1" + jest-diff "^23.6.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-resolve "^23.6.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^23.6.0" + semver "^5.5.0" + +jest-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561" + integrity sha1-TQY8uSe68KI4Mf9hvsLLv0l5NWE= + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + jest-message-util "^23.4.0" + mkdirp "^0.5.1" + slash "^1.0.0" + source-map "^0.6.0" + +jest-validate@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" + integrity sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A== + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + leven "^2.1.0" + pretty-format "^23.6.0" + +jest-watcher@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.4.0.tgz#d2e28ce74f8dad6c6afc922b92cabef6ed05c91c" + integrity sha1-0uKM50+NrWxq/JIrksq+9u0FyRw= + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + string-length "^2.0.0" + +jest-worker@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-23.2.0.tgz#faf706a8da36fae60eb26957257fa7b5d8ea02b9" + integrity sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk= + dependencies: + merge-stream "^1.0.1" + +jest@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-23.6.0.tgz#ad5835e923ebf6e19e7a1d7529a432edfee7813d" + integrity sha512-lWzcd+HSiqeuxyhG+EnZds6iO3Y3ZEnMrfZq/OTGvF/C+Z4fPMCdhWTGSAiO2Oym9rbEXfwddHhh6jqrTF3+Lw== + dependencies: + import-local "^1.0.0" + jest-cli "^23.6.0" + jmespath@0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" @@ -3803,7 +4718,12 @@ js-levenshtein@^1.1.3: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.10.0, js-yaml@^3.12.0: +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-yaml@^3.10.0, js-yaml@^3.12.0, js-yaml@^3.7.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== @@ -3816,6 +4736,43 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= +jsdom@^11.5.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -3858,6 +4815,11 @@ json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + json5@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" @@ -3936,6 +4898,11 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== +kleur@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300" + integrity sha512-77XF9iTllATmG9lSlIv0qdQ2BQ/h9t0bJllHlbvsQ0zUWfU7Yi0S8L5JXzPZgkefIiajLmBJJ4BsMJmqcf7oxQ== + latest-version@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" @@ -3950,6 +4917,16 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== + +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -3976,6 +4953,17 @@ linkifyjs@~2.1.7: react "^16.4.2" react-dom "^16.4.2" +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" @@ -4072,7 +5060,12 @@ lodash.once@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= -lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.11: +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.11: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -4116,6 +5109,13 @@ make-dir@^1.0.0, make-dir@^1.3.0: dependencies: pify "^3.0.0" +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" + map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -4128,6 +5128,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +math-random@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= + md5-hex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" @@ -4169,11 +5174,42 @@ merge-source-map@^1.1.0: dependencies: source-map "^0.6.1" +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= + dependencies: + readable-stream "^2.0.1" + +merge@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= +micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -4215,7 +5251,7 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: +minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -4227,7 +5263,7 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@1.2.0, minimist@^1.2.0: +minimist@1.2.0, minimist@^1.1.1, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= @@ -4260,30 +5296,13 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: +mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" -mocha@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" - integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== - dependencies: - browser-stdout "1.3.1" - commander "2.15.1" - debug "3.1.0" - diff "3.5.0" - escape-string-regexp "1.0.5" - glob "7.1.2" - growl "1.10.5" - he "1.1.1" - minimatch "3.0.4" - mkdirp "0.5.1" - supports-color "5.4.0" - moment@^2.22.2: version "2.22.2" resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" @@ -4386,11 +5405,26 @@ node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@~2.3.0: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + node-modules-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= +node-notifier@^5.2.1: + version "5.3.0" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.3.0.tgz#c77a4a7b84038733d5fb351aafd8a268bfe19a01" + integrity sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q== + dependencies: + growly "^1.3.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + node-pre-gyp@^0.10.0: version "0.10.3" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" @@ -4455,7 +5489,7 @@ normalize-package-data@^2.3.2: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.1.1: +normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= @@ -4524,6 +5558,11 @@ numeral@^2.0.6: resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" integrity sha1-StCAk21EPCVhrtnyGX7//iX05QY= +nwsapi@^2.0.7: + version "2.0.9" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016" + integrity sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ== + nyc@^13.1.0: version "13.1.0" resolved "https://registry.yarnpkg.com/nyc/-/nyc-13.1.0.tgz#463665c7ff6b5798e322624a5eb449a678db90e3" @@ -4604,6 +5643,14 @@ object.getownpropertydescriptors@^2.0.3: define-properties "^1.1.2" es-abstract "^1.5.1" +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -4618,7 +5665,7 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -once@^1.3.0: +once@^1.3.0, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -4667,7 +5714,7 @@ optimist@^0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" -optionator@^0.8.2: +optionator@^0.8.1, optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= @@ -4693,7 +5740,7 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= @@ -4778,6 +5825,16 @@ package-json@^4.0.0: registry-url "^3.0.3" semver "^5.1.0" +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -4798,6 +5855,11 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== + parse5@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" @@ -4853,7 +5915,7 @@ path-exists@^3.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= -path-is-absolute@^1.0.0: +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= @@ -4878,6 +5940,15 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" @@ -4967,6 +6038,11 @@ pluralize@^7.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -4991,7 +6067,20 @@ prepend-http@^1.0.1: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -private@^0.1.6: +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +pretty-format@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" + integrity sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw== + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + +private@^0.1.6, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== @@ -5006,6 +6095,14 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +prompts@^0.1.9: + version "0.1.14" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2" + integrity sha512-rxkyiE9YH6zAz/rZpywySLKkpaj0NMVyNw1qhsubdbjjSgcayjTShDreZGlFMcGSu5sab3bAKPfFk78PB90+8w== + dependencies: + kleur "^2.0.1" + sisteransi "^0.1.1" + prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" @@ -5051,6 +6148,11 @@ psl@^1.1.24: resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== +psl@^1.1.28: + version "1.1.31" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" + integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== + pstree.remy@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.6.tgz#73a55aad9e2d95814927131fbf4dc1b62d259f47" @@ -5061,7 +6163,7 @@ punycode@1.3.2: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@2.x.x, punycode@^2.1.0: +punycode@2.x.x, punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -5081,6 +6183,15 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" @@ -5126,6 +6237,14 @@ react@^16.4.2: prop-types "^15.6.2" scheduler "^0.11.2" +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" @@ -5142,6 +6261,15 @@ read-pkg-up@^4.0.0: find-up "^3.0.0" read-pkg "^3.0.0" +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" @@ -5170,7 +6298,7 @@ readable-stream@1.1.x: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.2, readable-stream@^2.0.6: +readable-stream@^2.0.1, 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== @@ -5201,6 +6329,13 @@ readdirp@^2.0.0: micromatch "^3.1.10" readable-stream "^2.0.2" +realpath-native@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560" + integrity sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g== + dependencies: + util.promisify "^1.0.0" + regenerate-unicode-properties@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" @@ -5235,6 +6370,13 @@ regenerator-transform@^0.13.3: dependencies: private "^0.1.6" +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -5304,12 +6446,35 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.6.1: +repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -request@^2.88.0: +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + integrity sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY= + dependencies: + lodash "^4.13.1" + +request-promise-native@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + integrity sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU= + dependencies: + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request@^2.87.0, request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -5353,11 +6518,23 @@ require-uncached@^1.0.3: caller-path "^0.1.0" resolve-from "^1.0.0" +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -5368,6 +6545,11 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" @@ -5393,13 +6575,18 @@ retry@0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= -rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: +rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== dependencies: glob "^7.0.5" +rsvp@^3.3.3: + version "3.6.2" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" + integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw== + run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -5436,6 +6623,22 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sane@^2.0.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa" + integrity sha1-tNwYYcIbQn6SlQej51HiosuKs/o= + dependencies: + anymatch "^2.0.0" + capture-exit "^1.2.0" + exec-sh "^0.2.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.2.3" + sanitize-html@~1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.20.0.tgz#9a602beb1c9faf960fb31f9890f61911cc4d9156" @@ -5568,11 +6771,26 @@ shell-quote@^1.6.1: array-reduce "~0.0.0" jsonify "~0.0.0" +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +sisteransi@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz#5431447d5f7d1675aac667ccd0b865a4994cb3ce" + integrity sha512-PmGOd02bM9YO5ifxpw36nrNMBTptEtfRl4qUYl9SndkolplkrZZOW7PGHjrZL53QvMVj9nQ+TKqUnRsw4tJa4g== + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" @@ -5635,7 +6853,14 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.5.1, source-map-support@^0.5.9: +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-support@^0.5.1, source-map-support@^0.5.6, source-map-support@^0.5.9: version "0.5.9" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== @@ -5648,7 +6873,7 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.0, source-map@^0.5.6: +source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -5731,6 +6956,11 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +stack-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" + integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -5749,11 +6979,24 @@ statuses@~1.4.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + streamsearch@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -5820,11 +7063,18 @@ strip-ansi@^5.0.0: dependencies: ansi-regex "^4.0.0" -strip-bom@^3.0.0: +strip-bom@3.0.0, strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -5846,18 +7096,18 @@ subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: symbol-observable "^1.0.4" ws "^5.2.0" -supports-color@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== - dependencies: - has-flag "^3.0.0" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= +supports-color@^3.1.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -5870,6 +7120,11 @@ symbol-observable@^1.0.2, symbol-observable@^1.0.4: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY= + table@^5.0.2: version "5.1.1" resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837" @@ -5900,6 +7155,17 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" +test-exclude@^4.2.1: + version "4.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20" + integrity sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA== + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + test-exclude@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.0.0.tgz#cdce7cece785e0e829cd5c2b27baf18bc583cfb7" @@ -5920,6 +7186,11 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= + through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -5937,6 +7208,16 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -5986,6 +7267,14 @@ touch@^3.1.0: dependencies: nopt "~1.0.10" +tough-cookie@>=2.3.3, tough-cookie@^2.3.4: + 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@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" @@ -5994,6 +7283,13 @@ tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -6238,6 +7534,13 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= + dependencies: + browser-process-hrtime "^0.1.2" + wait-on@~3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-3.2.0.tgz#c83924df0fc42a675c678324c49c769d378bcb85" @@ -6249,17 +7552,67 @@ wait-on@~3.2.0: request "^2.88.0" rx "^4.1.0" +walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + integrity sha1-KAlUdsbffJDJYxOJkMClQj60uYY= + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + whatwg-fetch@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== +whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.9, which@^1.3.0: +which@^1.2.12, which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -6303,7 +7656,7 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write-file-atomic@^2.0.0: +write-file-atomic@^2.0.0, write-file-atomic@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== @@ -6338,6 +7691,11 @@ xdg-basedir@^3.0.0: resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + xml2js@0.4.19, xml2js@^0.4.17: version "0.4.19" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" @@ -6378,7 +7736,7 @@ yargs-parser@^9.0.2: dependencies: camelcase "^4.1.0" -yargs@11.1.0: +yargs@11.1.0, yargs@^11.0.0: version "11.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A== From f15fb0bb1f6365b710398a9d35130ff0244eff99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 20 Dec 2018 18:01:55 +0100 Subject: [PATCH 175/554] Sketch a test to expose #49 --- src/graphql-schema.test.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/graphql-schema.test.js diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js new file mode 100644 index 000000000..f81c919de --- /dev/null +++ b/src/graphql-schema.test.js @@ -0,0 +1,18 @@ +describe('login', () => { + describe('asking for a `token`', () => { + describe('with valid email/password combination', () => { + xit('responds with a JWT token', () => {}) + }) + + describe('with a valid email but incorrect password', () => { + beforeEach(() => { + // create a user in the database + }) + xit('responds with "Wrong email/password combination"', () => {}) + }) + + describe('with a non-existing email', () => { + xit('responds with "Wrong email/password combination"', () => {}) + }) + }) +}) From 2ccbb1ca92fe16404ed447ddb4c66f5bad3f8b4c Mon Sep 17 00:00:00 2001 From: kachulio1 Date: Thu, 20 Dec 2018 20:39:48 +0300 Subject: [PATCH 176/554] add supertest --- package.json | 3 ++- src/graphql-schema.test.js | 12 ++++++++- yarn.lock | 54 ++++++++++++++++++++++++++++++++++---- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index f536720c8..97ce9e141 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "eslint-plugin-standard": "~4.0.0", "jest": "^23.6.0", "nodemon": "~1.18.9", - "nyc": "^13.1.0" + "nyc": "^13.1.0", + "supertest": "^3.3.0" } } diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index f81c919de..a44e74fbc 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -1,3 +1,8 @@ +import request from "supertest" +import server from './server' + + + describe('login', () => { describe('asking for a `token`', () => { describe('with valid email/password combination', () => { @@ -12,7 +17,12 @@ describe('login', () => { }) describe('with a non-existing email', () => { - xit('responds with "Wrong email/password combination"', () => {}) + + it('responds with "Wrong email/password combination"', async () => { + const app = (await server).createHttpServer({}); + + request(app).post('/graphql').send({}).expect(400) + }) }) }) }) diff --git a/yarn.lock b/yarn.lock index 95f261fdf..c7c6167df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2146,7 +2146,7 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= -component-emitter@^1.2.1: +component-emitter@^1.2.0, component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= @@ -2205,6 +2205,11 @@ 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" @@ -2987,7 +2992,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@~3.0.2: +extend@^3.0.0, 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== @@ -3205,7 +3210,7 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@~2.3.2: +form-data@^2.3.1, form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== @@ -3214,6 +3219,11 @@ 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" @@ -5186,7 +5196,7 @@ merge@^1.2.0: resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== -methods@~1.1.2: +methods@^1.1.1, 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= @@ -5246,6 +5256,11 @@ mime@1.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== +mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -6178,6 +6193,11 @@ qs@6.5.2, qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +qs@^6.5.1: + version "6.6.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.6.0.tgz#a99c0f69a8d26bf7ef012f871cdabb0aee4424c2" + integrity sha512-KIJqT9jQJDQx5h5uAVPimw6yVg2SekOKu959OCtktD3FjzbpvaPr8i4zzg07DOMz+igA4W/aNM7OV8H37pFYfA== + querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" @@ -6298,7 +6318,7 @@ readable-stream@1.1.x: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6: +readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -7096,6 +7116,30 @@ subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: symbol-observable "^1.0.4" ws "^5.2.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@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-3.3.0.tgz#79b27bd7d34392974ab33a31fa51a3e23385987e" + integrity sha512-dMQSzYdaZRSANH5LL8kX3UpgK9G1LRh/jnggs/TI0W2Sz7rkMx9Y48uia3K9NgcaWEV28tYkBnXE4tiFC77ygQ== + dependencies: + methods "^1.1.2" + superagent "^3.8.3" + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" From 01c4090792f781074f5db320b229f0e6f7f08112 Mon Sep 17 00:00:00 2001 From: Joseph Date: Thu, 20 Dec 2018 22:18:18 +0300 Subject: [PATCH 177/554] Update README.md add build command before db:seed --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1eb8cc528..17a26caad 100644 --- a/README.md +++ b/README.md @@ -117,8 +117,10 @@ Optionally you can seed the GraphQL service by executing mutations that will write sample data to the database: ```bash +yarn run build yarn run db:seed # -or- +npm run build npm run db:seed ``` From e58e228f0c3ebe7606c555c4ef492bd786838835 Mon Sep 17 00:00:00 2001 From: kachulio1 Date: Thu, 20 Dec 2018 22:44:52 +0300 Subject: [PATCH 178/554] remove supertest --- package.json | 1 + src/graphql-schema.test.js | 56 ++++++++++++++++++++++++-------------- yarn.lock | 2 +- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 97ce9e141..f40f582e9 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "eslint-plugin-node": "~8.0.0", "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", + "graphql-request": "^1.8.2", "jest": "^23.6.0", "nodemon": "~1.18.9", "nyc": "^13.1.0", diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index a44e74fbc..80b1bba54 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -1,28 +1,42 @@ -import request from "supertest" -import server from './server' +import { request } from "graphql-request"; +import server from "./server"; +describe("login", () => { + describe("asking for a `token`", () => { + describe("with valid email/password combination", () => { + xit("responds with a JWT token", () => {}); + }); - -describe('login', () => { - describe('asking for a `token`', () => { - describe('with valid email/password combination', () => { - xit('responds with a JWT token', () => {}) - }) - - describe('with a valid email but incorrect password', () => { + describe("with a valid email but incorrect password", () => { beforeEach(() => { // create a user in the database - }) - xit('responds with "Wrong email/password combination"', () => {}) - }) + }); + xit('responds with "Wrong email/password combination"', () => {}); + }); - describe('with a non-existing email', () => { + describe("with a non-existing email", () => { + let getHost; + + beforeEach(async () => { + const app = await server.start({ port: 0 }); + const { port } = app.address(); + getHost = () => `http://127.0.0.1:${port}`; + }); + + const email = "tom@bob.com"; + const password = "jalksdf"; + + const mutation = ` + mutation { + login(email:"asfasf@baldf.cm", password:"asdfasd"){ + token + } + }`; it('responds with "Wrong email/password combination"', async () => { - const app = (await server).createHttpServer({}); - - request(app).post('/graphql').send({}).expect(400) - }) - }) - }) -}) + const response = await request(getHost(), mutation); + expect(response).toBe({}); + }); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index c7c6167df..19abca68e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3506,7 +3506,7 @@ graphql-playground-middleware-lambda@1.7.6: dependencies: graphql-playground-html "1.6.4" -graphql-request@^1.5.0: +graphql-request@^1.5.0, graphql-request@^1.8.2: version "1.8.2" resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" integrity sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg== From 6b216be05c560f1dff3554578ec880f93a02872b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 21 Dec 2018 00:03:57 +0100 Subject: [PATCH 179/554] Add @mattwr18's code and fix linting --- .eslintrc.js | 4 ++- package.json | 3 +- src/graphql-schema.test.js | 56 +++++++++++++++++++------------------- yarn.lock | 7 ++++- 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index ae2dcb316..0fdbfd52d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,6 +4,7 @@ module.exports = { "env": { "es6": true, "node": true, + "jest/globals": true }, "rules": { "indent": [ @@ -14,5 +15,6 @@ module.exports = { "error", "single" ] - } + }, + "plugins": ["jest"] }; diff --git a/package.json b/package.json index f40f582e9..28c6b026f 100644 --- a/package.json +++ b/package.json @@ -66,9 +66,10 @@ "babel-eslint": "~10.0.1", "babel-jest": "^23.6.0", "chai": "~4.2.0", - "eslint": "~5.10.0", + "eslint": "^5.10.0", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.14.0", + "eslint-plugin-jest": "^22.1.2", "eslint-plugin-node": "~8.0.0", "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index 80b1bba54..409e1ab7a 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -1,42 +1,42 @@ -import { request } from "graphql-request"; -import server from "./server"; +import { request } from 'graphql-request' +import server from './server' -describe("login", () => { - describe("asking for a `token`", () => { - describe("with valid email/password combination", () => { - xit("responds with a JWT token", () => {}); - }); +describe('login', () => { + describe('asking for a `token`', () => { + describe('with valid email/password combination', () => { + xit('responds with a JWT token', () => {}) + }) - describe("with a valid email but incorrect password", () => { + describe('with a valid email but incorrect password', () => { beforeEach(() => { // create a user in the database - }); - xit('responds with "Wrong email/password combination"', () => {}); - }); + }) + xit('responds with "Wrong email/password combination"', () => {}) + }) - describe("with a non-existing email", () => { - let getHost; + describe('with a non-existing email', () => { + let getHost beforeEach(async () => { - const app = await server.start({ port: 0 }); - const { port } = app.address(); - getHost = () => `http://127.0.0.1:${port}`; - }); - - const email = "tom@bob.com"; - const password = "jalksdf"; + const app = await server.start({ port: 0 }) + const { port } = app.address() + getHost = () => `http://127.0.0.1:${port}` + }) const mutation = ` mutation { - login(email:"asfasf@baldf.cm", password:"asdfasd"){ + login(email:"user@example.com", password:"asdfasd"){ token } - }`; + }` it('responds with "Wrong email/password combination"', async () => { - const response = await request(getHost(), mutation); - expect(response).toBe({}); - }); - }); - }); -}); + try { + await request(getHost(), mutation) + } catch (error) { + expect(error.response.errors[0].message).toEqual('Wrong email/password combination') + } + }) + }) + }) +}) diff --git a/yarn.lock b/yarn.lock index 19abca68e..75748a7f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2728,6 +2728,11 @@ eslint-plugin-import@~2.14.0: read-pkg-up "^2.0.0" resolve "^1.6.0" +eslint-plugin-jest@^22.1.2: + version "22.1.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.1.2.tgz#1ea36cc3faedbdb788e702ca633d635ca14e91e8" + integrity sha512-jSPT4rVmNetkeCIyrvvOM0wJtgoUSbKHIUDoOGzIISsg51eWN/nISPNKVM+jXMMDI9oowbyapOnpKSXlsLiDpQ== + eslint-plugin-node@~8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.0.tgz#fb9e8911f4543514f154bb6a5924b599aa645568" @@ -2776,7 +2781,7 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@~5.10.0: +eslint@^5.10.0: version "5.10.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.10.0.tgz#24adcbe92bf5eb1fc2d2f2b1eebe0c5e0713903a" integrity sha512-HpqzC+BHULKlnPwWae9MaVZ5AXJKpkxCVXQHrFaRw3hbDj26V/9ArYM4Rr/SQ8pi6qUPLXSSXC4RBJlyq2Z2OQ== From ec9c205beea2e94ea214c2daaf908d250b537cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 21 Dec 2018 00:37:58 +0100 Subject: [PATCH 180/554] Export a function in server.js and test teardown --- src/graphql-schema.test.js | 25 +++++++++++------ src/index.js | 3 +- src/server.js | 56 +++++++++++++++++++------------------- 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index 409e1ab7a..f9be026f5 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -1,5 +1,20 @@ import { request } from 'graphql-request' -import server from './server' +import createServer from './server' + +let getHost +let app +let port + +beforeEach(async () => { + const server = createServer() + app = await server.start({ port: 0 }) + port = app.address().port + getHost = () => `http://127.0.0.1:${port}` +}) + +afterEach(async () => { + await app.close() +}) describe('login', () => { describe('asking for a `token`', () => { @@ -15,14 +30,6 @@ describe('login', () => { }) describe('with a non-existing email', () => { - let getHost - - beforeEach(async () => { - const app = await server.start({ port: 0 }) - const { port } = app.address() - getHost = () => `http://127.0.0.1:${port}` - }) - const mutation = ` mutation { login(email:"user@example.com", password:"asdfasd"){ diff --git a/src/index.js b/src/index.js index fee7b06dd..f594cb7f7 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import server from './server' +import createServer from './server' const serverConfig = { port: process.env.GRAPHQL_PORT || 4000 @@ -8,6 +8,7 @@ const serverConfig = { // } } +const server = createServer() server.start(serverConfig, options => { /* eslint-disable-next-line no-console */ console.log(`Server ready at ${process.env.GRAPHQL_URI} 🚀`) diff --git a/src/server.js b/src/server.js index bf3e07248..3b0e0a561 100644 --- a/src/server.js +++ b/src/server.js @@ -22,10 +22,6 @@ let schema = makeExecutableSchema({ const driver = neo4j().getDriver() -const MOCK = (process.env.MOCK === 'true') -/* eslint-disable-next-line no-console */ -console.log('MOCK:', MOCK) - schema = augmentSchema(schema, { query: { exclude: ['Statistics', 'LoggedInUser'] @@ -36,31 +32,35 @@ schema = augmentSchema(schema, { }) schema = applyScalars(applyDirectives(schema)) -const server = new GraphQLServer({ - context: async (req) => { - const payload = { - driver, - user: null, - req: req.request - } - try { - const token = payload.req.headers.authorization.replace('Bearer ', '') - payload.user = await jwt.verify(token, process.env.JWT_SECRET) - } catch (err) { - // nothing - } +const createServer = (options) => { + const defaults = { + context: async (req) => { + const payload = { + driver, + user: null, + req: req.request + } + try { + const token = payload.req.headers.authorization.replace('Bearer ', '') + payload.user = await jwt.verify(token, process.env.JWT_SECRET) + } catch (err) { + // nothing + } - return payload - }, - schema: schema, - tracing: true, - middlewares: middleware(schema), - mocks: MOCK ? mocks : false -}) + return payload + }, + schema: schema, + tracing: true, + middlewares: middleware(schema), + mocks: (process.env.MOCK === 'true') ? mocks : false + } + const server = new GraphQLServer(Object.assign({}, defaults, options)) -passport.use('jwt', jwtStrategy()) -server.express.use(passport.initialize()) + passport.use('jwt', jwtStrategy()) + server.express.use(passport.initialize()) -server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) + server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) + return server +} -export default server +export default createServer From cd651b07faae8474fcb4908f11ed8b6602684d37 Mon Sep 17 00:00:00 2001 From: Toverto Date: Sun, 23 Dec 2018 19:30:15 +0100 Subject: [PATCH 181/554] Change db scripts to run nodemon instead of node this way you don't have to run yarn run build before seeding the db --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3dcf5db74..41de1d7de 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,8 @@ "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", - "db:seed": "$npm_package_config_no_auth run-p --race start db:script:seed", - "db:reset": "$npm_package_config_no_auth run-p --race start db:script:reset" + "db:seed": "$npm_package_config_no_auth run-p --race dev db:script:seed", + "db:reset": "$npm_package_config_no_auth run-p --race dev db:script:reset" }, "author": "Human Connection gGmbH", "license": "MIT", From bd59f916b0c6c3c047e2554b62c92be4070b0206 Mon Sep 17 00:00:00 2001 From: Toverto Date: Wed, 26 Dec 2018 16:19:40 +0100 Subject: [PATCH 182/554] Remove the build instruction for seeding the db in README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 17a26caad..1eb8cc528 100644 --- a/README.md +++ b/README.md @@ -117,10 +117,8 @@ Optionally you can seed the GraphQL service by executing mutations that will write sample data to the database: ```bash -yarn run build yarn run db:seed # -or- -npm run build npm run db:seed ``` From 93d821825bb0356d122c0c31bd3eac4169afc658 Mon Sep 17 00:00:00 2001 From: Gerald Michelant Date: Thu, 27 Dec 2018 17:21:18 -0500 Subject: [PATCH 183/554] capture error in readable format with try and catch --- src/graphql-schema.js | 46 ++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index b52c9e232..7d2a8ce5f 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -5,6 +5,7 @@ import bcrypt from 'bcryptjs' import zipObject from 'lodash/zipObject' import generateJwt from './jwt/generateToken' import { fixUrl } from './middleware/fixImageUrlsMiddleware' +import { AuthenticationError } from 'apollo-server' export const typeDefs = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, 'schema.graphql')) @@ -95,32 +96,33 @@ export const resolvers = { // if (user && user.id) { // throw new Error('Already logged in.') // } - const session = driver.session() - const res = await session.run('MATCH (u:User {email: "' + email + '"}) RETURN u.id, u.slug, u.name, u.avatar, u.email, u.password, u.role LIMIT 1') - let u = res.records[0]._fields ? zipObject([ - 'id', - 'slug', - 'name', - 'avatar', - 'email', - 'password', - 'role' - ], res.records[0]._fields) : null - if (u) { - if (await bcrypt.compareSync(password, u.password)) { - delete u.password - u.avatar = fixUrl(u.avatar) - return Object.assign(u, { - token: generateJwt(u) - }) + try { + const res = await session.run('MATCH (u:User {email: "' + email + '"}) RETURN u.id, u.slug, u.name, u.avatar, u.email, u.password, u.role LIMIT 1') + const u = res.records[0]._fields ? zipObject([ + 'id', + 'slug', + 'name', + 'avatar', + 'email', + 'password', + 'role' + ], res.records[0]._fields) : null + if (u) { + if (await bcrypt.compareSync(password, u.password)) { + delete u.password + u.avatar = fixUrl(u.avatar) + return Object.assign(u, { + token: generateJwt(u) + }) + } + session.close() + throw new Error('Incorrect username or password.') } session.close() - throw new Error('Incorrect password.') + } catch (error) { + throw new AuthenticationError('Incorrect username or password.') } - - session.close() - throw new Error('No Such User exists.') } } } From 1e949f3fde454f8ad4f279bf526c0900b70f0703 Mon Sep 17 00:00:00 2001 From: Gerald Michelant Date: Fri, 28 Dec 2018 22:17:28 -0500 Subject: [PATCH 184/554] throw new AuthenticationError on password error --- src/graphql-schema.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 7d2a8ce5f..c298177c2 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -117,7 +117,7 @@ export const resolvers = { }) } session.close() - throw new Error('Incorrect username or password.') + throw new AuthenticationError('Incorrect username or password.') } session.close() } catch (error) { From 2959eeb931910f451e546811944196e79f4ed215 Mon Sep 17 00:00:00 2001 From: Gerald Michelant Date: Sun, 30 Dec 2018 16:44:08 -0500 Subject: [PATCH 185/554] rewritting of login method --- src/graphql-schema.js | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index c298177c2..830fda193 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -2,7 +2,6 @@ import fs from 'fs' import path from 'path' import bcrypt from 'bcryptjs' -import zipObject from 'lodash/zipObject' import generateJwt from './jwt/generateToken' import { fixUrl } from './middleware/fixImageUrlsMiddleware' import { AuthenticationError } from 'apollo-server' @@ -97,32 +96,23 @@ export const resolvers = { // throw new Error('Already logged in.') // } const session = driver.session() - try { - const res = await session.run('MATCH (u:User {email: "' + email + '"}) RETURN u.id, u.slug, u.name, u.avatar, u.email, u.password, u.role LIMIT 1') - const u = res.records[0]._fields ? zipObject([ - 'id', - 'slug', - 'name', - 'avatar', - 'email', - 'password', - 'role' - ], res.records[0]._fields) : null - if (u) { - if (await bcrypt.compareSync(password, u.password)) { - delete u.password - u.avatar = fixUrl(u.avatar) - return Object.assign(u, { - token: generateJwt(u) - }) - } + return session.run( + 'MATCH (user:User {email: "' + email + '"}) ' + + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1') + .then(async (result) => { session.close() - throw new AuthenticationError('Incorrect username or password.') - } - session.close() - } catch (error) { - throw new AuthenticationError('Incorrect username or password.') - } + const [currentUser] = await result.records.map(function (record) { + console.log(record.get('user')) + return record.get('user') + }) + if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { + delete currentUser.password + currentUser.avatar = fixUrl(currentUser.avatar) + return Object.assign(currentUser, { + token: generateJwt(currentUser) + }) + } else throw new AuthenticationError('Incorrect username or password.') + }) } } } From 9ff227d28fc3b48e27656e4cea09a758c6bd7f5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 31 Dec 2018 19:19:28 +0000 Subject: [PATCH 186/554] Bump @babel/node from 7.2.0 to 7.2.2 Bumps [@babel/node](https://github.com/babel/babel) from 7.2.0 to 7.2.2. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.2.0...v7.2.2) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 41de1d7de..3c681d036 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "devDependencies": { "@babel/cli": "~7.2.0", "@babel/core": "~7.2.0", - "@babel/node": "~7.2.0", + "@babel/node": "~7.2.2", "@babel/preset-env": "~7.2.0", "@babel/register": "~7.0.0", "apollo-server-testing": "~2.2.6", diff --git a/yarn.lock b/yarn.lock index f9d341118..26d375496 100644 --- a/yarn.lock +++ b/yarn.lock @@ -251,10 +251,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/node@~7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.2.0.tgz#0b601be8ef03897923e3908dc18129836d44e6fa" - integrity sha512-RFwVH5xWpwd4SfkOI0WsK9AnF5o+C9iMTvUkkTb7jUNaiDieV8BGK38t74bTPjgc4FCxSAWNKqaqgDW4fenkyA== +"@babel/node@~7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.2.2.tgz#1557dd23545b38d7b1d030a9c0e8fb225dbf70ab" + integrity sha512-jPqgTycE26uFsuWpLika9Ohz9dmLQHWjOnMNxBOjYb1HXO+eLKxEr5FfKSXH/tBvFwwaw+pzke3gagnurGOfCA== dependencies: "@babel/polyfill" "^7.0.0" "@babel/register" "^7.0.0" From 42006c51bc53a809a0dea3746c638d84f9cf517e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 2 Jan 2019 10:53:45 +0000 Subject: [PATCH 187/554] Bump @babel/cli from 7.2.0 to 7.2.3 Bumps [@babel/cli](https://github.com/babel/babel) from 7.2.0 to 7.2.3. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.2.0...v7.2.3) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 3c681d036..ec5f6c7c5 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "wait-on": "~3.2.0" }, "devDependencies": { - "@babel/cli": "~7.2.0", + "@babel/cli": "~7.2.3", "@babel/core": "~7.2.0", "@babel/node": "~7.2.2", "@babel/preset-env": "~7.2.0", diff --git a/yarn.lock b/yarn.lock index 26d375496..bea817e14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,10 +23,10 @@ resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz#022209e28a2b547dcde15b219f0c50f47aa5beb3" integrity sha512-lqK94b+caNtmKFs5oUVXlSpN3sm5IXZ+KfhMxOtr0LR2SqErzkoJilitjDvJ1WbjHlxLI7WtCjRmOLdOGJqtMQ== -"@babel/cli@~7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.2.0.tgz#505ed8d351daee6a88918da02c046c18c8c5a24f" - integrity sha512-FLteTkEoony0DX8NbnT51CmwmLBzINdlXmiJCSqCLmqWCDA/xk8EITPWqwDnVLbuK0bsZONt/grqHnQzQ15j0Q== +"@babel/cli@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.2.3.tgz#1b262e42a3e959d28ab3d205ba2718e1923cfee6" + integrity sha512-bfna97nmJV6nDJhXNPeEfxyMjWnt6+IjUAaDPiYRTBlm8L41n8nvw6UAqUCbvpFfU246gHPxW7sfWwqtF4FcYA== dependencies: commander "^2.8.1" convert-source-map "^1.1.0" From 3f6fa66bddfb1ab83f98cc94ad577c56cf3ac67c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 2 Jan 2019 11:10:31 +0000 Subject: [PATCH 188/554] Bump @babel/preset-env from 7.2.0 to 7.2.3 Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.2.0 to 7.2.3. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.2.0...v7.2.3) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ec5f6c7c5..320af5981 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "@babel/cli": "~7.2.3", "@babel/core": "~7.2.0", "@babel/node": "~7.2.2", - "@babel/preset-env": "~7.2.0", + "@babel/preset-env": "~7.2.3", "@babel/register": "~7.0.0", "apollo-server-testing": "~2.2.6", "babel-eslint": "~10.0.1", diff --git a/yarn.lock b/yarn.lock index bea817e14..5cb6126cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -560,10 +560,10 @@ core-js "^2.5.7" regenerator-runtime "^0.11.1" -"@babel/preset-env@~7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.2.0.tgz#a5030e7e4306af5a295dd5d7c78dc5464af3fee2" - integrity sha512-haGR38j5vOGVeBatrQPr3l0xHbs14505DcM57cbJy48kgMFvvHHoYEhHuRV+7vi559yyAUAVbTWzbK/B/pzJng== +"@babel/preset-env@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.2.3.tgz#948c8df4d4609c99c7e0130169f052ea6a7a8933" + integrity sha512-AuHzW7a9rbv5WXmvGaPX7wADxFkZIqKlbBh1dmZUQp4iwiPpkE/Qnrji6SC4UQCQzvWY/cpHET29eUhXS9cLPw== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" From 23b454025aeac1e543fe81f097d54d12409b7e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 2 Jan 2019 12:11:03 +0100 Subject: [PATCH 189/554] Implement user factory and database clean up --- README.md | 2 - package.json | 11 +++--- src/graphql-schema.test.js | 77 ++++++++++++++++++++++++++----------- src/seed/factories/index.js | 43 +++++++++++++++++++++ src/seed/factories/users.js | 36 +++++++++++++++++ src/server.js | 2 +- yarn.lock | 8 ++-- 7 files changed, 144 insertions(+), 35 deletions(-) create mode 100644 src/seed/factories/index.js create mode 100644 src/seed/factories/users.js diff --git a/README.md b/README.md index 17a26caad..1eb8cc528 100644 --- a/README.md +++ b/README.md @@ -117,10 +117,8 @@ Optionally you can seed the GraphQL service by executing mutations that will write sample data to the database: ```bash -yarn run build yarn run db:seed # -or- -npm run build npm run db:seed ``` diff --git a/package.json b/package.json index 28c6b026f..d4690c37e 100644 --- a/package.json +++ b/package.json @@ -11,14 +11,15 @@ "start": "node dist/", "dev": "nodemon --exec babel-node src/index.js", "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "jest": "jest", "lint": "eslint src --config .eslintrc.js", - "test": "nyc --reporter=text-lcov jest", + "test": "nyc --reporter=text-lcov test:jest", + "test:jest": "$npm_package_config_no_auth run-p --race start test:cmd:jest", + "test:cmd:jest": "jest", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", - "db:seed": "$npm_package_config_no_auth run-p --race start db:script:seed", - "db:reset": "$npm_package_config_no_auth run-p --race start db:script:reset" + "db:seed": "$npm_package_config_no_auth run-p --race dev db:script:seed", + "db:reset": "$npm_package_config_no_auth run-p --race dev db:script:reset" }, "author": "Human Connection gGmbH", "license": "MIT", @@ -58,7 +59,7 @@ "devDependencies": { "@babel/cli": "~7.2.0", "@babel/core": "^7.2.2", - "@babel/node": "~7.2.0", + "@babel/node": "~7.2.2", "@babel/preset-env": "~7.2.0", "@babel/register": "~7.0.0", "apollo-server-testing": "~2.2.6", diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index f9be026f5..d75095daa 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -1,12 +1,14 @@ import { request } from 'graphql-request' import createServer from './server' +import mocks from './mocks' +import { create, cleanDatabase } from './seed/factories' let getHost let app let port beforeEach(async () => { - const server = createServer() + const server = createServer({mocks}) app = await server.start({ port: 0 }) port = app.address().port getHost = () => `http://127.0.0.1:${port}` @@ -16,33 +18,62 @@ afterEach(async () => { await app.close() }) -describe('login', () => { - describe('asking for a `token`', () => { - describe('with valid email/password combination', () => { - xit('responds with a JWT token', () => {}) - }) - - describe('with a valid email but incorrect password', () => { - beforeEach(() => { - // create a user in the database - }) - xit('responds with "Wrong email/password combination"', () => {}) - }) - - describe('with a non-existing email', () => { - const mutation = ` +describe.only('login', () => { + let email + let password + const mutation = ` mutation { - login(email:"user@example.com", password:"asdfasd"){ + login(email:"${email}", password:"${password}"){ token } }` + describe('given an existing user', () => { + beforeEach(async () => { + await create('user', { + email: 'test@example.org', + password: '1234' + }) + }) - it('responds with "Wrong email/password combination"', async () => { - try { - await request(getHost(), mutation) - } catch (error) { - expect(error.response.errors[0].message).toEqual('Wrong email/password combination') - } + afterEach(async () => { + await cleanDatabase() + }) + + describe('asking for a `token`', () => { + describe('with valid email/password combination', () => { + it('responds with a JWT token', async () => { + email = 'user@example.org' + password = '1234' + try { + await request(getHost(), mutation) + } catch (error) { + expect(error.response.errors[0].message).toEqual('Wrong email/password combination') + } + }) + }) + + describe('with a valid email but incorrect password', () => { + it('responds with "Wrong email/password combination"', async () => { + email = 'user@example.org' + password = 'wrong' + try { + await request(getHost(), mutation) + } catch (error) { + expect(error.response.errors[0].message).toEqual('Wrong email/password combination') + } + }) + }) + + describe('with a non-existing email', () => { + it('responds with "Wrong email/password combination"', async () => { + email = 'non-existent@example.org' + password = '1234' + try { + await request(getHost(), mutation) + } catch (error) { + expect(error.response.errors[0].message).toEqual('Wrong email/password combination') + } + }) }) }) }) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js new file mode 100644 index 000000000..fa7e924b9 --- /dev/null +++ b/src/seed/factories/index.js @@ -0,0 +1,43 @@ +import ApolloClient from 'apollo-client' +import gql from 'graphql-tag' +import dotenv from 'dotenv' +import { HttpLink } from 'apollo-link-http' +import { InMemoryCache } from 'apollo-cache-inmemory' +import neo4j from '../../bootstrap/neo4j' +import { query } from '../../graphql-schema' + +dotenv.config() + +if (process.env.NODE_ENV === 'production') { + throw new Error('YOU CAN`T RUN FACTORIES IN PRODUCTION MODE') +} + +const client = new ApolloClient({ + link: new HttpLink({ uri: process.env.GRAPHQL_URI, fetch }), + cache: new InMemoryCache() +}) + +const driver = neo4j().getDriver() +const session = driver.session() + +const builders = { + "user": require('./users.js').default, +} + +const buildMutation = (model, parameters) => { + return builders[model](parameters) +} + +const create = async (model, parameters) => { + await client.mutate({mutation: gql(buildMutation(model, parameters))}) +} + +const cleanDatabase = async () => { + await query('MATCH (n) DETACH DELETE n', session) +} + +export { + create, + buildMutation, + cleanDatabase +} diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js new file mode 100644 index 000000000..6b63b32e9 --- /dev/null +++ b/src/seed/factories/users.js @@ -0,0 +1,36 @@ +import faker from 'faker' + +export default function (params) { + const defaults = { + name: faker.name.findName(), + email: faker.internet.email(), + password: '1234', + avatar: faker.internet.avatar() + } + const { + name, + email, + password, + avatar + } = Object.assign({}, defaults, params) + + return ` + mutation { + u1: CreateUser( + id: "u1", + name: "${name}", + password: "${password}", + email: "${email}", + avatar: "${avatar}", + role: admin, + disabled: false, + deleted: false) { + id + name + email + avatar + role + } + } + ` +} diff --git a/src/server.js b/src/server.js index 3b0e0a561..88d04a0ea 100644 --- a/src/server.js +++ b/src/server.js @@ -52,7 +52,7 @@ const createServer = (options) => { schema: schema, tracing: true, middlewares: middleware(schema), - mocks: (process.env.MOCK === 'true') ? mocks : false + mocks: true } const server = new GraphQLServer(Object.assign({}, defaults, options)) diff --git a/yarn.lock b/yarn.lock index 75748a7f3..d4d640efc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -262,10 +262,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/node@~7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.2.0.tgz#0b601be8ef03897923e3908dc18129836d44e6fa" - integrity sha512-RFwVH5xWpwd4SfkOI0WsK9AnF5o+C9iMTvUkkTb7jUNaiDieV8BGK38t74bTPjgc4FCxSAWNKqaqgDW4fenkyA== +"@babel/node@~7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.2.2.tgz#1557dd23545b38d7b1d030a9c0e8fb225dbf70ab" + integrity sha512-jPqgTycE26uFsuWpLika9Ohz9dmLQHWjOnMNxBOjYb1HXO+eLKxEr5FfKSXH/tBvFwwaw+pzke3gagnurGOfCA== dependencies: "@babel/polyfill" "^7.0.0" "@babel/register" "^7.0.0" From a0b42d9061a40713900cb8f2faf8f779aaaa5ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 2 Jan 2019 13:38:51 +0100 Subject: [PATCH 190/554] Properly reproduce #49 --- src/graphql-schema.test.js | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index d75095daa..6ce4658b9 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -2,6 +2,7 @@ import { request } from 'graphql-request' import createServer from './server' import mocks from './mocks' import { create, cleanDatabase } from './seed/factories' +import jwt from 'jsonwebtoken' let getHost let app @@ -19,14 +20,16 @@ afterEach(async () => { }) describe.only('login', () => { - let email - let password - const mutation = ` + const mutation = (params) => { + const { email, password } = params + return ` mutation { login(email:"${email}", password:"${password}"){ token } }` + } + describe('given an existing user', () => { beforeEach(async () => { await create('user', { @@ -42,22 +45,19 @@ describe.only('login', () => { describe('asking for a `token`', () => { describe('with valid email/password combination', () => { it('responds with a JWT token', async () => { - email = 'user@example.org' - password = '1234' - try { - await request(getHost(), mutation) - } catch (error) { - expect(error.response.errors[0].message).toEqual('Wrong email/password combination') - } + const data = await request(getHost(), mutation({email: 'test@example.org', password: '1234'})) + const { token } = data.login + jwt.verify(token, process.env.JWT_SECRET, (err, data) => { + expect(data.email).toEqual('test@example.org') + expect(err).toBeNull() + }) }) }) describe('with a valid email but incorrect password', () => { it('responds with "Wrong email/password combination"', async () => { - email = 'user@example.org' - password = 'wrong' try { - await request(getHost(), mutation) + await request(getHost(), mutation({email: 'test@example.org', password: 'wrong'})) } catch (error) { expect(error.response.errors[0].message).toEqual('Wrong email/password combination') } @@ -66,10 +66,8 @@ describe.only('login', () => { describe('with a non-existing email', () => { it('responds with "Wrong email/password combination"', async () => { - email = 'non-existent@example.org' - password = '1234' try { - await request(getHost(), mutation) + await request(getHost(), mutation({email: 'non-existent@example.org', password: 'wrong'})) } catch (error) { expect(error.response.errors[0].message).toEqual('Wrong email/password combination') } From 70320f3c047bbbba265c6dc196d27c44ffe8429f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 2 Jan 2019 14:43:17 +0100 Subject: [PATCH 191/554] Undo mocks --- src/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server.js b/src/server.js index 88d04a0ea..3b0e0a561 100644 --- a/src/server.js +++ b/src/server.js @@ -52,7 +52,7 @@ const createServer = (options) => { schema: schema, tracing: true, middlewares: middleware(schema), - mocks: true + mocks: (process.env.MOCK === 'true') ? mocks : false } const server = new GraphQLServer(Object.assign({}, defaults, options)) From ec5cebf90f623f07a245f9db5846dad345eb3e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 2 Jan 2019 14:56:55 +0100 Subject: [PATCH 192/554] DRY code with ES6 --- src/seed/factories/users.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index 6b63b32e9..9af86f3a8 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -1,18 +1,12 @@ import faker from 'faker' -export default function (params) { - const defaults = { - name: faker.name.findName(), - email: faker.internet.email(), - password: '1234', - avatar: faker.internet.avatar() - } +export default function (params){ const { - name, - email, - password, - avatar - } = Object.assign({}, defaults, params) + name = faker.name.findName(), + email = faker.internet.email(), + password = '1234', + avatar = faker.internet.avatar() + } = params return ` mutation { From 7634234afd22e46267450eacc54077373ebbe6f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 2 Jan 2019 15:15:48 +0100 Subject: [PATCH 193/554] Match error message in tests with production code --- src/graphql-schema.js | 2 +- src/graphql-schema.test.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 830fda193..243d6b551 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -111,7 +111,7 @@ export const resolvers = { return Object.assign(currentUser, { token: generateJwt(currentUser) }) - } else throw new AuthenticationError('Incorrect username or password.') + } else throw new AuthenticationError('Incorrect email address or password.') }) } } diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index 6ce4658b9..52bbed901 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -55,21 +55,21 @@ describe.only('login', () => { }) describe('with a valid email but incorrect password', () => { - it('responds with "Wrong email/password combination"', async () => { + it('responds with "Incorrect email address or password."', async () => { try { await request(getHost(), mutation({email: 'test@example.org', password: 'wrong'})) } catch (error) { - expect(error.response.errors[0].message).toEqual('Wrong email/password combination') + expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') } }) }) describe('with a non-existing email', () => { - it('responds with "Wrong email/password combination"', async () => { + it('responds with "Incorrect email address or password."', async () => { try { await request(getHost(), mutation({email: 'non-existent@example.org', password: 'wrong'})) } catch (error) { - expect(error.response.errors[0].message).toEqual('Wrong email/password combination') + expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') } }) }) From 0185f743e8d64917d993a290d3acfa3adfc58b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 2 Jan 2019 15:59:32 +0100 Subject: [PATCH 194/554] Update README with a warning and fix package.json --- README.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1eb8cc528..55e79b2b1 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,9 @@ npm run db:reset ``` ## Run Tests + +**Beware**: We have no multiple database setup at the moment. We clean the database after each test, running the tests will wipe out all your data! + ```bash yarn run test # -or- diff --git a/package.json b/package.json index 4f4d457c5..ee388d0e6 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dev": "nodemon --exec babel-node src/index.js", "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "lint": "eslint src --config .eslintrc.js", - "test": "nyc --reporter=text-lcov test:jest", + "test": "nyc --reporter=text-lcov yarn run test:jest", "test:jest": "$npm_package_config_no_auth run-p --race start test:cmd:jest", "test:cmd:jest": "jest", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", From d98a05a4764e0762011d9a398c39476adced2d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 2 Jan 2019 16:01:25 +0100 Subject: [PATCH 195/554] Fix eslint --- src/graphql-schema.test.js | 8 ++++---- src/seed/factories/index.js | 5 +++-- src/seed/factories/users.js | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index 52bbed901..4956c3ab0 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -9,7 +9,7 @@ let app let port beforeEach(async () => { - const server = createServer({mocks}) + const server = createServer({ mocks }) app = await server.start({ port: 0 }) port = app.address().port getHost = () => `http://127.0.0.1:${port}` @@ -45,7 +45,7 @@ describe.only('login', () => { describe('asking for a `token`', () => { describe('with valid email/password combination', () => { it('responds with a JWT token', async () => { - const data = await request(getHost(), mutation({email: 'test@example.org', password: '1234'})) + const data = await request(getHost(), mutation({ email: 'test@example.org', password: '1234' })) const { token } = data.login jwt.verify(token, process.env.JWT_SECRET, (err, data) => { expect(data.email).toEqual('test@example.org') @@ -57,7 +57,7 @@ describe.only('login', () => { describe('with a valid email but incorrect password', () => { it('responds with "Incorrect email address or password."', async () => { try { - await request(getHost(), mutation({email: 'test@example.org', password: 'wrong'})) + await request(getHost(), mutation({ email: 'test@example.org', password: 'wrong' })) } catch (error) { expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') } @@ -67,7 +67,7 @@ describe.only('login', () => { describe('with a non-existing email', () => { it('responds with "Incorrect email address or password."', async () => { try { - await request(getHost(), mutation({email: 'non-existent@example.org', password: 'wrong'})) + await request(getHost(), mutation({ email: 'non-existent@example.org', password: 'wrong' })) } catch (error) { expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') } diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index fa7e924b9..d665de4a0 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -5,6 +5,7 @@ import { HttpLink } from 'apollo-link-http' import { InMemoryCache } from 'apollo-cache-inmemory' import neo4j from '../../bootstrap/neo4j' import { query } from '../../graphql-schema' +import fetch from 'node-fetch' dotenv.config() @@ -21,7 +22,7 @@ const driver = neo4j().getDriver() const session = driver.session() const builders = { - "user": require('./users.js').default, + 'user': require('./users.js').default } const buildMutation = (model, parameters) => { @@ -29,7 +30,7 @@ const buildMutation = (model, parameters) => { } const create = async (model, parameters) => { - await client.mutate({mutation: gql(buildMutation(model, parameters))}) + await client.mutate({ mutation: gql(buildMutation(model, parameters)) }) } const cleanDatabase = async () => { diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index 9af86f3a8..452059a73 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -1,10 +1,10 @@ import faker from 'faker' -export default function (params){ +export default function (params) { const { name = faker.name.findName(), email = faker.internet.email(), - password = '1234', + password = '1234', avatar = faker.internet.avatar() } = params From b787b639c77845076d55e9c26c896886251e0cd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 31 Dec 2018 19:19:28 +0000 Subject: [PATCH 196/554] Bump @babel/node from 7.2.0 to 7.2.2 Bumps [@babel/node](https://github.com/babel/babel) from 7.2.0 to 7.2.2. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.2.0...v7.2.2) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 41de1d7de..3c681d036 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "devDependencies": { "@babel/cli": "~7.2.0", "@babel/core": "~7.2.0", - "@babel/node": "~7.2.0", + "@babel/node": "~7.2.2", "@babel/preset-env": "~7.2.0", "@babel/register": "~7.0.0", "apollo-server-testing": "~2.2.6", diff --git a/yarn.lock b/yarn.lock index f9d341118..26d375496 100644 --- a/yarn.lock +++ b/yarn.lock @@ -251,10 +251,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/node@~7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.2.0.tgz#0b601be8ef03897923e3908dc18129836d44e6fa" - integrity sha512-RFwVH5xWpwd4SfkOI0WsK9AnF5o+C9iMTvUkkTb7jUNaiDieV8BGK38t74bTPjgc4FCxSAWNKqaqgDW4fenkyA== +"@babel/node@~7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.2.2.tgz#1557dd23545b38d7b1d030a9c0e8fb225dbf70ab" + integrity sha512-jPqgTycE26uFsuWpLika9Ohz9dmLQHWjOnMNxBOjYb1HXO+eLKxEr5FfKSXH/tBvFwwaw+pzke3gagnurGOfCA== dependencies: "@babel/polyfill" "^7.0.0" "@babel/register" "^7.0.0" From e9ec677527bee0f209405301d18b4994b137d028 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 2 Jan 2019 10:53:45 +0000 Subject: [PATCH 197/554] Bump @babel/cli from 7.2.0 to 7.2.3 Bumps [@babel/cli](https://github.com/babel/babel) from 7.2.0 to 7.2.3. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.2.0...v7.2.3) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 3c681d036..ec5f6c7c5 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "wait-on": "~3.2.0" }, "devDependencies": { - "@babel/cli": "~7.2.0", + "@babel/cli": "~7.2.3", "@babel/core": "~7.2.0", "@babel/node": "~7.2.2", "@babel/preset-env": "~7.2.0", diff --git a/yarn.lock b/yarn.lock index 26d375496..bea817e14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,10 +23,10 @@ resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz#022209e28a2b547dcde15b219f0c50f47aa5beb3" integrity sha512-lqK94b+caNtmKFs5oUVXlSpN3sm5IXZ+KfhMxOtr0LR2SqErzkoJilitjDvJ1WbjHlxLI7WtCjRmOLdOGJqtMQ== -"@babel/cli@~7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.2.0.tgz#505ed8d351daee6a88918da02c046c18c8c5a24f" - integrity sha512-FLteTkEoony0DX8NbnT51CmwmLBzINdlXmiJCSqCLmqWCDA/xk8EITPWqwDnVLbuK0bsZONt/grqHnQzQ15j0Q== +"@babel/cli@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.2.3.tgz#1b262e42a3e959d28ab3d205ba2718e1923cfee6" + integrity sha512-bfna97nmJV6nDJhXNPeEfxyMjWnt6+IjUAaDPiYRTBlm8L41n8nvw6UAqUCbvpFfU246gHPxW7sfWwqtF4FcYA== dependencies: commander "^2.8.1" convert-source-map "^1.1.0" From 1bd5b2a8d8a41a514cb40e4fcca2008f2fc6a405 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 2 Jan 2019 11:10:31 +0000 Subject: [PATCH 198/554] Bump @babel/preset-env from 7.2.0 to 7.2.3 Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.2.0 to 7.2.3. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.2.0...v7.2.3) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ec5f6c7c5..320af5981 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "@babel/cli": "~7.2.3", "@babel/core": "~7.2.0", "@babel/node": "~7.2.2", - "@babel/preset-env": "~7.2.0", + "@babel/preset-env": "~7.2.3", "@babel/register": "~7.0.0", "apollo-server-testing": "~2.2.6", "babel-eslint": "~10.0.1", diff --git a/yarn.lock b/yarn.lock index bea817e14..5cb6126cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -560,10 +560,10 @@ core-js "^2.5.7" regenerator-runtime "^0.11.1" -"@babel/preset-env@~7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.2.0.tgz#a5030e7e4306af5a295dd5d7c78dc5464af3fee2" - integrity sha512-haGR38j5vOGVeBatrQPr3l0xHbs14505DcM57cbJy48kgMFvvHHoYEhHuRV+7vi559yyAUAVbTWzbK/B/pzJng== +"@babel/preset-env@~7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.2.3.tgz#948c8df4d4609c99c7e0130169f052ea6a7a8933" + integrity sha512-AuHzW7a9rbv5WXmvGaPX7wADxFkZIqKlbBh1dmZUQp4iwiPpkE/Qnrji6SC4UQCQzvWY/cpHET29eUhXS9cLPw== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" From 0b623cf0836c82379a8cd23c26902dca57e836b5 Mon Sep 17 00:00:00 2001 From: Gerald Michelant Date: Thu, 27 Dec 2018 17:21:18 -0500 Subject: [PATCH 199/554] capture error in readable format with try and catch --- src/graphql-schema.js | 46 ++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index b52c9e232..7d2a8ce5f 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -5,6 +5,7 @@ import bcrypt from 'bcryptjs' import zipObject from 'lodash/zipObject' import generateJwt from './jwt/generateToken' import { fixUrl } from './middleware/fixImageUrlsMiddleware' +import { AuthenticationError } from 'apollo-server' export const typeDefs = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, 'schema.graphql')) @@ -95,32 +96,33 @@ export const resolvers = { // if (user && user.id) { // throw new Error('Already logged in.') // } - const session = driver.session() - const res = await session.run('MATCH (u:User {email: "' + email + '"}) RETURN u.id, u.slug, u.name, u.avatar, u.email, u.password, u.role LIMIT 1') - let u = res.records[0]._fields ? zipObject([ - 'id', - 'slug', - 'name', - 'avatar', - 'email', - 'password', - 'role' - ], res.records[0]._fields) : null - if (u) { - if (await bcrypt.compareSync(password, u.password)) { - delete u.password - u.avatar = fixUrl(u.avatar) - return Object.assign(u, { - token: generateJwt(u) - }) + try { + const res = await session.run('MATCH (u:User {email: "' + email + '"}) RETURN u.id, u.slug, u.name, u.avatar, u.email, u.password, u.role LIMIT 1') + const u = res.records[0]._fields ? zipObject([ + 'id', + 'slug', + 'name', + 'avatar', + 'email', + 'password', + 'role' + ], res.records[0]._fields) : null + if (u) { + if (await bcrypt.compareSync(password, u.password)) { + delete u.password + u.avatar = fixUrl(u.avatar) + return Object.assign(u, { + token: generateJwt(u) + }) + } + session.close() + throw new Error('Incorrect username or password.') } session.close() - throw new Error('Incorrect password.') + } catch (error) { + throw new AuthenticationError('Incorrect username or password.') } - - session.close() - throw new Error('No Such User exists.') } } } From 57d9088c6cbc293a4ab01844ee68cd400cd0ca27 Mon Sep 17 00:00:00 2001 From: Gerald Michelant Date: Fri, 28 Dec 2018 22:17:28 -0500 Subject: [PATCH 200/554] throw new AuthenticationError on password error --- src/graphql-schema.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 7d2a8ce5f..c298177c2 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -117,7 +117,7 @@ export const resolvers = { }) } session.close() - throw new Error('Incorrect username or password.') + throw new AuthenticationError('Incorrect username or password.') } session.close() } catch (error) { From da1860bcd043c84ca2d925ea0b5b331b9730c2b7 Mon Sep 17 00:00:00 2001 From: Gerald Michelant Date: Sun, 30 Dec 2018 16:44:08 -0500 Subject: [PATCH 201/554] rewritting of login method --- src/graphql-schema.js | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index c298177c2..830fda193 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -2,7 +2,6 @@ import fs from 'fs' import path from 'path' import bcrypt from 'bcryptjs' -import zipObject from 'lodash/zipObject' import generateJwt from './jwt/generateToken' import { fixUrl } from './middleware/fixImageUrlsMiddleware' import { AuthenticationError } from 'apollo-server' @@ -97,32 +96,23 @@ export const resolvers = { // throw new Error('Already logged in.') // } const session = driver.session() - try { - const res = await session.run('MATCH (u:User {email: "' + email + '"}) RETURN u.id, u.slug, u.name, u.avatar, u.email, u.password, u.role LIMIT 1') - const u = res.records[0]._fields ? zipObject([ - 'id', - 'slug', - 'name', - 'avatar', - 'email', - 'password', - 'role' - ], res.records[0]._fields) : null - if (u) { - if (await bcrypt.compareSync(password, u.password)) { - delete u.password - u.avatar = fixUrl(u.avatar) - return Object.assign(u, { - token: generateJwt(u) - }) - } + return session.run( + 'MATCH (user:User {email: "' + email + '"}) ' + + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1') + .then(async (result) => { session.close() - throw new AuthenticationError('Incorrect username or password.') - } - session.close() - } catch (error) { - throw new AuthenticationError('Incorrect username or password.') - } + const [currentUser] = await result.records.map(function (record) { + console.log(record.get('user')) + return record.get('user') + }) + if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { + delete currentUser.password + currentUser.avatar = fixUrl(currentUser.avatar) + return Object.assign(currentUser, { + token: generateJwt(currentUser) + }) + } else throw new AuthenticationError('Incorrect username or password.') + }) } } } From 4f4b6e546900cbd913b930bbe025c0ed8fa8e0ba Mon Sep 17 00:00:00 2001 From: Gerald Michelant Date: Wed, 2 Jan 2019 10:04:45 -0500 Subject: [PATCH 202/554] changed method to inject variable to login --- src/graphql-schema.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 830fda193..eabde7a6b 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -97,8 +97,8 @@ export const resolvers = { // } const session = driver.session() return session.run( - 'MATCH (user:User {email: "' + email + '"}) ' + - 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1') + 'MATCH (user:User {email: $userEmail}) ' + + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', { userEmail: email }) .then(async (result) => { session.close() const [currentUser] = await result.records.map(function (record) { From 363105281b6a365ac1230e05d8e7780c67c04202 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 3 Jan 2019 04:33:35 +0000 Subject: [PATCH 203/554] Bump eslint from 5.10.0 to 5.11.1 Bumps [eslint](https://github.com/eslint/eslint) from 5.10.0 to 5.11.1. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v5.10.0...v5.11.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 320af5981..802c3a7a3 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "apollo-server-testing": "~2.2.6", "babel-eslint": "~10.0.1", "chai": "~4.2.0", - "eslint": "~5.10.0", + "eslint": "~5.11.1", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.14.0", "eslint-plugin-node": "~8.0.0", diff --git a/yarn.lock b/yarn.lock index 5cb6126cb..299174d7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2425,10 +2425,10 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@~5.10.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.10.0.tgz#24adcbe92bf5eb1fc2d2f2b1eebe0c5e0713903a" - integrity sha512-HpqzC+BHULKlnPwWae9MaVZ5AXJKpkxCVXQHrFaRw3hbDj26V/9ArYM4Rr/SQ8pi6qUPLXSSXC4RBJlyq2Z2OQ== +eslint@~5.11.1: + version "5.11.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.11.1.tgz#8deda83db9f354bf9d3f53f9677af7e0e13eadda" + integrity sha512-gOKhM8JwlFOc2acbOrkYR05NW8M6DCMSvfcJiBB5NDxRE1gv8kbvxKaC9u69e6ZGEMWXcswA/7eKR229cEIpvg== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.5.3" From 7f567be64ff620a6b360fe0878af44314e45156c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 3 Jan 2019 06:55:44 +0000 Subject: [PATCH 204/554] Bump neo4j-graphql-js from 2.0.1 to 2.1.1 Bumps [neo4j-graphql-js](https://github.com/neo4j-graphql/neo4j-graphql-js) from 2.0.1 to 2.1.1. - [Release notes](https://github.com/neo4j-graphql/neo4j-graphql-js/releases) - [Changelog](https://github.com/neo4j-graphql/neo4j-graphql-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/neo4j-graphql/neo4j-graphql-js/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 802c3a7a3..79702620d 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "lodash": "~4.17.11", "ms": "~2.1.1", "neo4j-driver": "~1.7.2", - "neo4j-graphql-js": "~2.0.1", + "neo4j-graphql-js": "~2.1.1", "node-fetch": "~2.3.0", "passport": "~0.4.0", "passport-jwt": "~4.0.0", diff --git a/yarn.lock b/yarn.lock index 299174d7f..2fd159272 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4354,10 +4354,10 @@ neo4j-driver@^1.7.2, neo4j-driver@~1.7.2: text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-graphql-js@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.0.1.tgz#76e10947873e1fde2e4f8427fe8d6a066aea2ce4" - integrity sha512-IadLuuQc4wo9DGqn8fhFoEp1wauTZlbYb975WXjIe5V3j6+Dd70LkgZjSg/BJb+ikv7td774ZsU7d6dQFo8Plw== +neo4j-graphql-js@~2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.1.1.tgz#bdb1af2fb45d1058492852ed9307586f6deab37d" + integrity sha512-OcDaFIfOKZF02jmxnWWTLQr64mu79RGAtDULfciwElW59GjRF425M2Yf4gLJuQFscnh7d+Qk/+Ng+jVbz+V4lA== dependencies: graphql "^14.0.2" lodash "^4.17.11" From 9fdee4480fea582a01e40687cffff404b749a8f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 3 Jan 2019 11:50:20 +0100 Subject: [PATCH 205/554] Setup neo4j service on Travis CI --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index eaba8dba3..3ce3b413c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ cache: - node_modules services: - docker + - neo4j env: - DOCKER_COMPOSE_VERSION=1.23.2 From d6622d082559fcb99d6391821b29ccb351c4a26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 3 Jan 2019 13:53:44 +0100 Subject: [PATCH 206/554] Revert "Setup neo4j service on Travis CI" This reverts commit 9fdee4480fea582a01e40687cffff404b749a8f1. @mattwr18 this was a rash decision, neo4j on Travis is not required if we run all the tests in docker. When I run the tests in docker on my machine, it terminates as expected. How is the situation on your machine? --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3ce3b413c..eaba8dba3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ cache: - node_modules services: - docker - - neo4j env: - DOCKER_COMPOSE_VERSION=1.23.2 From 5c88037d5ca82d6d7a7bb83948177de4ac58c3b4 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 3 Jan 2019 15:27:26 +0100 Subject: [PATCH 207/554] WIP - first try to create a report mutation which attaches nodes internally --- src/graphql-schema.js | 7 ++++ src/middleware/permissionsMiddleware.js | 9 +++-- src/schema.graphql | 22 ++++++++++++ src/seed/data/index.js | 4 ++- src/seed/data/reports.js | 45 +++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 src/seed/data/reports.js diff --git a/src/graphql-schema.js b/src/graphql-schema.js index b52c9e232..7a3e65e3c 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -5,6 +5,7 @@ import bcrypt from 'bcryptjs' import zipObject from 'lodash/zipObject' import generateJwt from './jwt/generateToken' import { fixUrl } from './middleware/fixImageUrlsMiddleware' +import { neo4jgraphql } from 'neo4j-graphql-js' export const typeDefs = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, 'schema.graphql')) @@ -121,6 +122,12 @@ export const resolvers = { session.close() throw new Error('No Such User exists.') + }, + report: async (parent, { resource, description }, { driver, req, user }, resolveInfo) => { + return neo4jgraphql(parent, { resource, description }, { driver, req, user }, resolveInfo) + // console.log('params', { resource, description }) + // console.log(`the user with the id ${user.id} tries to create a report on content of type ${resource.type} (${resource.id})`) + // throw new Error(`resource.id: ${resource.id}, resource.type: ${resource.type}, description: ${description}, user: ${user.id}`) } } } diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 5b0cb87d2..a0051e856 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -1,11 +1,13 @@ import { rule, shield, allow } from 'graphql-shield' /* - * TODO: implement - * See: https://github.com/Human-Connection/Nitro-Backend/pull/40#pullrequestreview-180898363 +* TODO: implement +* See: https://github.com/Human-Connection/Nitro-Backend/pull/40#pullrequestreview-180898363 +*/ const isAuthenticated = rule()(async (parent, args, ctx, info) => { return ctx.user !== null }) +/* const isAdmin = rule()(async (parent, args, ctx, info) => { return ctx.user.role === 'ADMIN' }) @@ -26,8 +28,9 @@ const permissions = shield({ // customers: and(isAuthenticated, isAdmin) }, Mutation: { + report: isAuthenticated // addFruitToBasket: isAuthenticated - // CreateUser: allow + // CreateUser: allow, }, User: { email: isOwner, diff --git a/src/schema.graphql b/src/schema.graphql index bc6a3829c..978981c6f 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -5,6 +5,7 @@ type Query { type Mutation { login(email: String!, password: String!): LoggedInUser signup(email: String!, password: String!): Boolean! + report(resource: Resource!, description: String): Report } type LoggedInUser { id: ID! @@ -32,6 +33,17 @@ scalar Date scalar Time scalar DateTime +input Resource { + id: ID!, + type: _ResourceType! +} + +enum _ResourceType { + contribution + comment + user +} + enum VisibilityEnum { public friends @@ -138,6 +150,16 @@ type Comment { disabled: Boolean } +type Report { + id: ID! + author: User @relation(name: "REPORTED", direction: "IN") + description: String + createdAt: String + comment: Comment @relation(name: "REPORTED", direction: "OUT") + contribution: Post @relation(name: "REPORTED", direction: "OUT") + user: User @relation(name: "REPORTED", direction: "OUT") +} + type Category { id: ID! name: String! diff --git a/src/seed/data/index.js b/src/seed/data/index.js index e66342fe3..e67ceb59e 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -15,7 +15,9 @@ const seed = { Organization: require('./organizations.js').default, Post: require('./posts.js').default, Comment: require('./comments.js').default, - UserShouts: require('./users-shouts.js').default + UserShouts: require('./users-shouts.js').default, + + Reports: require('./reports.js').default } let data = {} diff --git a/src/seed/data/reports.js b/src/seed/data/reports.js new file mode 100644 index 000000000..939fe087b --- /dev/null +++ b/src/seed/data/reports.js @@ -0,0 +1,45 @@ +export default function (data) { + return ` + mutation { + r1: CreateReport(id: "r1", description: "Bad Stuff") { + id + } + r2: CreateReport(id: "r2", description: "Please remove this sh**") { + id + } + r3: CreateReport(id: "r3", description: "The user have misbehaved!") { + id + } + ra1: AddReportAuthor(from: { id: "u1" }, to: { id: "r1" }) { + from { + id + } + } + ra2: AddReportAuthor(from: { id: "u2" }, to: { id: "r2" }) { + from { + id + } + } + ra3: AddReportAuthor(from: { id: "u3" }, to: { id: "r3" }) { + from { + id + } + } + rc1: AddReportContribution(from: { id: "r1" }, to: { id: "p2" }) { + from { + id + } + } + rc2: AddReportComment(from: { id: "r2" }, to: { id: "c2" }) { + from { + id + } + } + rc3: AddReportUser(from: { id: "r3" }, to: { id: "u4" }) { + from { + id + } + } + } + ` +} From 6cc6538758d083e864e5713a16d51ced788e2670 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 3 Jan 2019 17:30:18 +0100 Subject: [PATCH 208/554] Add forgotten schema file --- src/graphql-schema.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 7a3e65e3c..c23cd1f8f 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -124,10 +124,10 @@ export const resolvers = { throw new Error('No Such User exists.') }, report: async (parent, { resource, description }, { driver, req, user }, resolveInfo) => { - return neo4jgraphql(parent, { resource, description }, { driver, req, user }, resolveInfo) - // console.log('params', { resource, description }) - // console.log(`the user with the id ${user.id} tries to create a report on content of type ${resource.type} (${resource.id})`) - // throw new Error(`resource.id: ${resource.id}, resource.type: ${resource.type}, description: ${description}, user: ${user.id}`) + // return neo4jgraphql(parent, { resource, description }, { driver, req, user }, resolveInfo) + console.log('params', { resource, description }) + console.log(`the user with the id ${user.id} tries to create a report on content of type ${resource.type} (${resource.id})`) + throw new Error(`resource.id: ${resource.id}, resource.type: ${resource.type}, description: ${description}, user: ${user.id}`) } } } From 3a9cb31e1f6039aecd428b2fc250b4b88a18ccfa Mon Sep 17 00:00:00 2001 From: kachulio1 Date: Thu, 3 Jan 2019 20:29:37 +0300 Subject: [PATCH 209/554] add afterAll to make CI pass --- src/graphql-schema.test.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index 4956c3ab0..f8207ffa5 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -8,15 +8,17 @@ let getHost let app let port -beforeEach(async () => { +beforeEach(async (done) => { const server = createServer({ mocks }) app = await server.start({ port: 0 }) port = app.address().port getHost = () => `http://127.0.0.1:${port}` + done() }) -afterEach(async () => { +afterAll(async (done) => { await app.close() + done() }) describe.only('login', () => { @@ -31,45 +33,50 @@ describe.only('login', () => { } describe('given an existing user', () => { - beforeEach(async () => { + beforeEach(async (done) => { await create('user', { email: 'test@example.org', password: '1234' }) + done() }) - afterEach(async () => { + afterEach(async (done) => { await cleanDatabase() + done() }) describe('asking for a `token`', () => { describe('with valid email/password combination', () => { - it('responds with a JWT token', async () => { + it('responds with a JWT token', async (done) => { const data = await request(getHost(), mutation({ email: 'test@example.org', password: '1234' })) const { token } = data.login jwt.verify(token, process.env.JWT_SECRET, (err, data) => { expect(data.email).toEqual('test@example.org') expect(err).toBeNull() + done() }) }) }) describe('with a valid email but incorrect password', () => { - it('responds with "Incorrect email address or password."', async () => { + it('responds with "Incorrect email address or password."', async (done) => { try { await request(getHost(), mutation({ email: 'test@example.org', password: 'wrong' })) } catch (error) { expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') + done() } }) }) describe('with a non-existing email', () => { - it('responds with "Incorrect email address or password."', async () => { + it('responds with "Incorrect email address or password."', async (doen) => { try { await request(getHost(), mutation({ email: 'non-existent@example.org', password: 'wrong' })) } catch (error) { expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') + done() } }) }) From e1070e15f295027a76ee271a1d7f00bc49e85d73 Mon Sep 17 00:00:00 2001 From: kachulio1 Date: Thu, 3 Jan 2019 20:52:47 +0300 Subject: [PATCH 210/554] add done on async test --- package.json | 4 ++-- src/graphql-schema.test.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2d274daac..7dc67ec26 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,9 @@ "dev": "nodemon --exec babel-node src/index.js", "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "lint": "eslint src --config .eslintrc.js", - "test": "nyc --reporter=text-lcov yarn run test:jest", + "test": "nyc --reporter=text-lcov yarn run test:jest", "test:jest": "$npm_package_config_no_auth run-p --race start test:cmd:jest", - "test:cmd:jest": "jest", + "test:cmd:jest": "jest --forceExit", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index f8207ffa5..76050a2a8 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -71,7 +71,7 @@ describe.only('login', () => { }) describe('with a non-existing email', () => { - it('responds with "Incorrect email address or password."', async (doen) => { + it('responds with "Incorrect email address or password."', async (done) => { try { await request(getHost(), mutation({ email: 'non-existent@example.org', password: 'wrong' })) } catch (error) { From 96d9bb49bcee17cf08e5b37c770bcc4b810d4d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 3 Jan 2019 23:55:05 +0100 Subject: [PATCH 211/554] Revert "add afterAll to make CI pass" This reverts commit 3a9cb31e1f6039aecd428b2fc250b4b88a18ccfa. See https://github.com/Human-Connection/Nitro-Backend/pull/88#discussion_r245157595 --- src/graphql-schema.test.js | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index 76050a2a8..4956c3ab0 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -8,17 +8,15 @@ let getHost let app let port -beforeEach(async (done) => { +beforeEach(async () => { const server = createServer({ mocks }) app = await server.start({ port: 0 }) port = app.address().port getHost = () => `http://127.0.0.1:${port}` - done() }) -afterAll(async (done) => { +afterEach(async () => { await app.close() - done() }) describe.only('login', () => { @@ -33,50 +31,45 @@ describe.only('login', () => { } describe('given an existing user', () => { - beforeEach(async (done) => { + beforeEach(async () => { await create('user', { email: 'test@example.org', password: '1234' }) - done() }) - afterEach(async (done) => { + afterEach(async () => { await cleanDatabase() - done() }) describe('asking for a `token`', () => { describe('with valid email/password combination', () => { - it('responds with a JWT token', async (done) => { + it('responds with a JWT token', async () => { const data = await request(getHost(), mutation({ email: 'test@example.org', password: '1234' })) const { token } = data.login jwt.verify(token, process.env.JWT_SECRET, (err, data) => { expect(data.email).toEqual('test@example.org') expect(err).toBeNull() - done() }) }) }) describe('with a valid email but incorrect password', () => { - it('responds with "Incorrect email address or password."', async (done) => { + it('responds with "Incorrect email address or password."', async () => { try { await request(getHost(), mutation({ email: 'test@example.org', password: 'wrong' })) } catch (error) { expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') - done() } }) }) describe('with a non-existing email', () => { - it('responds with "Incorrect email address or password."', async (done) => { + it('responds with "Incorrect email address or password."', async () => { try { await request(getHost(), mutation({ email: 'non-existent@example.org', password: 'wrong' })) } catch (error) { expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') - done() } }) }) From e9bc848a334e30d4717c73325dd71f3d2bd39922 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 4 Jan 2019 15:14:51 +0100 Subject: [PATCH 212/554] Improved locale handling and moved MAPBOX_TOKEN to env --- .env.template | 1 + src/middleware/userMiddleware.js | 59 ++++++++++++++++++++++---------- src/schema.graphql | 9 ++--- src/server.js | 1 + 4 files changed, 48 insertions(+), 22 deletions(-) diff --git a/.env.template b/.env.template index 3ec0cbce9..8f05f50c1 100644 --- a/.env.template +++ b/.env.template @@ -7,3 +7,4 @@ CLIENT_URI=http://localhost:3000 MOCK=false JWT_SECRET=b/&&7b78BF&fv/Vd +MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ" diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 5e1f14493..56bb524c8 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -1,5 +1,11 @@ import request from 'request' -import zipObject from 'lodash/zipObject' + + +const asyncForEach = async (array, callback) => { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array) + } +} const fetch = url => { return new Promise((resolve, reject) => { @@ -13,15 +19,12 @@ const fetch = url => { }) } -const createOrUpdateLocations = async (userId, locationId, driver) =>{ - if (!locationId) { +const createOrUpdateLocations = async (userId, locationName, driver) =>{ + if (!locationName) { return } - console.log('userId', userId) - console.log('locationId', locationId) - - const mapboxToken = 'pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ' - const res = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${locationId}.json?access_token=${mapboxToken}&language=de`) + const mapboxToken = process.env.MAPBOX_TOKEN + const res = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${locationName}.json?access_token=${mapboxToken}&language=de`) // TODO: create location in db @@ -29,15 +32,35 @@ const createOrUpdateLocations = async (userId, locationId, driver) =>{ const data = res.features[0] const session = driver.session() - const r = await session.run(`MERGE (l:Location {id: "${data.id}"}) SET l.name = "${data.place_name}", l.type = "${data.place_type[0]}", l.lat = "${data.center[0]}", l.lng = "${data.center[1]}" RETURN l.id, l.name, l.type, l.lat, l.lng`) - // let location = r.records[0]._fields ? zipObject([ - // 'id', - // 'name', - // 'type', - // 'lat', - // 'lng' - // ], r.records[0]._fields) : null + await session.run( + `MERGE (l:Location {id: "${data.id}"}) ` + + `SET l.name = "${data.text}", ` + + `l.type = "${data.place_type[0].toLowerCase()}", ` + + `l.lat = "${data.center[0]}", ` + + `l.lng = "${data.center[1]}" ` + + 'RETURN l.id, l.name, l.type, l.lat, l.lng' + ) + let parent = data + + if (data.context) { + await asyncForEach(data.context, async ctx => { + const type = ctx.id.split('.')[0].toLowerCase() + await session.run( + `MERGE (l:Location {id: "${ctx.id}"}) ` + + `SET l.name = "${ctx.text}", ` + + `l.type = "${type}", ` + + `l.shortCode = "${ctx.short_code}" ` + + 'RETURN l.id, l.name, l.type' + ) + await session.run( + `MATCH (parent:Location {id: "${parent.id}"}), (child:Location {id: "${ctx.id}"}) ` + + 'MERGE (child)<-[:IS_IN]-(parent) ' + + 'RETURN child.id, parent.id') + + parent = ctx + }) + } // delete all current locations from user await session.run(`MATCH (u:User {id: "${userId}"})-[r:IS_IN]->(l:Location) DETACH DELETE r`) // connect user with location @@ -49,12 +72,12 @@ export default { Mutation: { CreateUser: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) - await createOrUpdateLocations(context.user.id, args.locationId, context.driver) + await createOrUpdateLocations(context.user.id, args.locationName, context.driver) return result }, UpdateUser: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) - await createOrUpdateLocations(context.user.id, args.locationId, context.driver) + await createOrUpdateLocations(context.user.id, args.locationName, context.driver) return result } } diff --git a/src/schema.graphql b/src/schema.graphql index 5ee0412a9..48b3c4302 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -50,8 +50,9 @@ type Location { id: ID! name: String! type: String! - lat: Float! - lng: Float! + lat: Float + lng: Float + parent: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l") } type User { @@ -65,8 +66,8 @@ type User { disabled: Boolean role: UserGroupEnum - location: [Location] @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l") - locationId: String + location: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l") + locationName: String about: String createdAt: String diff --git a/src/server.js b/src/server.js index 3b0e0a561..1175509e7 100644 --- a/src/server.js +++ b/src/server.js @@ -51,6 +51,7 @@ const createServer = (options) => { }, schema: schema, tracing: true, + debug: process.env.NODE_ENV !== 'production', middlewares: middleware(schema), mocks: (process.env.MOCK === 'true') ? mocks : false } From 30d4318d1738796b4c1f299a15fa8248e7da7002 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 4 Jan 2019 15:15:07 +0100 Subject: [PATCH 213/554] Throw an error if requried env vars are missing --- src/server.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/server.js b/src/server.js index 1175509e7..eff18f8d0 100644 --- a/src/server.js +++ b/src/server.js @@ -14,6 +14,13 @@ import jwtStrategy from './jwt/strategy' import jwt from 'jsonwebtoken' dotenv.config() +// check env and warn +const requiredEnvVars = ['MAPBOX_TOKEN', 'JWT_SECRET'] +requiredEnvVars.forEach(env => { + if (!process.env[env]) { + throw new Error(`ERROR: "${env}" env variable is missing`) + } +}) let schema = makeExecutableSchema({ typeDefs, From 486e01ddce9579e93a1a38b38f94bf16b3d621e4 Mon Sep 17 00:00:00 2001 From: Mike Aono Date: Sat, 5 Jan 2019 18:57:24 +0300 Subject: [PATCH 214/554] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 1eb8cc528..8b600351f 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,9 @@ Connect with other developers over [Discord](https://discord.gg/6ub73U3) ## Quick Start +### Forking the repository +Before you start, fork the repository using the fork button above, then clone it to your local machine using `git clone https://github.com/your-username/Nitro-Backend.git` + ### Installation with Docker Run: From 5fd5795f39125daf422d055631a5c04af24c3fbd Mon Sep 17 00:00:00 2001 From: Daksh Miglani Date: Mon, 7 Jan 2019 12:48:47 +0530 Subject: [PATCH 215/554] fix jwt strategy --- src/jwt/strategy.js | 31 +++++++++++++++++++++---------- src/server.js | 2 +- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/jwt/strategy.js b/src/jwt/strategy.js index 0807c3fd1..e2dccc91f 100644 --- a/src/jwt/strategy.js +++ b/src/jwt/strategy.js @@ -1,4 +1,5 @@ import { Strategy } from 'passport-jwt' +import { fixUrl } from '../middleware/fixImageUrlsMiddleware' const cookieExtractor = (req) => { var token = null @@ -8,7 +9,7 @@ const cookieExtractor = (req) => { return token } -export default () => { +export default (driver) => { const options = { jwtFromRequest: cookieExtractor, secretOrKey: process.env.JWT_SECRET, @@ -17,16 +18,26 @@ export default () => { } return new Strategy(options, - (JWTPayload, next) => { - // usually this would be a database call: - // var user = users[_.findIndex(users, {id: JWTPayload.id})] - // TODO: fix https://github.com/Human-Connection/Nitro-Backend/issues/41 - /* eslint-disable */ - if (true) { - /* eslint-enable */ - next(null, {}) + async (JWTPayload, next) => { + const session = driver.session(); + const result = await session.run( + 'MATCH (user:User {id: $userId}) ' + + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', + { + id: JWTPayload.id + } + ); + session.close(); + const [currentUser] = await result.records.map((record) => { + return record.get("user"); + }); + + if (currentUser) { + delete currentUser.password; + currentUser.avatar = fixUrl(currentUser.avatar) + return next(null, currentUser); } else { - next(null, false) + return next(null, false); } }) } diff --git a/src/server.js b/src/server.js index 3b0e0a561..860a4f8c4 100644 --- a/src/server.js +++ b/src/server.js @@ -56,7 +56,7 @@ const createServer = (options) => { } const server = new GraphQLServer(Object.assign({}, defaults, options)) - passport.use('jwt', jwtStrategy()) + passport.use('jwt', jwtStrategy(driver)) server.express.use(passport.initialize()) server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) From 016119e7689e0af9ccf0ff9ffd1083ed71b3190a Mon Sep 17 00:00:00 2001 From: Daksh Date: Mon, 7 Jan 2019 13:00:19 +0530 Subject: [PATCH 216/554] fix variableName from id to userId --- src/jwt/strategy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jwt/strategy.js b/src/jwt/strategy.js index e2dccc91f..d08b7988f 100644 --- a/src/jwt/strategy.js +++ b/src/jwt/strategy.js @@ -24,7 +24,7 @@ export default (driver) => { 'MATCH (user:User {id: $userId}) ' + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', { - id: JWTPayload.id + userId: JWTPayload.id } ); session.close(); From b6511b9a03c6b1c039f64b8403ef266100c3b86d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 7 Jan 2019 16:06:35 +0000 Subject: [PATCH 217/554] Bump apollo-client from 2.4.7 to 2.4.8 Bumps [apollo-client](https://github.com/apollographql/apollo-client) from 2.4.7 to 2.4.8. - [Release notes](https://github.com/apollographql/apollo-client/releases) - [Changelog](https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-client/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 7dc67ec26..5636e1283 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "license": "MIT", "dependencies": { "apollo-cache-inmemory": "~1.3.11", - "apollo-client": "~2.4.7", + "apollo-client": "~2.4.8", "apollo-link-http": "~1.5.9", "apollo-server": "~2.3.1", "bcryptjs": "~2.4.3", diff --git a/yarn.lock b/yarn.lock index 9855f96c8..1d861e0e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1023,23 +1023,23 @@ apollo-cache-inmemory@~1.3.11: apollo-utilities "^1.0.26" optimism "^0.6.6" -apollo-cache@1.1.21, apollo-cache@^1.1.21: - version "1.1.21" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.21.tgz#950025e2272741ba8e5064419906e3ac4072925d" - integrity sha512-5ErNb78KHtrJNimkDBTEigcvHkIqUmS7QJIk4lpZZ+XLVVgvk2fD+GhD1PLP+s8vHfAKVbO6vdbRxCCjGGrh5w== +apollo-cache@1.1.22, apollo-cache@^1.1.21: + version "1.1.22" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.22.tgz#d4682ea6e8b2508a934f61c2fd9e36b4a65041d9" + integrity sha512-8PoxhQLISj2oHwT7i/r4l+ly4y3RKZls+dtXzAewu3U77P9dNZKhYkRNAhx9iEfsrNoHgXBV8vMp64hb1uYh+g== dependencies: - apollo-utilities "^1.0.26" + apollo-utilities "^1.0.27" -apollo-client@~2.4.7: - version "2.4.7" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.7.tgz#b6712fd4c9ba346e3c44cfec7e6868e532b6a957" - integrity sha512-6aAm+16AFBYZhJF8eKxrup6AbYni01InDiwTfZhMMTP2xaXQWjsQnfaHbI2oE+hd3+AZFy1drkse8RZKghR/WQ== +apollo-client@~2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.8.tgz#3a798f1076243465a59061d44d11bd030b68deb9" + integrity sha512-OAFbCTnGPtaIv0j+EZYzY20d+MD2JNbJ/YXZ4s0/oZlSg87bb0gjcIbccw2lnytipymZcZNr5ArFFeh0saGEwA== dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.21" + apollo-cache "1.1.22" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "1.0.26" + apollo-utilities "1.0.27" symbol-observable "^1.0.2" zen-observable "^0.8.0" optionalDependencies: @@ -1307,10 +1307,10 @@ apollo-upload-server@^5.0.0: busboy "^0.2.14" object-path "^0.11.4" -apollo-utilities@1.0.26, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.26: - version "1.0.26" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.26.tgz#589c66bf4d16223531351cf667a230c787def1da" - integrity sha512-URw7o3phymliqYCYatcird2YRPUU2eWCNvip64U9gQrX56mEfK4m99yBIDCMTpmcvOFsKLii1sIEZsHIs/bvnw== +apollo-utilities@1.0.27, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.26, apollo-utilities@^1.0.27: + version "1.0.27" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.27.tgz#77c550f9086552376eca3a48e234a1466b5b057e" + integrity sha512-nzrMQ89JMpNmYnVGJ4t8zN75gQbql27UDhlxNi+3OModp0Masx5g+fQmQJ5B4w2dpRuYOsdwFLmj3lQbwOKV1Q== dependencies: fast-json-stable-stringify "^2.0.0" From 77e77229b90f2babc6b9770e8bce63d7bc49de02 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 7 Jan 2019 17:30:54 +0100 Subject: [PATCH 218/554] Fixed login and schema --- src/graphql-schema.js | 5 +++-- src/schema.graphql | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 9f6b4fc29..cbeb6bb55 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -98,11 +98,12 @@ export const resolvers = { const session = driver.session() return session.run( 'MATCH (user:User {email: $userEmail}) ' + - 'RETURN user {.id, .slug, .name, .avatar, .locationId, .about, .email, .password, .role} as user LIMIT 1', { userEmail: email }) + 'RETURN user {.id, .slug, .name, .avatar, .locationName, .about, .email, .password, .role} as user LIMIT 1', { + userEmail: email + }) .then(async (result) => { session.close() const [currentUser] = await result.records.map(function (record) { - console.log(record.get('user')) return record.get('user') }) if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { diff --git a/src/schema.graphql b/src/schema.graphql index 48b3c4302..cdc8aa7a2 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -13,7 +13,7 @@ type LoggedInUser { avatar:String! email: String! role: String! - locationId: String + locationName: String about: String token: String! } From 9fab4a8fe712e7ff7a41e5e881d515321555a7eb Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 7 Jan 2019 17:34:18 +0100 Subject: [PATCH 219/554] Fixed injection issues --- src/middleware/userMiddleware.js | 49 ++++++++++++++++++++++---------- src/server.js | 2 +- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 56bb524c8..5bf0d5af9 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -33,12 +33,18 @@ const createOrUpdateLocations = async (userId, locationName, driver) =>{ const data = res.features[0] const session = driver.session() await session.run( - `MERGE (l:Location {id: "${data.id}"}) ` + - `SET l.name = "${data.text}", ` + - `l.type = "${data.place_type[0].toLowerCase()}", ` + - `l.lat = "${data.center[0]}", ` + - `l.lng = "${data.center[1]}" ` + - 'RETURN l.id, l.name, l.type, l.lat, l.lng' + 'MERGE (l:Location {id: $id}) ' + + 'SET l.name = $name, ' + + 'l.type = $type, ' + + 'l.lat = $lat, ' + + 'l.lng = $lng ' + + 'RETURN l.id, l.name, l.type, l.lat, l.lng', { + id: data.id, + name: data.text, + type: data.place_type[0].toLowerCase(), + lat: data.center[0], + lng: data.center[1] + } ) let parent = data @@ -47,24 +53,37 @@ const createOrUpdateLocations = async (userId, locationName, driver) =>{ await asyncForEach(data.context, async ctx => { const type = ctx.id.split('.')[0].toLowerCase() await session.run( - `MERGE (l:Location {id: "${ctx.id}"}) ` + - `SET l.name = "${ctx.text}", ` + - `l.type = "${type}", ` + - `l.shortCode = "${ctx.short_code}" ` + - 'RETURN l.id, l.name, l.type' + 'MERGE (l:Location {id: $id}) ' + + 'SET l.name = $name, ' + + 'l.type = $type, ' + + 'l.shortCode = $short_code ' + + 'RETURN l.id, l.name, l.type', { + id: ctx.id, + name: ctx.text, + type: type, + shortCode: ctx.short_code + } ) await session.run( - `MATCH (parent:Location {id: "${parent.id}"}), (child:Location {id: "${ctx.id}"}) ` + + 'MATCH (parent:Location {id: $parentId}), (child:Location {id: $childId}) ' + 'MERGE (child)<-[:IS_IN]-(parent) ' + - 'RETURN child.id, parent.id') + 'RETURN child.id, parent.id', { + parentId: parent.id, + childId: ctx.id + }) parent = ctx }) } // delete all current locations from user - await session.run(`MATCH (u:User {id: "${userId}"})-[r:IS_IN]->(l:Location) DETACH DELETE r`) + await session.run('MATCH (u:User {id: $userId})-[r:IS_IN]->(l:Location) DETACH DELETE r', { + userId: userId + }) // connect user with location - await session.run(`MATCH (u:User {id: "${userId}"}), (l:Location {id: "${data.id}"}) MERGE (u)-[:IS_IN]->(l) RETURN l.id, u.id`) + await session.run('MATCH (u:User {id: $userId}), (l:Location {id: $locationId}) MERGE (u)-[:IS_IN]->(l) RETURN l.id, u.id', { + userId: userId, + locationId: data.id + }) session.close() } diff --git a/src/server.js b/src/server.js index eff18f8d0..1ecab800e 100644 --- a/src/server.js +++ b/src/server.js @@ -18,7 +18,7 @@ dotenv.config() const requiredEnvVars = ['MAPBOX_TOKEN', 'JWT_SECRET'] requiredEnvVars.forEach(env => { if (!process.env[env]) { - throw new Error(`ERROR: "${env}" env variable is missing`) + throw new Error(`ERROR: "${env}" env variable is missing.`) } }) From cffce564ea265eb629161ea055245fe83c02d73d Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 7 Jan 2019 17:58:27 +0100 Subject: [PATCH 220/554] Fixed short_code --- src/middleware/userMiddleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 5bf0d5af9..d0cefc139 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -56,7 +56,7 @@ const createOrUpdateLocations = async (userId, locationName, driver) =>{ 'MERGE (l:Location {id: $id}) ' + 'SET l.name = $name, ' + 'l.type = $type, ' + - 'l.shortCode = $short_code ' + + 'l.shortCode = $shortCode ' + 'RETURN l.id, l.name, l.type', { id: ctx.id, name: ctx.text, From a313f941c5e13ecc36f6096e5f24c99a22763193 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 7 Jan 2019 20:25:05 +0100 Subject: [PATCH 221/554] Fixed eslint issue --- src/middleware/userMiddleware.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index d0cefc139..28c419837 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -1,6 +1,5 @@ import request from 'request' - const asyncForEach = async (array, callback) => { for (let index = 0; index < array.length; index++) { await callback(array[index], index, array) @@ -19,7 +18,7 @@ const fetch = url => { }) } -const createOrUpdateLocations = async (userId, locationName, driver) =>{ +const createOrUpdateLocations = async (userId, locationName, driver) => { if (!locationName) { return } From 2156b08e8fa0f79f94d87d0d2d0d6a4dadafdb43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 8 Jan 2019 14:20:05 +0100 Subject: [PATCH 222/554] Run `yarn run lint --fix` @DakshMiglani check the build server for any errors: https://travis-ci.com/Human-Connection/Nitro-Backend/builds/96505757#L658 Here you can see the build was fine, only eslint complained. Eslint is a quick fix :wink: --- src/jwt/strategy.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/jwt/strategy.js b/src/jwt/strategy.js index d08b7988f..65e2d35c1 100644 --- a/src/jwt/strategy.js +++ b/src/jwt/strategy.js @@ -19,25 +19,25 @@ export default (driver) => { return new Strategy(options, async (JWTPayload, next) => { - const session = driver.session(); + const session = driver.session() const result = await session.run( 'MATCH (user:User {id: $userId}) ' + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', { userId: JWTPayload.id } - ); - session.close(); + ) + session.close() const [currentUser] = await result.records.map((record) => { - return record.get("user"); - }); + return record.get('user') + }) if (currentUser) { - delete currentUser.password; + delete currentUser.password currentUser.avatar = fixUrl(currentUser.avatar) - return next(null, currentUser); + return next(null, currentUser) } else { - return next(null, false); + return next(null, false) } }) } From b5649ca2e3fda41d6c4d2ebc8a1c23248dcbf860 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 8 Jan 2019 14:34:00 +0100 Subject: [PATCH 223/554] Internationalized Locations --- src/middleware/userMiddleware.js | 53 ++++++++++++++++++++++++++------ src/schema.graphql | 8 +++++ 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 28c419837..c4cba0c63 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -1,4 +1,5 @@ import request from 'request' +import { UserInputError } from 'apollo-server' const asyncForEach = async (array, callback) => { for (let index = 0; index < array.length; index++) { @@ -23,23 +24,38 @@ const createOrUpdateLocations = async (userId, locationName, driver) => { return } const mapboxToken = process.env.MAPBOX_TOKEN - const res = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${locationName}.json?access_token=${mapboxToken}&language=de`) + const res = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(locationName)}.json?access_token=${mapboxToken}&types=region,place,country&language=en,de,fr,nl,it,es,pt,pl&limit=1`) - // TODO: create location in db - - // TODO: get related region, district and country to build the location tree + if (!res || !res.features || !res.features[0]) { + throw new UserInputError('locationName is invalid') + } const data = res.features[0] const session = driver.session() await session.run( 'MERGE (l:Location {id: $id}) ' + - 'SET l.name = $name, ' + + 'SET l.name = $nameEN, ' + + 'l.nameEN = $nameEN, ' + + 'l.nameDE = $nameDE, ' + + 'l.nameFR = $nameFR, ' + + 'l.nameNL = $nameNL, ' + + 'l.nameIT = $nameIT, ' + + 'l.nameES = $nameES, ' + + 'l.namePT = $namePT, ' + + 'l.namePL = $namePL, ' + 'l.type = $type, ' + 'l.lat = $lat, ' + 'l.lng = $lng ' + - 'RETURN l.id, l.name, l.type, l.lat, l.lng', { + 'RETURN l.id', { id: data.id, - name: data.text, + nameEN: data.text_en, + nameDE: data.text_de, + nameFR: data.text_fr, + nameNL: data.text_nl, + nameIT: data.text_it, + nameES: data.text_es, + namePT: data.text_pt, + namePL: data.text_pl, type: data.place_type[0].toLowerCase(), lat: data.center[0], lng: data.center[1] @@ -53,12 +69,27 @@ const createOrUpdateLocations = async (userId, locationName, driver) => { const type = ctx.id.split('.')[0].toLowerCase() await session.run( 'MERGE (l:Location {id: $id}) ' + - 'SET l.name = $name, ' + + 'SET l.name = $nameEN, ' + + 'l.nameEN = $nameEN, ' + + 'l.nameDE = $nameDE, ' + + 'l.nameFR = $nameFR, ' + + 'l.nameNL = $nameNL, ' + + 'l.nameIT = $nameIT, ' + + 'l.nameES = $nameES, ' + + 'l.namePT = $namePT, ' + + 'l.namePL = $namePL, ' + 'l.type = $type, ' + 'l.shortCode = $shortCode ' + - 'RETURN l.id, l.name, l.type', { + 'RETURN l.id', { id: ctx.id, - name: ctx.text, + nameEN: ctx.text_en, + nameDE: ctx.text_de, + nameFR: ctx.text_fr, + nameNL: ctx.text_nl, + nameIT: ctx.text_it, + nameES: ctx.text_es, + namePT: ctx.text_pt, + namePL: ctx.text_pl, type: type, shortCode: ctx.short_code } @@ -94,6 +125,8 @@ export default { return result }, UpdateUser: async (resolve, root, args, context, info) => { + console.log(context.req.headers['accept-language']) + console.log(context.req.headers) const result = await resolve(root, args, context, info) await createOrUpdateLocations(context.user.id, args.locationName, context.driver) return result diff --git a/src/schema.graphql b/src/schema.graphql index cdc8aa7a2..3031ac0fe 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -49,6 +49,14 @@ enum UserGroupEnum { type Location { id: ID! name: String! + nameEN: String + nameDE: String + nameFR: String + nameNL: String + nameIT: String + nameES: String + namePT: String + namePL: String type: String! lat: Float lng: Float From ae39c189805b639cf107f6f8ad7d42256321b1c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 8 Jan 2019 14:55:33 +0100 Subject: [PATCH 224/554] Run all backend tests I accidently left `describe.only` in the test suite. That usually runs only one block of tests instead of all tests. My fault, sorry --- src/graphql-schema.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphql-schema.test.js b/src/graphql-schema.test.js index 4956c3ab0..a58fb3599 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.test.js @@ -19,7 +19,7 @@ afterEach(async () => { await app.close() }) -describe.only('login', () => { +describe('login', () => { const mutation = (params) => { const { email, password } = params return ` From 0bfa047a5a39e2014493c2ec38ea1153aa599a3b Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 8 Jan 2019 15:12:44 +0100 Subject: [PATCH 225/554] Fixed issues for non german / english languages --- src/middleware/userMiddleware.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index c4cba0c63..2d8de6a77 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -24,13 +24,27 @@ const createOrUpdateLocations = async (userId, locationName, driver) => { return } const mapboxToken = process.env.MAPBOX_TOKEN - const res = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(locationName)}.json?access_token=${mapboxToken}&types=region,place,country&language=en,de,fr,nl,it,es,pt,pl&limit=1`) + const res = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(locationName)}.json?access_token=${mapboxToken}&types=region,place,country&language=en,de,fr,nl,it,es,pt,pl`) if (!res || !res.features || !res.features[0]) { throw new UserInputError('locationName is invalid') } - const data = res.features[0] + let data + + res.features.forEach(item => { + if (item.matching_place_name === locationName) { + data = item + } + }) + if (!data) { + data = res.features[0] + } + + if (!data) { + throw new UserInputError('locationName is invalid') + } + const session = driver.session() await session.run( 'MERGE (l:Location {id: $id}) ' + @@ -125,8 +139,6 @@ export default { return result }, UpdateUser: async (resolve, root, args, context, info) => { - console.log(context.req.headers['accept-language']) - console.log(context.req.headers) const result = await resolve(root, args, context, info) await createOrUpdateLocations(context.user.id, args.locationName, context.driver) return result From 1dd852ee9f17ed4e4c6b0682788b00850696d4ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 9 Jan 2019 04:30:55 +0000 Subject: [PATCH 226/554] Bump neo4j-graphql-js from 2.1.1 to 2.2.0 Bumps [neo4j-graphql-js](https://github.com/neo4j-graphql/neo4j-graphql-js) from 2.1.1 to 2.2.0. - [Release notes](https://github.com/neo4j-graphql/neo4j-graphql-js/releases) - [Changelog](https://github.com/neo4j-graphql/neo4j-graphql-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/neo4j-graphql/neo4j-graphql-js/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 5636e1283..12df68317 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "lodash": "~4.17.11", "ms": "~2.1.1", "neo4j-driver": "~1.7.2", - "neo4j-graphql-js": "~2.1.1", + "neo4j-graphql-js": "~2.2.0", "node-fetch": "~2.3.0", "npm-run-all": "~4.1.5", "passport": "~0.4.0", diff --git a/yarn.lock b/yarn.lock index 1d861e0e6..ee9b4a0df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5393,10 +5393,10 @@ neo4j-driver@^1.7.2, neo4j-driver@~1.7.2: text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-graphql-js@~2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.1.1.tgz#bdb1af2fb45d1058492852ed9307586f6deab37d" - integrity sha512-OcDaFIfOKZF02jmxnWWTLQr64mu79RGAtDULfciwElW59GjRF425M2Yf4gLJuQFscnh7d+Qk/+Ng+jVbz+V4lA== +neo4j-graphql-js@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.2.0.tgz#f0d934b376e9476ef2aa1600e86eb1f8a74c10a2" + integrity sha512-DyYRE6wAVPKxDAHkRwiZmNYx+Vv3KVFQp2Ul1Ay4f2ahW52mWzwMFe/Rlbau3phFYSZZAeaRCT7XLBy++sg/cQ== dependencies: graphql "^14.0.2" lodash "^4.17.11" From 2571d82447acd2747e890119af38eb7bc81a705b Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 9 Jan 2019 13:12:37 +0100 Subject: [PATCH 227/554] Disabled cypther logs and added DEBUG env var --- src/graphql-schema.js | 2 +- src/seed/data/index.js | 2 +- src/server.js | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 9cee7ad51..33fc8b4c1 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -102,7 +102,7 @@ export const resolvers = { .then(async (result) => { session.close() const [currentUser] = await result.records.map(function (record) { - console.log(record.get('user')) + // console.log(record.get('user')) return record.get('user') }) if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { diff --git a/src/seed/data/index.js b/src/seed/data/index.js index e66342fe3..e50fececc 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -36,5 +36,5 @@ export default async function (client) { } }) /* eslint-disable-next-line no-console */ - console.log('Seeded Data', data) + console.log('Seeded Data...') } diff --git a/src/server.js b/src/server.js index 3b0e0a561..9a27aeb35 100644 --- a/src/server.js +++ b/src/server.js @@ -21,6 +21,7 @@ let schema = makeExecutableSchema({ }) const driver = neo4j().getDriver() +const debug = process.env.NODE_ENV !== 'production' && process.env.DEBUG === 'true' schema = augmentSchema(schema, { query: { @@ -28,7 +29,8 @@ schema = augmentSchema(schema, { }, mutation: { exclude: ['Statistics', 'LoggedInUser'] - } + }, + debug: debug }) schema = applyScalars(applyDirectives(schema)) @@ -50,7 +52,7 @@ const createServer = (options) => { return payload }, schema: schema, - tracing: true, + tracing: debug, middlewares: middleware(schema), mocks: (process.env.MOCK === 'true') ? mocks : false } From 86c7b9338653fb7afcfd68ef172084ccf03f6641 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 9 Jan 2019 13:14:18 +0100 Subject: [PATCH 228/554] Removed unneeded log --- src/graphql-schema.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 33fc8b4c1..95a62cb99 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -102,7 +102,6 @@ export const resolvers = { .then(async (result) => { session.close() const [currentUser] = await result.records.map(function (record) { - // console.log(record.get('user')) return record.get('user') }) if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { From 13666df3e2dad48da03e4c1928303b2c063a799e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 9 Jan 2019 13:48:44 +0100 Subject: [PATCH 229/554] Don't run tests in /dist folder If you ran `yarn run build` followed by `yarn run test:jest` it was running the tests twice, because it matched the `/dist` folder to. --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 12df68317..9d83da85b 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,10 @@ }, "author": "Human Connection gGmbH", "license": "MIT", + "jest": { + "verbose": true, + "testMatch": ["**/src/**/?(*.)+(spec|test).js?(x)" ] + }, "dependencies": { "apollo-cache-inmemory": "~1.3.11", "apollo-client": "~2.4.8", From 9262fbb44ffa53e3d89c0ecab8a8e625b015a7da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 8 Jan 2019 14:57:13 +0100 Subject: [PATCH 230/554] Start a test server only once. This keeps our tests small. It is quite a headache though, because of an issue with jest and with transpiling. For reasons that I don't understand running `yarn run test:jest` sometimes complains about open handles. I would love to hear how to make our build more reliable. --- README.md | 9 +++++ package.json | 6 ++-- ...-schema.test.js => graphql-schema.spec.js} | 17 +--------- src/jest/globalSetup.js | 1 + src/jest/globalTeardown.js | 1 + src/jest/hooks.js | 16 +++++++++ src/middleware/permissionsMiddleware.spec.js | 33 +++++++++++++++++++ src/middleware/permissionsMiddleware.test.js | 15 --------- 8 files changed, 65 insertions(+), 33 deletions(-) rename src/{graphql-schema.test.js => graphql-schema.spec.js} (85%) create mode 100644 src/jest/globalSetup.js create mode 100644 src/jest/globalTeardown.js create mode 100644 src/jest/hooks.js create mode 100644 src/middleware/permissionsMiddleware.spec.js delete mode 100644 src/middleware/permissionsMiddleware.test.js diff --git a/README.md b/README.md index da8758334..eb814d1f0 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,15 @@ npm run db:reset **Beware**: We have no multiple database setup at the moment. We clean the database after each test, running the tests will wipe out all your data! +First build `server.js`: +```bash +yarn run build +# -or- +npm run build +``` +The additional build step will become obsolete, as soon as [jest transforms global setup teardown modules](https://github.com/facebook/jest/issues/5164). + +Now run the tests: ```bash yarn run test # -or- diff --git a/package.json b/package.json index 9d83da85b..0b624efee 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", "test:jest": "$npm_package_config_no_auth run-p --race start test:cmd:jest", - "test:cmd:jest": "jest --forceExit", + "test:cmd:jest": "jest --forceExit --detectOpenHandles", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", @@ -25,7 +25,9 @@ "license": "MIT", "jest": { "verbose": true, - "testMatch": ["**/src/**/?(*.)+(spec|test).js?(x)" ] + "testMatch": ["**/src/**/?(*.)+(spec|test).js?(x)" ], + "globalSetup": "/src/jest/globalSetup", + "globalTeardown": "/src/jest/globalTeardown" }, "dependencies": { "apollo-cache-inmemory": "~1.3.11", diff --git a/src/graphql-schema.test.js b/src/graphql-schema.spec.js similarity index 85% rename from src/graphql-schema.test.js rename to src/graphql-schema.spec.js index a58fb3599..a9ea1108a 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.spec.js @@ -1,23 +1,8 @@ import { request } from 'graphql-request' -import createServer from './server' -import mocks from './mocks' import { create, cleanDatabase } from './seed/factories' import jwt from 'jsonwebtoken' -let getHost -let app -let port - -beforeEach(async () => { - const server = createServer({ mocks }) - app = await server.start({ port: 0 }) - port = app.address().port - getHost = () => `http://127.0.0.1:${port}` -}) - -afterEach(async () => { - await app.close() -}) +let getHost = () => 'http://127.0.0.1:3123' describe('login', () => { const mutation = (params) => { diff --git a/src/jest/globalSetup.js b/src/jest/globalSetup.js new file mode 100644 index 000000000..e2bfa24a5 --- /dev/null +++ b/src/jest/globalSetup.js @@ -0,0 +1 @@ +module.exports = require('./hooks').setup diff --git a/src/jest/globalTeardown.js b/src/jest/globalTeardown.js new file mode 100644 index 000000000..944503234 --- /dev/null +++ b/src/jest/globalTeardown.js @@ -0,0 +1 @@ +module.exports = require('./hooks').teardown diff --git a/src/jest/hooks.js b/src/jest/hooks.js new file mode 100644 index 000000000..d5bcf2f2e --- /dev/null +++ b/src/jest/hooks.js @@ -0,0 +1,16 @@ +const createServer = require('../../dist/server.js').default +let app + +const setup = async function () { + const server = createServer() + app = await server.start({ port: 3123 }) +} + +const teardown = async function () { + await app.close() +} + +module.exports = { + setup, + teardown +} diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js new file mode 100644 index 000000000..fb612bb91 --- /dev/null +++ b/src/middleware/permissionsMiddleware.spec.js @@ -0,0 +1,33 @@ +import { request } from 'graphql-request' +import createServer from '../server' +import mocks from '../mocks' +import { create, cleanDatabase } from '../seed/factories' +import generateJwt from '../jwt/generateToken' + +describe('authorization', () => { + describe('given an existing user', () => { + + describe('logged in', () => { + let jwt + beforeEach(() => { + // jwt = generateJwt(user) + }) + + describe('query own user profile', () => { + const mutation = (params) => { + const { email, password } = params + return `{ + User(email: "${email}") { + name + } + }` + } + + it('returns the owner\'s email address', async () => { + // const data = await request(getHost(), mutation({ email: 'test@example.org' })) + console.log('it runs') + }) + }) + }) + }) +}) diff --git a/src/middleware/permissionsMiddleware.test.js b/src/middleware/permissionsMiddleware.test.js deleted file mode 100644 index 3cf808e39..000000000 --- a/src/middleware/permissionsMiddleware.test.js +++ /dev/null @@ -1,15 +0,0 @@ -describe('query', () => { - describe('statistics', () => { - describe('authenticated user', () => { - describe('read', () => { - xit('is forbidden', () => {}) - }) - }) - - describe('admin', () => { - describe('read', () => { - xit('is permitted', () => {}) - }) - }) - }) -}) From 9629ca649ac92580af02e51252bb1aac96e1daf1 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 9 Jan 2019 17:20:25 +0100 Subject: [PATCH 231/554] Fixed user middleware --- src/middleware/userMiddleware.js | 7 ++++--- src/nodes/users/userMiddleware.js | 0 2 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 src/nodes/users/userMiddleware.js diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 2d8de6a77..adb6eb46f 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -1,5 +1,6 @@ import request from 'request' import { UserInputError } from 'apollo-server' +import isEmpty from 'lodash/isEmpty' const asyncForEach = async (array, callback) => { for (let index = 0; index < array.length; index++) { @@ -20,7 +21,7 @@ const fetch = url => { } const createOrUpdateLocations = async (userId, locationName, driver) => { - if (!locationName) { + if (isEmpty(locationName)) { return } const mapboxToken = process.env.MAPBOX_TOKEN @@ -135,12 +136,12 @@ export default { Mutation: { CreateUser: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) - await createOrUpdateLocations(context.user.id, args.locationName, context.driver) + await createOrUpdateLocations(args.id, args.locationName, context.driver) return result }, UpdateUser: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) - await createOrUpdateLocations(context.user.id, args.locationName, context.driver) + await createOrUpdateLocations(args.id, args.locationName, context.driver) return result } } diff --git a/src/nodes/users/userMiddleware.js b/src/nodes/users/userMiddleware.js deleted file mode 100644 index e69de29bb..000000000 From ced8bd78bbca0a3a1fa308a8fa1dcd85fc69eb30 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 9 Jan 2019 17:21:30 +0100 Subject: [PATCH 232/554] Added locations to seeded users --- src/seed/data/users.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/seed/data/users.js b/src/seed/data/users.js index 2c148bc0c..8106a75f4 100644 --- a/src/seed/data/users.js +++ b/src/seed/data/users.js @@ -9,6 +9,7 @@ export default function (data) { password: "1234", email: "admin@example.org", avatar: "${faker.internet.avatar()}", + locationName: "Hamburg, Germany", role: admin, disabled: false, deleted: false) { @@ -24,6 +25,7 @@ export default function (data) { password: "1234", email: "moderator@example.org", avatar: "${faker.internet.avatar()}", + locationName: "USA", role: moderator, disabled: false, deleted: false) { From 0893d3740e77f5fe1aa7dbfd06437d94e2347e79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 9 Jan 2019 18:56:57 +0100 Subject: [PATCH 233/554] Try to expose bug #106 It does not work as we have PERMISSIONS=disabled also in the server we're trying to test. --- src/graphql-schema.spec.js | 9 ++-- src/jest/helpers.js | 15 ++++++ src/middleware/permissionsMiddleware.spec.js | 49 ++++++++++++++------ src/seed/factories/index.js | 8 ++-- 4 files changed, 57 insertions(+), 24 deletions(-) create mode 100644 src/jest/helpers.js diff --git a/src/graphql-schema.spec.js b/src/graphql-schema.spec.js index a9ea1108a..69073444c 100644 --- a/src/graphql-schema.spec.js +++ b/src/graphql-schema.spec.js @@ -1,8 +1,7 @@ import { request } from 'graphql-request' import { create, cleanDatabase } from './seed/factories' import jwt from 'jsonwebtoken' - -let getHost = () => 'http://127.0.0.1:3123' +import { host } from './jest/helpers' describe('login', () => { const mutation = (params) => { @@ -30,7 +29,7 @@ describe('login', () => { describe('asking for a `token`', () => { describe('with valid email/password combination', () => { it('responds with a JWT token', async () => { - const data = await request(getHost(), mutation({ email: 'test@example.org', password: '1234' })) + const data = await request(host, mutation({ email: 'test@example.org', password: '1234' })) const { token } = data.login jwt.verify(token, process.env.JWT_SECRET, (err, data) => { expect(data.email).toEqual('test@example.org') @@ -42,7 +41,7 @@ describe('login', () => { describe('with a valid email but incorrect password', () => { it('responds with "Incorrect email address or password."', async () => { try { - await request(getHost(), mutation({ email: 'test@example.org', password: 'wrong' })) + await request(host, mutation({ email: 'test@example.org', password: 'wrong' })) } catch (error) { expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') } @@ -52,7 +51,7 @@ describe('login', () => { describe('with a non-existing email', () => { it('responds with "Incorrect email address or password."', async () => { try { - await request(getHost(), mutation({ email: 'non-existent@example.org', password: 'wrong' })) + await request(host, mutation({ email: 'non-existent@example.org', password: 'wrong' })) } catch (error) { expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') } diff --git a/src/jest/helpers.js b/src/jest/helpers.js new file mode 100644 index 000000000..f687305ea --- /dev/null +++ b/src/jest/helpers.js @@ -0,0 +1,15 @@ +import { request } from 'graphql-request' + +export const host = 'http://127.0.0.1:3123' + +export async function login ({ email, password }) { + const mutation = ` + mutation { + login(email:"${email}", password:"${password}"){ + token + } + }` + const data = await request(host, mutation) + const { token } = data.login + return token +} diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index fb612bb91..9da3a3e9d 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,31 +1,50 @@ -import { request } from 'graphql-request' -import createServer from '../server' -import mocks from '../mocks' +import { GraphQLClient } from 'graphql-request' import { create, cleanDatabase } from '../seed/factories' -import generateJwt from '../jwt/generateToken' +import { host, login } from '../jest/helpers' describe('authorization', () => { - describe('given an existing user', () => { + describe('given two existing users', () => { + beforeEach(async () => { + await create('user', { + email: 'test@example.org', + password: '1234' + }) + await create('user', { + email: 'someone@example.org', + password: 'hello' + }) + }) + + afterEach(async () => { + await cleanDatabase() + }) describe('logged in', () => { - let jwt - beforeEach(() => { - // jwt = generateJwt(user) + let jwt, graphQLClient + + beforeEach(async () => { + jwt = await login({ email: 'test@example.org', password: '1234' }) + graphQLClient = new GraphQLClient(host, { + headers: { + authorization: `Bearer ${jwt}` + } + }) }) - describe('query own user profile', () => { - const mutation = (params) => { - const { email, password } = params + describe('query email', () => { + const query = (params) => { + const { email } = params return `{ User(email: "${email}") { - name + email } }` } - it('returns the owner\'s email address', async () => { - // const data = await request(getHost(), mutation({ email: 'test@example.org' })) - console.log('it runs') + it('exposes the owner\'s email address', async () => { + const data = await graphQLClient.request(query({ email: 'test@example.org' })) + console.log(process.env) + expect(data).toEqual({ User: [ { email: 'test@example.org' } ] }) }) }) }) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index d665de4a0..69b0b15fd 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -29,12 +29,12 @@ const buildMutation = (model, parameters) => { return builders[model](parameters) } -const create = async (model, parameters) => { - await client.mutate({ mutation: gql(buildMutation(model, parameters)) }) +const create = (model, parameters) => { + return client.mutate({ mutation: gql(buildMutation(model, parameters)) }) } -const cleanDatabase = async () => { - await query('MATCH (n) DETACH DELETE n', session) +const cleanDatabase = () => { + return query('MATCH (n) DETACH DELETE n', session) } export { From da19dee1f2318c96059a9118e13928e4fb322df2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 10 Jan 2019 04:19:47 +0000 Subject: [PATCH 234/554] Bump eslint-plugin-jest from 22.1.2 to 22.1.3 Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 22.1.2 to 22.1.3. - [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases) - [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v22.1.2...v22.1.3) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 9d83da85b..dc75aca0f 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "eslint": "~5.11.1", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.14.0", - "eslint-plugin-jest": "^22.1.2", + "eslint-plugin-jest": "^22.1.3", "eslint-plugin-node": "~8.0.0", "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", diff --git a/yarn.lock b/yarn.lock index ee9b4a0df..9230961fb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2728,10 +2728,10 @@ eslint-plugin-import@~2.14.0: read-pkg-up "^2.0.0" resolve "^1.6.0" -eslint-plugin-jest@^22.1.2: - version "22.1.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.1.2.tgz#1ea36cc3faedbdb788e702ca633d635ca14e91e8" - integrity sha512-jSPT4rVmNetkeCIyrvvOM0wJtgoUSbKHIUDoOGzIISsg51eWN/nISPNKVM+jXMMDI9oowbyapOnpKSXlsLiDpQ== +eslint-plugin-jest@^22.1.3: + version "22.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.1.3.tgz#4444108dfcddc5d2117ed6dc551f529d7e73a99e" + integrity sha512-JTZTI6WQoNruAugNyCO8fXfTONVcDd5i6dMRFA5g3rUFn1UDDLILY1bTL6alvNXbW2U7Sc2OSpi8m08pInnq0A== eslint-plugin-node@~8.0.0: version "8.0.0" From 887cc8fddf35dc3c82f2f2578169cc9daeb56ce3 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 10 Jan 2019 15:59:10 +0100 Subject: [PATCH 235/554] Refactoring --- src/helpers/asyncForEach.js | 14 ++ src/{middleware => }/helpers/walkRecursive.js | 0 src/middleware/nodes/locations.js | 124 ++++++++++++++++ src/middleware/passwordMiddleware.js | 2 +- src/middleware/userMiddleware.js | 134 +----------------- src/middleware/xssMiddleware.js | 2 +- src/seed/data/index.js | 4 +- src/seed/seed-helpers.js | 18 +-- 8 files changed, 146 insertions(+), 152 deletions(-) create mode 100644 src/helpers/asyncForEach.js rename src/{middleware => }/helpers/walkRecursive.js (100%) create mode 100644 src/middleware/nodes/locations.js diff --git a/src/helpers/asyncForEach.js b/src/helpers/asyncForEach.js new file mode 100644 index 000000000..1f05ea915 --- /dev/null +++ b/src/helpers/asyncForEach.js @@ -0,0 +1,14 @@ +/** + * Provide a way to iterate for each element in an array while waiting for async functions to finish + * + * @param array + * @param callback + * @returns {Promise} + */ +async function asyncForEach (array, callback) { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array) + } +} + +export default asyncForEach diff --git a/src/middleware/helpers/walkRecursive.js b/src/helpers/walkRecursive.js similarity index 100% rename from src/middleware/helpers/walkRecursive.js rename to src/helpers/walkRecursive.js diff --git a/src/middleware/nodes/locations.js b/src/middleware/nodes/locations.js new file mode 100644 index 000000000..735b047dd --- /dev/null +++ b/src/middleware/nodes/locations.js @@ -0,0 +1,124 @@ + +import request from 'request' +import { UserInputError } from 'apollo-server' +import isEmpty from 'lodash/isEmpty' +import asyncForEach from '../../helpers/asyncForEach' + +const fetch = url => { + return new Promise((resolve, reject) => { + request(url, function (error, response, body) { + if (error) { + reject(error) + } else { + resolve(JSON.parse(body)) + } + }) + }) +} + +const locales = [ + 'en', + 'de', + 'fr', + 'nl', + 'it', + 'es', + 'pt', + 'pl' +] + +const createLocation = async (session, mapboxData) => { + const data = { + id: mapboxData.id, + nameEN: mapboxData.text_en, + nameDE: mapboxData.text_de, + nameFR: mapboxData.text_fr, + nameNL: mapboxData.text_nl, + nameIT: mapboxData.text_it, + nameES: mapboxData.text_es, + namePT: mapboxData.text_pt, + namePL: mapboxData.text_pl, + type: mapboxData.id.split('.')[0].toLowerCase(), + lat: (mapboxData.center && mapboxData.center.length) ? mapboxData.center[0] : null, + lng: (mapboxData.center && mapboxData.center.length) ? mapboxData.center[1] : null + } + + let query = 'MERGE (l:Location {id: $id}) ' + + 'SET l.name = $nameEN, ' + + 'l.nameEN = $nameEN, ' + + 'l.nameDE = $nameDE, ' + + 'l.nameFR = $nameFR, ' + + 'l.nameNL = $nameNL, ' + + 'l.nameIT = $nameIT, ' + + 'l.nameES = $nameES, ' + + 'l.namePT = $namePT, ' + + 'l.namePL = $namePL, ' + + 'l.type = $type' + + if (data.lat && data.lng) { + query += ', l.lat = $lat, l.lng = $lng' + } + query += ' RETURN l.id' + + await session.run(query, data) +} + +const createOrUpdateLocations = async (userId, locationName, driver) => { + if (isEmpty(locationName)) { + return + } + const mapboxToken = process.env.MAPBOX_TOKEN + const res = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(locationName)}.json?access_token=${mapboxToken}&types=region,place,country&language=${locales.join(',')}`) + + if (!res || !res.features || !res.features[0]) { + throw new UserInputError('locationName is invalid') + } + + let data + + res.features.forEach(item => { + if (item.matching_place_name === locationName) { + data = item + } + }) + if (!data) { + data = res.features[0] + } + + if (!data || !data.place_type || !data.place_type.length) { + throw new UserInputError('locationName is invalid') + } + + const session = driver.session() + await createLocation(session, data) + + let parent = data + + if (data.context) { + await asyncForEach(data.context, async ctx => { + await createLocation(session, ctx) + + await session.run( + 'MATCH (parent:Location {id: $parentId}), (child:Location {id: $childId}) ' + + 'MERGE (child)<-[:IS_IN]-(parent) ' + + 'RETURN child.id, parent.id', { + parentId: parent.id, + childId: ctx.id + }) + + parent = ctx + }) + } + // delete all current locations from user + await session.run('MATCH (u:User {id: $userId})-[r:IS_IN]->(l:Location) DETACH DELETE r', { + userId: userId + }) + // connect user with location + await session.run('MATCH (u:User {id: $userId}), (l:Location {id: $locationId}) MERGE (u)-[:IS_IN]->(l) RETURN l.id, u.id', { + userId: userId, + locationId: data.id + }) + session.close() +} + +export default createOrUpdateLocations diff --git a/src/middleware/passwordMiddleware.js b/src/middleware/passwordMiddleware.js index 4f551fe5d..16480b126 100644 --- a/src/middleware/passwordMiddleware.js +++ b/src/middleware/passwordMiddleware.js @@ -1,5 +1,5 @@ import bcrypt from 'bcryptjs' -import walkRecursive from './helpers/walkRecursive' +import walkRecursive from '../helpers/walkRecursive' export default { Mutation: { diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index adb6eb46f..55b181bc9 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -1,136 +1,4 @@ -import request from 'request' -import { UserInputError } from 'apollo-server' -import isEmpty from 'lodash/isEmpty' - -const asyncForEach = async (array, callback) => { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array) - } -} - -const fetch = url => { - return new Promise((resolve, reject) => { - request(url, function (error, response, body) { - if (error) { - reject(error) - } else { - resolve(JSON.parse(body)) - } - }) - }) -} - -const createOrUpdateLocations = async (userId, locationName, driver) => { - if (isEmpty(locationName)) { - return - } - const mapboxToken = process.env.MAPBOX_TOKEN - const res = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(locationName)}.json?access_token=${mapboxToken}&types=region,place,country&language=en,de,fr,nl,it,es,pt,pl`) - - if (!res || !res.features || !res.features[0]) { - throw new UserInputError('locationName is invalid') - } - - let data - - res.features.forEach(item => { - if (item.matching_place_name === locationName) { - data = item - } - }) - if (!data) { - data = res.features[0] - } - - if (!data) { - throw new UserInputError('locationName is invalid') - } - - const session = driver.session() - await session.run( - 'MERGE (l:Location {id: $id}) ' + - 'SET l.name = $nameEN, ' + - 'l.nameEN = $nameEN, ' + - 'l.nameDE = $nameDE, ' + - 'l.nameFR = $nameFR, ' + - 'l.nameNL = $nameNL, ' + - 'l.nameIT = $nameIT, ' + - 'l.nameES = $nameES, ' + - 'l.namePT = $namePT, ' + - 'l.namePL = $namePL, ' + - 'l.type = $type, ' + - 'l.lat = $lat, ' + - 'l.lng = $lng ' + - 'RETURN l.id', { - id: data.id, - nameEN: data.text_en, - nameDE: data.text_de, - nameFR: data.text_fr, - nameNL: data.text_nl, - nameIT: data.text_it, - nameES: data.text_es, - namePT: data.text_pt, - namePL: data.text_pl, - type: data.place_type[0].toLowerCase(), - lat: data.center[0], - lng: data.center[1] - } - ) - - let parent = data - - if (data.context) { - await asyncForEach(data.context, async ctx => { - const type = ctx.id.split('.')[0].toLowerCase() - await session.run( - 'MERGE (l:Location {id: $id}) ' + - 'SET l.name = $nameEN, ' + - 'l.nameEN = $nameEN, ' + - 'l.nameDE = $nameDE, ' + - 'l.nameFR = $nameFR, ' + - 'l.nameNL = $nameNL, ' + - 'l.nameIT = $nameIT, ' + - 'l.nameES = $nameES, ' + - 'l.namePT = $namePT, ' + - 'l.namePL = $namePL, ' + - 'l.type = $type, ' + - 'l.shortCode = $shortCode ' + - 'RETURN l.id', { - id: ctx.id, - nameEN: ctx.text_en, - nameDE: ctx.text_de, - nameFR: ctx.text_fr, - nameNL: ctx.text_nl, - nameIT: ctx.text_it, - nameES: ctx.text_es, - namePT: ctx.text_pt, - namePL: ctx.text_pl, - type: type, - shortCode: ctx.short_code - } - ) - await session.run( - 'MATCH (parent:Location {id: $parentId}), (child:Location {id: $childId}) ' + - 'MERGE (child)<-[:IS_IN]-(parent) ' + - 'RETURN child.id, parent.id', { - parentId: parent.id, - childId: ctx.id - }) - - parent = ctx - }) - } - // delete all current locations from user - await session.run('MATCH (u:User {id: $userId})-[r:IS_IN]->(l:Location) DETACH DELETE r', { - userId: userId - }) - // connect user with location - await session.run('MATCH (u:User {id: $userId}), (l:Location {id: $locationId}) MERGE (u)-[:IS_IN]->(l) RETURN l.id, u.id', { - userId: userId, - locationId: data.id - }) - session.close() -} +import createOrUpdateLocations from './nodes/locations' export default { Mutation: { diff --git a/src/middleware/xssMiddleware.js b/src/middleware/xssMiddleware.js index ac71f3421..59ce8800f 100644 --- a/src/middleware/xssMiddleware.js +++ b/src/middleware/xssMiddleware.js @@ -1,4 +1,4 @@ -import walkRecursive from './helpers/walkRecursive' +import walkRecursive from '../helpers/walkRecursive' // import { getByDot, setByDot, getItems, replaceItems } from 'feathers-hooks-common' import sanitizeHtml from 'sanitize-html' // import { isEmpty, intersection } from 'lodash' diff --git a/src/seed/data/index.js b/src/seed/data/index.js index e50fececc..33bc56f36 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -1,5 +1,5 @@ import gql from 'graphql-tag' -import helper from '../seed-helpers' +import asyncForEach from '../../helpers/asyncForEach' const seed = { Badge: require('./badges.js').default, @@ -22,7 +22,7 @@ let data = {} export default async function (client) { // iterate through seeds - await helper.asyncForEach(Object.keys(seed), async key => { + await asyncForEach(Object.keys(seed), async key => { const mutations = seed[key] try { const res = await client diff --git a/src/seed/seed-helpers.js b/src/seed/seed-helpers.js index 48b9ba01d..23bde40ae 100644 --- a/src/seed/seed-helpers.js +++ b/src/seed/seed-helpers.js @@ -46,7 +46,7 @@ export default { let randomIds = _.shuffle(ids) return items[randomIds.pop()] }, - randomItems: (items, key = '_id', min = 1, max = 1) => { + randomItems: (items, key = 'id', min = 1, max = 1) => { let randomIds = _.shuffle(_.keys(items)) let res = [] @@ -54,7 +54,7 @@ export default { for (let i = 0; i < count; i++) { let r = items[randomIds.pop()][key] - if (key === '_id') { + if (key === 'id') { r = r.toString() } res.push(r) @@ -117,22 +117,10 @@ export default { mapIdsByKey: (items, values, key) => { let res = [] values.forEach(value => { - res.push(_.find(items, [key, value])._id.toString()) + res.push(_.find(items, [key, value]).id.toString()) }) return res }, - /** - * Provide a way to iterate for each element in an array while waiting for async functions to finish - * - * @param array - * @param callback - * @returns {Promise} - */ - asyncForEach: async (array, callback) => { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array) - } - }, genInviteCode: () => { const chars = '23456789abcdefghkmnpqrstuvwxyzABCDEFGHJKLMNPRSTUVWXYZ' let code = '' From ca38892322ab2f2910ff07e622d9b7412455e17d Mon Sep 17 00:00:00 2001 From: Daksh Date: Thu, 10 Jan 2019 21:49:01 +0530 Subject: [PATCH 236/554] remove password from query. --- src/jwt/strategy.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/jwt/strategy.js b/src/jwt/strategy.js index 65e2d35c1..5b1ea1231 100644 --- a/src/jwt/strategy.js +++ b/src/jwt/strategy.js @@ -22,7 +22,7 @@ export default (driver) => { const session = driver.session() const result = await session.run( 'MATCH (user:User {id: $userId}) ' + - 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', + 'RETURN user {.id, .slug, .name, .avatar, .email, .role} as user LIMIT 1', { userId: JWTPayload.id } @@ -33,7 +33,6 @@ export default (driver) => { }) if (currentUser) { - delete currentUser.password currentUser.avatar = fixUrl(currentUser.avatar) return next(null, currentUser) } else { From fb3c169f65cafbb639b9901eef38553dea3c3c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 11 Jan 2019 14:29:56 +0100 Subject: [PATCH 237/554] Add missing env variable to `docker-compose.yml` @appinteractive always run the docker-compose up workflow at least once. --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 459496173..639592b88 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,7 @@ services: - GRAPHQL_URI=http://localhost:4000 - CLIENT_URI=http://localhost:3000 - JWT_SECRET=b/&&7b78BF&fv/Vd + - MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ" - MOCK=false neo4j: From 52c32bb646e22657222ccf9f7bad134098585596 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 11 Jan 2019 16:34:06 +0100 Subject: [PATCH 238/554] Report now works --- src/graphql-schema.js | 48 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index c23cd1f8f..56a774861 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -4,6 +4,7 @@ import path from 'path' import bcrypt from 'bcryptjs' import zipObject from 'lodash/zipObject' import generateJwt from './jwt/generateToken' +import uuid from 'uuid/v4' import { fixUrl } from './middleware/fixImageUrlsMiddleware' import { neo4jgraphql } from 'neo4j-graphql-js' @@ -124,10 +125,49 @@ export const resolvers = { throw new Error('No Such User exists.') }, report: async (parent, { resource, description }, { driver, req, user }, resolveInfo) => { - // return neo4jgraphql(parent, { resource, description }, { driver, req, user }, resolveInfo) - console.log('params', { resource, description }) - console.log(`the user with the id ${user.id} tries to create a report on content of type ${resource.type} (${resource.id})`) - throw new Error(`resource.id: ${resource.id}, resource.type: ${resource.type}, description: ${description}, user: ${user.id}`) + const contextId = uuid() + const session = driver.session() + const data = { + id: contextId, + type: resource.type, + createdAt: (new Date()).toISOString(), + description: resource.description + } + await session.run( + 'CREATE (r:Report $report) ' + + 'RETURN r.id, r.type, r.description', { + report: data + } + ) + let contentType + + switch (resource.type) { + case 'post': + case 'contribution': + contentType = 'Post' + break + case 'comment': + contentType = 'Comment' + break + case 'user': + contentType = 'User' + break + } + + await session.run( + `MATCH (author:User {id: $userId}), (context:${contentType} {id: $resourceId}), (report:Report {id: $contextId}) ` + + 'MERGE (report)<-[:REPORTED]-(author) ' + + 'MERGE (context)<-[:REPORTED]-(report) ' + + 'RETURN context', { + resourceId: resource.id, + userId: user.id, + contextId: contextId + } + ) + session.close() + + // TODO: output Report compatible object + return data } } } From f4f69cfe0f0b74fe35873542cba6a9d0d8240285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 11 Jan 2019 17:59:06 +0100 Subject: [PATCH 239/554] Quote JWT Token (consistency) --- .env.template | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.template b/.env.template index 8f05f50c1..42211b184 100644 --- a/.env.template +++ b/.env.template @@ -6,5 +6,5 @@ GRAPHQL_URI=http://localhost:4000 CLIENT_URI=http://localhost:3000 MOCK=false -JWT_SECRET=b/&&7b78BF&fv/Vd +JWT_SECRET="b/&&7b78BF&fv/Vd" MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ" diff --git a/docker-compose.yml b/docker-compose.yml index 639592b88..755169b2d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,7 +17,7 @@ services: - GRAPHQL_PORT=4000 - GRAPHQL_URI=http://localhost:4000 - CLIENT_URI=http://localhost:3000 - - JWT_SECRET=b/&&7b78BF&fv/Vd + - JWT_SECRET="b/&&7b78BF&fv/Vd" - MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ" - MOCK=false From feadc0e543470425bb363b67e27518e092cd35fe Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 11 Jan 2019 19:17:10 +0100 Subject: [PATCH 240/554] Rename _ResourceType to RecourceType in schema --- src/schema.graphql | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index 978981c6f..44c0cc509 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -35,10 +35,10 @@ scalar DateTime input Resource { id: ID!, - type: _ResourceType! + type: ResourceEnum! } -enum _ResourceType { +enum ResourceEnum { contribution comment user @@ -152,8 +152,9 @@ type Comment { type Report { id: ID! - author: User @relation(name: "REPORTED", direction: "IN") + reporter: User @relation(name: "REPORTED", direction: "IN") description: String + type: ResourceEnum! createdAt: String comment: Comment @relation(name: "REPORTED", direction: "OUT") contribution: Post @relation(name: "REPORTED", direction: "OUT") From aa9cfceba98b662a606cf43dec0be8b473db039f Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sat, 12 Jan 2019 15:50:51 +0100 Subject: [PATCH 241/554] Try to fix build issues --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index ed6c274ce..750d284dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,7 @@ CMD ["yarn", "run", "start"] FROM base as builder RUN yarn install --frozen-lockfile --non-interactive COPY . . +RUN cp .env.template .env RUN yarn run build # reduce image size with a multistage build From 53044c4cf6687f23bfb5d8b4220dc5595935ced7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Sat, 12 Jan 2019 20:51:19 +0000 Subject: [PATCH 242/554] Bump apollo-cache-inmemory from 1.3.11 to 1.3.12 Bumps [apollo-cache-inmemory](https://github.com/apollographql/apollo-client) from 1.3.11 to 1.3.12. - [Release notes](https://github.com/apollographql/apollo-client/releases) - [Changelog](https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-client/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index dc75aca0f..ab2241a06 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "testMatch": ["**/src/**/?(*.)+(spec|test).js?(x)" ] }, "dependencies": { - "apollo-cache-inmemory": "~1.3.11", + "apollo-cache-inmemory": "~1.3.12", "apollo-client": "~2.4.8", "apollo-link-http": "~1.5.9", "apollo-server": "~2.3.1", diff --git a/yarn.lock b/yarn.lock index 9230961fb..caf47bcca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1014,16 +1014,16 @@ apollo-cache-control@^0.1.0: dependencies: graphql-extensions "^0.0.x" -apollo-cache-inmemory@~1.3.11: - version "1.3.11" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.11.tgz#6cb8f24ec812715169f9acbb0b67833f9a19ec90" - integrity sha512-fSoyjBV5RV57J3i/VHDDB74ZgXc0PFiogheNFHEhC0mL6rg5e/DjTx0Vg+csIBk23gvlzTvV+eypx7Q2NJ+dYg== +apollo-cache-inmemory@~1.3.12: + version "1.3.12" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.12.tgz#cf7ef7c15730d0b6787d79047d5c06087ac31991" + integrity sha512-jxWcW64QoYQZ09UH6v3syvCCl3MWr6bsxT3wYYL6ORi8svdJUpnNrHTcv5qXqJYVg/a+NHhfEt+eGjJUG2ytXA== dependencies: - apollo-cache "^1.1.21" - apollo-utilities "^1.0.26" - optimism "^0.6.6" + apollo-cache "^1.1.22" + apollo-utilities "^1.0.27" + optimism "^0.6.8" -apollo-cache@1.1.22, apollo-cache@^1.1.21: +apollo-cache@1.1.22, apollo-cache@^1.1.22: version "1.1.22" resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.22.tgz#d4682ea6e8b2508a934f61c2fd9e36b4a65041d9" integrity sha512-8PoxhQLISj2oHwT7i/r4l+ly4y3RKZls+dtXzAewu3U77P9dNZKhYkRNAhx9iEfsrNoHgXBV8vMp64hb1uYh+g== @@ -1307,7 +1307,7 @@ apollo-upload-server@^5.0.0: busboy "^0.2.14" object-path "^0.11.4" -apollo-utilities@1.0.27, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.26, apollo-utilities@^1.0.27: +apollo-utilities@1.0.27, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.27: version "1.0.27" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.27.tgz#77c550f9086552376eca3a48e234a1466b5b057e" integrity sha512-nzrMQ89JMpNmYnVGJ4t8zN75gQbql27UDhlxNi+3OModp0Masx5g+fQmQJ5B4w2dpRuYOsdwFLmj3lQbwOKV1Q== @@ -5719,7 +5719,7 @@ opn@4.0.2: object-assign "^4.0.1" pinkie-promise "^2.0.0" -optimism@^0.6.6: +optimism@^0.6.8: version "0.6.8" resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.8.tgz#0780b546da8cd0a72e5207e0c3706c990c8673a6" integrity sha512-bN5n1KCxSqwBDnmgDnzMtQTHdL+uea2HYFx1smvtE+w2AMl0Uy31g0aXnP/Nt85OINnMJPRpJyfRQLTCqn5Weg== From 6bbc76911acd340c4ac05f17d7d63db8cdc652b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 14 Jan 2019 16:07:52 +0100 Subject: [PATCH 243/554] Refactor test cases --- src/jest/helpers.js | 18 +++++++++++++++--- src/middleware/permissionsMiddleware.spec.js | 13 +++---------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/jest/helpers.js b/src/jest/helpers.js index f687305ea..28aed9f98 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -1,15 +1,27 @@ import { request } from 'graphql-request' +import { GraphQLClient } from 'graphql-request' export const host = 'http://127.0.0.1:3123' -export async function login ({ email, password }) { +export async function getJWT({ email, password }) { const mutation = ` mutation { login(email:"${email}", password:"${password}"){ token } }` - const data = await request(host, mutation) - const { token } = data.login + const response = await request(host, mutation) + const { token } = response.login + if(!token) throw `Could not get a JWT token from the backend:\n${response}` return token } + +export async function authenticatedGraphQLClient(params){ + const jwt = await getJWT(params) + const options = { + headers: { + 'Authorization': `Bearer ${jwt}` + } + } + return new GraphQLClient(host, options) +} diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 9da3a3e9d..e88362a34 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,6 +1,5 @@ -import { GraphQLClient } from 'graphql-request' import { create, cleanDatabase } from '../seed/factories' -import { host, login } from '../jest/helpers' +import { authenticatedGraphQLClient } from '../jest/helpers' describe('authorization', () => { describe('given two existing users', () => { @@ -20,15 +19,10 @@ describe('authorization', () => { }) describe('logged in', () => { - let jwt, graphQLClient + let graphQLClient beforeEach(async () => { - jwt = await login({ email: 'test@example.org', password: '1234' }) - graphQLClient = new GraphQLClient(host, { - headers: { - authorization: `Bearer ${jwt}` - } - }) + graphQLClient = await authenticatedGraphQLClient({ email: 'test@example.org', password: '1234' }) }) describe('query email', () => { @@ -43,7 +37,6 @@ describe('authorization', () => { it('exposes the owner\'s email address', async () => { const data = await graphQLClient.request(query({ email: 'test@example.org' })) - console.log(process.env) expect(data).toEqual({ User: [ { email: 'test@example.org' } ] }) }) }) From 79749e657035d65e5adbaeceb07c72acf0a4ab0f Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 14 Jan 2019 17:07:20 +0100 Subject: [PATCH 244/554] Fixed isOwner permission --- src/middleware/permissionsMiddleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 5b0cb87d2..6f786583e 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -14,7 +14,7 @@ const isModerator = rule()(async (parent, args, ctx, info) => { }) */ -const isOwner = rule()(async (parent, args, ctx, info) => { +const isOwner = rule({ cache: 'no_cache' })(async (parent, args, ctx, info) => { return ctx.user.id === parent.id }) From d0b975e78280c8d3732dfafe8d1091589360f9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 14 Jan 2019 20:53:07 +0100 Subject: [PATCH 245/554] Getting strange non-deterministic errors --- package.json | 4 ++- src/jest/helpers.js | 33 +++++++++++++------- src/middleware/permissionsMiddleware.spec.js | 28 +++++++++-------- src/seed/factories/index.js | 13 ++++++-- yarn.lock | 2 +- 5 files changed, 51 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index 1fa42cb49..dc1ffd822 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,9 @@ "license": "MIT", "jest": { "verbose": true, - "testMatch": ["**/src/**/?(*.)+(spec|test).js?(x)" ], + "testMatch": [ + "**/src/**/?(*.)+(spec|test).js?(x)" + ], "globalSetup": "/src/jest/globalSetup", "globalTeardown": "/src/jest/globalTeardown" }, diff --git a/src/jest/helpers.js b/src/jest/helpers.js index 28aed9f98..06cfc0e0b 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -1,9 +1,9 @@ import { request } from 'graphql-request' -import { GraphQLClient } from 'graphql-request' +import fetch from 'node-fetch' export const host = 'http://127.0.0.1:3123' -export async function getJWT({ email, password }) { +export async function authenticatedHeaders ({ email, password }) { const mutation = ` mutation { login(email:"${email}", password:"${password}"){ @@ -12,16 +12,27 @@ export async function getJWT({ email, password }) { }` const response = await request(host, mutation) const { token } = response.login - if(!token) throw `Could not get a JWT token from the backend:\n${response}` - return token + if (!token) throw new Error(`Could not get a JWT token from the backend:\n${response}`) + return { + authorization: `Bearer ${token}` + } } -export async function authenticatedGraphQLClient(params){ - const jwt = await getJWT(params) - const options = { - headers: { - 'Authorization': `Bearer ${jwt}` - } +export async function queryServer ({ headers, query, variables }) { + const defaultHeaders = { + Accept: 'application/json', + 'Content-Type': 'application/json' } - return new GraphQLClient(host, options) + const response = await fetch(host, { + method: 'POST', + authenticatedHeaders, + headers: Object.assign({}, defaultHeaders, headers), + body: JSON.stringify({ + operationName: null, + query, + variables + }) + }) + const json = await response.json() + return json.data } diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index e88362a34..88f095d8c 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,5 +1,5 @@ import { create, cleanDatabase } from '../seed/factories' -import { authenticatedGraphQLClient } from '../jest/helpers' +import { authenticatedHeaders, queryServer } from '../jest/helpers' describe('authorization', () => { describe('given two existing users', () => { @@ -19,25 +19,27 @@ describe('authorization', () => { }) describe('logged in', () => { - let graphQLClient + let headers = {} beforeEach(async () => { - graphQLClient = await authenticatedGraphQLClient({ email: 'test@example.org', password: '1234' }) + // headers = authenticatedHeaders({ + // email: 'test@example.org', + // password: '1234' + // }) }) - describe('query email', () => { - const query = (params) => { - const { email } = params - return `{ - User(email: "${email}") { + describe('query email', async () => { + it('exposes the owner\'s email address', async () => { + const options = { + headers, + query: `{ + User(email: "test@example.org") { email } }` - } - - it('exposes the owner\'s email address', async () => { - const data = await graphQLClient.request(query({ email: 'test@example.org' })) - expect(data).toEqual({ User: [ { email: 'test@example.org' } ] }) + } + const json = await queryServer(options) + expect(json).toEqual({ User: [ { email: 'test@example.org' } ] }) }) }) }) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 69b0b15fd..93985407f 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -4,7 +4,6 @@ import dotenv from 'dotenv' import { HttpLink } from 'apollo-link-http' import { InMemoryCache } from 'apollo-cache-inmemory' import neo4j from '../../bootstrap/neo4j' -import { query } from '../../graphql-schema' import fetch from 'node-fetch' dotenv.config() @@ -19,7 +18,6 @@ const client = new ApolloClient({ }) const driver = neo4j().getDriver() -const session = driver.session() const builders = { 'user': require('./users.js').default @@ -34,7 +32,16 @@ const create = (model, parameters) => { } const cleanDatabase = () => { - return query('MATCH (n) DETACH DELETE n', session) + const session = driver.session() + const cypher = 'MATCH (n) DETACH DELETE n' + return session + .run(cypher) + .then(function (result) { + session.close() + }) + .catch(function (error) { + console.log(error) + }) } export { diff --git a/yarn.lock b/yarn.lock index caf47bcca..58532f857 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5420,7 +5420,7 @@ node-fetch@2.1.2: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= -node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@~2.3.0: +node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== From 75ee9bf9b44ab2edc1ca489a0c5a35d8b3d9fccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 14 Jan 2019 21:50:42 +0100 Subject: [PATCH 246/554] Fix seed data in docker environment @appinteractive Running ``` docker-compose -f ../Nitro-Backend/docker-compose.yml -f ../Nitro-Backend/docker-compose.travis.yml up ``` from the Nitro-Web folder gives me an error when running seed data. The configuration in this commit fixes it on my machine. I guess that will fix the frontend build, too. --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 755169b2d..8e4a6c498 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,9 +17,9 @@ services: - GRAPHQL_PORT=4000 - GRAPHQL_URI=http://localhost:4000 - CLIENT_URI=http://localhost:3000 - - JWT_SECRET="b/&&7b78BF&fv/Vd" - - MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ" + - JWT_SECRET=b/&&7b78BF&fv/Vd - MOCK=false + - MAPBOX_TOKEN=pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ neo4j: image: humanconnection/neo4j:latest From 70b20302fefabad461415d3fa5ad69d29ea13caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 14 Jan 2019 23:00:21 +0100 Subject: [PATCH 247/554] Probably exposed #106 --- src/middleware/permissionsMiddleware.spec.js | 57 ++++++++++++-------- src/seed/factories/index.js | 17 +++--- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 88f095d8c..3ea3f9e55 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -5,12 +5,12 @@ describe('authorization', () => { describe('given two existing users', () => { beforeEach(async () => { await create('user', { - email: 'test@example.org', - password: '1234' + email: 'owner@example.org', + password: 'iamtheowner' }) await create('user', { email: 'someone@example.org', - password: 'hello' + password: 'else' }) }) @@ -18,28 +18,43 @@ describe('authorization', () => { await cleanDatabase() }) - describe('logged in', () => { + describe('access email address', () => { let headers = {} - - beforeEach(async () => { - // headers = authenticatedHeaders({ - // email: 'test@example.org', - // password: '1234' - // }) - }) - - describe('query email', async () => { - it('exposes the owner\'s email address', async () => { - const options = { - headers, - query: `{ - User(email: "test@example.org") { + const action = async (headers) => { + const options = { + headers, + query: `{ + User(email: "owner@example.org") { email } }` - } - const json = await queryServer(options) - expect(json).toEqual({ User: [ { email: 'test@example.org' } ] }) + } + return await queryServer(options) + } + + describe('not logged in', async () => { + it('does not expose the owner\'s email address', async () => { + expect(await action(headers)).toEqual({ User: [ { email: null } ] }) + }) + }) + + describe('as owner', () => { + it('exposes the owner\'s email address', async () => { + headers = await authenticatedHeaders({ + email: 'owner@example.org', + password: 'iamtheowner' + }) + expect(await action(headers)).toEqual({ User: [ { email: 'owner@example.org' } ] }) + }) + }) + + describe('as someone else', () => { + it('does not expose the owner\'s email address', async () => { + headers = await authenticatedHeaders({ + email: 'someone@example.org', + password: 'else' + }) + expect(await action(headers)).toEqual({ User: [ { email: null } ] }) }) }) }) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 93985407f..89a462531 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -31,17 +31,16 @@ const create = (model, parameters) => { return client.mutate({ mutation: gql(buildMutation(model, parameters)) }) } -const cleanDatabase = () => { +const cleanDatabase = async () => { const session = driver.session() const cypher = 'MATCH (n) DETACH DELETE n' - return session - .run(cypher) - .then(function (result) { - session.close() - }) - .catch(function (error) { - console.log(error) - }) + try { + const result = await session.run(cypher) + session.close() + return result + } catch (error) { + console.log(error) + } } export { From 6f487e2687a1c17df07c43249bb170eb337d4f74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 14 Jan 2019 23:22:12 +0100 Subject: [PATCH 248/554] Fix non-deterministic erros in testing Without the `--runInBand` flag, jest will create a worker pool of child processes and run the tests withing. No surprise, why the tests were running completely non-deterministically! If we clear the database in the middle of the tests we will end up with no records, or if we run the factories in several tests we end up with many duplicate records. FYI: @mattwr18 @appinteractive @tansaku @Kachulio1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dc1ffd822..5b024eace 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", "test:jest": "$npm_package_config_no_auth run-p --race start test:cmd:jest", - "test:cmd:jest": "jest --forceExit --detectOpenHandles", + "test:cmd:jest": "jest --forceExit --detectOpenHandles --runInBand", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", From 9d541d8f27e1e070b9ca0fa68b1d442836295410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 14 Jan 2019 23:31:00 +0100 Subject: [PATCH 249/554] Clean up helper.js --- src/jest/helpers.js | 23 +------------------- src/middleware/permissionsMiddleware.spec.js | 18 +++++++-------- 2 files changed, 9 insertions(+), 32 deletions(-) diff --git a/src/jest/helpers.js b/src/jest/helpers.js index 06cfc0e0b..cd66a9d04 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -11,28 +11,7 @@ export async function authenticatedHeaders ({ email, password }) { } }` const response = await request(host, mutation) - const { token } = response.login - if (!token) throw new Error(`Could not get a JWT token from the backend:\n${response}`) return { - authorization: `Bearer ${token}` + authorization: `Bearer ${response.login.token}` } } - -export async function queryServer ({ headers, query, variables }) { - const defaultHeaders = { - Accept: 'application/json', - 'Content-Type': 'application/json' - } - const response = await fetch(host, { - method: 'POST', - authenticatedHeaders, - headers: Object.assign({}, defaultHeaders, headers), - body: JSON.stringify({ - operationName: null, - query, - variables - }) - }) - const json = await response.json() - return json.data -} diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 3ea3f9e55..50f6ebadd 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,5 +1,6 @@ import { create, cleanDatabase } from '../seed/factories' -import { authenticatedHeaders, queryServer } from '../jest/helpers' +import { host, authenticatedHeaders, queryServer } from '../jest/helpers' +import { GraphQLClient } from 'graphql-request' describe('authorization', () => { describe('given two existing users', () => { @@ -21,15 +22,12 @@ describe('authorization', () => { describe('access email address', () => { let headers = {} const action = async (headers) => { - const options = { - headers, - query: `{ - User(email: "owner@example.org") { - email - } - }` - } - return await queryServer(options) + const graphQLClient = new GraphQLClient(host, { headers }) + return await graphQLClient.request(`{ + User(email: "owner@example.org") { + email + } + }`) } describe('not logged in', async () => { From b2d1685b06c750c23f4435c9166b14b4284f4dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 15 Jan 2019 00:39:06 +0100 Subject: [PATCH 250/554] WIP: Integrate permissionless app into setup hooks --- package.json | 3 +-- src/jest/helpers.js | 2 +- src/jest/hooks.js | 7 ++++++- src/seed/factories/index.js | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 5b024eace..a3a75a60f 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,7 @@ "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", - "test:jest": "$npm_package_config_no_auth run-p --race start test:cmd:jest", - "test:cmd:jest": "jest --forceExit --detectOpenHandles --runInBand", + "test:jest": "cross-env PERMISSIONS=disabled jest --forceExit --detectOpenHandles --runInBand", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", diff --git a/src/jest/helpers.js b/src/jest/helpers.js index cd66a9d04..0e66c7595 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -1,7 +1,7 @@ import { request } from 'graphql-request' import fetch from 'node-fetch' -export const host = 'http://127.0.0.1:3123' +export const host = 'http://127.0.0.1:4123' export async function authenticatedHeaders ({ email, password }) { const mutation = ` diff --git a/src/jest/hooks.js b/src/jest/hooks.js index d5bcf2f2e..1d285961a 100644 --- a/src/jest/hooks.js +++ b/src/jest/hooks.js @@ -1,13 +1,18 @@ const createServer = require('../../dist/server.js').default let app +let permissionlessApp const setup = async function () { const server = createServer() - app = await server.start({ port: 3123 }) + app = await server.start({ port: 4123 }) + + const permissionless = createServer() + permissionlessApp = await server.start({ port: 4001 }) } const teardown = async function () { await app.close() + await permissionlessApp.close() } module.exports = { diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 89a462531..e62e98869 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -13,7 +13,7 @@ if (process.env.NODE_ENV === 'production') { } const client = new ApolloClient({ - link: new HttpLink({ uri: process.env.GRAPHQL_URI, fetch }), + link: new HttpLink({ uri: 'http://localhost:4001', fetch }), cache: new InMemoryCache() }) From 9e28704d9b520482f0e2656597abbf33821358b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 15 Jan 2019 01:20:32 +0100 Subject: [PATCH 251/554] Fix all cypress tests but one @appinteractive, it's super strange but apparently the JWT has to be enclosed in quotes whereas the MAPBOX_TOKEN must not be enclosed. This commit fixes almost all tests running in the docker containers on my machine. The remaining test case is: ``` About me and and location I set my location to "Mecklenburg-Vorpommern" (example #2) ``` @appinteractive when I try to repeat the cypress test on my machine I get no results for "Mecklenburg-Vorpommern" only cities and states. can you check if regions really work? --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 8e4a6c498..5a7650aa1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,7 +17,7 @@ services: - GRAPHQL_PORT=4000 - GRAPHQL_URI=http://localhost:4000 - CLIENT_URI=http://localhost:3000 - - JWT_SECRET=b/&&7b78BF&fv/Vd + - JWT_SECRET="b/&&7b78BF&fv/Vd" - MOCK=false - MAPBOX_TOKEN=pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ From 57a6b259ebf8582e6a253042e3530794b5a589dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 15 Jan 2019 20:32:34 +0100 Subject: [PATCH 252/554] Copy remote-dump.sh as a starting piont Just added the two environment variables for neo4j. --- scripts/import-legacy-db/.gitignore | 4 + scripts/import-legacy-db/README.md | 82 ++++++++++++++++++++ scripts/import-legacy-db/import-legacy-db.sh | 37 +++++++++ 3 files changed, 123 insertions(+) create mode 100644 scripts/import-legacy-db/.gitignore create mode 100644 scripts/import-legacy-db/README.md create mode 100755 scripts/import-legacy-db/import-legacy-db.sh diff --git a/scripts/import-legacy-db/.gitignore b/scripts/import-legacy-db/.gitignore new file mode 100644 index 000000000..82c26eeec --- /dev/null +++ b/scripts/import-legacy-db/.gitignore @@ -0,0 +1,4 @@ +* +!import-legacy-db.sh +!README.md +!.gitignore diff --git a/scripts/import-legacy-db/README.md b/scripts/import-legacy-db/README.md new file mode 100644 index 000000000..9ad50d658 --- /dev/null +++ b/scripts/import-legacy-db/README.md @@ -0,0 +1,82 @@ +# MongoDB scripts + +This README explains how to directly access the production or staging database +for backup or query purposes. + +## Backup script + +The backup script is intended to be used as a cron job or as a single command from your laptop. +It uses SSH tunneling to a remote host and dumps the mongo database on your machine. +Therefore, a public SSH key needs to be copied to the remote machine. + +### Usage + +All parameters must be supplied as environment variables: + +| Name | required | +|-----------------------|-----------| +| SSH\_USERNAME | yes | +| SSH\_HOST | yes | +| MONGODB\_USERNAME | yes | +| MONGODB\_PASSWORD | yes | +| MONGODB\_DATABASE | yes | +| NEO4J\_USER | yes | +| NEO4J\_PASSWORD | yes | +| OUTPUT | | +| GPG\_PASSWORD | | + +If you set `GPG_PASSWORD`, the resulting archive will be encrypted (symmetrically, with the given passphrase). +This is recommended if you dump the database on your personal laptop because of data security. + +After exporting these environment variables to your bash, run: + +```bash +./import-legacy-db.sh +``` + + +### Import into your local mongo db (optional) + +Run (but change the file name accordingly): +```bash +mongorestore --gzip --archive=human-connection-dump_2018-11-21.archive +``` + +If you previously encrypted your dump, run: +```bash +gpg --decrypt human-connection-dump_2018-11-21.archive.gpg | mongorestore --gzip --archive +``` + + +## Query remote MongoDB + +In contrast to the backup script, querying the database is expected to be done +interactively and on demand by the user. Therefore our suggestion is to use a +tool like [MongoDB compass](https://www.mongodb.com/products/compass) to query +the mongo db through an SSH tunnel. This tool can export a collection as .csv +file and you can further do custom processing with a csv tool like +[q](https://github.com/harelba/q). + +### Suggested workflow + +Read on the mongodb compass documentation how to connect to the remote mongo +database [through SSH](https://docs.mongodb.com/compass/master/connect/). You +will need all the credentials and a public SSH key on the server as for the +backup script above. + +Once you have a connection, use the MongoDB Compass +[query bar](https://docs.mongodb.com/compass/master/query-bar/) to query for the +desired data. You can +[export the result](https://docs.mongodb.com/compass/master/import-export/) as +.json or .csv. + +Once you have the .csv file on your machine, use standard SQL queries through +the command line tool q to further process the data. + +For example +```sh +q "SELECT email FROM ./invites.csv INTERSECT SELECT email FROM ./emails.csv" -H --delimiter=, +``` + +[Q's website](http://harelba.github.io/q/usage.html) explains the usage fairly +well. diff --git a/scripts/import-legacy-db/import-legacy-db.sh b/scripts/import-legacy-db/import-legacy-db.sh new file mode 100755 index 000000000..263ea9a53 --- /dev/null +++ b/scripts/import-legacy-db/import-legacy-db.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "NEO4J_USER" "NEO4J_PASSWORD" +do + if [[ -z "${!var}" ]]; then + echo "${var} is undefined" + exit -1 + fi +done + +OUTPUT_FILE_NAME=${OUTPUT:-human-connection-dump}_$(date -I).archive + +echo "SSH_USERNAME ${SSH_USERNAME}" +echo "SSH_HOST ${SSH_HOST}" +echo "MONGODB_USERNAME ${MONGODB_USERNAME}" +echo "MONGODB_PASSWORD ${MONGODB_PASSWORD}" +echo "MONGODB_DATABASE ${MONGODB_DATABASE}" +echo "NEO4J_USER ${NEO4J_USER}" +echo "NEO4J_PASSWORD ${NEO4J_PASSWORD}" +echo "OUTPUT_FILE_NAME ${OUTPUT_FILE_NAME}" +echo "GPG_PASSWORD ${GPG_PASSWORD:-}" +echo "-------------------------------------------------" + +ssh -M -S my-ctrl-socket -fnNT -L 27018:localhost:27017 -l ${SSH_USERNAME} ${SSH_HOST} + +if [[ -z "${!GPG_PASSWORD}" ]]; then + mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase admin --gzip --archive | gpg -c --batch --passphrase ${GPG_PASSWORD} --output ${OUTPUT_FILE_NAME}.gpg +else + mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase admin --gzip --archive=${OUTPUT_FILE_NAME} +fi + + +ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST} +ssh -S my-ctrl-socket -O exit -l ${SSH_USERNAME} ${SSH_HOST} + + + From 0970014a5949bd1476549329c6bfd4bb8562e3cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 16 Jan 2019 00:37:21 +0100 Subject: [PATCH 253/554] Create db-migration-worker as a docker container The idea is to import/dump the remote database via SSH, restore it to the local mongodb, export .json collections to a shared volume and import the json collections with cypher-shell. --- .dockerignore | 2 + db-migration-worker/.gitignore | 1 + db-migration-worker/Dockerfile | 9 +++ db-migration-worker/import.sh | 32 ++++++++ docker-compose.override.yml | 26 +++++++ scripts/import-legacy-db/.gitignore | 4 - scripts/import-legacy-db/README.md | 82 -------------------- scripts/import-legacy-db/import-legacy-db.sh | 37 --------- 8 files changed, 70 insertions(+), 123 deletions(-) create mode 100644 db-migration-worker/.gitignore create mode 100644 db-migration-worker/Dockerfile create mode 100755 db-migration-worker/import.sh delete mode 100644 scripts/import-legacy-db/.gitignore delete mode 100644 scripts/import-legacy-db/README.md delete mode 100755 scripts/import-legacy-db/import-legacy-db.sh diff --git a/.dockerignore b/.dockerignore index 84b5adc92..6b6b2193f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,6 +6,7 @@ .env Dockerfile +docker-compose*.yml ./*.png ./*.log @@ -14,3 +15,4 @@ kubernetes/ node_modules/ scripts/ dist/ +db-migration-worker/ diff --git a/db-migration-worker/.gitignore b/db-migration-worker/.gitignore new file mode 100644 index 000000000..690bae050 --- /dev/null +++ b/db-migration-worker/.gitignore @@ -0,0 +1 @@ +id_rsa diff --git a/db-migration-worker/Dockerfile b/db-migration-worker/Dockerfile new file mode 100644 index 000000000..844f65e16 --- /dev/null +++ b/db-migration-worker/Dockerfile @@ -0,0 +1,9 @@ +FROM mongo:latest +ARG KNOWN_HOST + +RUN apt-get update +RUN apt-get -y install openssh-client +COPY id_rsa /root/.ssh/id_rsa +RUN ssh-keyscan -H $KNOWN_HOST >> /root/.ssh/known_hosts +COPY import.sh . + diff --git a/db-migration-worker/import.sh b/db-migration-worker/import.sh new file mode 100755 index 000000000..ccc2cf19b --- /dev/null +++ b/db-migration-worker/import.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "NEO4J_USERNAME" "NEO4J_PASSWORD" "MONGODB_AUTH_DB" +do + if [[ -z "${!var}" ]]; then + echo "${var} is undefined" + exit -1 + fi +done + +OUTPUT_FILE_NAME=${OUTPUT_FILE_NAME:-human-connection-dump}.archive + +echo "SSH_USERNAME ${SSH_USERNAME}" +echo "SSH_HOST ${SSH_HOST}" +echo "MONGODB_USERNAME ${MONGODB_USERNAME}" +echo "MONGODB_PASSWORD ${MONGODB_PASSWORD}" +echo "MONGODB_DATABASE ${MONGODB_DATABASE}" +echo "MONGODB_AUTH_DB ${MONGODB_AUTH_DB}" +echo "NEO4J_USERNAME ${NEO4J_USERNAME}" +echo "NEO4J_PASSWORD ${NEO4J_PASSWORD}" +echo "-------------------------------------------------" + +ssh -4 -M -S my-ctrl-socket -fnNT -L 27018:localhost:27017 -l ${SSH_USERNAME} ${SSH_HOST} +mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --gzip --archive=${OUTPUT_FILE_NAME} +ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST} +ssh -S my-ctrl-socket -O exit -l ${SSH_USERNAME} ${SSH_HOST} + +mongorestore --gzip --archive=human-connection-dump.archive +# cat ./neo4j_import.cql | /usr/share/neo4j/bin/cypher-shell + + + diff --git a/docker-compose.override.yml b/docker-compose.override.yml index ef7d52c7e..f2b3fa0fc 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -11,6 +11,32 @@ services: - /nitro-backend/node_modules command: yarn run dev neo4j: + volumes: + - mongo-export:/mongo-export ports: - 7687:7687 - 7474:7474 + environment: + - NEO4J_apoc_import_file_enabled=true + db-migration-worker: + build: + context: db-migration-worker + args: + - "KNOWN_HOST=${SSH_HOST}" + volumes: + - mongo-export:/mongo-export + networks: + - hc-network + environment: + - "SSH_USERNAME=${SSH_USERNAME}" + - "SSH_HOST=${SSH_HOST}" + - "MONGODB_USERNAME=${MONGODB_USERNAME}" + - "MONGODB_PASSWORD=${MONGODB_PASSWORD}" + - "MONGODB_AUTH_DB=${MONGODB_AUTH_DB}" + - "MONGODB_DATABASE=${MONGODB_DATABASE}" + - "NEO4J_USERNAME=${NEO4J_USERNAME}" + - "NEO4J_PASSWORD=${NEO4J_PASSWORD}" + command: "--smallfiles --logpath=/dev/null" + +volumes: + mongo-export: diff --git a/scripts/import-legacy-db/.gitignore b/scripts/import-legacy-db/.gitignore deleted file mode 100644 index 82c26eeec..000000000 --- a/scripts/import-legacy-db/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!import-legacy-db.sh -!README.md -!.gitignore diff --git a/scripts/import-legacy-db/README.md b/scripts/import-legacy-db/README.md deleted file mode 100644 index 9ad50d658..000000000 --- a/scripts/import-legacy-db/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# MongoDB scripts - -This README explains how to directly access the production or staging database -for backup or query purposes. - -## Backup script - -The backup script is intended to be used as a cron job or as a single command from your laptop. -It uses SSH tunneling to a remote host and dumps the mongo database on your machine. -Therefore, a public SSH key needs to be copied to the remote machine. - -### Usage - -All parameters must be supplied as environment variables: - -| Name | required | -|-----------------------|-----------| -| SSH\_USERNAME | yes | -| SSH\_HOST | yes | -| MONGODB\_USERNAME | yes | -| MONGODB\_PASSWORD | yes | -| MONGODB\_DATABASE | yes | -| NEO4J\_USER | yes | -| NEO4J\_PASSWORD | yes | -| OUTPUT | | -| GPG\_PASSWORD | | - -If you set `GPG_PASSWORD`, the resulting archive will be encrypted (symmetrically, with the given passphrase). -This is recommended if you dump the database on your personal laptop because of data security. - -After exporting these environment variables to your bash, run: - -```bash -./import-legacy-db.sh -``` - - -### Import into your local mongo db (optional) - -Run (but change the file name accordingly): -```bash -mongorestore --gzip --archive=human-connection-dump_2018-11-21.archive -``` - -If you previously encrypted your dump, run: -```bash -gpg --decrypt human-connection-dump_2018-11-21.archive.gpg | mongorestore --gzip --archive -``` - - -## Query remote MongoDB - -In contrast to the backup script, querying the database is expected to be done -interactively and on demand by the user. Therefore our suggestion is to use a -tool like [MongoDB compass](https://www.mongodb.com/products/compass) to query -the mongo db through an SSH tunnel. This tool can export a collection as .csv -file and you can further do custom processing with a csv tool like -[q](https://github.com/harelba/q). - -### Suggested workflow - -Read on the mongodb compass documentation how to connect to the remote mongo -database [through SSH](https://docs.mongodb.com/compass/master/connect/). You -will need all the credentials and a public SSH key on the server as for the -backup script above. - -Once you have a connection, use the MongoDB Compass -[query bar](https://docs.mongodb.com/compass/master/query-bar/) to query for the -desired data. You can -[export the result](https://docs.mongodb.com/compass/master/import-export/) as -.json or .csv. - -Once you have the .csv file on your machine, use standard SQL queries through -the command line tool q to further process the data. - -For example -```sh -q "SELECT email FROM ./invites.csv INTERSECT SELECT email FROM ./emails.csv" -H --delimiter=, -``` - -[Q's website](http://harelba.github.io/q/usage.html) explains the usage fairly -well. diff --git a/scripts/import-legacy-db/import-legacy-db.sh b/scripts/import-legacy-db/import-legacy-db.sh deleted file mode 100755 index 263ea9a53..000000000 --- a/scripts/import-legacy-db/import-legacy-db.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "NEO4J_USER" "NEO4J_PASSWORD" -do - if [[ -z "${!var}" ]]; then - echo "${var} is undefined" - exit -1 - fi -done - -OUTPUT_FILE_NAME=${OUTPUT:-human-connection-dump}_$(date -I).archive - -echo "SSH_USERNAME ${SSH_USERNAME}" -echo "SSH_HOST ${SSH_HOST}" -echo "MONGODB_USERNAME ${MONGODB_USERNAME}" -echo "MONGODB_PASSWORD ${MONGODB_PASSWORD}" -echo "MONGODB_DATABASE ${MONGODB_DATABASE}" -echo "NEO4J_USER ${NEO4J_USER}" -echo "NEO4J_PASSWORD ${NEO4J_PASSWORD}" -echo "OUTPUT_FILE_NAME ${OUTPUT_FILE_NAME}" -echo "GPG_PASSWORD ${GPG_PASSWORD:-}" -echo "-------------------------------------------------" - -ssh -M -S my-ctrl-socket -fnNT -L 27018:localhost:27017 -l ${SSH_USERNAME} ${SSH_HOST} - -if [[ -z "${!GPG_PASSWORD}" ]]; then - mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase admin --gzip --archive | gpg -c --batch --passphrase ${GPG_PASSWORD} --output ${OUTPUT_FILE_NAME}.gpg -else - mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase admin --gzip --archive=${OUTPUT_FILE_NAME} -fi - - -ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST} -ssh -S my-ctrl-socket -O exit -l ${SSH_USERNAME} ${SSH_HOST} - - - From 1c04b8f3deb538195bec48f3a054d9e0e6563948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 16 Jan 2019 00:47:28 +0100 Subject: [PATCH 254/554] Import mongodb on-the-fly --- db-migration-worker/import.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/db-migration-worker/import.sh b/db-migration-worker/import.sh index ccc2cf19b..02fae0f7e 100755 --- a/db-migration-worker/import.sh +++ b/db-migration-worker/import.sh @@ -8,8 +8,6 @@ do fi done -OUTPUT_FILE_NAME=${OUTPUT_FILE_NAME:-human-connection-dump}.archive - echo "SSH_USERNAME ${SSH_USERNAME}" echo "SSH_HOST ${SSH_HOST}" echo "MONGODB_USERNAME ${MONGODB_USERNAME}" @@ -21,11 +19,10 @@ echo "NEO4J_PASSWORD ${NEO4J_PASSWORD}" echo "-------------------------------------------------" ssh -4 -M -S my-ctrl-socket -fnNT -L 27018:localhost:27017 -l ${SSH_USERNAME} ${SSH_HOST} -mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --gzip --archive=${OUTPUT_FILE_NAME} +mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --gzip --archive | mongorestore --gzip --archive ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST} ssh -S my-ctrl-socket -O exit -l ${SSH_USERNAME} ${SSH_HOST} -mongorestore --gzip --archive=human-connection-dump.archive # cat ./neo4j_import.cql | /usr/share/neo4j/bin/cypher-shell From 433cd7a52e0b73f30abdde7cbf7ba18a70eb302f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 16 Jan 2019 01:13:42 +0100 Subject: [PATCH 255/554] Export all relevant collection to a shared folder --- db-migration-worker/import.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/db-migration-worker/import.sh b/db-migration-worker/import.sh index 02fae0f7e..2ff3d6443 100755 --- a/db-migration-worker/import.sh +++ b/db-migration-worker/import.sh @@ -23,7 +23,7 @@ mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONG ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST} ssh -S my-ctrl-socket -O exit -l ${SSH_USERNAME} ${SSH_HOST} -# cat ./neo4j_import.cql | /usr/share/neo4j/bin/cypher-shell - - - +for collection in "categories" "badges" "users" "contributions" "comments" "follows" "shouts" +do + mongoexport --db ${MONGODB_DATABASE} --collection $collection --out "/mongo-export/$collection.json" +done From 8d8dfb06401e80c9888fbd2d84618311ba09e8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 16 Jan 2019 01:50:01 +0100 Subject: [PATCH 256/554] Provision neo4j container with import script --- .dockerignore | 2 + docker-compose.override.yml | 4 +- docker-compose.yml | 3 +- Dockerfile.neo4j => neo4j/Dockerfile | 1 + neo4j/import.cql | 75 ++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 4 deletions(-) rename Dockerfile.neo4j => neo4j/Dockerfile (88%) create mode 100644 neo4j/import.cql diff --git a/.dockerignore b/.dockerignore index 6b6b2193f..f5a08be39 100644 --- a/.dockerignore +++ b/.dockerignore @@ -15,4 +15,6 @@ kubernetes/ node_modules/ scripts/ dist/ + db-migration-worker/ +neo4j/ diff --git a/docker-compose.override.yml b/docker-compose.override.yml index f2b3fa0fc..c1ac0569d 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -18,6 +18,8 @@ services: - 7474:7474 environment: - NEO4J_apoc_import_file_enabled=true + - "NEO4J_USERNAME=${NEO4J_USERNAME}" + - "NEO4J_PASSWORD=${NEO4J_PASSWORD}" db-migration-worker: build: context: db-migration-worker @@ -34,8 +36,6 @@ services: - "MONGODB_PASSWORD=${MONGODB_PASSWORD}" - "MONGODB_AUTH_DB=${MONGODB_AUTH_DB}" - "MONGODB_DATABASE=${MONGODB_DATABASE}" - - "NEO4J_USERNAME=${NEO4J_USERNAME}" - - "NEO4J_PASSWORD=${NEO4J_PASSWORD}" command: "--smallfiles --logpath=/dev/null" volumes: diff --git a/docker-compose.yml b/docker-compose.yml index 5a7650aa1..df8de6b01 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,8 +24,7 @@ services: neo4j: image: humanconnection/neo4j:latest build: - context: . - dockerfile: Dockerfile.neo4j + context: neo4j networks: - hc-network volumes: diff --git a/Dockerfile.neo4j b/neo4j/Dockerfile similarity index 88% rename from Dockerfile.neo4j rename to neo4j/Dockerfile index cb7fd228f..2ef9443a5 100644 --- a/Dockerfile.neo4j +++ b/neo4j/Dockerfile @@ -1,2 +1,3 @@ FROM neo4j:3.5.0 RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.1/apoc-3.5.0.1-all.jar -P plugins/ +COPY import.cql . diff --git a/neo4j/import.cql b/neo4j/import.cql new file mode 100644 index 000000000..521cc1221 --- /dev/null +++ b/neo4j/import.cql @@ -0,0 +1,75 @@ +CALL apoc.load.json('file:/mongo-export/categories.json') YIELD value as category +MERGE(c:Category {id: category._id["$oid"]}) +ON CREATE SET c.name = category.title, + c.slug = category.slug, + c.icon = category.icon + + +CALL apoc.load.json('file:/mongo-export/badges.json') YIELD value as badge +MERGE(b:Badge {id: badge._id["$oid"]}) +ON CREATE SET b.key = badge.key, + b.type = badge.type, + b.icon = badge.image.path, + b.status = badge.status + + +CALL apoc.load.json('file:/mongo-export/users.json') YIELD value as user +MERGE(u:User {id: user._id["$oid"]}) +ON CREATE SET u.name = user.name, + u.slug = user.slug, + u.email = user.email, + u.password = user.password, + u.avatar = user.avatar, + u.coverImg = user.coverImg, + u.wasInvited = user.wasInvited, + u.role = apoc.text.toUpperCase(user.role) +WITH u, user, user.badgeIds AS badgeIds +UNWIND badgeIds AS badgeId +MATCH (b:Badge {id: badgeId}) +MERGE (b)-[:REWARDED]->(u) + + + +CALL apoc.load.json('file:/mongo-export/contributions.json') YIELD value as post +MERGE (p:Post {id: post._id["$oid"]}) +ON CREATE SET p.title = post.title, + p.slug = post.slug, + p.image = post.teaserImg, + p.content = post.content, + p.contentExcerpt = post.contentExcerpt, + p.visibility = apoc.text.toUpperCase(post.visibility), + p.createdAt = datetime(post.createdAt["$date"]), + p.updatedAt = datetime(post.updatedAt["$date"]) +WITH p, post, post.tags AS tags, post.categoryIds as categoryIds +UNWIND tags AS tag +UNWIND categoryIds AS categoryId +MATCH (c:Category {id: categoryId}), + (u:User {id: post.userId}) +MERGE (t:Tag {id: apoc.create.uuid(), name: tag}) +MERGE (p)-[:TAGGED]->(t) +MERGE (u)-[:WROTE]->(p) +MERGE (p)-[:CATEGORIZED]->(c) + + +CALL apoc.load.json('file:/mongo-export/comments.json') YIELD value as comment +MERGE (c:Comment {id: comment._id["$oid"]}) +ON CREATE SET c.content = comment.content, + c.contentExcerpt = comment.contentExcerpt, + c.deleted = comment.deleted +WITH comment +MATCH (p:Post {id: comment.contributionId}), + (u:User {id: comment.userId}) +MERGE (c)-[:COMMENTS]->(p) +MERGE (u)-[:WROTE]->(c) + + +CALL apoc.load.json('file:/mongo-export/follows.json') YIELD value as follow +MATCH (u1:User {id: follow.userId}), + (u2:User {id: follow.foreignId}) +MERGE (u1)-[:FOLLOWS]->(u2) + + +CALL apoc.load.json('file:/mongo-export/shouts.json') YIELD value as shout +MATCH (u:User {id: shout.userId}), + (p:Post {id: shout.foreignId}) +MERGE (u)-[:SHOUTED]->(p) From bfad62130604eb114cfd43fa4c5e4415c1bcbd79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 16 Jan 2019 02:19:02 +0100 Subject: [PATCH 257/554] Disable automatic know-hosts for now This will require user interaction when running the import script --- db-migration-worker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db-migration-worker/Dockerfile b/db-migration-worker/Dockerfile index 844f65e16..39ef39275 100644 --- a/db-migration-worker/Dockerfile +++ b/db-migration-worker/Dockerfile @@ -4,6 +4,6 @@ ARG KNOWN_HOST RUN apt-get update RUN apt-get -y install openssh-client COPY id_rsa /root/.ssh/id_rsa -RUN ssh-keyscan -H $KNOWN_HOST >> /root/.ssh/known_hosts +# RUN ssh-keyscan -H $KNOWN_HOST >> /root/.ssh/known_hosts COPY import.sh . From 541e44e04c03ad08901dcd3ce4693662cc7a21f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 17 Jan 2019 04:31:44 +0000 Subject: [PATCH 258/554] Bump supertest from 3.3.0 to 3.4.1 Bumps [supertest](https://github.com/visionmedia/supertest) from 3.3.0 to 3.4.1. - [Release notes](https://github.com/visionmedia/supertest/releases) - [Changelog](https://github.com/visionmedia/supertest/blob/master/History.md) - [Commits](https://github.com/visionmedia/supertest/compare/v3.3.0...v3.4.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ab2241a06..b7080f3e5 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,6 @@ "jest": "^23.6.0", "nodemon": "~1.18.9", "nyc": "^13.1.0", - "supertest": "^3.3.0" + "supertest": "^3.4.1" } } diff --git a/yarn.lock b/yarn.lock index caf47bcca..0f674623b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7137,10 +7137,10 @@ superagent@^3.8.3: qs "^6.5.1" readable-stream "^2.3.5" -supertest@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/supertest/-/supertest-3.3.0.tgz#79b27bd7d34392974ab33a31fa51a3e23385987e" - integrity sha512-dMQSzYdaZRSANH5LL8kX3UpgK9G1LRh/jnggs/TI0W2Sz7rkMx9Y48uia3K9NgcaWEV28tYkBnXE4tiFC77ygQ== +supertest@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-3.4.1.tgz#91b19ea34804c205769d0ff5ad947aff3eb2731d" + integrity sha512-r4AmsjjKxC50LxGACe/E4xKjau2amiFlj3aCT2sZCRig2o3l4XFN6Acw7crDu4d8Af1f5chafIyLkQ1mac/boA== dependencies: methods "^1.1.2" superagent "^3.8.3" From 9e4edca35b2da0b3a0419e6df9e5c9ec6bc36b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 15:09:31 +0100 Subject: [PATCH 259/554] Use node `spawn` to spin off several servers --- package.json | 3 +- src/jest/helpers.js | 1 - src/jest/hooks.js | 36 +++++++++++++++----- src/middleware/permissionsMiddleware.spec.js | 4 +-- yarn.lock | 2 +- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index a3a75a60f..2824aab37 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", - "test:jest": "cross-env PERMISSIONS=disabled jest --forceExit --detectOpenHandles --runInBand", + "test:jest": "jest --forceExit --detectOpenHandles --runInBand", + "test:jest:debug": "node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", diff --git a/src/jest/helpers.js b/src/jest/helpers.js index 0e66c7595..01a26e9d3 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -1,5 +1,4 @@ import { request } from 'graphql-request' -import fetch from 'node-fetch' export const host = 'http://127.0.0.1:4123' diff --git a/src/jest/hooks.js b/src/jest/hooks.js index 1d285961a..80f0de8eb 100644 --- a/src/jest/hooks.js +++ b/src/jest/hooks.js @@ -1,18 +1,36 @@ -const createServer = require('../../dist/server.js').default -let app -let permissionlessApp +const { spawn } = require('child_process') +const waitOn = require('wait-on') + +let server +let seeder const setup = async function () { - const server = createServer() - app = await server.start({ port: 4123 }) + server = spawn('node', ['dist/'], { + env: Object.assign({}, process.env, { + GRAPHQL_URI: 'http://localhost:4123', + GRAPHQL_PORT: '4123' + }) + }) - const permissionless = createServer() - permissionlessApp = await server.start({ port: 4001 }) + seeder = spawn('node', ['dist/'], { + env: Object.assign({}, process.env, { + GRAPHQL_URI: 'http://localhost:4001', + GRAPHQL_PORT: '4001', + PERMISSIONS: 'disabled' + }) + }) + + try { + await waitOn({ + resources: ['http://localhost:4123', 'http://localhost:4001'] + }) + } catch (err) { + console.log(err) + } } const teardown = async function () { - await app.close() - await permissionlessApp.close() + [server, seeder].forEach(app => app.kill()) } module.exports = { diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 50f6ebadd..7896f0348 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,5 +1,5 @@ import { create, cleanDatabase } from '../seed/factories' -import { host, authenticatedHeaders, queryServer } from '../jest/helpers' +import { host, authenticatedHeaders } from '../jest/helpers' import { GraphQLClient } from 'graphql-request' describe('authorization', () => { @@ -23,7 +23,7 @@ describe('authorization', () => { let headers = {} const action = async (headers) => { const graphQLClient = new GraphQLClient(host, { headers }) - return await graphQLClient.request(`{ + return graphQLClient.request(`{ User(email: "owner@example.org") { email } diff --git a/yarn.lock b/yarn.lock index 58532f857..caf47bcca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5420,7 +5420,7 @@ node-fetch@2.1.2: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= -node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@^2.3.0: +node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== From d50015af3ca032924bf45740acab054f3a9c287c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 15:23:24 +0100 Subject: [PATCH 260/554] Replace node with babel-node This should ensure that you don't have to reubild the server all the time --- README.md | 10 +--------- dist/.gitkeep | 0 src/jest/hooks.js | 4 ++-- 3 files changed, 3 insertions(+), 11 deletions(-) delete mode 100644 dist/.gitkeep diff --git a/README.md b/README.md index eb814d1f0..1b12562d2 100644 --- a/README.md +++ b/README.md @@ -137,15 +137,7 @@ npm run db:reset **Beware**: We have no multiple database setup at the moment. We clean the database after each test, running the tests will wipe out all your data! -First build `server.js`: -```bash -yarn run build -# -or- -npm run build -``` -The additional build step will become obsolete, as soon as [jest transforms global setup teardown modules](https://github.com/facebook/jest/issues/5164). - -Now run the tests: +Run the tests: ```bash yarn run test # -or- diff --git a/dist/.gitkeep b/dist/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/jest/hooks.js b/src/jest/hooks.js index 80f0de8eb..15daccbdf 100644 --- a/src/jest/hooks.js +++ b/src/jest/hooks.js @@ -5,14 +5,14 @@ let server let seeder const setup = async function () { - server = spawn('node', ['dist/'], { + server = spawn('babel-node', ['src/index'], { env: Object.assign({}, process.env, { GRAPHQL_URI: 'http://localhost:4123', GRAPHQL_PORT: '4123' }) }) - seeder = spawn('node', ['dist/'], { + seeder = spawn('babel-node', ['src/index'], { env: Object.assign({}, process.env, { GRAPHQL_URI: 'http://localhost:4001', GRAPHQL_PORT: '4001', From cd3f0955f9bf7a1fc89769723bf594e36ba66331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 15:29:47 +0100 Subject: [PATCH 261/554] Properly test 106 I had the wrong test setup for the "expected-to-be-green" side tests (for debugging). --- src/middleware/permissionsMiddleware.spec.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 7896f0348..9e153fe5e 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -32,7 +32,12 @@ describe('authorization', () => { describe('not logged in', async () => { it('does not expose the owner\'s email address', async () => { - expect(await action(headers)).toEqual({ User: [ { email: null } ] }) + try { + await action(headers) + } catch (error) { + expect(error.response.errors[0].message).toEqual('Not Authorised!') + expect(error.response.data).toEqual({ User: [ { email: null } ] }) + } }) }) @@ -52,7 +57,12 @@ describe('authorization', () => { email: 'someone@example.org', password: 'else' }) - expect(await action(headers)).toEqual({ User: [ { email: null } ] }) + try { + await action(headers) + } catch (error) { + expect(error.response.errors[0].message).toEqual('Not Authorised!') + expect(error.response.data).toEqual({ User: [ { email: null } ] }) + } }) }) }) From ad8e64d0604e6b007e451549b7953c94d0fa1728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 16:01:03 +0100 Subject: [PATCH 262/554] Properly exit if seeding fails --- src/seed/data/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/seed/data/index.js b/src/seed/data/index.js index 33bc56f36..1184408d9 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -33,6 +33,7 @@ export default async function (client) { } catch (err) { /* eslint-disable-next-line no-console */ console.error(err) + process.exit(1) } }) /* eslint-disable-next-line no-console */ From a5c87e0cd5a6688742c62cb2e45ae88b2895aacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 18:03:05 +0100 Subject: [PATCH 263/554] Add --ci on Travis (it's our ci server :smile:) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index eaba8dba3..f4a01b147 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ install: script: - docker-compose exec backend yarn run lint - - docker-compose exec backend yarn run test + - docker-compose exec backend yarn run test --ci - docker-compose exec backend yarn run test:coverage - docker-compose exec backend yarn run db:reset - docker-compose exec backend yarn run db:seed From 6340efbfc585227052455501c118ddf4af474296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 18:03:28 +0100 Subject: [PATCH 264/554] Fix #106 Thank you @appinteractive ! :gift_heart: FYI: @kachulio1 @mattwr18 --- src/middleware/userMiddleware.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 55b181bc9..161309164 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -1,4 +1,5 @@ import createOrUpdateLocations from './nodes/locations' +import find from 'lodash/find' export default { Mutation: { @@ -12,5 +13,28 @@ export default { await createOrUpdateLocations(args.id, args.locationName, context.driver) return result } + }, + Query: { + User: async (resolve, root, args, context, info) => { + let isIdPresent + let removeIdFromResult + try { + isIdPresent = find(info.fieldNodes[0].selectionSet.selections, item => item.name.value === 'id') + if (!isIdPresent) { + // add id to request as the user did not ask but we need it + info.fieldNodes[0].selectionSet.selections.unshift({ + kind: 'Field', + name: { kind: 'Name', value: 'id' } + }) + removeIdFromResult = true + } + } catch(err) {} + const result = await resolve(root, args, context, info) + if (!isIdPresent && removeIdFromResult) { + // remove id if the user did not ask for it + info.fieldNodes[0].selectionSet.selections.shift() + } + return result + } } } From 918bd863edb36c70868b5b6b62a6f9ba73cd6536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 18:06:53 +0100 Subject: [PATCH 265/554] Fix typo Replace password with Asterix and Obelix See: http://www.topkool.com/fr/wp-content/uploads/2012/10/asterix-et-obelix-017.jpg @appinteractive :laughing: --- src/middleware/passwordMiddleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/passwordMiddleware.js b/src/middleware/passwordMiddleware.js index 16480b126..0aff222c8 100644 --- a/src/middleware/passwordMiddleware.js +++ b/src/middleware/passwordMiddleware.js @@ -13,7 +13,7 @@ export default { Query: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) return walkRecursive(result, ['password'], () => { - // replace password with asterix + // replace password with asterisk return '*****' }) } From 47e9e52a840a69dd128c31a324e94a8cd52aa112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 18:31:39 +0100 Subject: [PATCH 266/554] Refactor test to be less confusing --- src/middleware/permissionsMiddleware.spec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 9e153fe5e..cf86d11c9 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -7,10 +7,12 @@ describe('authorization', () => { beforeEach(async () => { await create('user', { email: 'owner@example.org', + name: 'Owner', password: 'iamtheowner' }) await create('user', { email: 'someone@example.org', + name: 'Someone else', password: 'else' }) }) @@ -24,7 +26,7 @@ describe('authorization', () => { const action = async (headers) => { const graphQLClient = new GraphQLClient(host, { headers }) return graphQLClient.request(`{ - User(email: "owner@example.org") { + User(name: "Owner") { email } }`) From 8e6299c804892587831e23adcd321ee3eaced3ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 17 Jan 2019 20:06:56 +0000 Subject: [PATCH 267/554] Bump eslint from 5.11.1 to 5.12.0 Bumps [eslint](https://github.com/eslint/eslint) from 5.11.1 to 5.12.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v5.11.1...v5.12.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 55 ++++++++++++++++++++++++---------------------------- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index b7080f3e5..b998fd430 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "babel-eslint": "~10.0.1", "babel-jest": "^23.6.0", "chai": "~4.2.0", - "eslint": "~5.11.1", + "eslint": "~5.12.0", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.14.0", "eslint-plugin-jest": "^22.1.3", diff --git a/yarn.lock b/yarn.lock index 0f674623b..7160da987 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1921,23 +1921,16 @@ caching-transform@^2.0.0: package-hash "^2.0.0" write-file-atomic "^2.0.0" -caller-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= - dependencies: - callsites "^0.2.0" - -callsites@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" - integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= - callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= +callsites@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3" + integrity sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw== + camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -2781,10 +2774,10 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@~5.11.1: - version "5.11.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.11.1.tgz#8deda83db9f354bf9d3f53f9677af7e0e13eadda" - integrity sha512-gOKhM8JwlFOc2acbOrkYR05NW8M6DCMSvfcJiBB5NDxRE1gv8kbvxKaC9u69e6ZGEMWXcswA/7eKR229cEIpvg== +eslint@~5.12.0: + version "5.12.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.12.0.tgz#fab3b908f60c52671fb14e996a450b96c743c859" + integrity sha512-LntwyPxtOHrsJdcSwyQKVtHofPHdv+4+mFwEe91r2V13vqpM8yLr7b1sW+Oo/yheOPkWYsYlYJCkzlFAt8KV7g== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.5.3" @@ -2803,6 +2796,7 @@ eslint@~5.11.1: glob "^7.1.2" globals "^11.7.0" ignore "^4.0.6" + import-fresh "^3.0.0" imurmurhash "^0.1.4" inquirer "^6.1.0" js-yaml "^3.12.0" @@ -2817,7 +2811,6 @@ eslint@~5.11.1: pluralize "^7.0.0" progress "^2.0.0" regexpp "^2.0.1" - require-uncached "^1.0.3" semver "^5.5.1" strip-ansi "^4.0.0" strip-json-comments "^2.0.1" @@ -3841,6 +3834,14 @@ immutable-tuple@^0.4.9: resolved "https://registry.yarnpkg.com/immutable-tuple/-/immutable-tuple-0.4.9.tgz#473ebdd6c169c461913a454bf87ef8f601a20ff0" integrity sha512-LWbJPZnidF8eczu7XmcnLBsumuyRBkpwIRPCZxlojouhBo5jEBO4toj6n7hMy6IxHU/c+MqDSWkvaTpPlMQcyA== +import-fresh@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390" + integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -5845,6 +5846,13 @@ package-json@^4.0.0: registry-url "^3.0.3" semver "^5.1.0" +parent-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.0.tgz#df250bdc5391f4a085fb589dad761f5ad6b865b5" + integrity sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA== + dependencies: + callsites "^3.0.0" + parse-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" @@ -6535,14 +6543,6 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= -require-uncached@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= - dependencies: - caller-path "^0.1.0" - resolve-from "^1.0.0" - resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -6550,11 +6550,6 @@ resolve-cwd@^2.0.0: dependencies: resolve-from "^3.0.0" -resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= - resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" From b9e348d2d377b6052c199417504f1dfc9fb0b12e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 17 Jan 2019 20:19:53 +0000 Subject: [PATCH 268/554] Bump eslint-plugin-node from 8.0.0 to 8.0.1 Bumps [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) from 8.0.0 to 8.0.1. - [Release notes](https://github.com/mysticatea/eslint-plugin-node/releases) - [Commits](https://github.com/mysticatea/eslint-plugin-node/compare/v8.0.0...v8.0.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index b998fd430..2e7083c2e 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.14.0", "eslint-plugin-jest": "^22.1.3", - "eslint-plugin-node": "~8.0.0", + "eslint-plugin-node": "~8.0.1", "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", "graphql-request": "^1.8.2", diff --git a/yarn.lock b/yarn.lock index 7160da987..98238316e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2726,10 +2726,10 @@ eslint-plugin-jest@^22.1.3: resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.1.3.tgz#4444108dfcddc5d2117ed6dc551f529d7e73a99e" integrity sha512-JTZTI6WQoNruAugNyCO8fXfTONVcDd5i6dMRFA5g3rUFn1UDDLILY1bTL6alvNXbW2U7Sc2OSpi8m08pInnq0A== -eslint-plugin-node@~8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.0.tgz#fb9e8911f4543514f154bb6a5924b599aa645568" - integrity sha512-Y+ln8iQ52scz9+rSPnSWRaAxeWaoJZ4wIveDR0vLHkuSZGe44Vk1J4HX7WvEP5Cm+iXPE8ixo7OM7gAO3/OKpQ== +eslint-plugin-node@~8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.1.tgz#55ae3560022863d141fa7a11799532340a685964" + integrity sha512-ZjOjbjEi6jd82rIpFSgagv4CHWzG9xsQAVp1ZPlhRnnYxcTgENUVBvhYmkQ7GvT1QFijUSo69RaiOJKhMu6i8w== dependencies: eslint-plugin-es "^1.3.1" eslint-utils "^1.3.1" From 5dbe5b16a410833f268d886f48e35443cad078bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 23:38:55 +0100 Subject: [PATCH 269/554] Help @mattwr18 to debug the subprocesses --- src/jest/hooks.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/jest/hooks.js b/src/jest/hooks.js index 15daccbdf..77fa159f2 100644 --- a/src/jest/hooks.js +++ b/src/jest/hooks.js @@ -20,6 +20,11 @@ const setup = async function () { }) }) + server.stdout.on('data', data => console.log(`server stdout:\n${data}`)) + server.stderr.on('data', data => console.log(`server stderr:\n${data}`)) + seeder.stdout.on('data', data => console.log(`seeder stdout:\n${data}`)) + seeder.stderr.on('data', data => console.log(`seeder stderr:\n${data}`)) + try { await waitOn({ resources: ['http://localhost:4123', 'http://localhost:4001'] @@ -30,7 +35,8 @@ const setup = async function () { } const teardown = async function () { - [server, seeder].forEach(app => app.kill()) + server.kill() + seeder.kill() } module.exports = { From c1395f7ec1caed1f2816a72f19a61d8850c0fa08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 18 Jan 2019 01:58:05 +0100 Subject: [PATCH 270/554] Fix leakage of subprocesses @mattwr18 and I could not find any other way how to prevent leftover processes than using a complex list of npm scripts. Watch: http://youtu.be/byovuFwNXiw and see how we despearately try to fix this stupid problem. --- package.json | 14 +++++----- scripts/test.sh | 1 + src/jest/globalSetup.js | 1 - src/jest/globalTeardown.js | 1 - src/jest/hooks.js | 45 -------------------------------- src/middleware/userMiddleware.js | 2 +- 6 files changed, 10 insertions(+), 54 deletions(-) create mode 100755 scripts/test.sh delete mode 100644 src/jest/globalSetup.js delete mode 100644 src/jest/globalTeardown.js delete mode 100644 src/jest/hooks.js diff --git a/package.json b/package.json index 2824aab37..58d25ebe4 100644 --- a/package.json +++ b/package.json @@ -9,12 +9,16 @@ "scripts": { "build": "babel src/ -d dist/ --copy-files", "start": "node dist/", - "dev": "nodemon --exec babel-node src/index.js", + "dev": "nodemon --exec babel-node src/", "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", - "test:jest": "jest --forceExit --detectOpenHandles --runInBand", - "test:jest:debug": "node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand", + "test:before:server": "cross-env GRAPHQL_URI=http://localhost:4123 GRAPHQL_PORT=4123 babel-node src/ 2> /dev/null", + "test:before:seeder": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 PERMISSIONS=disabled babel-node src/ 2> /dev/null", + "test:jest:cmd": "wait-on tcp:4001 tcp:4123 && jest --forceExit --detectOpenHandles --runInBand", + "test:jest:cmd:debug": "wait-on tcp:4001 tcp:4123 && node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand", + "test:jest": "run-p --race test:before:* 'test:jest:cmd {@}' --", + "test:jest:debug": "run-p --race test:before:* 'test:jest:cmd:debug {@}' --", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", @@ -27,9 +31,7 @@ "verbose": true, "testMatch": [ "**/src/**/?(*.)+(spec|test).js?(x)" - ], - "globalSetup": "/src/jest/globalSetup", - "globalTeardown": "/src/jest/globalTeardown" + ] }, "dependencies": { "apollo-cache-inmemory": "~1.3.12", diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100755 index 000000000..f1f641af1 --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1 @@ +#!/usr/bin/env bash diff --git a/src/jest/globalSetup.js b/src/jest/globalSetup.js deleted file mode 100644 index e2bfa24a5..000000000 --- a/src/jest/globalSetup.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./hooks').setup diff --git a/src/jest/globalTeardown.js b/src/jest/globalTeardown.js deleted file mode 100644 index 944503234..000000000 --- a/src/jest/globalTeardown.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./hooks').teardown diff --git a/src/jest/hooks.js b/src/jest/hooks.js deleted file mode 100644 index 77fa159f2..000000000 --- a/src/jest/hooks.js +++ /dev/null @@ -1,45 +0,0 @@ -const { spawn } = require('child_process') -const waitOn = require('wait-on') - -let server -let seeder - -const setup = async function () { - server = spawn('babel-node', ['src/index'], { - env: Object.assign({}, process.env, { - GRAPHQL_URI: 'http://localhost:4123', - GRAPHQL_PORT: '4123' - }) - }) - - seeder = spawn('babel-node', ['src/index'], { - env: Object.assign({}, process.env, { - GRAPHQL_URI: 'http://localhost:4001', - GRAPHQL_PORT: '4001', - PERMISSIONS: 'disabled' - }) - }) - - server.stdout.on('data', data => console.log(`server stdout:\n${data}`)) - server.stderr.on('data', data => console.log(`server stderr:\n${data}`)) - seeder.stdout.on('data', data => console.log(`seeder stdout:\n${data}`)) - seeder.stderr.on('data', data => console.log(`seeder stderr:\n${data}`)) - - try { - await waitOn({ - resources: ['http://localhost:4123', 'http://localhost:4001'] - }) - } catch (err) { - console.log(err) - } -} - -const teardown = async function () { - server.kill() - seeder.kill() -} - -module.exports = { - setup, - teardown -} diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 161309164..d4648413a 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -28,7 +28,7 @@ export default { }) removeIdFromResult = true } - } catch(err) {} + } catch (err) {} const result = await resolve(root, args, context, info) if (!isIdPresent && removeIdFromResult) { // remove id if the user did not ask for it From 4618c1d8be8326e7dff4d679a8aa216e8cac18c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 18 Jan 2019 04:19:45 +0000 Subject: [PATCH 271/554] Bump graphql-tag from 2.10.0 to 2.10.1 Bumps [graphql-tag](https://github.com/apollostack/graphql-tag) from 2.10.0 to 2.10.1. - [Release notes](https://github.com/apollostack/graphql-tag/releases) - [Changelog](https://github.com/apollographql/graphql-tag/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollostack/graphql-tag/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 2e7083c2e..186b0015f 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "graphql-iso-date": "~3.6.1", "graphql-middleware": "~1.7.8", "graphql-shield": "~4.1.2", - "graphql-tag": "~2.10.0", + "graphql-tag": "~2.10.1", "graphql-yoga": "~1.16.7", "jsonwebtoken": "~8.4.0", "linkifyjs": "~2.1.7", diff --git a/yarn.lock b/yarn.lock index 98238316e..cf600e248 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3533,10 +3533,10 @@ graphql-subscriptions@^1.0.0: dependencies: iterall "^1.2.1" -graphql-tag@^2.9.2, graphql-tag@~2.10.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" - integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w== +graphql-tag@^2.9.2, graphql-tag@~2.10.1: + version "2.10.1" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02" + integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg== graphql-tools@^4.0.0, graphql-tools@^4.0.1, graphql-tools@^4.0.2: version "4.0.3" From 097a4c1b8fef115a2e8ad3ffddc8c70ddce1f1aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 18 Jan 2019 07:59:43 +0000 Subject: [PATCH 272/554] Bump apollo-client from 2.4.8 to 2.4.9 Bumps [apollo-client](https://github.com/apollographql/apollo-client) from 2.4.8 to 2.4.9. - [Release notes](https://github.com/apollographql/apollo-client/releases) - [Changelog](https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-client/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 186b0015f..3599bf849 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ }, "dependencies": { "apollo-cache-inmemory": "~1.3.12", - "apollo-client": "~2.4.8", + "apollo-client": "~2.4.9", "apollo-link-http": "~1.5.9", "apollo-server": "~2.3.1", "bcryptjs": "~2.4.3", diff --git a/yarn.lock b/yarn.lock index cf600e248..5c79a82a9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1023,23 +1023,23 @@ apollo-cache-inmemory@~1.3.12: apollo-utilities "^1.0.27" optimism "^0.6.8" -apollo-cache@1.1.22, apollo-cache@^1.1.22: - version "1.1.22" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.22.tgz#d4682ea6e8b2508a934f61c2fd9e36b4a65041d9" - integrity sha512-8PoxhQLISj2oHwT7i/r4l+ly4y3RKZls+dtXzAewu3U77P9dNZKhYkRNAhx9iEfsrNoHgXBV8vMp64hb1uYh+g== +apollo-cache@1.1.23, apollo-cache@^1.1.22: + version "1.1.23" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.23.tgz#4765571223cae756ab7faf29792f1ab9a8450a91" + integrity sha512-9FcavymJQdjaYX6of1xgjFmWp8UUCtlW/S9k5bfMMnMNAAQMDnuOFVEklawdSbyAhM4hh1kSymyt/r23K1tVSA== dependencies: - apollo-utilities "^1.0.27" + apollo-utilities "^1.1.0" -apollo-client@~2.4.8: - version "2.4.8" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.8.tgz#3a798f1076243465a59061d44d11bd030b68deb9" - integrity sha512-OAFbCTnGPtaIv0j+EZYzY20d+MD2JNbJ/YXZ4s0/oZlSg87bb0gjcIbccw2lnytipymZcZNr5ArFFeh0saGEwA== +apollo-client@~2.4.9: + version "2.4.9" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.9.tgz#c5fbd4d04645e228dd6a49f5b03b41cb1c2e5ae7" + integrity sha512-7IoIz+3hAk3166663ioyrsPdlTSAQa24HsJPVWw2QM/UE1wZTommu+uhwj9KugL6vpE/wyhyYgEs/9R7PlCsQA== dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.22" + apollo-cache "1.1.23" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "1.0.27" + apollo-utilities "1.1.0" symbol-observable "^1.0.2" zen-observable "^0.8.0" optionalDependencies: @@ -1307,10 +1307,10 @@ apollo-upload-server@^5.0.0: busboy "^0.2.14" object-path "^0.11.4" -apollo-utilities@1.0.27, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.27: - version "1.0.27" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.27.tgz#77c550f9086552376eca3a48e234a1466b5b057e" - integrity sha512-nzrMQ89JMpNmYnVGJ4t8zN75gQbql27UDhlxNi+3OModp0Masx5g+fQmQJ5B4w2dpRuYOsdwFLmj3lQbwOKV1Q== +apollo-utilities@1.1.0, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.27, apollo-utilities@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.0.tgz#e7603f834b57e4e109be6b450dc1cc1037aac94c" + integrity sha512-D3scmF6vJkCBECMasMEc0J9dNNHVULl6h2d7/oGJxWid1fgcAPHZJN5XLCZisuOfn0Dvvu3Unf/zK00Z3e49Qg== dependencies: fast-json-stable-stringify "^2.0.0" From dfd2550cf8474823a280826bf155548564a8dfcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 18 Jan 2019 08:23:32 +0000 Subject: [PATCH 273/554] Bump graphql-yoga from 1.16.7 to 1.17.0 Bumps [graphql-yoga](https://github.com/prisma/graphql-yoga) from 1.16.7 to 1.17.0. - [Release notes](https://github.com/prisma/graphql-yoga/releases) - [Commits](https://github.com/prisma/graphql-yoga/compare/v1.16.7...v1.17.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 44 +++++++++++++++++++------------------------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 3599bf849..9d6bbba89 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "graphql-middleware": "~1.7.8", "graphql-shield": "~4.1.2", "graphql-tag": "~2.10.1", - "graphql-yoga": "~1.16.7", + "graphql-yoga": "~1.17.0", "jsonwebtoken": "~8.4.0", "linkifyjs": "~2.1.7", "lodash": "~4.17.11", diff --git a/yarn.lock b/yarn.lock index 5c79a82a9..424aa751a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -644,13 +644,6 @@ core-js "^2.5.7" regenerator-runtime "^0.12.0" -"@babel/runtime@^7.0.0-beta.40": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.2.0.tgz#b03e42eeddf5898e00646e4c840fa07ba8dcad7f" - integrity sha512-oouEibCbHMVdZSDlJBO6bZmID/zA/G/Qx3H1d3rSNPTD+L8UNKvCat7aKWSJ74zYbm5zWGh0GQN0hKj8zYFTCg== - dependencies: - regenerator-runtime "^0.12.0" - "@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2": version "7.1.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" @@ -1298,13 +1291,14 @@ apollo-tracing@^0.1.0: dependencies: graphql-extensions "~0.0.9" -apollo-upload-server@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/apollo-upload-server/-/apollo-upload-server-5.0.0.tgz#c953b523608313966e0c8444637f4ae8ef77d5bc" - integrity sha512-CzbHvMo/6TO5XrovzmV/ojTft17s9Cd+vKLGngChpB0UW1ObxKlNLlcXRLD+yt6Nec32/Kt209HmA31hnwxB/g== +apollo-upload-server@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/apollo-upload-server/-/apollo-upload-server-7.1.0.tgz#21e07b52252b3749b913468599813e13cfca805f" + integrity sha512-cD9ReCeyurYwZyEDqJYb5TOc9dt8yhPzS+MtrY3iJdqw+pqiiyPngAvVXHjN+Ca7Lajvom4/AT/PBrYVDMM3Kw== dependencies: - "@babel/runtime" "^7.0.0-beta.40" busboy "^0.2.14" + fs-capacitor "^1.0.0" + http-errors "^1.7.0" object-path "^0.11.4" apollo-utilities@1.1.0, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.27, apollo-utilities@^1.1.0: @@ -3469,12 +3463,12 @@ graphql-iso-date@~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@1.7.7: - version "1.7.7" - resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.7.tgz#0a7a7193a873c4769401df2aef4ffb9c6ca97f43" - integrity sha512-Y4aXFMVLaGiZ19ukibZ4x/RejuUPhsJteijQFRlvmkGpF+XBHG/xozeDTWt0M1aJRjJWmwjna0nko6/o/DJQRQ== +graphql-middleware@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-3.0.0.tgz#df498cc2c19ca5936fc67e9e39df6c484dbf4d80" + integrity sha512-m1V5G8jTatG8ZbFWLWBqrlVbHNpJv/U15LJ8U3XAoLjxm5HRY9rVXns6I4gigJqUt/0i/xYO7Lk3YkxqHi8QmQ== dependencies: - graphql-tools "^4.0.1" + graphql-tools "^4.0.3" graphql-middleware@~1.7.8: version "1.7.8" @@ -3538,7 +3532,7 @@ graphql-tag@^2.9.2, graphql-tag@~2.10.1: resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02" integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg== -graphql-tools@^4.0.0, graphql-tools@^4.0.1, graphql-tools@^4.0.2: +graphql-tools@^4.0.0, graphql-tools@^4.0.2, graphql-tools@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.3.tgz#23b5cb52c519212b1b2e4630a361464396ad264b" integrity sha512-NNZM0WSnVLX1zIMUxu7SjzLZ4prCp15N5L2T2ro02OVyydZ0fuCnZYRnx/yK9xjGWbZA0Q58yEO//Bv/psJWrg== @@ -3559,10 +3553,10 @@ graphql-upload@^8.0.2: http-errors "^1.7.1" object-path "^0.11.4" -graphql-yoga@~1.16.7: - version "1.16.7" - resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.16.7.tgz#05bdfadf9a4623b0409bee3c5b75b7b3f7249e6f" - integrity sha512-N82SmBpKyDD7GXXo2NbVBMPffbxFWD+YOf/Vqx3Kujj/hNOX+0s/7G+EPp4TgJZqHQjcOw5TqQ0kOANO8w6Kmg== +graphql-yoga@~1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.17.0.tgz#54836fbb43720a19f5ff2357273c2f380e536ed7" + integrity sha512-2uPz7tmkOP8ktnsFIc6blRO6R5RTofWY0ugxKcvR4QlTveNcfKwOiXMVEn8yJulodEGhJLENXJklSxEIyeIbOg== dependencies: "@types/cors" "^2.8.4" "@types/express" "^4.11.1" @@ -3571,7 +3565,7 @@ graphql-yoga@~1.16.7: "@types/zen-observable" "^0.5.3" apollo-server-express "^1.3.6" apollo-server-lambda "1.3.6" - apollo-upload-server "^5.0.0" + apollo-upload-server "^7.0.0" aws-lambda "^0.1.2" body-parser-graphql "1.1.0" cors "^2.8.4" @@ -3579,7 +3573,7 @@ graphql-yoga@~1.16.7: graphql "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0" graphql-deduplicator "^2.0.1" graphql-import "^0.7.0" - graphql-middleware "1.7.7" + graphql-middleware "3.0.0" graphql-playground-middleware-express "1.7.6" graphql-playground-middleware-lambda "1.7.6" graphql-subscriptions "^0.5.8" @@ -3763,7 +3757,7 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -http-errors@^1.7.1: +http-errors@^1.7.0, http-errors@^1.7.1: version "1.7.1" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.1.tgz#6a4ffe5d35188e1c39f872534690585852e1f027" integrity sha512-jWEUgtZWGSMba9I1N3gc1HmvpBUaNC9vDdA46yScAdp+C5rdEuKWUBLWTQpW9FwSWSbYYs++b6SDCxf9UEJzfw== From a9d271ca475ae936b4324170840306c0666b5c22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 18 Jan 2019 09:00:09 +0000 Subject: [PATCH 274/554] Bump apollo-cache-inmemory from 1.3.12 to 1.4.0 Bumps [apollo-cache-inmemory](https://github.com/apollographql/apollo-client) from 1.3.12 to 1.4.0. - [Release notes](https://github.com/apollographql/apollo-client/releases) - [Changelog](https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-client/commits/v1.4.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 9d6bbba89..3efca40be 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "testMatch": ["**/src/**/?(*.)+(spec|test).js?(x)" ] }, "dependencies": { - "apollo-cache-inmemory": "~1.3.12", + "apollo-cache-inmemory": "~1.4.0", "apollo-client": "~2.4.9", "apollo-link-http": "~1.5.9", "apollo-server": "~2.3.1", diff --git a/yarn.lock b/yarn.lock index 424aa751a..a38f8fe6b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1007,16 +1007,16 @@ apollo-cache-control@^0.1.0: dependencies: graphql-extensions "^0.0.x" -apollo-cache-inmemory@~1.3.12: - version "1.3.12" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.3.12.tgz#cf7ef7c15730d0b6787d79047d5c06087ac31991" - integrity sha512-jxWcW64QoYQZ09UH6v3syvCCl3MWr6bsxT3wYYL6ORi8svdJUpnNrHTcv5qXqJYVg/a+NHhfEt+eGjJUG2ytXA== +apollo-cache-inmemory@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.4.0.tgz#8bcb1de8d1950dcdbd42f9af6d16fccca8e9e9ca" + integrity sha512-gqwiZCApG+hRXEbtDrNIUtNcKKeO3RTih4mydJZRJpFp+PgBf8AZ2z4/uTJFFijmR9krmUWdCRfW1Aesb5+Ktg== dependencies: - apollo-cache "^1.1.22" - apollo-utilities "^1.0.27" + apollo-cache "^1.1.23" + apollo-utilities "^1.1.0" optimism "^0.6.8" -apollo-cache@1.1.23, apollo-cache@^1.1.22: +apollo-cache@1.1.23, apollo-cache@^1.1.23: version "1.1.23" resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.23.tgz#4765571223cae756ab7faf29792f1ab9a8450a91" integrity sha512-9FcavymJQdjaYX6of1xgjFmWp8UUCtlW/S9k5bfMMnMNAAQMDnuOFVEklawdSbyAhM4hh1kSymyt/r23K1tVSA== @@ -1301,7 +1301,7 @@ apollo-upload-server@^7.0.0: http-errors "^1.7.0" object-path "^0.11.4" -apollo-utilities@1.1.0, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.27, apollo-utilities@^1.1.0: +apollo-utilities@1.1.0, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.0.tgz#e7603f834b57e4e109be6b450dc1cc1037aac94c" integrity sha512-D3scmF6vJkCBECMasMEc0J9dNNHVULl6h2d7/oGJxWid1fgcAPHZJN5XLCZisuOfn0Dvvu3Unf/zK00Z3e49Qg== From 8b20f447f33cbee7efba314ea03ac9b2f8173a0c Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 18 Jan 2019 10:51:33 +0100 Subject: [PATCH 275/554] Fixed lint issues --- package.json | 4 +- src/graphql-schema.js | 20 +++---- yarn.lock | 126 +++++++++++++++++++++++------------------- 3 files changed, 81 insertions(+), 69 deletions(-) diff --git a/package.json b/package.json index 3efca40be..e564a50e7 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,9 @@ "license": "MIT", "jest": { "verbose": true, - "testMatch": ["**/src/**/?(*.)+(spec|test).js?(x)" ] + "testMatch": [ + "**/src/**/?(*.)+(spec|test).js?(x)" + ] }, "dependencies": { "apollo-cache-inmemory": "~1.4.0", diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 8f6d605e2..e9475539b 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -135,16 +135,16 @@ export const resolvers = { let contentType switch (resource.type) { - case 'post': - case 'contribution': - contentType = 'Post' - break - case 'comment': - contentType = 'Comment' - break - case 'user': - contentType = 'User' - break + case 'post': + case 'contribution': + contentType = 'Post' + break + case 'comment': + contentType = 'Comment' + break + case 'user': + contentType = 'User' + break } await session.run( diff --git a/yarn.lock b/yarn.lock index a38f8fe6b..6b79c3a40 100644 --- a/yarn.lock +++ b/yarn.lock @@ -841,9 +841,9 @@ integrity sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA== "@types/node@*", "@types/node@^10.1.0": - version "10.12.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.12.tgz#e15a9d034d9210f00320ef718a50c4a799417c47" - integrity sha512-Pr+6JRiKkfsFvmU/LK68oBRCQeEg36TyAbPhc2xpez24OOZZCuoIhWGTd39VZy6nGafSbxzGouFPTFD/rR1A0A== + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== "@types/range-parser@*": version "1.2.3" @@ -984,13 +984,13 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -apollo-cache-control@0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.3.tgz#ad71d8f786e06f0275b2432004c15c2d37c48484" - integrity sha512-X6JhKfIaMLfl2jpsK/880BflXA+2lmm2sAsOZL4Bn2VrMsDtOssI1Ij9vNRbch9k9cA4WJvKed7Sql/wUIa1Eg== +apollo-cache-control@0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.4.tgz#286344a417f5489ab034f9fb22ba106ebafbd666" + integrity sha512-9Z9cAfsTQELGvn0CZ4lEg/Kk5WnjRafU58Q9lMi+XOqSrYyX+MRe5pX4dI6jMVMTWfD0D7lyJZxAzoNrF/yZHA== dependencies: apollo-server-env "2.2.0" - graphql-extensions "0.3.3" + graphql-extensions "0.3.7" apollo-cache-control@0.4.0: version "0.4.0" @@ -1046,10 +1046,10 @@ apollo-datasource@0.2.1: apollo-server-caching "0.2.1" apollo-server-env "2.2.0" -apollo-engine-reporting-protobuf@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.1.0.tgz#fbc220cac2a3b7800ffc155d7e54c21c56b7848e" - integrity sha512-GReJtAYTmpwg0drb9VgFtqObYYTCHkJhlHEYCeXY8bJV4fOgXsAZ7CIXR9nPKO0mBaoHIHaGYvXGcyCLrZ36VA== +apollo-engine-reporting-protobuf@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.1.1.tgz#016d9ee1a73c6c0c666de975d117797fb8b390ea" + integrity sha512-HoXf7mcz0ZqTiubXLnymPK50iZOyw4h/HlzVETxCwE+PHNBcVBAA+fWram/oW1cqK2JPTQOYWszxHxPwcus+eQ== dependencies: protobufjs "^6.8.6" @@ -1060,15 +1060,15 @@ apollo-engine-reporting-protobuf@0.2.0: dependencies: protobufjs "^6.8.6" -apollo-engine-reporting@0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.3.tgz#85ad6ffd71db8f877202ce8b3d7dbfa7cabfbcf9" - integrity sha512-VkjiifHMHIAxydXecT+ck0WtqpFIsMlylKnKeuNAXfIfAXHX/JYtLhbArTTyhDunLrphMiUewfFv9P0K+aX2jw== +apollo-engine-reporting@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.4.tgz#2fb52f2cf8880f758a4d790a11bb246e7c934492" + integrity sha512-484nvAuwpmm3WHgIFs7FQ1dhHmRClTHqMT0sLsxJBgpd/MwTWBAw8lDxRa+FrJrqegeWc30K8tCa24hZ3+Ifrw== dependencies: - apollo-engine-reporting-protobuf "0.1.0" + apollo-engine-reporting-protobuf "0.1.1" apollo-server-env "2.2.0" async-retry "^1.2.1" - graphql-extensions "0.3.3" + graphql-extensions "0.3.7" lodash "^4.17.10" apollo-engine-reporting@0.2.0: @@ -1127,24 +1127,24 @@ apollo-server-caching@0.2.1: dependencies: lru-cache "^5.0.0" -apollo-server-core@2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.6.tgz#33031a3e1156d4cd0ad3c5c49de263173f521b32" - integrity sha512-hC3+Y9A4rN4W2X2cWqjrWWHkjKaG/jUQjtAVpQteDW+7n3bLKHCrpDFiFad++lq0ymRVW8diAaYDS4myJwjmoA== +apollo-server-core@2.2.7: + version "2.2.7" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.7.tgz#1229f5ed54438bafbf2bb3f1c872d5c551b62833" + integrity sha512-fIdoZGoBtYW9U5NWlCdKNb17TOmrdrYIN/f12ILcysoBxTyAsBImZMLOLvyTV0sUSgx7Q9dV7ddiMufXGdAy5Q== dependencies: "@apollographql/apollo-tools" "^0.2.6" "@apollographql/apollo-upload-server" "^5.0.3" "@apollographql/graphql-playground-html" "^1.6.6" "@types/ws" "^6.0.0" - apollo-cache-control "0.3.3" + apollo-cache-control "0.3.4" apollo-datasource "0.2.1" - apollo-engine-reporting "0.1.3" + apollo-engine-reporting "0.1.4" apollo-server-caching "0.2.1" apollo-server-env "2.2.0" apollo-server-errors "2.2.0" - apollo-server-plugin-base "0.1.6" - apollo-tracing "0.3.3" - graphql-extensions "0.3.6" + apollo-server-plugin-base "0.1.7" + apollo-tracing "0.3.4" + graphql-extensions "0.3.7" graphql-subscriptions "^1.0.0" graphql-tag "^2.9.2" graphql-tools "^4.0.0" @@ -1240,10 +1240,10 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== -apollo-server-plugin-base@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.6.tgz#56932c0e3a0366e03952a6e2805efe5fa2e046bf" - integrity sha512-nh6I2+mgSL5cYxqYXymAr8xBZ/ju8nunPjHp/21+/mgbF4Is0xtM9oDq5Qf0Q/cGh/djF6YcBuB1yUG+68gJXw== +apollo-server-plugin-base@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.7.tgz#fb91a0ba8ff505c01287227c874de6f272e5512a" + integrity sha512-Bfw++UWh0kzoAHqlsiYa/bxQSftCvwsF4KteFArTOKQjquBn1TTCWb64JTR5itZYuC5GDsoXGFQjQA3wWJyDVw== apollo-server-plugin-base@0.2.1: version "0.2.1" @@ -1251,11 +1251,11 @@ apollo-server-plugin-base@0.2.1: integrity sha512-497NIY9VWRYCrMSkgR11IrIUO4Fsy6aGgnpOJoTdLQAnkDD9SJDSRzwKj4gypUoTT2unfKDng4eMxXVZlHvjOw== apollo-server-testing@~2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.2.6.tgz#3ec60b6f099c2c55bd313cdbb8c177d8c86cda6d" - integrity sha512-1wUisLnY6fPNPK3RuE56q45K5bWWYIrEzfbw6dJudCBo7dtkMg33IfVwHvekbSFmRXmHIsnD0c1GSA10PV307A== + version "2.2.7" + resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.2.7.tgz#8210e15ac2d53f174e15f4856a7b47d3a00d8c53" + integrity sha512-S+5yLcbwKe1sJ/mG8tPKSrc9mOCqGq07nCqbzaTwiorkJiKxoChMugHT30CGuNGoa0B7Vfdg2wOq3/zsO1i67w== dependencies: - apollo-server-core "2.2.6" + apollo-server-core "2.2.7" apollo-server@~2.3.1: version "2.3.1" @@ -1268,13 +1268,13 @@ apollo-server@~2.3.1: graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" -apollo-tracing@0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.3.tgz#b819942180480c1c4d89e613cf2eff8f6d8b595a" - integrity sha512-gsTYgDVjtMlnomPq46aky7yk8XshCQfj9rxalCCismLlMomVW44fq+8GKQnZIkFOwiAsazRy4dzZ0cBbygA9sA== +apollo-tracing@0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.4.tgz#32f1c3dad6a0a5aa1fb442f006bf2ef248a125ae" + integrity sha512-U10mTuCic6Xi7Xez7SZic+nNuwFmZ4OlQnR835qGIkE8tq2GtXfFNcofO8kEDnGAnJasoUng8KIrZkSlUJdUSg== dependencies: apollo-server-env "2.2.0" - graphql-extensions "0.3.3" + graphql-extensions "0.3.7" apollo-tracing@0.4.0: version "0.4.0" @@ -2212,14 +2212,19 @@ core-js@^2.5.0: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042" integrity sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg== -core-js@^2.5.3, core-js@^2.5.7: +core-js@^2.5.3: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" +core-js@^2.5.7: + version "2.6.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.2.tgz#267988d7268323b349e20b4588211655f0e83944" + integrity sha512-NdBPF/RVwPW6jr0NCILuyN9RiqLo2b1mddWHkUL+VnvcB7dzlnBJ1bXYntjpTGOgkZiiLWj2JxmOr7eGE3qK6g== + core-js@^3.0.0-beta.3: - version "3.0.0-beta.4" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.4.tgz#7443c32990d21198d23de18acb061a5e5bc9f549" - integrity sha512-yz4iJCkkSQLQSLHPGUln6r5ZBkLPzZSvHG0g1nfvcdnmpIe+KE9WOb1ZEEf6EEaEmjp9Ol0Kw5J5vnoIWc5eWw== + version "3.0.0-beta.9" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.9.tgz#1897789a5ef0ee1190d54777f35f80c38c077633" + integrity sha512-OGLbGro2f0s8UXVyu2s9kIW42pcuRoNEqJsmn8a4rAOO9G5A2t96l++rf+4mHNw9GKrbdozZ9G5ieDKOBl68zQ== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -2623,7 +2628,7 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.4.3, es-abstract@^1.5.1: +es-abstract@^1.4.3: version "1.12.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== @@ -2634,7 +2639,19 @@ es-abstract@^1.4.3, es-abstract@^1.5.1: is-callable "^1.1.3" is-regex "^1.0.4" -es-to-primitive@^1.1.1: +es-abstract@^1.5.1: + 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== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-keys "^1.0.12" + +es-to-primitive@^1.1.1, es-to-primitive@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== @@ -3414,17 +3431,10 @@ graphql-deduplicator@^2.0.1: resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3" integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA== -graphql-extensions@0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.3.tgz#277efe11976bbdfd59915551606a2d550247bb45" - integrity sha512-pudOaHq7Ok+rh1ElzlqFaoYZWGefUNsqn/jX6eKns7rl0VHuB4qZBfhpVLTpquJpM6Y19/hsCYZNPfnUVMFIiA== - dependencies: - "@apollographql/apollo-tools" "^0.2.6" - -graphql-extensions@0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.6.tgz#9ddb294b4b3303df4bbfd8258f10ad402e290dba" - integrity sha512-QGnDQ0TkF1YpVE/ZvKVl3bZ1PfwSbynVBcNU5U1DPU56pLkltETORiFL4TQ/Tt7RzagBX/xVaI3q0xJC6h9M5w== +graphql-extensions@0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.7.tgz#1a7bb99a0e29c105dd64d8dccb955ddc8ddc31ad" + integrity sha512-i9Zo1w5uZmHoKP2qlh4PfxD85Ju08lMYrjUL6tROqipWTdrGMc107kUWBsiRvAVipcTyagKhDLF75FIvJiaHBg== dependencies: "@apollographql/apollo-tools" "^0.2.6" @@ -3681,7 +3691,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.1: +has@^1.0.1, has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== From 4c265bf3b8395735087406aac16e302ea83b6721 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 18 Jan 2019 11:22:44 +0100 Subject: [PATCH 276/554] Fixed report seeding --- src/seed/data/reports.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/seed/data/reports.js b/src/seed/data/reports.js index 939fe087b..9cecc4f9a 100644 --- a/src/seed/data/reports.js +++ b/src/seed/data/reports.js @@ -1,26 +1,26 @@ export default function (data) { return ` mutation { - r1: CreateReport(id: "r1", description: "Bad Stuff") { + r1: CreateReport(id: "r1", type: contribution, description: "Bad Stuff") { id } - r2: CreateReport(id: "r2", description: "Please remove this sh**") { + r2: CreateReport(id: "r2", type: comment, description: "Please remove this sh**") { id } - r3: CreateReport(id: "r3", description: "The user have misbehaved!") { + r3: CreateReport(id: "r3", type: user, description: "The user have misbehaved!") { id } - ra1: AddReportAuthor(from: { id: "u1" }, to: { id: "r1" }) { + ra1: AddReportReporter(from: { id: "u1" }, to: { id: "r1" }) { from { id } } - ra2: AddReportAuthor(from: { id: "u2" }, to: { id: "r2" }) { + ra2: AddReportReporter(from: { id: "u2" }, to: { id: "r2" }) { from { id } } - ra3: AddReportAuthor(from: { id: "u3" }, to: { id: "r3" }) { + ra3: AddReportReporter(from: { id: "u3" }, to: { id: "r3" }) { from { id } From f0c18e2ccabae1438ba9ba88ce9c1cbe85e09d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 18 Jan 2019 21:07:24 +0100 Subject: [PATCH 277/554] Clean up Dockerfile, add known_hosts file @appinteractive it's troublesome to add the SSH private key via environment variable. You have to convert newlines to spaces and convert them back - which I think is error prone. I hope we can transfer the private key file on to our deployed container later on. --- db-migration-worker/.gitignore | 2 +- db-migration-worker/.ssh/.dockerignore | 1 + db-migration-worker/.ssh/known_hosts | 1 + db-migration-worker/Dockerfile | 4 +--- db-migration-worker/import.sh | 9 +++++---- docker-compose.override.yml | 5 +---- 6 files changed, 10 insertions(+), 12 deletions(-) create mode 100644 db-migration-worker/.ssh/.dockerignore create mode 100644 db-migration-worker/.ssh/known_hosts diff --git a/db-migration-worker/.gitignore b/db-migration-worker/.gitignore index 690bae050..87cb01310 100644 --- a/db-migration-worker/.gitignore +++ b/db-migration-worker/.gitignore @@ -1 +1 @@ -id_rsa +.ssh/id_rsa diff --git a/db-migration-worker/.ssh/.dockerignore b/db-migration-worker/.ssh/.dockerignore new file mode 100644 index 000000000..87cb01310 --- /dev/null +++ b/db-migration-worker/.ssh/.dockerignore @@ -0,0 +1 @@ +.ssh/id_rsa diff --git a/db-migration-worker/.ssh/known_hosts b/db-migration-worker/.ssh/known_hosts new file mode 100644 index 000000000..0ce0dce0d --- /dev/null +++ b/db-migration-worker/.ssh/known_hosts @@ -0,0 +1 @@ +|1|GuOYlVEhTowidPs18zj9p5F2j3o=|sDHJYLz9Ftv11oXeGEjs7SpVyg0= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBM5N29bI5CeKu1/RBPyM2fwyf7fuajOO+tyhKe1+CC2sZ1XNB5Ff6t6MtCLNRv2mUuvzTbW/HkisDiA5tuXUHOk= diff --git a/db-migration-worker/Dockerfile b/db-migration-worker/Dockerfile index 39ef39275..139b3403a 100644 --- a/db-migration-worker/Dockerfile +++ b/db-migration-worker/Dockerfile @@ -1,9 +1,7 @@ FROM mongo:latest -ARG KNOWN_HOST RUN apt-get update RUN apt-get -y install openssh-client -COPY id_rsa /root/.ssh/id_rsa -# RUN ssh-keyscan -H $KNOWN_HOST >> /root/.ssh/known_hosts +COPY .ssh /root/.ssh/ COPY import.sh . diff --git a/db-migration-worker/import.sh b/db-migration-worker/import.sh index 2ff3d6443..b1042844b 100755 --- a/db-migration-worker/import.sh +++ b/db-migration-worker/import.sh @@ -1,6 +1,6 @@ -#!/bin/bash +#!/usr/bin/env bash -for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "NEO4J_USERNAME" "NEO4J_PASSWORD" "MONGODB_AUTH_DB" +for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "MONGODB_AUTH_DB" do if [[ -z "${!var}" ]]; then echo "${var} is undefined" @@ -14,10 +14,11 @@ echo "MONGODB_USERNAME ${MONGODB_USERNAME}" echo "MONGODB_PASSWORD ${MONGODB_PASSWORD}" echo "MONGODB_DATABASE ${MONGODB_DATABASE}" echo "MONGODB_AUTH_DB ${MONGODB_AUTH_DB}" -echo "NEO4J_USERNAME ${NEO4J_USERNAME}" -echo "NEO4J_PASSWORD ${NEO4J_PASSWORD}" echo "-------------------------------------------------" +mongo ${MONGODB_DATABASE} --eval "db.dropDatabase();" +rm -f /mongo-export/* + ssh -4 -M -S my-ctrl-socket -fnNT -L 27018:localhost:27017 -l ${SSH_USERNAME} ${SSH_HOST} mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --gzip --archive | mongorestore --gzip --archive ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST} diff --git a/docker-compose.override.yml b/docker-compose.override.yml index c1ac0569d..c8644a6f8 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -18,15 +18,12 @@ services: - 7474:7474 environment: - NEO4J_apoc_import_file_enabled=true - - "NEO4J_USERNAME=${NEO4J_USERNAME}" - - "NEO4J_PASSWORD=${NEO4J_PASSWORD}" db-migration-worker: build: context: db-migration-worker - args: - - "KNOWN_HOST=${SSH_HOST}" volumes: - mongo-export:/mongo-export + - ./db-migration-worker/.ssh/:/root/.ssh/ networks: - hc-network environment: From 4534f1ae9e215def40842536cea4b3efb37d00b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 18 Jan 2019 21:18:59 +0100 Subject: [PATCH 278/554] Add production server to known_hosts --- db-migration-worker/.ssh/known_hosts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/db-migration-worker/.ssh/known_hosts b/db-migration-worker/.ssh/known_hosts index 0ce0dce0d..947840cb2 100644 --- a/db-migration-worker/.ssh/known_hosts +++ b/db-migration-worker/.ssh/known_hosts @@ -1 +1,3 @@ |1|GuOYlVEhTowidPs18zj9p5F2j3o=|sDHJYLz9Ftv11oXeGEjs7SpVyg0= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBM5N29bI5CeKu1/RBPyM2fwyf7fuajOO+tyhKe1+CC2sZ1XNB5Ff6t6MtCLNRv2mUuvzTbW/HkisDiA5tuXUHOk= +|1|2KP9NV+Q5g2MrtjAeFSVcs8YeOI=|nf3h4wWVwC4xbBS1kzgzE2tBldk= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNhRK6BeIEUxXlS0z/pOfkUkSPfn33g4J1U3L+MyUQYHm+7agT08799ANJhnvELKE1tt4Vx80I9UR81oxzZcy3E= +|1|HonYIRNhKyroUHPKU1HSZw0+Qzs=|5T1btfwFBz2vNSldhqAIfTbfIgQ= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNhRK6BeIEUxXlS0z/pOfkUkSPfn33g4J1U3L+MyUQYHm+7agT08799ANJhnvELKE1tt4Vx80I9UR81oxzZcy3E= From 97e6acf46b6753ffe262a00ee5ab73487d79d2a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 18 Jan 2019 22:45:29 +0100 Subject: [PATCH 279/554] Import of all users in one script: ```sh docker-compose exec neo4j import/import.sh ``` --- docker-compose.override.yml | 1 + neo4j/Dockerfile | 2 +- neo4j/import/import.sh | 4 ++++ neo4j/{import.cql => import/import.todo} | 17 ----------------- neo4j/import/users.cql | 20 ++++++++++++++++++++ src/seed/reset-db.js | 7 ++++++- 6 files changed, 32 insertions(+), 19 deletions(-) create mode 100755 neo4j/import/import.sh rename neo4j/{import.cql => import/import.todo} (79%) create mode 100644 neo4j/import/users.cql diff --git a/docker-compose.override.yml b/docker-compose.override.yml index c8644a6f8..c5e7d5cf9 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -13,6 +13,7 @@ services: neo4j: volumes: - mongo-export:/mongo-export + - ./neo4j/import:/var/lib/neo4j/import ports: - 7687:7687 - 7474:7474 diff --git a/neo4j/Dockerfile b/neo4j/Dockerfile index 2ef9443a5..07344b47b 100644 --- a/neo4j/Dockerfile +++ b/neo4j/Dockerfile @@ -1,3 +1,3 @@ FROM neo4j:3.5.0 RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.1/apoc-3.5.0.1-all.jar -P plugins/ -COPY import.cql . +COPY import ./import diff --git a/neo4j/import/import.sh b/neo4j/import/import.sh new file mode 100755 index 000000000..88a2666dc --- /dev/null +++ b/neo4j/import/import.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +echo "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r;" | cypher-shell +cat $SCRIPT_DIRECTORY/*.cql | cypher-shell diff --git a/neo4j/import.cql b/neo4j/import/import.todo similarity index 79% rename from neo4j/import.cql rename to neo4j/import/import.todo index 521cc1221..672ef0116 100644 --- a/neo4j/import.cql +++ b/neo4j/import/import.todo @@ -13,23 +13,6 @@ ON CREATE SET b.key = badge.key, b.status = badge.status -CALL apoc.load.json('file:/mongo-export/users.json') YIELD value as user -MERGE(u:User {id: user._id["$oid"]}) -ON CREATE SET u.name = user.name, - u.slug = user.slug, - u.email = user.email, - u.password = user.password, - u.avatar = user.avatar, - u.coverImg = user.coverImg, - u.wasInvited = user.wasInvited, - u.role = apoc.text.toUpperCase(user.role) -WITH u, user, user.badgeIds AS badgeIds -UNWIND badgeIds AS badgeId -MATCH (b:Badge {id: badgeId}) -MERGE (b)-[:REWARDED]->(u) - - - CALL apoc.load.json('file:/mongo-export/contributions.json') YIELD value as post MERGE (p:Post {id: post._id["$oid"]}) ON CREATE SET p.title = post.title, diff --git a/neo4j/import/users.cql b/neo4j/import/users.cql new file mode 100644 index 000000000..96abb1637 --- /dev/null +++ b/neo4j/import/users.cql @@ -0,0 +1,20 @@ +CALL apoc.load.json('file:/mongo-export/users.json') YIELD value as user +MERGE(u:User {id: user._id["$oid"]}) +ON CREATE SET +u.name = user.name, +u.slug = user.slug, +u.email = user.email, +u.password = user.password, +u.avatar = user.avatar, +u.coverImg = user.coverImg, +u.wasInvited = user.wasInvited, +u.role = toLower(user.role), +u.createdAt = user.createdAt.`$date`, +u.updatedAt = user.updatedAt.`$date`, +u.deleted = false, +u.disabled = false +WITH u, user, user.badgeIds AS badgeIds +UNWIND badgeIds AS badgeId +MATCH (b:Badge {id: badgeId}) +MERGE (b)-[:REWARDED]->(u) +; diff --git a/src/seed/reset-db.js b/src/seed/reset-db.js index 616ff71e8..7d7c4f3f9 100644 --- a/src/seed/reset-db.js +++ b/src/seed/reset-db.js @@ -11,7 +11,12 @@ if (process.env.NODE_ENV === 'production') { const driver = neo4j().getDriver() const session = driver.session() -query('MATCH (n) DETACH DELETE n', session).then(() => { +const deleteAll = ` +MATCH (n) +OPTIONAL MATCH (n)-[r]-() +DELETE n,r +` +query(deleteAll, session).then(() => { /* eslint-disable-next-line no-console */ console.log('Successfully deleted all nodes and relations!') }).catch((err) => { From 887a6d201f8140b280a99f01c19b10b0cf92d7a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 18 Jan 2019 23:53:00 +0100 Subject: [PATCH 280/554] Import contributions to neo4j --- neo4j/import/contributions.cql | 23 +++++++++++++++++++++++ neo4j/import/{import.todo => todo} | 19 ------------------- neo4j/import/users.cql | 2 +- 3 files changed, 24 insertions(+), 20 deletions(-) create mode 100644 neo4j/import/contributions.cql rename neo4j/import/{import.todo => todo} (61%) diff --git a/neo4j/import/contributions.cql b/neo4j/import/contributions.cql new file mode 100644 index 000000000..86226b98f --- /dev/null +++ b/neo4j/import/contributions.cql @@ -0,0 +1,23 @@ +CALL apoc.load.json('file:/mongo-export/contributions.json') YIELD value as post +MERGE (p:Post {id: post._id["$oid"]}) +ON CREATE SET +p.title = post.title, +p.slug = post.slug, +p.image = post.teaserImg, +p.content = post.content, +p.contentExcerpt = post.contentExcerpt, +p.visibility = toLower(post.visibility), +p.createdAt = post.createdAt.`$date`, +p.updatedAt = post.updatedAt.`$date`, +p.deleted = post.deleted, +p.disabled = NOT post.isEnabled +WITH p, post, post.tags AS tags, post.categoryIds as categoryIds +UNWIND tags AS tag +UNWIND categoryIds AS categoryId +MATCH (c:Category {id: categoryId}), + (u:User {id: post.userId}) +MERGE (t:Tag {id: apoc.create.uuid(), name: tag}) +MERGE (p)-[:TAGGED]->(t) +MERGE (u)-[:WROTE]->(p) +MERGE (p)-[:CATEGORIZED]->(c) +; diff --git a/neo4j/import/import.todo b/neo4j/import/todo similarity index 61% rename from neo4j/import/import.todo rename to neo4j/import/todo index 672ef0116..2d912c5d4 100644 --- a/neo4j/import/import.todo +++ b/neo4j/import/todo @@ -13,25 +13,6 @@ ON CREATE SET b.key = badge.key, b.status = badge.status -CALL apoc.load.json('file:/mongo-export/contributions.json') YIELD value as post -MERGE (p:Post {id: post._id["$oid"]}) -ON CREATE SET p.title = post.title, - p.slug = post.slug, - p.image = post.teaserImg, - p.content = post.content, - p.contentExcerpt = post.contentExcerpt, - p.visibility = apoc.text.toUpperCase(post.visibility), - p.createdAt = datetime(post.createdAt["$date"]), - p.updatedAt = datetime(post.updatedAt["$date"]) -WITH p, post, post.tags AS tags, post.categoryIds as categoryIds -UNWIND tags AS tag -UNWIND categoryIds AS categoryId -MATCH (c:Category {id: categoryId}), - (u:User {id: post.userId}) -MERGE (t:Tag {id: apoc.create.uuid(), name: tag}) -MERGE (p)-[:TAGGED]->(t) -MERGE (u)-[:WROTE]->(p) -MERGE (p)-[:CATEGORIZED]->(c) CALL apoc.load.json('file:/mongo-export/comments.json') YIELD value as comment diff --git a/neo4j/import/users.cql b/neo4j/import/users.cql index 96abb1637..5f87bb273 100644 --- a/neo4j/import/users.cql +++ b/neo4j/import/users.cql @@ -11,7 +11,7 @@ u.wasInvited = user.wasInvited, u.role = toLower(user.role), u.createdAt = user.createdAt.`$date`, u.updatedAt = user.updatedAt.`$date`, -u.deleted = false, +u.deleted = user.deletedAt IS NOT NULL, u.disabled = false WITH u, user, user.badgeIds AS badgeIds UNWIND badgeIds AS badgeId From b2720249337a7ac0a4a2c3d23f214251a727db73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sat, 19 Jan 2019 00:01:30 +0100 Subject: [PATCH 281/554] Import comments --- neo4j/import/comments.cql | 12 ++++++++++++ neo4j/import/todo | 10 ---------- 2 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 neo4j/import/comments.cql diff --git a/neo4j/import/comments.cql b/neo4j/import/comments.cql new file mode 100644 index 000000000..16537b730 --- /dev/null +++ b/neo4j/import/comments.cql @@ -0,0 +1,12 @@ +CALL apoc.load.json('file:/mongo-export/comments.json') YIELD value as comment +MERGE (c:Comment {id: comment._id["$oid"]}) +ON CREATE SET +c.content = comment.content, +c.contentExcerpt = comment.contentExcerpt, +c.deleted = comment.deleted, +c.disabled = false +WITH comment +MATCH (p:Post {id: comment.contributionId}), (u:User {id: comment.userId}) +MERGE (c)-[:COMMENTS]->(p) +MERGE (u)-[:WROTE]->(c) +; diff --git a/neo4j/import/todo b/neo4j/import/todo index 2d912c5d4..0b86c8bc5 100644 --- a/neo4j/import/todo +++ b/neo4j/import/todo @@ -15,16 +15,6 @@ ON CREATE SET b.key = badge.key, -CALL apoc.load.json('file:/mongo-export/comments.json') YIELD value as comment -MERGE (c:Comment {id: comment._id["$oid"]}) -ON CREATE SET c.content = comment.content, - c.contentExcerpt = comment.contentExcerpt, - c.deleted = comment.deleted -WITH comment -MATCH (p:Post {id: comment.contributionId}), - (u:User {id: comment.userId}) -MERGE (c)-[:COMMENTS]->(p) -MERGE (u)-[:WROTE]->(c) CALL apoc.load.json('file:/mongo-export/follows.json') YIELD value as follow From 4a21e5b885df9fc161934aac99b6829cc3c88205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sat, 19 Jan 2019 00:27:37 +0100 Subject: [PATCH 282/554] Implement test for image middleware --- src/middleware/fixImageUrlsMiddleware.js | 2 +- src/middleware/fixImageUrlsMiddleware.spec.js | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/middleware/fixImageUrlsMiddleware.spec.js diff --git a/src/middleware/fixImageUrlsMiddleware.js b/src/middleware/fixImageUrlsMiddleware.js index 919a46ab6..8d72e2233 100644 --- a/src/middleware/fixImageUrlsMiddleware.js +++ b/src/middleware/fixImageUrlsMiddleware.js @@ -7,7 +7,7 @@ export const fixUrl = (url) => { url = url.replace(urlSearchLocal, '') return url } -const fixImageURLs = (result, recursive) => { +export const fixImageURLs = (result, recursive) => { if (result && typeof result === 'string' && (result.indexOf(urlSearchAlpha) === 0 || result.indexOf(urlSearchLocal) === 0)) { result = fixUrl(result) } else if (result && Array.isArray(result)) { diff --git a/src/middleware/fixImageUrlsMiddleware.spec.js b/src/middleware/fixImageUrlsMiddleware.spec.js new file mode 100644 index 000000000..837bd0d82 --- /dev/null +++ b/src/middleware/fixImageUrlsMiddleware.spec.js @@ -0,0 +1,30 @@ +import { fixImageURLs } from './fixImageUrlsMiddleware' + +describe('fixImageURLs', () => { + describe('image url of legacy alpha', () => { + it('removes domain', () => { + const url = 'https://api-alpha.human-connection.org/uploads/4bfaf9172c4ba03d7645108bbbd16f0a696a37d01eacd025fb131e5da61b15d9.png' + expect(fixImageURLs(url)).toEqual('/uploads/4bfaf9172c4ba03d7645108bbbd16f0a696a37d01eacd025fb131e5da61b15d9.png') + }) + }) + + describe('image url of legacy staging', () => { + it('removes domain', () => { + const url = 'https://staging-api.human-connection.org/uploads/1b3c39a24f27e2fb62b69074b2f71363b63b263f0c4574047d279967124c026e.jpeg' + expect(fixImageURLs(url)).toEqual('/uploads/1b3c39a24f27e2fb62b69074b2f71363b63b263f0c4574047d279967124c026e.jpeg') + }) + }) + + describe('object', () => { + it('returns untouched', () => { + const object = { some: 'thing' } + expect(fixImageURLs(object)).toEqual(object) + }) + }) + + describe('some string', () => { + it('returns untouched', () => {}) + const string = "Yeah I'm a String" + expect(fixImageURLs(string)).toEqual(string) + }) +}) From 5701185d3480b482efdb82ae580cecd316f608b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sat, 19 Jan 2019 00:36:55 +0100 Subject: [PATCH 283/554] Fix urls for staging-alpha --- src/middleware/fixImageUrlsMiddleware.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/middleware/fixImageUrlsMiddleware.js b/src/middleware/fixImageUrlsMiddleware.js index 8d72e2233..eacf5a090 100644 --- a/src/middleware/fixImageUrlsMiddleware.js +++ b/src/middleware/fixImageUrlsMiddleware.js @@ -1,14 +1,25 @@ -const urlSearchAlpha = 'https://api-alpha.human-connection.org' -const urlSearchLocal = 'http://localhost:3000' +const legacyUrls = [ + 'https://api-alpha.human-connection.org', + 'https://staging-api.human-connection.org', + 'http://localhost:3000' +] export const fixUrl = (url) => { - url = url.replace(urlSearchAlpha, '') - url = url.replace(urlSearchLocal, '') + legacyUrls.forEach((legacyUrl) => { + url = url.replace(legacyUrl, '') + }) return url } + +const checkUrl = (thing) => { + return thing && typeof thing === 'string' && legacyUrls.find((legacyUrl) => { + return thing.indexOf(legacyUrl) === 0 + }) +} + export const fixImageURLs = (result, recursive) => { - if (result && typeof result === 'string' && (result.indexOf(urlSearchAlpha) === 0 || result.indexOf(urlSearchLocal) === 0)) { + if(checkUrl(result)) { result = fixUrl(result) } else if (result && Array.isArray(result)) { result.forEach((res, index) => { From 8591816dfa7894b26ae776f9a2c4e69d01de9852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sat, 19 Jan 2019 00:57:12 +0100 Subject: [PATCH 284/554] Fix CodeFactor --- db-migration-worker/Dockerfile | 8 +++++--- db-migration-worker/import.sh | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/db-migration-worker/Dockerfile b/db-migration-worker/Dockerfile index 139b3403a..92dff618f 100644 --- a/db-migration-worker/Dockerfile +++ b/db-migration-worker/Dockerfile @@ -1,7 +1,9 @@ -FROM mongo:latest +FROM mongo:4 -RUN apt-get update -RUN apt-get -y install openssh-client +RUN apt-get update \ + && apt-get -y install --no-install-recommends openssh-client \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* COPY .ssh /root/.ssh/ COPY import.sh . diff --git a/db-migration-worker/import.sh b/db-migration-worker/import.sh index b1042844b..ba07217c0 100755 --- a/db-migration-worker/import.sh +++ b/db-migration-worker/import.sh @@ -4,7 +4,7 @@ for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONG do if [[ -z "${!var}" ]]; then echo "${var} is undefined" - exit -1 + exit 1 fi done From d0fa8b7e21fcba8c3943d3b9266cb7a6733d2a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sat, 19 Jan 2019 01:04:42 +0100 Subject: [PATCH 285/554] Run `yarn run lint --fix` --- docker-compose.yml | 2 +- src/middleware/fixImageUrlsMiddleware.js | 2 +- src/middleware/fixImageUrlsMiddleware.spec.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index df8de6b01..6905bb893 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,7 +17,7 @@ services: - GRAPHQL_PORT=4000 - GRAPHQL_URI=http://localhost:4000 - CLIENT_URI=http://localhost:3000 - - JWT_SECRET="b/&&7b78BF&fv/Vd" + - JWT_SECRET=b/&&7b78BF&fv/Vd - MOCK=false - MAPBOX_TOKEN=pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ diff --git a/src/middleware/fixImageUrlsMiddleware.js b/src/middleware/fixImageUrlsMiddleware.js index eacf5a090..c3b828dae 100644 --- a/src/middleware/fixImageUrlsMiddleware.js +++ b/src/middleware/fixImageUrlsMiddleware.js @@ -19,7 +19,7 @@ const checkUrl = (thing) => { } export const fixImageURLs = (result, recursive) => { - if(checkUrl(result)) { + if (checkUrl(result)) { result = fixUrl(result) } else if (result && Array.isArray(result)) { result.forEach((res, index) => { diff --git a/src/middleware/fixImageUrlsMiddleware.spec.js b/src/middleware/fixImageUrlsMiddleware.spec.js index 837bd0d82..081154c5c 100644 --- a/src/middleware/fixImageUrlsMiddleware.spec.js +++ b/src/middleware/fixImageUrlsMiddleware.spec.js @@ -24,7 +24,7 @@ describe('fixImageURLs', () => { describe('some string', () => { it('returns untouched', () => {}) - const string = "Yeah I'm a String" - expect(fixImageURLs(string)).toEqual(string) + const string = 'Yeah I\'m a String' + expect(fixImageURLs(string)).toEqual(string) }) }) From 3aef664c8c087e4ea6a734189cad21ec730a3468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sun, 20 Jan 2019 23:18:42 +0100 Subject: [PATCH 286/554] Import collections in order --- neo4j/import/import.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/neo4j/import/import.sh b/neo4j/import/import.sh index 88a2666dc..a08115005 100755 --- a/neo4j/import/import.sh +++ b/neo4j/import/import.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" echo "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r;" | cypher-shell -cat $SCRIPT_DIRECTORY/*.cql | cypher-shell +for collection in "users" "contributions" "comments" +do + echo "Import ${collection}..." && cat $SCRIPT_DIRECTORY/$collection.cql | cypher-shell +done From 5ccfed29945aa3c4b5d0d3d59bc5992600ca2ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sun, 20 Jan 2019 23:32:56 +0100 Subject: [PATCH 287/554] Fix CodeFactor --- neo4j/import/import.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neo4j/import/import.sh b/neo4j/import/import.sh index a08115005..319f1a591 100755 --- a/neo4j/import/import.sh +++ b/neo4j/import/import.sh @@ -3,5 +3,5 @@ SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pw echo "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r;" | cypher-shell for collection in "users" "contributions" "comments" do - echo "Import ${collection}..." && cat $SCRIPT_DIRECTORY/$collection.cql | cypher-shell + echo "Import ${collection}..." && cypher-shell < $SCRIPT_DIRECTORY/$collection.cql done From 670292b3ec686bb134ef5acdb22c7b162d5abf3c Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 21 Jan 2019 11:08:37 +0100 Subject: [PATCH 288/554] Disabled report seeding to fix tests --- src/seed/data/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/seed/data/index.js b/src/seed/data/index.js index 84deed404..41f8bddd2 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -15,9 +15,9 @@ const seed = { Organization: require('./organizations.js').default, Post: require('./posts.js').default, Comment: require('./comments.js').default, - UserShouts: require('./users-shouts.js').default, + UserShouts: require('./users-shouts.js').default - Reports: require('./reports.js').default + // Reports: require('./reports.js').default } let data = {} From e46c8d18e5da4caf34246d2b5e52d28d3801e6ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 21 Jan 2019 21:32:53 +0100 Subject: [PATCH 289/554] Implement public folder --- src/middleware/fixImageUrlsMiddleware.js | 2 +- src/middleware/fixImageUrlsMiddleware.spec.js | 4 ++-- src/server.js | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/middleware/fixImageUrlsMiddleware.js b/src/middleware/fixImageUrlsMiddleware.js index c3b828dae..e5dc47a6d 100644 --- a/src/middleware/fixImageUrlsMiddleware.js +++ b/src/middleware/fixImageUrlsMiddleware.js @@ -7,7 +7,7 @@ const legacyUrls = [ export const fixUrl = (url) => { legacyUrls.forEach((legacyUrl) => { - url = url.replace(legacyUrl, '') + url = url.replace(legacyUrl, '/api') }) return url } diff --git a/src/middleware/fixImageUrlsMiddleware.spec.js b/src/middleware/fixImageUrlsMiddleware.spec.js index 081154c5c..89d2a520d 100644 --- a/src/middleware/fixImageUrlsMiddleware.spec.js +++ b/src/middleware/fixImageUrlsMiddleware.spec.js @@ -4,14 +4,14 @@ describe('fixImageURLs', () => { describe('image url of legacy alpha', () => { it('removes domain', () => { const url = 'https://api-alpha.human-connection.org/uploads/4bfaf9172c4ba03d7645108bbbd16f0a696a37d01eacd025fb131e5da61b15d9.png' - expect(fixImageURLs(url)).toEqual('/uploads/4bfaf9172c4ba03d7645108bbbd16f0a696a37d01eacd025fb131e5da61b15d9.png') + expect(fixImageURLs(url)).toEqual('/api/uploads/4bfaf9172c4ba03d7645108bbbd16f0a696a37d01eacd025fb131e5da61b15d9.png') }) }) describe('image url of legacy staging', () => { it('removes domain', () => { const url = 'https://staging-api.human-connection.org/uploads/1b3c39a24f27e2fb62b69074b2f71363b63b263f0c4574047d279967124c026e.jpeg' - expect(fixImageURLs(url)).toEqual('/uploads/1b3c39a24f27e2fb62b69074b2f71363b63b263f0c4574047d279967124c026e.jpeg') + expect(fixImageURLs(url)).toEqual('/api/uploads/1b3c39a24f27e2fb62b69074b2f71363b63b263f0c4574047d279967124c026e.jpeg') }) }) diff --git a/src/server.js b/src/server.js index 76e8419b7..728237562 100644 --- a/src/server.js +++ b/src/server.js @@ -2,6 +2,7 @@ import { GraphQLServer } from 'graphql-yoga' import { makeExecutableSchema } from 'apollo-server' import { augmentSchema } from 'neo4j-graphql-js' import { typeDefs, resolvers } from './graphql-schema' +import express from 'express' import dotenv from 'dotenv' import mocks from './mocks' import middleware from './middleware' @@ -68,6 +69,7 @@ const createServer = (options) => { passport.use('jwt', jwtStrategy(driver)) server.express.use(passport.initialize()) + server.express.use(express.static('public')) server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) return server From 509e4feeb9ec6c289a7fd49d097aa5e8182ea94a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 21 Jan 2019 22:12:50 +0100 Subject: [PATCH 290/554] Add workflow to download remote uploads * remote uploads directory * download content of uploads directory with `scp` * share uploads volume with backend container --- db-migration-worker/import.sh | 4 +++- docker-compose.override.yml | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/db-migration-worker/import.sh b/db-migration-worker/import.sh index ba07217c0..cb7e82ce6 100755 --- a/db-migration-worker/import.sh +++ b/db-migration-worker/import.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "MONGODB_AUTH_DB" +for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "MONGODB_AUTH_DB" "UPLOADS_DIRECTORY" do if [[ -z "${!var}" ]]; then echo "${var} is undefined" @@ -14,6 +14,7 @@ echo "MONGODB_USERNAME ${MONGODB_USERNAME}" echo "MONGODB_PASSWORD ${MONGODB_PASSWORD}" echo "MONGODB_DATABASE ${MONGODB_DATABASE}" echo "MONGODB_AUTH_DB ${MONGODB_AUTH_DB}" +echo "UPLOADS_DIRECTORY ${UPLOADS_DIRECTORY}" echo "-------------------------------------------------" mongo ${MONGODB_DATABASE} --eval "db.dropDatabase();" @@ -21,6 +22,7 @@ rm -f /mongo-export/* ssh -4 -M -S my-ctrl-socket -fnNT -L 27018:localhost:27017 -l ${SSH_USERNAME} ${SSH_HOST} mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --gzip --archive | mongorestore --gzip --archive +scp -r ${SSH_USERNAME}@${SSH_HOST}:${UPLOADS_DIRECTORY}/* /uploads/ ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST} ssh -S my-ctrl-socket -O exit -l ${SSH_USERNAME} ${SSH_HOST} diff --git a/docker-compose.override.yml b/docker-compose.override.yml index c5e7d5cf9..0592b801b 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -9,6 +9,7 @@ services: volumes: - .:/nitro-backend - /nitro-backend/node_modules + - uploads:/nitro-backend/public/uploads command: yarn run dev neo4j: volumes: @@ -24,6 +25,7 @@ services: context: db-migration-worker volumes: - mongo-export:/mongo-export + - uploads:/uploads - ./db-migration-worker/.ssh/:/root/.ssh/ networks: - hc-network @@ -34,7 +36,9 @@ services: - "MONGODB_PASSWORD=${MONGODB_PASSWORD}" - "MONGODB_AUTH_DB=${MONGODB_AUTH_DB}" - "MONGODB_DATABASE=${MONGODB_DATABASE}" + - "UPLOADS_DIRECTORY=${UPLOADS_DIRECTORY}" command: "--smallfiles --logpath=/dev/null" volumes: mongo-export: + uploads: From c9b8b23915fd7ee191ad2364705039ef157667fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 21 Jan 2019 22:17:00 +0100 Subject: [PATCH 291/554] Keep public folder empty --- .dockerignore | 2 ++ .gitignore | 2 ++ public/.gitkeep | 0 3 files changed, 4 insertions(+) create mode 100644 public/.gitkeep diff --git a/.dockerignore b/.dockerignore index f5a08be39..161805c9c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -18,3 +18,5 @@ dist/ db-migration-worker/ neo4j/ + +public/ diff --git a/.gitignore b/.gitignore index a5e987954..e34da736c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ yarn-error.log dist/* coverage.lcov .nyc_output/ +public/* +!.gitkeep diff --git a/public/.gitkeep b/public/.gitkeep new file mode 100644 index 000000000..e69de29bb From 2cab6fe9cf13fa8582d33eda8c1a7c73b4992c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 21 Jan 2019 22:33:32 +0100 Subject: [PATCH 292/554] Replace `scp` with `rsync` `rsync` is faster on multiple runs. The `--update` flag will only download newer images and does not overwrite existing files. Thus, it will only download missing images. --- db-migration-worker/Dockerfile | 2 +- db-migration-worker/import.sh | 3 ++- neo4j/import/todo | 7 ------- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/db-migration-worker/Dockerfile b/db-migration-worker/Dockerfile index 92dff618f..025be88a4 100644 --- a/db-migration-worker/Dockerfile +++ b/db-migration-worker/Dockerfile @@ -1,7 +1,7 @@ FROM mongo:4 RUN apt-get update \ - && apt-get -y install --no-install-recommends openssh-client \ + && apt-get -y install --no-install-recommends openssh-client rsync \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* COPY .ssh /root/.ssh/ diff --git a/db-migration-worker/import.sh b/db-migration-worker/import.sh index cb7e82ce6..0251a3582 100755 --- a/db-migration-worker/import.sh +++ b/db-migration-worker/import.sh @@ -22,10 +22,11 @@ rm -f /mongo-export/* ssh -4 -M -S my-ctrl-socket -fnNT -L 27018:localhost:27017 -l ${SSH_USERNAME} ${SSH_HOST} mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --gzip --archive | mongorestore --gzip --archive -scp -r ${SSH_USERNAME}@${SSH_HOST}:${UPLOADS_DIRECTORY}/* /uploads/ ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST} ssh -S my-ctrl-socket -O exit -l ${SSH_USERNAME} ${SSH_HOST} +rsync --archive --update --verbose ${SSH_USERNAME}@${SSH_HOST}:${UPLOADS_DIRECTORY}/* /uploads/ + for collection in "categories" "badges" "users" "contributions" "comments" "follows" "shouts" do mongoexport --db ${MONGODB_DATABASE} --collection $collection --out "/mongo-export/$collection.json" diff --git a/neo4j/import/todo b/neo4j/import/todo index 0b86c8bc5..0e0f259f0 100644 --- a/neo4j/import/todo +++ b/neo4j/import/todo @@ -4,7 +4,6 @@ ON CREATE SET c.name = category.title, c.slug = category.slug, c.icon = category.icon - CALL apoc.load.json('file:/mongo-export/badges.json') YIELD value as badge MERGE(b:Badge {id: badge._id["$oid"]}) ON CREATE SET b.key = badge.key, @@ -12,17 +11,11 @@ ON CREATE SET b.key = badge.key, b.icon = badge.image.path, b.status = badge.status - - - - - CALL apoc.load.json('file:/mongo-export/follows.json') YIELD value as follow MATCH (u1:User {id: follow.userId}), (u2:User {id: follow.foreignId}) MERGE (u1)-[:FOLLOWS]->(u2) - CALL apoc.load.json('file:/mongo-export/shouts.json') YIELD value as shout MATCH (u:User {id: shout.userId}), (p:Post {id: shout.foreignId}) From f69a0daeefdab5e57af8d1d488a7de6d3529f706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 21 Jan 2019 23:13:32 +0100 Subject: [PATCH 293/554] Import categories, manually assign correct icon Big fun :+1: --- neo4j/import/categories.cql | 89 +++++++++++++++++++++++++++++++++++++ neo4j/import/import.sh | 2 +- neo4j/import/todo | 6 --- 3 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 neo4j/import/categories.cql diff --git a/neo4j/import/categories.cql b/neo4j/import/categories.cql new file mode 100644 index 000000000..a2bf6a352 --- /dev/null +++ b/neo4j/import/categories.cql @@ -0,0 +1,89 @@ +CALL apoc.load.json('file:/mongo-export/categories.json') YIELD value as category +MERGE(c:Category {id: category._id["$oid"]}) +ON CREATE SET +c.name = category.title, +c.slug = category.slug, +c.icon = category.icon, +c.createdAt = category.createdAt.`$date`, +c.updatedAt = category.updatedAt.`$date` +; + +MATCH (c:Category) +WHERE (c.icon = "categories-justforfun") +SET c.icon = 'smile' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-luck") +SET c.icon = 'heart-o' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-health") +SET c.icon = 'medkit' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-environment") +SET c.icon = 'tree' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-animal-justice") +SET c.icon = 'paw' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-human-rights") +SET c.icon = 'balance-scale' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-education") +SET c.icon = 'graduation-cap' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-cooperation") +SET c.icon = 'users' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-politics") +SET c.icon = 'university' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-economy") +SET c.icon = 'money' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-technology") +SET c.icon = 'flash' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-internet") +SET c.icon = 'mouse-pointer' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-art") +SET c.icon = 'paint-brush' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-freedom-of-speech") +SET c.icon = 'bullhorn' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-sustainability") +SET c.icon = 'shopping-cart' +; + +MATCH (c:Category) +WHERE (c.icon = "categories-peace") +SET c.icon = 'angellist' +; diff --git a/neo4j/import/import.sh b/neo4j/import/import.sh index 319f1a591..7c4571991 100755 --- a/neo4j/import/import.sh +++ b/neo4j/import/import.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" echo "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r;" | cypher-shell -for collection in "users" "contributions" "comments" +for collection in "categories" "users" "contributions" "comments" do echo "Import ${collection}..." && cypher-shell < $SCRIPT_DIRECTORY/$collection.cql done diff --git a/neo4j/import/todo b/neo4j/import/todo index 0e0f259f0..8ee1bb83a 100644 --- a/neo4j/import/todo +++ b/neo4j/import/todo @@ -1,9 +1,3 @@ -CALL apoc.load.json('file:/mongo-export/categories.json') YIELD value as category -MERGE(c:Category {id: category._id["$oid"]}) -ON CREATE SET c.name = category.title, - c.slug = category.slug, - c.icon = category.icon - CALL apoc.load.json('file:/mongo-export/badges.json') YIELD value as badge MERGE(b:Badge {id: badge._id["$oid"]}) ON CREATE SET b.key = badge.key, From ce7ce4027265189dd2ed32f30bf1da44ea6c722d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 21 Jan 2019 23:26:45 +0100 Subject: [PATCH 294/554] Import badges --- .dockerignore | 3 ++- .gitignore | 2 +- neo4j/import/badges.cql | 10 ++++++++++ neo4j/import/import.sh | 2 +- public/img/badges/fundraisingbox_de_airship.svg | 1 + public/img/badges/fundraisingbox_de_alienship.svg | 1 + public/img/badges/fundraisingbox_de_balloon.svg | 1 + public/img/badges/fundraisingbox_de_bigballoon.svg | 1 + public/img/badges/fundraisingbox_de_crane.svg | 1 + public/img/badges/fundraisingbox_de_glider.svg | 1 + public/img/badges/fundraisingbox_de_helicopter.svg | 1 + public/img/badges/fundraisingbox_de_starter.svg | 1 + public/img/badges/indiegogo_en_bear.svg | 1 + public/img/badges/indiegogo_en_panda.svg | 1 + public/img/badges/indiegogo_en_rabbit.svg | 1 + public/img/badges/indiegogo_en_racoon.svg | 1 + public/img/badges/indiegogo_en_rhino.svg | 1 + public/img/badges/indiegogo_en_tiger.svg | 1 + public/img/badges/indiegogo_en_turtle.svg | 1 + public/img/badges/indiegogo_en_whale.svg | 1 + public/img/badges/indiegogo_en_wolf.svg | 1 + public/img/badges/user_role_admin.svg | 1 + public/img/badges/user_role_developer.svg | 1 + public/img/badges/user_role_moderator.svg | 1 + public/img/badges/wooold_de_bee.svg | 1 + public/img/badges/wooold_de_butterfly.svg | 1 + public/img/badges/wooold_de_double_rainbow.svg | 1 + public/img/badges/wooold_de_end_of_rainbow.svg | 1 + public/img/badges/wooold_de_flower.svg | 1 + public/img/badges/wooold_de_lifetree.svg | 1 + public/img/badges/wooold_de_magic_rainbow.svg | 1 + public/img/badges/wooold_de_super_founder.svg | 1 + 32 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 neo4j/import/badges.cql create mode 100644 public/img/badges/fundraisingbox_de_airship.svg create mode 100644 public/img/badges/fundraisingbox_de_alienship.svg create mode 100644 public/img/badges/fundraisingbox_de_balloon.svg create mode 100644 public/img/badges/fundraisingbox_de_bigballoon.svg create mode 100644 public/img/badges/fundraisingbox_de_crane.svg create mode 100644 public/img/badges/fundraisingbox_de_glider.svg create mode 100644 public/img/badges/fundraisingbox_de_helicopter.svg create mode 100644 public/img/badges/fundraisingbox_de_starter.svg create mode 100644 public/img/badges/indiegogo_en_bear.svg create mode 100644 public/img/badges/indiegogo_en_panda.svg create mode 100644 public/img/badges/indiegogo_en_rabbit.svg create mode 100644 public/img/badges/indiegogo_en_racoon.svg create mode 100644 public/img/badges/indiegogo_en_rhino.svg create mode 100644 public/img/badges/indiegogo_en_tiger.svg create mode 100644 public/img/badges/indiegogo_en_turtle.svg create mode 100644 public/img/badges/indiegogo_en_whale.svg create mode 100644 public/img/badges/indiegogo_en_wolf.svg create mode 100644 public/img/badges/user_role_admin.svg create mode 100644 public/img/badges/user_role_developer.svg create mode 100644 public/img/badges/user_role_moderator.svg create mode 100644 public/img/badges/wooold_de_bee.svg create mode 100644 public/img/badges/wooold_de_butterfly.svg create mode 100644 public/img/badges/wooold_de_double_rainbow.svg create mode 100644 public/img/badges/wooold_de_end_of_rainbow.svg create mode 100644 public/img/badges/wooold_de_flower.svg create mode 100644 public/img/badges/wooold_de_lifetree.svg create mode 100644 public/img/badges/wooold_de_magic_rainbow.svg create mode 100644 public/img/badges/wooold_de_super_founder.svg diff --git a/.dockerignore b/.dockerignore index 161805c9c..dba77200f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -19,4 +19,5 @@ dist/ db-migration-worker/ neo4j/ -public/ +public/uploads/* +!.gitkeep diff --git a/.gitignore b/.gitignore index e34da736c..cbfa0b7c8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,5 @@ yarn-error.log dist/* coverage.lcov .nyc_output/ -public/* +public/uploads/* !.gitkeep diff --git a/neo4j/import/badges.cql b/neo4j/import/badges.cql new file mode 100644 index 000000000..90e4755b4 --- /dev/null +++ b/neo4j/import/badges.cql @@ -0,0 +1,10 @@ +CALL apoc.load.json('file:/mongo-export/badges.json') YIELD value as badge +MERGE(b:Badge {id: badge._id["$oid"]}) +ON CREATE SET +b.key = badge.key, +b.type = badge.type, +b.icon = badge.image.path, +b.status = badge.status, +b.createdAt = badge.createdAt.`$date`, +b.updatedAt = badge.updatedAt.`$date` +; diff --git a/neo4j/import/import.sh b/neo4j/import/import.sh index 7c4571991..86224d240 100755 --- a/neo4j/import/import.sh +++ b/neo4j/import/import.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" echo "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r;" | cypher-shell -for collection in "categories" "users" "contributions" "comments" +for collection in "badges" "categories" "users" "contributions" "comments" do echo "Import ${collection}..." && cypher-shell < $SCRIPT_DIRECTORY/$collection.cql done diff --git a/public/img/badges/fundraisingbox_de_airship.svg b/public/img/badges/fundraisingbox_de_airship.svg new file mode 100644 index 000000000..078dcf4f9 --- /dev/null +++ b/public/img/badges/fundraisingbox_de_airship.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/fundraisingbox_de_alienship.svg b/public/img/badges/fundraisingbox_de_alienship.svg new file mode 100644 index 000000000..e891c5fa9 --- /dev/null +++ b/public/img/badges/fundraisingbox_de_alienship.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/fundraisingbox_de_balloon.svg b/public/img/badges/fundraisingbox_de_balloon.svg new file mode 100644 index 000000000..6fc436d86 --- /dev/null +++ b/public/img/badges/fundraisingbox_de_balloon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/fundraisingbox_de_bigballoon.svg b/public/img/badges/fundraisingbox_de_bigballoon.svg new file mode 100644 index 000000000..e2650963a --- /dev/null +++ b/public/img/badges/fundraisingbox_de_bigballoon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/fundraisingbox_de_crane.svg b/public/img/badges/fundraisingbox_de_crane.svg new file mode 100644 index 000000000..4904c5ec5 --- /dev/null +++ b/public/img/badges/fundraisingbox_de_crane.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/fundraisingbox_de_glider.svg b/public/img/badges/fundraisingbox_de_glider.svg new file mode 100644 index 000000000..0c15955de --- /dev/null +++ b/public/img/badges/fundraisingbox_de_glider.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/fundraisingbox_de_helicopter.svg b/public/img/badges/fundraisingbox_de_helicopter.svg new file mode 100644 index 000000000..3a84e4466 --- /dev/null +++ b/public/img/badges/fundraisingbox_de_helicopter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/fundraisingbox_de_starter.svg b/public/img/badges/fundraisingbox_de_starter.svg new file mode 100644 index 000000000..99980560e --- /dev/null +++ b/public/img/badges/fundraisingbox_de_starter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/indiegogo_en_bear.svg b/public/img/badges/indiegogo_en_bear.svg new file mode 100644 index 000000000..43465a0e6 --- /dev/null +++ b/public/img/badges/indiegogo_en_bear.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/indiegogo_en_panda.svg b/public/img/badges/indiegogo_en_panda.svg new file mode 100644 index 000000000..a2f211e85 --- /dev/null +++ b/public/img/badges/indiegogo_en_panda.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/indiegogo_en_rabbit.svg b/public/img/badges/indiegogo_en_rabbit.svg new file mode 100644 index 000000000..c8c0c9727 --- /dev/null +++ b/public/img/badges/indiegogo_en_rabbit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/indiegogo_en_racoon.svg b/public/img/badges/indiegogo_en_racoon.svg new file mode 100644 index 000000000..619cb75f1 --- /dev/null +++ b/public/img/badges/indiegogo_en_racoon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/indiegogo_en_rhino.svg b/public/img/badges/indiegogo_en_rhino.svg new file mode 100644 index 000000000..71c0eb1ad --- /dev/null +++ b/public/img/badges/indiegogo_en_rhino.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/indiegogo_en_tiger.svg b/public/img/badges/indiegogo_en_tiger.svg new file mode 100644 index 000000000..88583a472 --- /dev/null +++ b/public/img/badges/indiegogo_en_tiger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/indiegogo_en_turtle.svg b/public/img/badges/indiegogo_en_turtle.svg new file mode 100644 index 000000000..6b5431c2e --- /dev/null +++ b/public/img/badges/indiegogo_en_turtle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/indiegogo_en_whale.svg b/public/img/badges/indiegogo_en_whale.svg new file mode 100644 index 000000000..458e03b6d --- /dev/null +++ b/public/img/badges/indiegogo_en_whale.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/indiegogo_en_wolf.svg b/public/img/badges/indiegogo_en_wolf.svg new file mode 100644 index 000000000..e4952d86f --- /dev/null +++ b/public/img/badges/indiegogo_en_wolf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/user_role_admin.svg b/public/img/badges/user_role_admin.svg new file mode 100644 index 000000000..101e7458d --- /dev/null +++ b/public/img/badges/user_role_admin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/user_role_developer.svg b/public/img/badges/user_role_developer.svg new file mode 100644 index 000000000..55d363c9a --- /dev/null +++ b/public/img/badges/user_role_developer.svg @@ -0,0 +1 @@ +</> \ No newline at end of file diff --git a/public/img/badges/user_role_moderator.svg b/public/img/badges/user_role_moderator.svg new file mode 100644 index 000000000..bb2e5fde6 --- /dev/null +++ b/public/img/badges/user_role_moderator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/wooold_de_bee.svg b/public/img/badges/wooold_de_bee.svg new file mode 100644 index 000000000..e716c6116 --- /dev/null +++ b/public/img/badges/wooold_de_bee.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/wooold_de_butterfly.svg b/public/img/badges/wooold_de_butterfly.svg new file mode 100644 index 000000000..6d2b83e31 --- /dev/null +++ b/public/img/badges/wooold_de_butterfly.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/wooold_de_double_rainbow.svg b/public/img/badges/wooold_de_double_rainbow.svg new file mode 100644 index 000000000..406001188 --- /dev/null +++ b/public/img/badges/wooold_de_double_rainbow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/wooold_de_end_of_rainbow.svg b/public/img/badges/wooold_de_end_of_rainbow.svg new file mode 100644 index 000000000..2ae24cb7b --- /dev/null +++ b/public/img/badges/wooold_de_end_of_rainbow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/wooold_de_flower.svg b/public/img/badges/wooold_de_flower.svg new file mode 100644 index 000000000..ffc4b3da4 --- /dev/null +++ b/public/img/badges/wooold_de_flower.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/wooold_de_lifetree.svg b/public/img/badges/wooold_de_lifetree.svg new file mode 100644 index 000000000..5a89fa5f9 --- /dev/null +++ b/public/img/badges/wooold_de_lifetree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/wooold_de_magic_rainbow.svg b/public/img/badges/wooold_de_magic_rainbow.svg new file mode 100644 index 000000000..74df95190 --- /dev/null +++ b/public/img/badges/wooold_de_magic_rainbow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/badges/wooold_de_super_founder.svg b/public/img/badges/wooold_de_super_founder.svg new file mode 100644 index 000000000..b437f6383 --- /dev/null +++ b/public/img/badges/wooold_de_super_founder.svg @@ -0,0 +1 @@ + \ No newline at end of file From 932a593cfa3cbefff6aee3f0b4cdbfd2f601749a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 21 Jan 2019 23:38:48 +0100 Subject: [PATCH 295/554] Import follows --- neo4j/import/follows.cql | 4 ++++ neo4j/import/import.sh | 2 +- neo4j/import/todo | 10 ---------- 3 files changed, 5 insertions(+), 11 deletions(-) create mode 100644 neo4j/import/follows.cql diff --git a/neo4j/import/follows.cql b/neo4j/import/follows.cql new file mode 100644 index 000000000..0dad6a435 --- /dev/null +++ b/neo4j/import/follows.cql @@ -0,0 +1,4 @@ +CALL apoc.load.json('file:/mongo-export/follows.json') YIELD value as follow +MATCH (u1:User {id: follow.userId}), (u2:User {id: follow.foreignId}) +MERGE (u1)-[:FOLLOWS]->(u2) +; diff --git a/neo4j/import/import.sh b/neo4j/import/import.sh index 86224d240..d712dea0a 100755 --- a/neo4j/import/import.sh +++ b/neo4j/import/import.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" echo "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r;" | cypher-shell -for collection in "badges" "categories" "users" "contributions" "comments" +for collection in "badges" "categories" "users" "follows" "contributions" "comments" do echo "Import ${collection}..." && cypher-shell < $SCRIPT_DIRECTORY/$collection.cql done diff --git a/neo4j/import/todo b/neo4j/import/todo index 8ee1bb83a..73eae2396 100644 --- a/neo4j/import/todo +++ b/neo4j/import/todo @@ -1,14 +1,4 @@ -CALL apoc.load.json('file:/mongo-export/badges.json') YIELD value as badge -MERGE(b:Badge {id: badge._id["$oid"]}) -ON CREATE SET b.key = badge.key, - b.type = badge.type, - b.icon = badge.image.path, - b.status = badge.status -CALL apoc.load.json('file:/mongo-export/follows.json') YIELD value as follow -MATCH (u1:User {id: follow.userId}), - (u2:User {id: follow.foreignId}) -MERGE (u1)-[:FOLLOWS]->(u2) CALL apoc.load.json('file:/mongo-export/shouts.json') YIELD value as shout MATCH (u:User {id: shout.userId}), From 494748c4c459f886e78a491c6f022e2a0da96ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 21 Jan 2019 23:43:23 +0100 Subject: [PATCH 296/554] Import shouts --- neo4j/import/import.sh | 2 +- neo4j/import/shouts.cql | 4 ++++ neo4j/import/todo | 4 ---- 3 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 neo4j/import/shouts.cql diff --git a/neo4j/import/import.sh b/neo4j/import/import.sh index d712dea0a..80b6595fc 100755 --- a/neo4j/import/import.sh +++ b/neo4j/import/import.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" echo "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r;" | cypher-shell -for collection in "badges" "categories" "users" "follows" "contributions" "comments" +for collection in "badges" "categories" "users" "follows" "contributions" "shouts" "comments" do echo "Import ${collection}..." && cypher-shell < $SCRIPT_DIRECTORY/$collection.cql done diff --git a/neo4j/import/shouts.cql b/neo4j/import/shouts.cql new file mode 100644 index 000000000..60aca50c9 --- /dev/null +++ b/neo4j/import/shouts.cql @@ -0,0 +1,4 @@ +CALL apoc.load.json('file:/mongo-export/shouts.json') YIELD value as shout +MATCH (u:User {id: shout.userId}), (p:Post {id: shout.foreignId}) +MERGE (u)-[:SHOUTED]->(p) +; diff --git a/neo4j/import/todo b/neo4j/import/todo index 73eae2396..139597f9c 100644 --- a/neo4j/import/todo +++ b/neo4j/import/todo @@ -1,6 +1,2 @@ -CALL apoc.load.json('file:/mongo-export/shouts.json') YIELD value as shout -MATCH (u:User {id: shout.userId}), - (p:Post {id: shout.foreignId}) -MERGE (u)-[:SHOUTED]->(p) From 73c8bb282ba005a08e2b561feb8f5386f5e7ba41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 22 Jan 2019 13:57:28 +0000 Subject: [PATCH 297/554] Bump eslint from 5.12.0 to 5.12.1 Bumps [eslint](https://github.com/eslint/eslint) from 5.12.0 to 5.12.1. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v5.12.0...v5.12.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 116d923fb..c84177fb4 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "babel-eslint": "~10.0.1", "babel-jest": "^23.6.0", "chai": "~4.2.0", - "eslint": "~5.12.0", + "eslint": "~5.12.1", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.14.0", "eslint-plugin-jest": "^22.1.3", diff --git a/yarn.lock b/yarn.lock index 6b79c3a40..514cee7c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2785,10 +2785,10 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@~5.12.0: - version "5.12.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.12.0.tgz#fab3b908f60c52671fb14e996a450b96c743c859" - integrity sha512-LntwyPxtOHrsJdcSwyQKVtHofPHdv+4+mFwEe91r2V13vqpM8yLr7b1sW+Oo/yheOPkWYsYlYJCkzlFAt8KV7g== +eslint@~5.12.1: + version "5.12.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.12.1.tgz#5ca9931fb9029d04e7be92b03ce3b58edfac7e3b" + integrity sha512-54NV+JkTpTu0d8+UYSA8mMKAG4XAsaOrozA9rCW7tgneg1mevcL7wIotPC+fZ0SkWwdhNqoXoxnQCTBp7UvTsg== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.5.3" From 3f0bdb792c0f5f983002be8555de74dc5dfd9b8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 23 Jan 2019 04:25:03 +0000 Subject: [PATCH 298/554] Bump supertest from 3.4.1 to 3.4.2 Bumps [supertest](https://github.com/visionmedia/supertest) from 3.4.1 to 3.4.2. - [Release notes](https://github.com/visionmedia/supertest/releases) - [Changelog](https://github.com/visionmedia/supertest/blob/master/History.md) - [Commits](https://github.com/visionmedia/supertest/compare/v3.4.1...v3.4.2) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index c84177fb4..2578c1628 100644 --- a/package.json +++ b/package.json @@ -88,6 +88,6 @@ "jest": "^23.6.0", "nodemon": "~1.18.9", "nyc": "^13.1.0", - "supertest": "^3.4.1" + "supertest": "^3.4.2" } } diff --git a/yarn.lock b/yarn.lock index 514cee7c3..9377827b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7136,10 +7136,10 @@ superagent@^3.8.3: qs "^6.5.1" readable-stream "^2.3.5" -supertest@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/supertest/-/supertest-3.4.1.tgz#91b19ea34804c205769d0ff5ad947aff3eb2731d" - integrity sha512-r4AmsjjKxC50LxGACe/E4xKjau2amiFlj3aCT2sZCRig2o3l4XFN6Acw7crDu4d8Af1f5chafIyLkQ1mac/boA== +supertest@^3.4.2: + version "3.4.2" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-3.4.2.tgz#bad7de2e43d60d27c8caeb8ab34a67c8a5f71aad" + integrity sha512-WZWbwceHUo2P36RoEIdXvmqfs47idNNZjCuJOqDz6rvtkk8ym56aU5oglORCpPeXGxT7l9rkJ41+O1lffQXYSA== dependencies: methods "^1.1.2" superagent "^3.8.3" From 13f8e57467777e4211af346023d5fa59da731176 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 23 Jan 2019 12:46:30 +0000 Subject: [PATCH 299/554] Bump eslint-plugin-import from 2.14.0 to 2.15.0 Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.14.0 to 2.15.0. - [Release notes](https://github.com/benmosher/eslint-plugin-import/releases) - [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md) - [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.14.0...v2.15.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 53 +++++++++++++++++++++++----------------------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index 2578c1628..21349ffb2 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "chai": "~4.2.0", "eslint": "~5.12.1", "eslint-config-standard": "~12.0.0", - "eslint-plugin-import": "~2.14.0", + "eslint-plugin-import": "~2.15.0", "eslint-plugin-jest": "^22.1.3", "eslint-plugin-node": "~8.0.1", "eslint-plugin-promise": "~4.0.1", diff --git a/yarn.lock b/yarn.lock index 9377827b5..50b8a7cc6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2692,7 +2692,7 @@ eslint-config-standard@~12.0.0: resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9" integrity sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ== -eslint-import-resolver-node@^0.3.1: +eslint-import-resolver-node@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== @@ -2700,13 +2700,13 @@ eslint-import-resolver-node@^0.3.1: debug "^2.6.9" resolve "^1.5.0" -eslint-module-utils@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" - integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= +eslint-module-utils@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz#546178dab5e046c8b562bbb50705e2456d7bda49" + integrity sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w== dependencies: debug "^2.6.8" - pkg-dir "^1.0.0" + pkg-dir "^2.0.0" eslint-plugin-es@^1.3.1: version "1.4.0" @@ -2716,21 +2716,21 @@ eslint-plugin-es@^1.3.1: eslint-utils "^1.3.0" regexpp "^2.0.1" -eslint-plugin-import@~2.14.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" - integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== +eslint-plugin-import@~2.15.0: + version "2.15.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.15.0.tgz#d8f3c28b8988ccde5df964706faa7c1e52f0602a" + integrity sha512-LEHqgR+RcnpGqYW7h9WMkPb/tP+ekKxWdQDztfTtZeV43IHF+X8lXU+1HOCcR4oXD24qRgEwNSxIweD5uNKGVg== dependencies: contains-path "^0.1.0" - debug "^2.6.8" + debug "^2.6.9" doctrine "1.5.0" - eslint-import-resolver-node "^0.3.1" - eslint-module-utils "^2.2.0" - has "^1.0.1" - lodash "^4.17.4" - minimatch "^3.0.3" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.3.0" + has "^1.0.3" + lodash "^4.17.11" + minimatch "^3.0.4" read-pkg-up "^2.0.0" - resolve "^1.6.0" + resolve "^1.9.0" eslint-plugin-jest@^22.1.3: version "22.1.3" @@ -5962,7 +5962,7 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.5: +path-parse@^1.0.5, path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== @@ -6044,13 +6044,6 @@ pirates@^4.0.0: dependencies: node-modules-regexp "^1.0.0" -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= - dependencies: - find-up "^1.0.0" - pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -6574,12 +6567,12 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" - integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== +resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" + integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== dependencies: - path-parse "^1.0.5" + path-parse "^1.0.6" restore-cursor@^2.0.0: version "2.0.0" From de6e2feea1cd78056035663bbdd860f82a8c24bd Mon Sep 17 00:00:00 2001 From: Armin Date: Sun, 27 Jan 2019 22:27:14 +0100 Subject: [PATCH 300/554] Move troubleshoots to end; add install links for docker and minikube --- .gitignore | 1 + kubernetes/README.md | 21 ++++++++++----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index a5e987954..6d42de246 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ node_modules/ .env .vscode +.idea yarn-error.log dist/* coverage.lcov diff --git a/kubernetes/README.md b/kubernetes/README.md index 5192f9a19..ffbf225b2 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -1,23 +1,15 @@ # Usage with minikube - -assuming you installed the packages git, docker, minikube and virtualbox here... +Assuming you installed the packages git, docker ([all-distributions](https://docs.docker.com/install/)), minikube ([ubuntu]([minikube](https://computingforgeeks.com/how-to-install-minikube-on-ubuntu-18-04/)), [all-distributions](https://kubernetes.io/docs/tasks/tools/install-minikube/)) and virtualbox here... First of all start minikube on your machine: ```sh minikube start ``` -**[troubleshoot]** If you get an error message along th lines of 'The vboxdrv kernel module is not loaded.' - then you have the same issue i had. to solve this you need to install the propper linux kernel host modules package. Here an example for Manjaro: -https://forum.manjaro.org/t/installing-virtualbox-kernel-modules/6999 -**[troubleshoot]** When you can not start minikube, try also to remove the cluster with `minikube delete` and start again with `minikube start`. Sometimes this fix startup problems of the cluster. You can always get an overview and see what's going on with your minikube: ```sh minikube dashboard ``` -**[troubleshoot]** now again you might run into trouble with an error like 'kubectl could not be found on your path.' In this case run the following command: -```sh -curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.10.0/bin/linux/amd64/kubectl && chmod +x kubectl && sudo cp kubectl /usr/local/bin/ && rm kubectl -``` From now on stay in your favorite work directory. First let's clone the necessary sources: ```sh @@ -32,7 +24,7 @@ docker build -t humanconnection/nitro-backend:latest Nitro-Backend/ docker build -t humanconnection/neo4j:latest -f Nitro-Backend/Dockerfile.neo4j Nitro-Backend/ ``` -check that the image is in Minikube’s Docker registry: +Check that the image is in Minikube’s Docker registry: ```sh minikube ssh docker images ``` @@ -48,5 +40,12 @@ You can see the backend in action with: minikube service backend ``` +### Troubleshoot - +1. If you get an error message along th lines of 'The vboxdrv kernel module is not loaded.' - then you have the same issue i had. to solve this you need to install the propper linux kernel host modules package. Here an example for Manjaro: +https://forum.manjaro.org/t/installing-virtualbox-kernel-modules/6999 +2. When you can not start minikube, try also to remove the cluster with `minikube delete` and start again with `minikube start`. Sometimes this fix startup problems of the cluster. +3. Now again you might run into trouble with an error like 'kubectl could not be found on your path.' In this case run the following command: + ```sh + curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.10.0/bin/linux/amd64/kubectl && chmod +x kubectl && sudo cp kubectl /usr/local/bin/ && rm kubectl + ``` From 31d44fe395908d73e5799dba437ef869284b6fab Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 28 Jan 2019 10:06:30 +0100 Subject: [PATCH 301/554] Improved xss cleaning --- src/middleware/xssMiddleware.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/middleware/xssMiddleware.js b/src/middleware/xssMiddleware.js index 59ce8800f..31b2110a7 100644 --- a/src/middleware/xssMiddleware.js +++ b/src/middleware/xssMiddleware.js @@ -95,15 +95,22 @@ function clean (dirty) { .replace(/<[a-z]>[\s]*<\/[a-z]>/igm, '') // remove all iframes .replace(/(]*)(>)[^>]*\/*>/igm, '') - // replace all p tags with line breaks (and spaces) only by single linebreaks - .replace(/

[\s]*(
)+[\s]*<\/p>/igm, '
') - // replace multiple linebreaks with single ones - // limit linebreaks to max 2 (equivalent to html "br" linebreak) - .replace(/(
){2,}/igm, '
') .replace(/[\n]{3,}/igm, '\n\n') .replace(/(\r\n|\n\r|\r|\n)/g, '
$1') + + // replace all p tags with line breaks (and spaces) only by single linebreaks + // limit linebreaks to max 2 (equivalent to html "br" linebreak) + .replace(/(
\s*){2,}/gim, '
') + // remove additional linebreaks after p tags + .replace( + /<\/(p|div|th|tr)>\s*(
\s*)+\s*<(p|div|th|tr)>/gim, + '

' + ) // remove additional linebreaks inside p tags - .replace(/


<\/p>/g, '') + .replace( + /<(p|div|th|tr)>\s*(
\s*)+\s*<\/(p|div|th|tr)>/gim, + '' + ) return dirty } From 8c36d9a740a7fe265259eda24c30db076f73757c Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 28 Jan 2019 11:06:54 +0100 Subject: [PATCH 302/554] Updated XSS --- src/middleware/xssMiddleware.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/middleware/xssMiddleware.js b/src/middleware/xssMiddleware.js index 31b2110a7..ef842497e 100644 --- a/src/middleware/xssMiddleware.js +++ b/src/middleware/xssMiddleware.js @@ -92,15 +92,18 @@ function clean (dirty) { // remove empty html tags and duplicated linebreaks and returns dirty = dirty // remove all tags with "space only" - .replace(/<[a-z]>[\s]*<\/[a-z]>/igm, '') + .replace(/<[a-z-]+>[\s]+<\/[a-z-]+>/gim, '') // remove all iframes - .replace(/(]*)(>)[^>]*\/*>/igm, '') - .replace(/[\n]{3,}/igm, '\n\n') - .replace(/(\r\n|\n\r|\r|\n)/g, '
$1') + .replace( + /(]*)(>)[^>]*\/*>/gim, + '' + ) + .replace(/[\n]{3,}/gim, '\n\n') + .replace(/(\r\n|\n\r|\r|\n)/g, '
') // replace all p tags with line breaks (and spaces) only by single linebreaks // limit linebreaks to max 2 (equivalent to html "br" linebreak) - .replace(/(
\s*){2,}/gim, '
') + .replace(/(
\s*){2,}/gim, '
') // remove additional linebreaks after p tags .replace( /<\/(p|div|th|tr)>\s*(
\s*)+\s*<(p|div|th|tr)>/gim, @@ -108,9 +111,13 @@ function clean (dirty) { ) // remove additional linebreaks inside p tags .replace( - /<(p|div|th|tr)>\s*(
\s*)+\s*<\/(p|div|th|tr)>/gim, + /<[a-z-]+>(<[a-z-]+>)*\s*(
\s*)+\s*(<\/[a-z-]+>)*<\/[a-z-]+>/gim, '' ) + // remove additional linebreaks when first child inside p tags + .replace(/

(\s*
\s*)+/gim, '

') + // remove additional linebreaks when last child inside p tags + .replace(/(\s*
\s*)+<\/p+>/gim, '

') return dirty } From 827687b3bc76fc07d4afc9b5ffcb8bc87e25711b Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 28 Jan 2019 12:19:35 +0100 Subject: [PATCH 303/554] Add content excerpt also on update --- src/middleware/excerptMiddleware.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/middleware/excerptMiddleware.js b/src/middleware/excerptMiddleware.js index 4b54c5341..544dc3529 100644 --- a/src/middleware/excerptMiddleware.js +++ b/src/middleware/excerptMiddleware.js @@ -7,15 +7,30 @@ export default { const result = await resolve(root, args, context, info) return result }, + UpdatePost: async (resolve, root, args, context, info) => { + args.contentExcerpt = trunc(args.content, 120).html + const result = await resolve(root, args, context, info) + return result + }, CreateComment: async (resolve, root, args, context, info) => { args.contentExcerpt = trunc(args.content, 180).html const result = await resolve(root, args, context, info) return result }, + UpdateComment: async (resolve, root, args, context, info) => { + args.contentExcerpt = trunc(args.content, 180).html + const result = await resolve(root, args, context, info) + return result + }, CreateOrganization: async (resolve, root, args, context, info) => { args.descriptionExcerpt = trunc(args.description, 120).html const result = await resolve(root, args, context, info) return result + }, + UpdateOrganization: async (resolve, root, args, context, info) => { + args.descriptionExcerpt = trunc(args.description, 120).html + const result = await resolve(root, args, context, info) + return result } } } From aba356395b9cb3a211aa93aacce59bcc9677afe3 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 28 Jan 2019 12:19:48 +0100 Subject: [PATCH 304/554] allow h3, h4 nad hr tags --- src/middleware/xssMiddleware.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/middleware/xssMiddleware.js b/src/middleware/xssMiddleware.js index ef842497e..c2fee7976 100644 --- a/src/middleware/xssMiddleware.js +++ b/src/middleware/xssMiddleware.js @@ -24,7 +24,7 @@ function clean (dirty) { dirty = embedToAnchor(dirty) dirty = linkifyHtml(dirty) dirty = sanitizeHtml(dirty, { - allowedTags: ['iframe', 'img', 'p', 'br', 'b', 'i', 'em', 'strong', 'a', 'pre', 'ul', 'li', 'ol', 's', 'strike', 'span', 'blockquote'], + allowedTags: ['iframe', 'img', 'p', 'h3', 'h4', 'br', 'hr', 'b', 'i', 'em', 'strong', 'a', 'pre', 'ul', 'li', 'ol', 's', 'strike', 'span', 'blockquote'], allowedAttributes: { a: ['href', 'class', 'target', 'data-*', 'contenteditable'], span: ['contenteditable', 'class', 'data-*'], @@ -47,6 +47,11 @@ function clean (dirty) { } } }, + h1: 'h3', + h2: 'h3', + h3: 'h3', + h4: 'h4', + h5: 'strong', i: 'em', // a: function (tagName, attribs) { // return { @@ -99,7 +104,7 @@ function clean (dirty) { '' ) .replace(/[\n]{3,}/gim, '\n\n') - .replace(/(\r\n|\n\r|\r|\n)/g, '
') + .replace(/(\r\n|\n\r|\r|\n)/g, '
$1') // replace all p tags with line breaks (and spaces) only by single linebreaks // limit linebreaks to max 2 (equivalent to html "br" linebreak) From 5bdc7280281c422135880cff1db7ec2535be46c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 28 Jan 2019 17:28:52 +0100 Subject: [PATCH 305/554] Don't copy private SSH key into docker image We can mount the .ssh at runtime. This will allow us to push the docker image to dockerhub without exposing any secrects. --- db-migration-worker/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/db-migration-worker/Dockerfile b/db-migration-worker/Dockerfile index 025be88a4..d7265ac02 100644 --- a/db-migration-worker/Dockerfile +++ b/db-migration-worker/Dockerfile @@ -4,6 +4,5 @@ RUN apt-get update \ && apt-get -y install --no-install-recommends openssh-client rsync \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -COPY .ssh /root/.ssh/ COPY import.sh . From 3dcbbafcd6c31b68fcf27f6dc8dc487eaa04c314 Mon Sep 17 00:00:00 2001 From: Sam Joseph Date: Mon, 28 Jan 2019 17:29:21 +0000 Subject: [PATCH 306/554] Create CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..19f3854c1 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at developer@human-connection.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ From 17d87c6a9d0be477f2e41daa46db666961f65699 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 29 Jan 2019 03:34:22 +0000 Subject: [PATCH 307/554] Bump graphql-yoga from 1.17.0 to 1.17.1 Bumps [graphql-yoga](https://github.com/prisma/graphql-yoga) from 1.17.0 to 1.17.1. - [Release notes](https://github.com/prisma/graphql-yoga/releases) - [Commits](https://github.com/prisma/graphql-yoga/compare/v1.17.0...v1.17.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 21349ffb2..d24d801ad 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "graphql-middleware": "~1.7.8", "graphql-shield": "~4.1.2", "graphql-tag": "~2.10.1", - "graphql-yoga": "~1.17.0", + "graphql-yoga": "~1.17.1", "jsonwebtoken": "~8.4.0", "linkifyjs": "~2.1.7", "lodash": "~4.17.11", diff --git a/yarn.lock b/yarn.lock index 50b8a7cc6..310133908 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3473,12 +3473,12 @@ graphql-iso-date@~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@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-3.0.0.tgz#df498cc2c19ca5936fc67e9e39df6c484dbf4d80" - integrity sha512-m1V5G8jTatG8ZbFWLWBqrlVbHNpJv/U15LJ8U3XAoLjxm5HRY9rVXns6I4gigJqUt/0i/xYO7Lk3YkxqHi8QmQ== +graphql-middleware@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-3.0.1.tgz#8e1f1b2b9738002c1132372cb51d9cceb1b962ec" + integrity sha512-mKXoFYBozbFfAwUPqADO/xpL/DcLKE8fGc0qHTL1ssA6+6Ynt609m4V36/c4FAxcnJsgsV1p22aBbiraXg+ddA== dependencies: - graphql-tools "^4.0.3" + graphql-tools "^4.0.4" graphql-middleware@~1.7.8: version "1.7.8" @@ -3542,10 +3542,10 @@ graphql-tag@^2.9.2, graphql-tag@~2.10.1: resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02" integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg== -graphql-tools@^4.0.0, graphql-tools@^4.0.2, graphql-tools@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.3.tgz#23b5cb52c519212b1b2e4630a361464396ad264b" - integrity sha512-NNZM0WSnVLX1zIMUxu7SjzLZ4prCp15N5L2T2ro02OVyydZ0fuCnZYRnx/yK9xjGWbZA0Q58yEO//Bv/psJWrg== +graphql-tools@^4.0.0, graphql-tools@^4.0.2, graphql-tools@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.4.tgz#ca08a63454221fdde825fe45fbd315eb2a6d566b" + integrity sha512-chF12etTIGVVGy3fCTJ1ivJX2KB7OSG4c6UOJQuqOHCmBQwTyNgCDuejZKvpYxNZiEx7bwIjrodDgDe9RIkjlw== dependencies: apollo-link "^1.2.3" apollo-utilities "^1.0.1" @@ -3563,10 +3563,10 @@ graphql-upload@^8.0.2: http-errors "^1.7.1" object-path "^0.11.4" -graphql-yoga@~1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.17.0.tgz#54836fbb43720a19f5ff2357273c2f380e536ed7" - integrity sha512-2uPz7tmkOP8ktnsFIc6blRO6R5RTofWY0ugxKcvR4QlTveNcfKwOiXMVEn8yJulodEGhJLENXJklSxEIyeIbOg== +graphql-yoga@~1.17.1: + version "1.17.1" + resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.17.1.tgz#13bace9f063e4c57ab7da40c60b9aea4135b89a4" + integrity sha512-8j2omHHMsSFFn4XFb4hXiMIhBAdqra/Ok5lJxBihMlC2ocNU16aa8sMXjAcwwpgcAV0dpDOU5fL3X1DS0pmTQA== dependencies: "@types/cors" "^2.8.4" "@types/express" "^4.11.1" @@ -3583,7 +3583,7 @@ graphql-yoga@~1.17.0: graphql "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0" graphql-deduplicator "^2.0.1" graphql-import "^0.7.0" - graphql-middleware "3.0.0" + graphql-middleware "3.0.1" graphql-playground-middleware-express "1.7.6" graphql-playground-middleware-lambda "1.7.6" graphql-subscriptions "^0.5.8" From 064e98943dcfc60e5738a21a19c0a3dac32d16cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Feb 2019 12:37:03 +0100 Subject: [PATCH 308/554] Remove sub-directories in /mongo-export On Digital Ocean a persistent volume has a folder `lost+found` by default. This script stops throws error messages because it can't remove that folder if we don't add `-r` flag. --- db-migration-worker/import.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db-migration-worker/import.sh b/db-migration-worker/import.sh index 0251a3582..8e949a123 100755 --- a/db-migration-worker/import.sh +++ b/db-migration-worker/import.sh @@ -18,7 +18,7 @@ echo "UPLOADS_DIRECTORY ${UPLOADS_DIRECTORY}" echo "-------------------------------------------------" mongo ${MONGODB_DATABASE} --eval "db.dropDatabase();" -rm -f /mongo-export/* +rm -rf /mongo-export/* ssh -4 -M -S my-ctrl-socket -fnNT -L 27018:localhost:27017 -l ${SSH_USERNAME} ${SSH_HOST} mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --gzip --archive | mongorestore --gzip --archive From 20908cd0628ee452086a52deff7dcfd2a584beaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Feb 2019 12:41:03 +0100 Subject: [PATCH 309/554] Docker and .gitignore entire .ssh folder On kubernetes, the ssh keys are added as a volume from a secret --- db-migration-worker/.dockerignore | 1 + db-migration-worker/.gitignore | 2 +- db-migration-worker/.ssh/.dockerignore | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 db-migration-worker/.dockerignore delete mode 100644 db-migration-worker/.ssh/.dockerignore diff --git a/db-migration-worker/.dockerignore b/db-migration-worker/.dockerignore new file mode 100644 index 000000000..59ba63a8b --- /dev/null +++ b/db-migration-worker/.dockerignore @@ -0,0 +1 @@ +.ssh/ diff --git a/db-migration-worker/.gitignore b/db-migration-worker/.gitignore index 87cb01310..59ba63a8b 100644 --- a/db-migration-worker/.gitignore +++ b/db-migration-worker/.gitignore @@ -1 +1 @@ -.ssh/id_rsa +.ssh/ diff --git a/db-migration-worker/.ssh/.dockerignore b/db-migration-worker/.ssh/.dockerignore deleted file mode 100644 index 87cb01310..000000000 --- a/db-migration-worker/.ssh/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -.ssh/id_rsa From 5492b282bc2e8ff598b9375b003c8473037af6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Feb 2019 14:31:40 +0100 Subject: [PATCH 310/554] Refactoring: No uploads/ vol,access neo4j directly Digital Ocean does not support shared directories. So we have to uploads the images in `/uploads` via `kubectl cp` or something similar. Likewise, it is not possible to share the exported mongodb .json files with neo4j container. Therefore let's install `cypher-shell`, included in `neo4j` package, to directly open a neo4j connection and bulk import the data. --- db-migration-worker/Dockerfile | 13 +++++++++---- db-migration-worker/migrate.sh | 2 ++ db-migration-worker/{ => mongo}/import.sh | 3 +-- .../import => db-migration-worker/neo4j}/badges.cql | 0 .../neo4j}/categories.cql | 0 .../neo4j}/comments.cql | 0 .../neo4j}/contributions.cql | 0 .../neo4j}/follows.cql | 0 .../import => db-migration-worker/neo4j}/import.sh | 2 ++ .../import => db-migration-worker/neo4j}/shouts.cql | 0 .../import => db-migration-worker/neo4j}/users.cql | 0 docker-compose.override.yml | 4 +--- neo4j/Dockerfile | 1 - neo4j/import/todo | 2 -- 14 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 db-migration-worker/migrate.sh rename db-migration-worker/{ => mongo}/import.sh (93%) rename {neo4j/import => db-migration-worker/neo4j}/badges.cql (100%) rename {neo4j/import => db-migration-worker/neo4j}/categories.cql (100%) rename {neo4j/import => db-migration-worker/neo4j}/comments.cql (100%) rename {neo4j/import => db-migration-worker/neo4j}/contributions.cql (100%) rename {neo4j/import => db-migration-worker/neo4j}/follows.cql (100%) rename {neo4j/import => db-migration-worker/neo4j}/import.sh (97%) rename {neo4j/import => db-migration-worker/neo4j}/shouts.cql (100%) rename {neo4j/import => db-migration-worker/neo4j}/users.cql (100%) delete mode 100644 neo4j/import/todo diff --git a/db-migration-worker/Dockerfile b/db-migration-worker/Dockerfile index d7265ac02..7d6203057 100644 --- a/db-migration-worker/Dockerfile +++ b/db-migration-worker/Dockerfile @@ -1,8 +1,13 @@ +FROM neo4j:3.5.0 as neo4j FROM mongo:4 -RUN apt-get update \ - && apt-get -y install --no-install-recommends openssh-client rsync \ +RUN apt-get update +RUN apt-get -y install --no-install-recommends wget apt-transport-https +RUN wget -O - https://debian.neo4j.org/neotechnology.gpg.key | apt-key add - +RUN echo 'deb https://debian.neo4j.org/repo stable/' | tee /etc/apt/sources.list.d/neo4j.list +RUN apt-get update +RUN apt-get -y install --no-install-recommends openjdk-8-jre openssh-client neo4j rsync \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -COPY import.sh . - +COPY neo4j/ mongo/ ./ +COPY migrate.sh /usr/local/bin/migrate diff --git a/db-migration-worker/migrate.sh b/db-migration-worker/migrate.sh new file mode 100644 index 000000000..0aea5bc89 --- /dev/null +++ b/db-migration-worker/migrate.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +/mongo/import.sh && /neo4j/import.sh diff --git a/db-migration-worker/import.sh b/db-migration-worker/mongo/import.sh similarity index 93% rename from db-migration-worker/import.sh rename to db-migration-worker/mongo/import.sh index 8e949a123..d93900339 100755 --- a/db-migration-worker/import.sh +++ b/db-migration-worker/mongo/import.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -e for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "MONGODB_AUTH_DB" "UPLOADS_DIRECTORY" do @@ -25,8 +26,6 @@ mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONG ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST} ssh -S my-ctrl-socket -O exit -l ${SSH_USERNAME} ${SSH_HOST} -rsync --archive --update --verbose ${SSH_USERNAME}@${SSH_HOST}:${UPLOADS_DIRECTORY}/* /uploads/ - for collection in "categories" "badges" "users" "contributions" "comments" "follows" "shouts" do mongoexport --db ${MONGODB_DATABASE} --collection $collection --out "/mongo-export/$collection.json" diff --git a/neo4j/import/badges.cql b/db-migration-worker/neo4j/badges.cql similarity index 100% rename from neo4j/import/badges.cql rename to db-migration-worker/neo4j/badges.cql diff --git a/neo4j/import/categories.cql b/db-migration-worker/neo4j/categories.cql similarity index 100% rename from neo4j/import/categories.cql rename to db-migration-worker/neo4j/categories.cql diff --git a/neo4j/import/comments.cql b/db-migration-worker/neo4j/comments.cql similarity index 100% rename from neo4j/import/comments.cql rename to db-migration-worker/neo4j/comments.cql diff --git a/neo4j/import/contributions.cql b/db-migration-worker/neo4j/contributions.cql similarity index 100% rename from neo4j/import/contributions.cql rename to db-migration-worker/neo4j/contributions.cql diff --git a/neo4j/import/follows.cql b/db-migration-worker/neo4j/follows.cql similarity index 100% rename from neo4j/import/follows.cql rename to db-migration-worker/neo4j/follows.cql diff --git a/neo4j/import/import.sh b/db-migration-worker/neo4j/import.sh similarity index 97% rename from neo4j/import/import.sh rename to db-migration-worker/neo4j/import.sh index 80b6595fc..d5a846384 100755 --- a/neo4j/import/import.sh +++ b/db-migration-worker/neo4j/import.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +set -e + SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" echo "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r;" | cypher-shell for collection in "badges" "categories" "users" "follows" "contributions" "shouts" "comments" diff --git a/neo4j/import/shouts.cql b/db-migration-worker/neo4j/shouts.cql similarity index 100% rename from neo4j/import/shouts.cql rename to db-migration-worker/neo4j/shouts.cql diff --git a/neo4j/import/users.cql b/db-migration-worker/neo4j/users.cql similarity index 100% rename from neo4j/import/users.cql rename to db-migration-worker/neo4j/users.cql diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 0592b801b..205d964e0 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -9,7 +9,6 @@ services: volumes: - .:/nitro-backend - /nitro-backend/node_modules - - uploads:/nitro-backend/public/uploads command: yarn run dev neo4j: volumes: @@ -25,11 +24,11 @@ services: context: db-migration-worker volumes: - mongo-export:/mongo-export - - uploads:/uploads - ./db-migration-worker/.ssh/:/root/.ssh/ networks: - hc-network environment: + - NEO4J_URI=bolt://neo4j:7687 - "SSH_USERNAME=${SSH_USERNAME}" - "SSH_HOST=${SSH_HOST}" - "MONGODB_USERNAME=${MONGODB_USERNAME}" @@ -41,4 +40,3 @@ services: volumes: mongo-export: - uploads: diff --git a/neo4j/Dockerfile b/neo4j/Dockerfile index 07344b47b..cb7fd228f 100644 --- a/neo4j/Dockerfile +++ b/neo4j/Dockerfile @@ -1,3 +1,2 @@ FROM neo4j:3.5.0 RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.1/apoc-3.5.0.1-all.jar -P plugins/ -COPY import ./import diff --git a/neo4j/import/todo b/neo4j/import/todo deleted file mode 100644 index 139597f9c..000000000 --- a/neo4j/import/todo +++ /dev/null @@ -1,2 +0,0 @@ - - From cdf92cc6eaa8061703abf321d6bd5ce12d6b2460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Feb 2019 15:36:39 +0100 Subject: [PATCH 311/554] Remove obsolete kubernetes folder --- kubernetes/README.md | 51 ------------------- kubernetes/backend-deployment.yaml | 41 --------------- kubernetes/backend-service.json | 35 ------------- kubernetes/dashboard-admin.yml | 14 ----- .../neo4j-data-persistentvolumeclaim.yaml | 14 ----- kubernetes/neo4j-deployment.yaml | 40 --------------- kubernetes/neo4j-service.json | 43 ---------------- 7 files changed, 238 deletions(-) delete mode 100644 kubernetes/README.md delete mode 100644 kubernetes/backend-deployment.yaml delete mode 100644 kubernetes/backend-service.json delete mode 100644 kubernetes/dashboard-admin.yml delete mode 100644 kubernetes/neo4j-data-persistentvolumeclaim.yaml delete mode 100644 kubernetes/neo4j-deployment.yaml delete mode 100644 kubernetes/neo4j-service.json diff --git a/kubernetes/README.md b/kubernetes/README.md deleted file mode 100644 index ffbf225b2..000000000 --- a/kubernetes/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Usage with minikube -Assuming you installed the packages git, docker ([all-distributions](https://docs.docker.com/install/)), minikube ([ubuntu]([minikube](https://computingforgeeks.com/how-to-install-minikube-on-ubuntu-18-04/)), [all-distributions](https://kubernetes.io/docs/tasks/tools/install-minikube/)) and virtualbox here... - -First of all start minikube on your machine: -```sh -minikube start -``` - -You can always get an overview and see what's going on with your minikube: -```sh -minikube dashboard -``` - -From now on stay in your favorite work directory. First let's clone the necessary sources: -```sh -git clone https://github.com/Human-Connection/Nitro-Backend.git -git clone https://github.com/Human-Connection/Nitro-Web.git -``` - -Build Docker images, using the Minikube Docker daemon: -```sh -eval $(minikube docker-env) -docker build -t humanconnection/nitro-backend:latest Nitro-Backend/ -docker build -t humanconnection/neo4j:latest -f Nitro-Backend/Dockerfile.neo4j Nitro-Backend/ -``` - -Check that the image is in Minikube’s Docker registry: -```sh -minikube ssh docker images -``` - -Now change into directory Nitro-Backend/kubernetes and create services and deployments: -```sh -cd Nitro-Backend/kubernetes -kubectl create -f neo4j-deployment.yaml,neo4j-data-persistentvolumeclaim.yaml,backend-deployment.yaml,neo4j-service.json,backend-service.json -``` - -You can see the backend in action with: -```sh -minikube service backend -``` - -### Troubleshoot - -1. If you get an error message along th lines of 'The vboxdrv kernel module is not loaded.' - then you have the same issue i had. to solve this you need to install the propper linux kernel host modules package. Here an example for Manjaro: -https://forum.manjaro.org/t/installing-virtualbox-kernel-modules/6999 -2. When you can not start minikube, try also to remove the cluster with `minikube delete` and start again with `minikube start`. Sometimes this fix startup problems of the cluster. -3. Now again you might run into trouble with an error like 'kubectl could not be found on your path.' In this case run the following command: - ```sh - curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.10.0/bin/linux/amd64/kubectl && chmod +x kubectl && sudo cp kubectl /usr/local/bin/ && rm kubectl - ``` diff --git a/kubernetes/backend-deployment.yaml b/kubernetes/backend-deployment.yaml deleted file mode 100644 index f75920f0d..000000000 --- a/kubernetes/backend-deployment.yaml +++ /dev/null @@ -1,41 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - annotations: - kompose.cmd: kompose convert -f ../docker-compose.yml - kompose.version: 1.16.0 (0c01309) - creationTimestamp: null - labels: - io.kompose.service: backend - name: backend -spec: - replicas: 1 - strategy: {} - template: - metadata: - creationTimestamp: null - labels: - io.kompose.service: backend - spec: - containers: - - env: - - name: CLIENT_URI - value: http://localhost:3000 - - name: GRAPHQL_PORT - value: "4000" - - name: GRAPHQL_URI - value: http://localhost:4000 - - name: JWT_SECRET - value: b/&&7b78BF&fv/Vd - - name: MOCK - value: "false" - - name: NEO4J_URI - value: bolt://neo4j:7687 - image: humanconnection/nitro-backend:latest - name: backend - ports: - - containerPort: 4000 - resources: {} - imagePullPolicy: IfNotPresent - restartPolicy: Always -status: {} diff --git a/kubernetes/backend-service.json b/kubernetes/backend-service.json deleted file mode 100644 index 28581be45..000000000 --- a/kubernetes/backend-service.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "backend", - "namespace": "default", - "selfLink": "/api/v1/namespaces/default/services/backend", - "uid": "57749bc1-dea3-11e8-ace2-080027b5d96d", - "resourceVersion": "8321", - "creationTimestamp": "2018-11-02T13:29:36Z", - "labels": { - "io.kompose.service": "backend" - } - }, - "spec": { - "ports": [ - { - "protocol": "TCP", - "port": 4000, - "targetPort": 4000, - "nodePort": 32633 - } - ], - "selector": { - "io.kompose.service": "backend" - }, - "clusterIP": "10.110.129.92", - "type": "LoadBalancer", - "sessionAffinity": "None", - "externalTrafficPolicy": "Cluster" - }, - "status": { - "loadBalancer": {} - } -} diff --git a/kubernetes/dashboard-admin.yml b/kubernetes/dashboard-admin.yml deleted file mode 100644 index 5d76d3902..000000000 --- a/kubernetes/dashboard-admin.yml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding -metadata: - name: kubernetes-dashboard - labels: - k8s-app: kubernetes-dashboard -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: cluster-admin -subjects: -- kind: ServiceAccount - name: kubernetes-dashboard - namespace: kube-system diff --git a/kubernetes/neo4j-data-persistentvolumeclaim.yaml b/kubernetes/neo4j-data-persistentvolumeclaim.yaml deleted file mode 100644 index de9c89e2f..000000000 --- a/kubernetes/neo4j-data-persistentvolumeclaim.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - creationTimestamp: null - labels: - io.kompose.service: neo4j-data - name: neo4j-data -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 100Mi -status: {} diff --git a/kubernetes/neo4j-deployment.yaml b/kubernetes/neo4j-deployment.yaml deleted file mode 100644 index 13f4d52e3..000000000 --- a/kubernetes/neo4j-deployment.yaml +++ /dev/null @@ -1,40 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - annotations: - kompose.cmd: kompose convert -f ../docker-compose.yml - kompose.version: 1.16.0 (0c01309) - creationTimestamp: null - labels: - io.kompose.service: neo4j - name: neo4j -spec: - replicas: 1 - strategy: - type: Recreate - template: - metadata: - creationTimestamp: null - labels: - io.kompose.service: neo4j - spec: - containers: - - env: - - name: NEO4J_AUTH - value: none - image: humanconnection/neo4j:latest - name: neo4j - ports: - - containerPort: 7687 - - containerPort: 7474 - resources: {} - imagePullPolicy: IfNotPresent - volumeMounts: - - mountPath: /data - name: neo4j-data - restartPolicy: Always - volumes: - - name: neo4j-data - persistentVolumeClaim: - claimName: neo4j-data -status: {} diff --git a/kubernetes/neo4j-service.json b/kubernetes/neo4j-service.json deleted file mode 100644 index 89ac10367..000000000 --- a/kubernetes/neo4j-service.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "neo4j", - "namespace": "default", - "selfLink": "/api/v1/namespaces/default/services/neo4j", - "uid": "57de6181-dea3-11e8-ace2-080027b5d96d", - "resourceVersion": "8326", - "creationTimestamp": "2018-11-02T13:29:37Z", - "labels": { - "io.kompose.service": "neo4j" - } - }, - "spec": { - "ports": [ - { - "name": "port-1", - "protocol": "TCP", - "port": 7687, - "targetPort": 7687, - "nodePort": 30116 - }, - { - "name": "port-2", - "protocol": "TCP", - "port": 7474, - "targetPort": 7474, - "nodePort": 32658 - } - ], - "selector": { - "io.kompose.service": "neo4j" - }, - "clusterIP": "10.108.175.122", - "type": "LoadBalancer", - "sessionAffinity": "None", - "externalTrafficPolicy": "Cluster" - }, - "status": { - "loadBalancer": {} - } -} From ca076bbcb9f312a7248479c5a15faed27e38e66a Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 4 Feb 2019 17:19:26 +0100 Subject: [PATCH 312/554] Assign post to current user on creation --- src/middleware/userMiddleware.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index d4648413a..db5595e87 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -11,6 +11,24 @@ export default { UpdateUser: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) await createOrUpdateLocations(args.id, args.locationName, context.driver) + return result + }, + CreatePost: async (resolve, root, args, context, info) => { + const result = await resolve(root, args, context, info) + + try { + const session = context.driver.session() + await session.run( + 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + + 'MERGE (post)<-[:WROTE]-(author) ' + + 'RETURN author', { + userId: context.user.id, + postId: result.id + }) + session.close() + // eslint-disable-next-line no-empty + } catch (err) {} + return result } }, From cc5701a193e8ce892efce67283b4fedc3e410196 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 4 Feb 2019 17:20:04 +0100 Subject: [PATCH 313/554] Do not catch issues on user assign at post create --- src/middleware/userMiddleware.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index db5595e87..cf42709e9 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -16,18 +16,15 @@ export default { CreatePost: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) - try { - const session = context.driver.session() - await session.run( - 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + - 'MERGE (post)<-[:WROTE]-(author) ' + - 'RETURN author', { - userId: context.user.id, - postId: result.id - }) - session.close() - // eslint-disable-next-line no-empty - } catch (err) {} + const session = context.driver.session() + await session.run( + 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + + 'MERGE (post)<-[:WROTE]-(author) ' + + 'RETURN author', { + userId: context.user.id, + postId: result.id + }) + session.close() return result } From 01a145be29a272ae1cdd8ed05f4a634131cfd79e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Feb 2019 15:43:21 +0100 Subject: [PATCH 314/554] Container db-migration-worker need no volumes You can simply run `docker-compose exec db-migration-worker migrate` and that's it. Of course you have to provide all the environment variables. --- .dockerignore | 1 - db-migration-worker/Dockerfile | 3 +-- db-migration-worker/migrate.sh | 4 +++- db-migration-worker/{ => migration}/mongo/import.sh | 3 +-- db-migration-worker/{ => migration}/neo4j/badges.cql | 0 .../{ => migration}/neo4j/categories.cql | 0 .../{ => migration}/neo4j/comments.cql | 0 .../{ => migration}/neo4j/contributions.cql | 0 .../{ => migration}/neo4j/follows.cql | 0 db-migration-worker/{ => migration}/neo4j/import.sh | 12 ++++++++++-- db-migration-worker/{ => migration}/neo4j/shouts.cql | 0 db-migration-worker/{ => migration}/neo4j/users.cql | 0 docker-compose.override.yml | 3 ++- 13 files changed, 17 insertions(+), 9 deletions(-) mode change 100644 => 100755 db-migration-worker/migrate.sh rename db-migration-worker/{ => migration}/mongo/import.sh (91%) rename db-migration-worker/{ => migration}/neo4j/badges.cql (100%) rename db-migration-worker/{ => migration}/neo4j/categories.cql (100%) rename db-migration-worker/{ => migration}/neo4j/comments.cql (100%) rename db-migration-worker/{ => migration}/neo4j/contributions.cql (100%) rename db-migration-worker/{ => migration}/neo4j/follows.cql (100%) rename db-migration-worker/{ => migration}/neo4j/import.sh (55%) rename db-migration-worker/{ => migration}/neo4j/shouts.cql (100%) rename db-migration-worker/{ => migration}/neo4j/users.cql (100%) diff --git a/.dockerignore b/.dockerignore index dba77200f..31f5b28f3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,7 +11,6 @@ docker-compose*.yml ./*.png ./*.log -kubernetes/ node_modules/ scripts/ dist/ diff --git a/db-migration-worker/Dockerfile b/db-migration-worker/Dockerfile index 7d6203057..cd6e57258 100644 --- a/db-migration-worker/Dockerfile +++ b/db-migration-worker/Dockerfile @@ -1,4 +1,3 @@ -FROM neo4j:3.5.0 as neo4j FROM mongo:4 RUN apt-get update @@ -9,5 +8,5 @@ RUN apt-get update RUN apt-get -y install --no-install-recommends openjdk-8-jre openssh-client neo4j rsync \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -COPY neo4j/ mongo/ ./ +COPY migration ./migration COPY migrate.sh /usr/local/bin/migrate diff --git a/db-migration-worker/migrate.sh b/db-migration-worker/migrate.sh old mode 100644 new mode 100755 index 0aea5bc89..108453bba --- a/db-migration-worker/migrate.sh +++ b/db-migration-worker/migrate.sh @@ -1,2 +1,4 @@ #!/usr/bin/env bash -/mongo/import.sh && /neo4j/import.sh +set -e +/migration/mongo/import.sh +/migration/neo4j/import.sh diff --git a/db-migration-worker/mongo/import.sh b/db-migration-worker/migration/mongo/import.sh similarity index 91% rename from db-migration-worker/mongo/import.sh rename to db-migration-worker/migration/mongo/import.sh index d93900339..4f59551aa 100755 --- a/db-migration-worker/mongo/import.sh +++ b/db-migration-worker/migration/mongo/import.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -e -for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "MONGODB_AUTH_DB" "UPLOADS_DIRECTORY" +for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "MONGODB_AUTH_DB" do if [[ -z "${!var}" ]]; then echo "${var} is undefined" @@ -15,7 +15,6 @@ echo "MONGODB_USERNAME ${MONGODB_USERNAME}" echo "MONGODB_PASSWORD ${MONGODB_PASSWORD}" echo "MONGODB_DATABASE ${MONGODB_DATABASE}" echo "MONGODB_AUTH_DB ${MONGODB_AUTH_DB}" -echo "UPLOADS_DIRECTORY ${UPLOADS_DIRECTORY}" echo "-------------------------------------------------" mongo ${MONGODB_DATABASE} --eval "db.dropDatabase();" diff --git a/db-migration-worker/neo4j/badges.cql b/db-migration-worker/migration/neo4j/badges.cql similarity index 100% rename from db-migration-worker/neo4j/badges.cql rename to db-migration-worker/migration/neo4j/badges.cql diff --git a/db-migration-worker/neo4j/categories.cql b/db-migration-worker/migration/neo4j/categories.cql similarity index 100% rename from db-migration-worker/neo4j/categories.cql rename to db-migration-worker/migration/neo4j/categories.cql diff --git a/db-migration-worker/neo4j/comments.cql b/db-migration-worker/migration/neo4j/comments.cql similarity index 100% rename from db-migration-worker/neo4j/comments.cql rename to db-migration-worker/migration/neo4j/comments.cql diff --git a/db-migration-worker/neo4j/contributions.cql b/db-migration-worker/migration/neo4j/contributions.cql similarity index 100% rename from db-migration-worker/neo4j/contributions.cql rename to db-migration-worker/migration/neo4j/contributions.cql diff --git a/db-migration-worker/neo4j/follows.cql b/db-migration-worker/migration/neo4j/follows.cql similarity index 100% rename from db-migration-worker/neo4j/follows.cql rename to db-migration-worker/migration/neo4j/follows.cql diff --git a/db-migration-worker/neo4j/import.sh b/db-migration-worker/migration/neo4j/import.sh similarity index 55% rename from db-migration-worker/neo4j/import.sh rename to db-migration-worker/migration/neo4j/import.sh index d5a846384..9a5045d62 100755 --- a/db-migration-worker/neo4j/import.sh +++ b/db-migration-worker/migration/neo4j/import.sh @@ -1,9 +1,17 @@ #!/usr/bin/env bash set -e +for var in "NEO4J_URI" +do + if [[ -z "${!var}" ]]; then + echo "${var} is undefined" + exit 1 + fi +done + SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -echo "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r;" | cypher-shell +echo "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r;" | cypher-shell -a $NEO4J_URI for collection in "badges" "categories" "users" "follows" "contributions" "shouts" "comments" do - echo "Import ${collection}..." && cypher-shell < $SCRIPT_DIRECTORY/$collection.cql + echo "Import ${collection}..." && cypher-shell -a $NEO4J_URI < $SCRIPT_DIRECTORY/$collection.cql done diff --git a/db-migration-worker/neo4j/shouts.cql b/db-migration-worker/migration/neo4j/shouts.cql similarity index 100% rename from db-migration-worker/neo4j/shouts.cql rename to db-migration-worker/migration/neo4j/shouts.cql diff --git a/db-migration-worker/neo4j/users.cql b/db-migration-worker/migration/neo4j/users.cql similarity index 100% rename from db-migration-worker/neo4j/users.cql rename to db-migration-worker/migration/neo4j/users.cql diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 205d964e0..6bc594099 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -27,6 +27,8 @@ services: - ./db-migration-worker/.ssh/:/root/.ssh/ networks: - hc-network + depends_on: + - backend environment: - NEO4J_URI=bolt://neo4j:7687 - "SSH_USERNAME=${SSH_USERNAME}" @@ -35,7 +37,6 @@ services: - "MONGODB_PASSWORD=${MONGODB_PASSWORD}" - "MONGODB_AUTH_DB=${MONGODB_AUTH_DB}" - "MONGODB_DATABASE=${MONGODB_DATABASE}" - - "UPLOADS_DIRECTORY=${UPLOADS_DIRECTORY}" command: "--smallfiles --logpath=/dev/null" volumes: From 955383f169ee5d6aed2f1ca00ce8dddeedb75436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Feb 2019 19:19:31 +0100 Subject: [PATCH 315/554] Separate `docker-compose.yml` to test db migration I think it's not that relevant to our new contributors to install the db-migration-worker. --- docker-compose.db-migration.yml | 29 +++++++++++++++++++++++++++++ docker-compose.override.yml | 27 --------------------------- 2 files changed, 29 insertions(+), 27 deletions(-) create mode 100644 docker-compose.db-migration.yml diff --git a/docker-compose.db-migration.yml b/docker-compose.db-migration.yml new file mode 100644 index 000000000..360fbef82 --- /dev/null +++ b/docker-compose.db-migration.yml @@ -0,0 +1,29 @@ +version: "3.7" + +services: + neo4j: + volumes: + - mongo-export:/mongo-export + environment: + - NEO4J_apoc_import_file_enabled=true + db-migration-worker: + build: + context: db-migration-worker + volumes: + - mongo-export:/mongo-export + - ./db-migration-worker/.ssh/:/root/.ssh/ + networks: + - hc-network + depends_on: + - backend + environment: + - NEO4J_URI=bolt://neo4j:7687 + - "SSH_USERNAME=${SSH_USERNAME}" + - "SSH_HOST=${SSH_HOST}" + - "MONGODB_USERNAME=${MONGODB_USERNAME}" + - "MONGODB_PASSWORD=${MONGODB_PASSWORD}" + - "MONGODB_AUTH_DB=${MONGODB_AUTH_DB}" + - "MONGODB_DATABASE=${MONGODB_DATABASE}" + +volumes: + mongo-export: diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 6bc594099..ef7d52c7e 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -11,33 +11,6 @@ services: - /nitro-backend/node_modules command: yarn run dev neo4j: - volumes: - - mongo-export:/mongo-export - - ./neo4j/import:/var/lib/neo4j/import ports: - 7687:7687 - 7474:7474 - environment: - - NEO4J_apoc_import_file_enabled=true - db-migration-worker: - build: - context: db-migration-worker - volumes: - - mongo-export:/mongo-export - - ./db-migration-worker/.ssh/:/root/.ssh/ - networks: - - hc-network - depends_on: - - backend - environment: - - NEO4J_URI=bolt://neo4j:7687 - - "SSH_USERNAME=${SSH_USERNAME}" - - "SSH_HOST=${SSH_HOST}" - - "MONGODB_USERNAME=${MONGODB_USERNAME}" - - "MONGODB_PASSWORD=${MONGODB_PASSWORD}" - - "MONGODB_AUTH_DB=${MONGODB_AUTH_DB}" - - "MONGODB_DATABASE=${MONGODB_DATABASE}" - command: "--smallfiles --logpath=/dev/null" - -volumes: - mongo-export: From 084f610ec8c9a6e06c16fc4ce8f3a252341f9ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Feb 2019 19:44:39 +0100 Subject: [PATCH 316/554] Turnaround: *use* volumes for sharing data ... but use it in the same pod. It seems to be possible to have shared volumes in the same pod: https://kubernetes.io/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/ --- db-migration-worker/Dockerfile | 1 + db-migration-worker/sync_uploads.sh | 12 ++++++++++++ docker-compose.db-migration.yml | 6 ++++++ 3 files changed, 19 insertions(+) create mode 100755 db-migration-worker/sync_uploads.sh diff --git a/db-migration-worker/Dockerfile b/db-migration-worker/Dockerfile index cd6e57258..8a7f8d758 100644 --- a/db-migration-worker/Dockerfile +++ b/db-migration-worker/Dockerfile @@ -10,3 +10,4 @@ RUN apt-get -y install --no-install-recommends openjdk-8-jre openssh-client neo4 && rm -rf /var/lib/apt/lists/* COPY migration ./migration COPY migrate.sh /usr/local/bin/migrate +COPY sync_uploads.sh /usr/local/bin/sync_uploads diff --git a/db-migration-worker/sync_uploads.sh b/db-migration-worker/sync_uploads.sh new file mode 100755 index 000000000..d24936e3b --- /dev/null +++ b/db-migration-worker/sync_uploads.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e + +for var in "SSH_USERNAME" "SSH_HOST" "UPLOADS_DIRECTORY" +do + if [[ -z "${!var}" ]]; then + echo "${var} is undefined" + exit 1 + fi +done + +rsync --archive --update --verbose ${SSH_USERNAME}@${SSH_HOST}:${UPLOADS_DIRECTORY}/* /uploads/ diff --git a/docker-compose.db-migration.yml b/docker-compose.db-migration.yml index 360fbef82..7d421e968 100644 --- a/docker-compose.db-migration.yml +++ b/docker-compose.db-migration.yml @@ -1,6 +1,9 @@ version: "3.7" services: + backend: + volumes: + - uploads:/nitro-backend/public/uploads neo4j: volumes: - mongo-export:/mongo-export @@ -11,6 +14,7 @@ services: context: db-migration-worker volumes: - mongo-export:/mongo-export + - uploads:/uploads - ./db-migration-worker/.ssh/:/root/.ssh/ networks: - hc-network @@ -24,6 +28,8 @@ services: - "MONGODB_PASSWORD=${MONGODB_PASSWORD}" - "MONGODB_AUTH_DB=${MONGODB_AUTH_DB}" - "MONGODB_DATABASE=${MONGODB_DATABASE}" + - "UPLOADS_DIRECTORY=${UPLOADS_DIRECTORY}" volumes: mongo-export: + uploads: From 2bc1e88920d6de1954d37a5bd2093f9650a92c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Feb 2019 19:54:43 +0100 Subject: [PATCH 317/554] Make CodeFactor happy --- db-migration-worker/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/db-migration-worker/Dockerfile b/db-migration-worker/Dockerfile index 8a7f8d758..865a4c330 100644 --- a/db-migration-worker/Dockerfile +++ b/db-migration-worker/Dockerfile @@ -1,11 +1,11 @@ FROM mongo:4 -RUN apt-get update -RUN apt-get -y install --no-install-recommends wget apt-transport-https +RUN apt-get update && apt-get -y install --no-install-recommends wget apt-transport-https \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* RUN wget -O - https://debian.neo4j.org/neotechnology.gpg.key | apt-key add - RUN echo 'deb https://debian.neo4j.org/repo stable/' | tee /etc/apt/sources.list.d/neo4j.list -RUN apt-get update -RUN apt-get -y install --no-install-recommends openjdk-8-jre openssh-client neo4j rsync \ +RUN apt-get update && apt-get -y install --no-install-recommends openjdk-8-jre openssh-client neo4j rsync \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* COPY migration ./migration From 5b674cd95fe8cb299b010b8783243186abc8e8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Feb 2019 21:33:48 +0100 Subject: [PATCH 318/554] Hopefully fix `migrate` on Digital Ocean It kept crashing, maybe because we're piping too much stuff to STDOUT. Let's see. --- db-migration-worker/migration/mongo/import.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db-migration-worker/migration/mongo/import.sh b/db-migration-worker/migration/mongo/import.sh index 4f59551aa..fb13a151f 100755 --- a/db-migration-worker/migration/mongo/import.sh +++ b/db-migration-worker/migration/mongo/import.sh @@ -21,7 +21,8 @@ mongo ${MONGODB_DATABASE} --eval "db.dropDatabase();" rm -rf /mongo-export/* ssh -4 -M -S my-ctrl-socket -fnNT -L 27018:localhost:27017 -l ${SSH_USERNAME} ${SSH_HOST} -mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --gzip --archive | mongorestore --gzip --archive +mongodump --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --gzip --archive=/tmp/mongodump.archive +mongorestore --gzip --archive=/tmp/mongodump.archive ssh -S my-ctrl-socket -O check -l ${SSH_USERNAME} ${SSH_HOST} ssh -S my-ctrl-socket -O exit -l ${SSH_USERNAME} ${SSH_HOST} From 82c679aaf143b0a77cb57b0174049ceeea75c409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Feb 2019 21:42:44 +0100 Subject: [PATCH 319/554] Check the environment variables early on I was missing NEO4J_URI and was told very late - let's check env vars at the very beginning. --- db-migration-worker/migrate.sh | 8 ++++++++ db-migration-worker/migration/mongo/import.sh | 8 -------- db-migration-worker/migration/neo4j/import.sh | 8 -------- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/db-migration-worker/migrate.sh b/db-migration-worker/migrate.sh index 108453bba..214da53d8 100755 --- a/db-migration-worker/migrate.sh +++ b/db-migration-worker/migrate.sh @@ -1,4 +1,12 @@ #!/usr/bin/env bash set -e +for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "MONGODB_AUTH_DB" "NEO4J_URI" +do + if [[ -z "${!var}" ]]; then + echo "${var} is undefined" + exit 1 + fi +done + /migration/mongo/import.sh /migration/neo4j/import.sh diff --git a/db-migration-worker/migration/mongo/import.sh b/db-migration-worker/migration/mongo/import.sh index fb13a151f..7cf3e91e4 100755 --- a/db-migration-worker/migration/mongo/import.sh +++ b/db-migration-worker/migration/mongo/import.sh @@ -1,14 +1,6 @@ #!/usr/bin/env bash set -e -for var in "SSH_USERNAME" "SSH_HOST" "MONGODB_USERNAME" "MONGODB_PASSWORD" "MONGODB_DATABASE" "MONGODB_AUTH_DB" -do - if [[ -z "${!var}" ]]; then - echo "${var} is undefined" - exit 1 - fi -done - echo "SSH_USERNAME ${SSH_USERNAME}" echo "SSH_HOST ${SSH_HOST}" echo "MONGODB_USERNAME ${MONGODB_USERNAME}" diff --git a/db-migration-worker/migration/neo4j/import.sh b/db-migration-worker/migration/neo4j/import.sh index 9a5045d62..6f539c501 100755 --- a/db-migration-worker/migration/neo4j/import.sh +++ b/db-migration-worker/migration/neo4j/import.sh @@ -1,14 +1,6 @@ #!/usr/bin/env bash set -e -for var in "NEO4J_URI" -do - if [[ -z "${!var}" ]]; then - echo "${var} is undefined" - exit 1 - fi -done - SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" echo "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r;" | cypher-shell -a $NEO4J_URI for collection in "badges" "categories" "users" "follows" "contributions" "shouts" "comments" From 6610266a5bc2b47edc8bcd62bd5928081b339d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 5 Feb 2019 14:32:20 +0100 Subject: [PATCH 320/554] Mount /migration for quick development --- docker-compose.db-migration.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.db-migration.yml b/docker-compose.db-migration.yml index 7d421e968..02f054d1b 100644 --- a/docker-compose.db-migration.yml +++ b/docker-compose.db-migration.yml @@ -15,6 +15,7 @@ services: volumes: - mongo-export:/mongo-export - uploads:/uploads + - ./db-migration-worker/migration/:/migration - ./db-migration-worker/.ssh/:/root/.ssh/ networks: - hc-network From 0705ab1bf5585d7afa3b39a567f2bbfe9d403f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 5 Feb 2019 14:48:13 +0100 Subject: [PATCH 321/554] Fix missing contribution author Bug: Only if a tag and a category was present, the author was assigned. --- .../migration/neo4j/contributions.cql | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/db-migration-worker/migration/neo4j/contributions.cql b/db-migration-worker/migration/neo4j/contributions.cql index 86226b98f..0c7b18959 100644 --- a/db-migration-worker/migration/neo4j/contributions.cql +++ b/db-migration-worker/migration/neo4j/contributions.cql @@ -11,13 +11,15 @@ p.createdAt = post.createdAt.`$date`, p.updatedAt = post.updatedAt.`$date`, p.deleted = post.deleted, p.disabled = NOT post.isEnabled -WITH p, post, post.tags AS tags, post.categoryIds as categoryIds -UNWIND tags AS tag +WITH p, post +MATCH (u:User {id: post.userId}) +MERGE (u)-[:WROTE]->(p) +WITH p, post, post.categoryIds as categoryIds UNWIND categoryIds AS categoryId -MATCH (c:Category {id: categoryId}), - (u:User {id: post.userId}) +MATCH (c:Category {id: categoryId}) +MERGE (p)-[:CATEGORIZED]->(c) +WITH p, post.tags AS tags +UNWIND tags AS tag MERGE (t:Tag {id: apoc.create.uuid(), name: tag}) MERGE (p)-[:TAGGED]->(t) -MERGE (u)-[:WROTE]->(p) -MERGE (p)-[:CATEGORIZED]->(c) ; From 9656bd4eb7758ec4f09624c9736471347a240889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 5 Feb 2019 20:02:59 +0100 Subject: [PATCH 322/554] Fix comments import @appinteractive --- .../migration/neo4j/comments.cql | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/db-migration-worker/migration/neo4j/comments.cql b/db-migration-worker/migration/neo4j/comments.cql index 16537b730..6709acbc8 100644 --- a/db-migration-worker/migration/neo4j/comments.cql +++ b/db-migration-worker/migration/neo4j/comments.cql @@ -1,12 +1,14 @@ -CALL apoc.load.json('file:/mongo-export/comments.json') YIELD value as comment -MERGE (c:Comment {id: comment._id["$oid"]}) +CALL apoc.load.json('file:/mongo-export/comments.json') YIELD value as json +MERGE (comment:Comment {id: json._id["$oid"]}) ON CREATE SET -c.content = comment.content, -c.contentExcerpt = comment.contentExcerpt, -c.deleted = comment.deleted, -c.disabled = false -WITH comment -MATCH (p:Post {id: comment.contributionId}), (u:User {id: comment.userId}) -MERGE (c)-[:COMMENTS]->(p) -MERGE (u)-[:WROTE]->(c) +comment.content = json.content, +comment.contentExcerpt = json.contentExcerpt, +comment.deleted = json.deleted, +comment.disabled = false +WITH comment, json, json.contributionId as postId +MATCH (post:Post {id: postId}) +WITH comment, post, json.userId as userId +MATCH (author:User {id: userId}) +MERGE (comment)-[:COMMENTS]->(post) +MERGE (author)-[:WROTE]->(comment) ; From ad2bba586e119f8e746d380d424d9a0e811485fa Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 6 Feb 2019 17:20:38 +0100 Subject: [PATCH 323/554] Fixed link target --- src/middleware/xssMiddleware.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/middleware/xssMiddleware.js b/src/middleware/xssMiddleware.js index c2fee7976..64ff8717d 100644 --- a/src/middleware/xssMiddleware.js +++ b/src/middleware/xssMiddleware.js @@ -53,15 +53,15 @@ function clean (dirty) { h4: 'h4', h5: 'strong', i: 'em', - // a: function (tagName, attribs) { - // return { - // tagName: 'a', - // attribs: { - // href: attribs.href, - // target: '_blank', - // } - // } - // }, + a: function (tagName, attribs) { + return { + tagName: 'a', + attribs: { + href: attribs.href, + target: '_blank' + } + } + }, b: 'strong', s: 'strike', img: function (tagName, attribs) { From 2f2bc5e507b0de71d80b4b76cd6f937309b05408 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 7 Feb 2019 08:46:34 +0100 Subject: [PATCH 324/554] Improved link cleaning --- src/middleware/xssMiddleware.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/middleware/xssMiddleware.js b/src/middleware/xssMiddleware.js index 64ff8717d..2607f4210 100644 --- a/src/middleware/xssMiddleware.js +++ b/src/middleware/xssMiddleware.js @@ -58,7 +58,8 @@ function clean (dirty) { tagName: 'a', attribs: { href: attribs.href, - target: '_blank' + target: '_blank', + rel: 'noopener noreferrer nofollow' } } }, From ae9ebcc3ab3e60409de59a3095901d8f58527852 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 7 Feb 2019 15:36:07 +0100 Subject: [PATCH 325/554] Upgraded graphql from 0.13.0 to 14.1.1 --- package.json | 6 +++--- src/graphql-schema.js | 18 +++++++++--------- src/server.js | 27 +++++++++++++-------------- yarn.lock | 10 +++++----- 4 files changed, 30 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index d24d801ad..cc8da26eb 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,9 @@ "test": "nyc --reporter=text-lcov yarn run test:jest", "test:before:server": "cross-env GRAPHQL_URI=http://localhost:4123 GRAPHQL_PORT=4123 babel-node src/ 2> /dev/null", "test:before:seeder": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 PERMISSIONS=disabled babel-node src/ 2> /dev/null", - "test:jest:cmd": "wait-on tcp:4001 tcp:4123 && jest --forceExit --detectOpenHandles --runInBand", + "test:jest:cmd": "wait-on tcp:4001 tcp:4123 && jest --forceExit --detectOpenHandles --runInBand", "test:jest:cmd:debug": "wait-on tcp:4001 tcp:4123 && node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand", - "test:jest": "run-p --race test:before:* 'test:jest:cmd {@}' --", + "test:jest": "run-p --race test:before:* 'test:jest:cmd {@}' --", "test:jest:debug": "run-p --race test:before:* 'test:jest:cmd:debug {@}' --", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", @@ -44,7 +44,7 @@ "date-fns": "^2.0.0-alpha.26", "dotenv": "~6.2.0", "faker": "~4.1.0", - "graphql": "~0.13.0", + "graphql": "~14.1.1", "graphql-custom-directives": "~0.2.14", "graphql-iso-date": "~3.6.1", "graphql-middleware": "~1.7.8", diff --git a/src/graphql-schema.js b/src/graphql-schema.js index e9475539b..8b5f369e0 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -66,15 +66,15 @@ export const resolvers = { countShouts: 'MATCH (:User)-[r:SHOUTED]->(:Post) RETURN COUNT(r) AS countShouts' } let data = { - countUsers: (await queryOne(queries.countUsers, session)).countUsers, - countPosts: (await queryOne(queries.countPosts, session)).countPosts, - countComments: (await queryOne(queries.countComments, session)).countComments, - countNotifications: (await queryOne(queries.countNotifications, session)).countNotifications, - countOrganizations: (await queryOne(queries.countOrganizations, session)).countOrganizations, - countProjects: (await queryOne(queries.countProjects, session)).countProjects, - countInvites: (await queryOne(queries.countInvites, session)).countInvites, - countFollows: (await queryOne(queries.countFollows, session)).countFollows, - countShouts: (await queryOne(queries.countShouts, session)).countShouts + countUsers: (await queryOne(queries.countUsers, session)).countUsers.low, + countPosts: (await queryOne(queries.countPosts, session)).countPosts.low, + countComments: (await queryOne(queries.countComments, session)).countComments.low, + countNotifications: (await queryOne(queries.countNotifications, session)).countNotifications.low, + countOrganizations: (await queryOne(queries.countOrganizations, session)).countOrganizations.low, + countProjects: (await queryOne(queries.countProjects, session)).countProjects.low, + countInvites: (await queryOne(queries.countInvites, session)).countInvites.low, + countFollows: (await queryOne(queries.countFollows, session)).countFollows.low, + countShouts: (await queryOne(queries.countShouts, session)).countShouts.low } resolve(data) }) diff --git a/src/server.js b/src/server.js index 728237562..e94ad9a77 100644 --- a/src/server.js +++ b/src/server.js @@ -1,6 +1,6 @@ import { GraphQLServer } from 'graphql-yoga' import { makeExecutableSchema } from 'apollo-server' -import { augmentSchema } from 'neo4j-graphql-js' +import { augmentSchema, makeAugmentedSchema } from 'neo4j-graphql-js' import { typeDefs, resolvers } from './graphql-schema' import express from 'express' import dotenv from 'dotenv' @@ -23,22 +23,21 @@ requiredEnvVars.forEach(env => { } }) -let schema = makeExecutableSchema({ - typeDefs, - resolvers -}) - const driver = neo4j().getDriver() const debug = process.env.NODE_ENV !== 'production' && process.env.DEBUG === 'true' -schema = augmentSchema(schema, { - query: { - exclude: ['Statistics', 'LoggedInUser'] - }, - mutation: { - exclude: ['Statistics', 'LoggedInUser'] - }, - debug: debug +let schema = makeAugmentedSchema({ + typeDefs, + resolvers, + config: { + query: { + exclude: ['Statistics', 'LoggedInUser'] + }, + mutation: { + exclude: ['Statistics', 'LoggedInUser'] + }, + debug: debug + } }) schema = applyScalars(applyDirectives(schema)) diff --git a/yarn.lock b/yarn.lock index 310133908..9f5e9cab6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3597,12 +3597,12 @@ graphql-yoga@~1.17.1: dependencies: iterall "^1.2.2" -graphql@~0.13.0: - version "0.13.2" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" - integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== +graphql@~14.1.1: + version "14.1.1" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.1.1.tgz#d5d77df4b19ef41538d7215d1e7a28834619fac0" + integrity sha512-C5zDzLqvfPAgTtP8AUPIt9keDabrdRAqSWjj2OPRKrKxI9Fb65I36s1uCs1UUBFnSWTdO7hyHi7z1ZbwKMKF6Q== dependencies: - iterall "^1.2.1" + iterall "^1.2.2" growly@^1.3.0: version "1.3.0" From d84def310bd160178d763285064ab8f8dd0775d3 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 7 Feb 2019 15:52:07 +0100 Subject: [PATCH 326/554] Upgraded apollo-server and graphql-yoga --- package.json | 4 +- yarn.lock | 230 +++++++++++++++++++++++++++++---------------------- 2 files changed, 133 insertions(+), 101 deletions(-) diff --git a/package.json b/package.json index cc8da26eb..9a12ad317 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "apollo-cache-inmemory": "~1.4.0", "apollo-client": "~2.4.9", "apollo-link-http": "~1.5.9", - "apollo-server": "~2.3.1", + "apollo-server": "~2.4.0", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", "cross-env": "~5.2.0", @@ -50,7 +50,7 @@ "graphql-middleware": "~1.7.8", "graphql-shield": "~4.1.2", "graphql-tag": "~2.10.1", - "graphql-yoga": "~1.17.1", + "graphql-yoga": "~1.17.4", "jsonwebtoken": "~8.4.0", "linkifyjs": "~2.1.7", "lodash": "~4.17.11", diff --git a/yarn.lock b/yarn.lock index 9f5e9cab6..da824f1dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,6 +9,13 @@ dependencies: apollo-env "0.2.5" +"@apollographql/apollo-tools@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.3.2.tgz#415c984955c4ae249550def698cbffab8d27bda4" + integrity sha512-IiuO1XaxxvbZa19gGHBOEgQKmMHB+ghXaNjSbY5dWqCEQgBDgJBA/2a1Oq9tMPhEPAmEY2FOuhaWRxxKxmVdlQ== + dependencies: + apollo-env "0.3.2" + "@apollographql/apollo-upload-server@^5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" @@ -811,7 +818,7 @@ "@types/node" "*" "@types/range-parser" "*" -"@types/express@*", "@types/express@4.16.0", "@types/express@^4.11.1": +"@types/express@*", "@types/express@^4.11.1": version "4.16.0" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.0.tgz#6d8bc42ccaa6f35cf29a2b7c3333cb47b5a32a19" integrity sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w== @@ -820,6 +827,15 @@ "@types/express-serve-static-core" "*" "@types/serve-static" "*" +"@types/express@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.1.tgz#d756bd1a85c34d87eaf44c888bad27ba8a4b7cf0" + integrity sha512-V0clmJow23WeyblmACoxbHBu2JKlE5TiIme6Lem14FnPW9gsttyHtk6wq7njcdIWH1njAaFgR8gW09lgY98gQg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/serve-static" "*" + "@types/graphql-deduplicator@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/graphql-deduplicator/-/graphql-deduplicator-2.0.0.tgz#9e577b8f3feb3d067b0ca756f4a1fb356d533922" @@ -992,13 +1008,13 @@ apollo-cache-control@0.3.4: apollo-server-env "2.2.0" graphql-extensions "0.3.7" -apollo-cache-control@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.4.0.tgz#fec343e6ec95aa4f1b88e07e62f067bee0c48397" - integrity sha512-WuriaNQIugTE8gYwfBWWCbbQTSKul/cV4JMi5UgqNIUvjHvnKZQLKbt5uYWow6QQNMkLT9hey8QPYkWpogkeSA== +apollo-cache-control@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.5.0.tgz#78cfefec57c5c0a9648137e3250b91172998061e" + integrity sha512-zu26CFj7CboxLB6cckZQEiSUGXIr8MViEGIC5Vesz2yd37sjtevMfRwQhxFuK0HinR0T/WC3dz2k5cj+33vQQQ== dependencies: apollo-server-env "2.2.0" - graphql-extensions "0.4.0" + graphql-extensions "0.5.0" apollo-cache-control@^0.1.0: version "0.1.1" @@ -1046,6 +1062,14 @@ apollo-datasource@0.2.1: apollo-server-caching "0.2.1" apollo-server-env "2.2.0" +apollo-datasource@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.3.0.tgz#88c680edd63a2f7ea05fc25da290a430632d39f4" + integrity sha512-+jWs3ezhx4lcAAPIHtlj0Zoiv2tvwfzn7feHuhxub3xFwkJm39T8hPjb3aMQCsuS7TukBD+F5ndgVob5hL/5Nw== + dependencies: + apollo-server-caching "0.3.0" + apollo-server-env "2.2.0" + apollo-engine-reporting-protobuf@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.1.1.tgz#016d9ee1a73c6c0c666de975d117797fb8b390ea" @@ -1071,16 +1095,17 @@ apollo-engine-reporting@0.1.4: graphql-extensions "0.3.7" lodash "^4.17.10" -apollo-engine-reporting@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.2.0.tgz#e71816b1f46e782f8538c5a118148d4c0e628e25" - integrity sha512-Q6FfVb10v/nrv8FaFsPjIYlWh62jaYav3LuMgM9PsHWGK/zRQFXOEwLxcY2UCvG7O1moxF3XGmfBhMgo54py+Q== +apollo-engine-reporting@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.0.0.tgz#af93b755482ad5a6c52f9f728f3e24e801aa2385" + integrity sha512-9gZSME9ggZwL1nBBvfgSehwc+PtcvZC1/3NYrBOFgidJbrEFita2w5A0jM8Brjo+N2FMKNYWGj8WQ1ywO21JPg== dependencies: apollo-engine-reporting-protobuf "0.2.0" + apollo-graphql "0.1.0" + apollo-server-core "2.4.0" apollo-server-env "2.2.0" async-retry "^1.2.1" - graphql-extensions "0.4.0" - lodash "^4.17.10" + graphql-extensions "0.5.0" apollo-env@0.2.5: version "0.2.5" @@ -1090,6 +1115,21 @@ apollo-env@0.2.5: core-js "^3.0.0-beta.3" node-fetch "^2.2.0" +apollo-env@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.3.2.tgz#7cd9abd7a65cb0e00c4cfc057a999864f6157b55" + integrity sha512-r6nrOw5Pyk6YLNKEtvBiTguJK+oPI1sthKogd7tp6jfkJ+q8SR/9sOoTxyV3vsmR/mMENuBHF89BGLLo9rxDiA== + dependencies: + core-js "3.0.0-beta.3" + node-fetch "^2.2.0" + +apollo-graphql@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.1.0.tgz#e453b133daa8b686644da05ec8e556cf31c57037" + integrity sha512-Mi5GqZJz1A/0i8SEm9EVHWe/LkGbYzV5wzobUY+1Q0SI1NdFtRgqHZUdHU0hz1jDnL+dpRqK1huVmtOO/DGa/A== + dependencies: + lodash.sortby "^4.7.0" + apollo-link-dedup@^1.0.0: version "1.0.11" resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.11.tgz#6f34ea748d2834850329ad03111ef18445232b05" @@ -1127,6 +1167,13 @@ apollo-server-caching@0.2.1: dependencies: lru-cache "^5.0.0" +apollo-server-caching@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.3.0.tgz#96669b5e3bf693e6a54683edfab4b9495deb17d8" + integrity sha512-dHwWUsRZu7I1yUfzTwPJgOigMsftgp8w3X96Zdch1ICWN7cM6aNxks9tTnLd+liUSEzdYLlTmEy5VUturF2IAw== + dependencies: + lru-cache "^5.0.0" + apollo-server-core@2.2.7: version "2.2.7" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.7.tgz#1229f5ed54438bafbf2bb3f1c872d5c551b62833" @@ -1153,28 +1200,28 @@ apollo-server-core@2.2.7: subscriptions-transport-ws "^0.9.11" ws "^6.0.0" -apollo-server-core@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.3.1.tgz#cbdc0020a0dfecf2220cf5062dbb304fdf56edf2" - integrity sha512-8jMWYOQIZi9mDJlHe2rXg8Cp4xKYogeRu23jkcNy+k5UjZL+eO+kHXbNFiTaP4HLYYEpe2XE3asxp6q5YUEQeQ== +apollo-server-core@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.4.0.tgz#928c563f68d9f69a4288e7a4bf14ca79f8599f2b" + integrity sha512-rTFJa12NzTWC9IJrXDr8AZMs1Slbes9YxbyaI+cMC5fs8O9wkCkb34C/1Tp7xKX0fgauXrKZpXv7yPTSm+4YFg== dependencies: - "@apollographql/apollo-tools" "^0.2.6" + "@apollographql/apollo-tools" "^0.3.0" "@apollographql/graphql-playground-html" "^1.6.6" "@types/ws" "^6.0.0" - apollo-cache-control "0.4.0" - apollo-datasource "0.2.1" - apollo-engine-reporting "0.2.0" - apollo-server-caching "0.2.1" + apollo-cache-control "0.5.0" + apollo-datasource "0.3.0" + apollo-engine-reporting "1.0.0" + apollo-server-caching "0.3.0" apollo-server-env "2.2.0" apollo-server-errors "2.2.0" - apollo-server-plugin-base "0.2.1" - apollo-tracing "0.4.0" - graphql-extensions "0.4.1" + apollo-server-plugin-base "0.3.0" + apollo-tracing "0.5.0" + fast-json-stable-stringify "^2.0.0" + graphql-extensions "0.5.0" graphql-subscriptions "^1.0.0" graphql-tag "^2.9.2" graphql-tools "^4.0.0" graphql-upload "^8.0.2" - json-stable-stringify "^1.0.1" lodash "^4.17.10" subscriptions-transport-ws "^0.9.11" ws "^6.0.0" @@ -1201,18 +1248,18 @@ apollo-server-errors@2.2.0: resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== -apollo-server-express@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.3.1.tgz#0598e2fa0a0d9e6eb570c0bb6ce65c31810a9c09" - integrity sha512-J+rObr4GdT/5j6qTByUJoSvZSjTAX/7VqIkr2t+GxwcVUFGet2MdOHuV6rtWKc8CRgvVKfKN6iBrb2EOFcp2LQ== +apollo-server-express@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.4.0.tgz#fe8e748f07f01a837d1449e4c28ab27ae7b7d054" + integrity sha512-uDS7OZJ3EwFr4eZ9k1MiBtUTaqKgCXUUTCknPTdCbTzBel7TjNsa6PNKrSQk+jrLja2H8VwNjbra8uBF5z70Pw== dependencies: "@apollographql/graphql-playground-html" "^1.6.6" "@types/accepts" "^1.3.5" "@types/body-parser" "1.17.0" "@types/cors" "^2.8.4" - "@types/express" "4.16.0" + "@types/express" "4.16.1" accepts "^1.3.5" - apollo-server-core "2.3.1" + apollo-server-core "2.4.0" body-parser "^1.18.3" cors "^2.8.4" graphql-subscriptions "^1.0.0" @@ -1245,10 +1292,10 @@ apollo-server-plugin-base@0.1.7: resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.7.tgz#fb91a0ba8ff505c01287227c874de6f272e5512a" integrity sha512-Bfw++UWh0kzoAHqlsiYa/bxQSftCvwsF4KteFArTOKQjquBn1TTCWb64JTR5itZYuC5GDsoXGFQjQA3wWJyDVw== -apollo-server-plugin-base@0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.2.1.tgz#d08c9576f7f11ab6e212f352d482faaa4059a31e" - integrity sha512-497NIY9VWRYCrMSkgR11IrIUO4Fsy6aGgnpOJoTdLQAnkDD9SJDSRzwKj4gypUoTT2unfKDng4eMxXVZlHvjOw== +apollo-server-plugin-base@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.0.tgz#26c7f9c020b2d444de5bebd2e3c406bebd9c302e" + integrity sha512-SOwp4cpZwyklvP1MkMcY6+12c1hrb5gwC4vK4a23kL5rr9FC0sENcXo3uVVM4XlDGOXIkY+sCM8ngKFuef2flw== apollo-server-testing@~2.2.6: version "2.2.7" @@ -1257,13 +1304,13 @@ apollo-server-testing@~2.2.6: dependencies: apollo-server-core "2.2.7" -apollo-server@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.3.1.tgz#4d2b6bbb48b44d86076680304705b8b7ae952d37" - integrity sha512-+S+/BhLJF9Ms99OK9HpC4P6rcVWTobWWKeLSVdgxqG487i/kwMrCAw/ICrDVJGeOGJRi6PndVu9XdHWHuX1lvQ== +apollo-server@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.4.0.tgz#cfcf0431001451d7cda0d89f5ea8f7116aa1a1f4" + integrity sha512-dEc2lGA1qkvffnArlNXDtJ74+gh4dNKbtTYsnoTveve3ML96DK8G2u5yNqwRqxZHUQmLrx3jiehFaPBqk+Cuhw== dependencies: - apollo-server-core "2.3.1" - apollo-server-express "2.3.1" + apollo-server-core "2.4.0" + apollo-server-express "2.4.0" express "^4.0.0" graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" @@ -1276,13 +1323,13 @@ apollo-tracing@0.3.4: apollo-server-env "2.2.0" graphql-extensions "0.3.7" -apollo-tracing@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.4.0.tgz#4b939063f4292422ac5a3564b76d1d88dec0a916" - integrity sha512-BlM8iQUQva4fm0xD/pLwkcz0degfB9a/aAn4k4cK36eLVD8XUkl7ptEB0c+cwcj7tOYpV1r5QX1XwdayBzlHSg== +apollo-tracing@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.5.0.tgz#6eebaf1e840ece99299103def689d39fe49780a3" + integrity sha512-j0icEhLYf0xS6Q/iCXA2j9KfpYw0a/XvLSUio7fm5yUwtXP2Pp11x5BtK1dI8sLMiaOqUrREz2XjV4PKLzQPuA== dependencies: apollo-server-env "2.2.0" - graphql-extensions "0.4.0" + graphql-extensions "0.5.0" apollo-tracing@^0.1.0: version "0.1.4" @@ -2202,6 +2249,11 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +core-js@3.0.0-beta.3: + version "3.0.0-beta.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.3.tgz#b0f22009972b8c6c04550ebf38513ca4b3cc9559" + integrity sha512-kM/OfrnMThP5PwGAj5HhQLdjUqzjrllqN2EVnk/X9qrLsfYjR2hzZ+E/8CzH0xuosexZtqMTLQrk//BULrBj9w== + core-js@^2.4.0: version "2.6.0" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.0.tgz#1e30793e9ee5782b307e37ffa22da0eacddd84d4" @@ -3405,17 +3457,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== -graphql-config@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-2.2.1.tgz#5fd0ec77ac7428ca5fb2026cf131be10151a0cb2" - integrity sha512-U8+1IAhw9m6WkZRRcyj8ZarK96R6lQBQ0an4lp76Ps9FyhOXENC5YQOxOFGm5CxPrX2rD0g3Je4zG5xdNJjwzQ== - dependencies: - graphql-import "^0.7.1" - graphql-request "^1.5.0" - js-yaml "^3.10.0" - lodash "^4.17.4" - minimatch "^3.0.4" - 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" @@ -3438,19 +3479,12 @@ graphql-extensions@0.3.7: dependencies: "@apollographql/apollo-tools" "^0.2.6" -graphql-extensions@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.4.0.tgz#5857c7b7b9f20dbccbfd88730fffa5963b3c61ee" - integrity sha512-8TUgIIUVpXWOcqq9RdmTSHUrhc3a/s+saKv9cCl8TYWHK9vyJIdea7ZaSKHGDthZNcsN+C3LulZYRL3Ah8ukoA== +graphql-extensions@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.0.tgz#117b9872e5cafbebef5254ad795b41fa97037c14" + integrity sha512-2i0rpe4/D8jZj6XmxXGLFDAsGLhkFrSdpS5WfvTAzoXOc52hUAxNdsbgRQGeKMFhmanqA6FDXxO/s+BtPHChVA== dependencies: - "@apollographql/apollo-tools" "^0.2.6" - -graphql-extensions@0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.4.1.tgz#92c49a8409ffbfb24559d7661ab60cc90d6086e4" - integrity sha512-Xei4rBxbsTHU6dYiq9y1xxbpRMU3+Os7yD3vXV5W4HbTaxRMizDmu6LAvV4oBEi0ttwICHARQjYTjDTDhHnxrQ== - dependencies: - "@apollographql/apollo-tools" "^0.2.6" + "@apollographql/apollo-tools" "^0.3.0" graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: version "0.0.10" @@ -3460,7 +3494,7 @@ graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: core-js "^2.5.3" source-map-support "^0.5.1" -graphql-import@^0.7.0, graphql-import@^0.7.1: +graphql-import@^0.7.0: version "0.7.1" resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.7.1.tgz#4add8d91a5f752d764b0a4a7a461fcd93136f223" integrity sha512-YpwpaPjRUVlw2SN3OPljpWbVRWAhMAyfSba5U47qGMOSsPLi2gYeJtngGpymjm9nk57RFWEpjqwh4+dpYuFAPw== @@ -3473,10 +3507,10 @@ graphql-iso-date@~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@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-3.0.1.tgz#8e1f1b2b9738002c1132372cb51d9cceb1b962ec" - integrity sha512-mKXoFYBozbFfAwUPqADO/xpL/DcLKE8fGc0qHTL1ssA6+6Ynt609m4V36/c4FAxcnJsgsV1p22aBbiraXg+ddA== +graphql-middleware@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-3.0.2.tgz#c8cdb67615eec02aec237b455e679f5fc973ddc4" + integrity sha512-sRqu1sF+77z42z1OVM1QDHKQWnWY5K3nAgqWiZwx3U4tqNZprrDuXxSChPMliV343IrVkpYdejUYq9w24Ot3FA== dependencies: graphql-tools "^4.0.4" @@ -3487,28 +3521,26 @@ graphql-middleware@~1.7.8: dependencies: graphql-tools "^4.0.2" -graphql-playground-html@1.6.4: - version "1.6.4" - resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.4.tgz#be7c5a6213d67aeedf03d90b7e7d55fec4d42212" - integrity sha512-mnpAVYSR3TesYsJ5OLJVJMA0muTCw4npsCI1cKMtW35lbA6KljZkLkz3ZWXhEIYPnHKIeUHEtbn1ZGkEXtAxLg== - dependencies: - graphql-config "2.2.1" +graphql-playground-html@1.6.12: + version "1.6.12" + resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.12.tgz#8b3b34ab6013e2c877f0ceaae478fafc8ca91b85" + integrity sha512-yOYFwwSMBL0MwufeL8bkrNDgRE7eF/kTHiwrqn9FiR9KLcNIl1xw9l9a+6yIRZM56JReQOHpbQFXTZn1IuSKRg== -graphql-playground-middleware-express@1.7.6: - version "1.7.6" - resolved "https://registry.yarnpkg.com/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.6.tgz#aca38d2b8e5147914fc8fa613d151edd4ed0bc44" - integrity sha512-fICPxYGIdhCxtFlwCnP3uZ2uRWeQ9wj7OkcWUiHNwaFma2TbRD5nNKaPA2u21YWha9xv26qIDxxcdW27F/lcbQ== +graphql-playground-middleware-express@1.7.11: + version "1.7.11" + resolved "https://registry.yarnpkg.com/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.11.tgz#bbffd784a37133bfa7165bdd8f429081dbf4bcf6" + integrity sha512-sKItB4s3FxqlwCgXdMfwRAfssSoo31bcFsGAAg/HzaZLicY6CDlofKXP8G5iPDerB6NaoAcAaBLutLzl9sd4fQ== dependencies: - graphql-playground-html "1.6.4" + graphql-playground-html "1.6.12" -graphql-playground-middleware-lambda@1.7.6: - version "1.7.6" - resolved "https://registry.yarnpkg.com/graphql-playground-middleware-lambda/-/graphql-playground-middleware-lambda-1.7.6.tgz#03aa4e3592144f4eb390a216f09b39f6b29f12d2" - integrity sha512-C4XYi32UTwP4YpHBgK9hiuxGBULiNFTu7qeFjHGWoXQIg/lioydyKnd3hVWB06QRUoHWLQj/pAI9ay3bdzCx3w== +graphql-playground-middleware-lambda@1.7.12: + version "1.7.12" + resolved "https://registry.yarnpkg.com/graphql-playground-middleware-lambda/-/graphql-playground-middleware-lambda-1.7.12.tgz#1b06440a288dbcd53f935b43e5b9ca2738a06305" + integrity sha512-fJ1Y0Ck5ctmfaQFoWv7vNnVP7We19P3miVmOT85YPrjpzbMYv0wPfxm4Zjt8nnqXr0KU9nGW53tz3K7/Lvzxtw== dependencies: - graphql-playground-html "1.6.4" + graphql-playground-html "1.6.12" -graphql-request@^1.5.0, graphql-request@^1.8.2: +graphql-request@^1.8.2: version "1.8.2" resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" integrity sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg== @@ -3563,10 +3595,10 @@ graphql-upload@^8.0.2: http-errors "^1.7.1" object-path "^0.11.4" -graphql-yoga@~1.17.1: - version "1.17.1" - resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.17.1.tgz#13bace9f063e4c57ab7da40c60b9aea4135b89a4" - integrity sha512-8j2omHHMsSFFn4XFb4hXiMIhBAdqra/Ok5lJxBihMlC2ocNU16aa8sMXjAcwwpgcAV0dpDOU5fL3X1DS0pmTQA== +graphql-yoga@~1.17.4: + version "1.17.4" + resolved "https://registry.yarnpkg.com/graphql-yoga/-/graphql-yoga-1.17.4.tgz#6d325a6270399edf0776fb5f60a2e9e19512e63c" + integrity sha512-zOXFtmS43xDLoECKiuA3xVWH/wLDvLH1D/5fBKcaMFdF43ifDfnA9N6dlGggqAoOhqBnrqHwDpoKlJ6sI1LuxA== dependencies: "@types/cors" "^2.8.4" "@types/express" "^4.11.1" @@ -3583,9 +3615,9 @@ graphql-yoga@~1.17.1: graphql "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0" graphql-deduplicator "^2.0.1" graphql-import "^0.7.0" - graphql-middleware "3.0.1" - graphql-playground-middleware-express "1.7.6" - graphql-playground-middleware-lambda "1.7.6" + graphql-middleware "3.0.2" + graphql-playground-middleware-express "1.7.11" + graphql-playground-middleware-lambda "1.7.12" graphql-subscriptions "^0.5.8" graphql-tools "^4.0.0" subscriptions-transport-ws "^0.9.8" @@ -4743,7 +4775,7 @@ js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-yaml@^3.10.0, js-yaml@^3.12.0, js-yaml@^3.7.0: +js-yaml@^3.12.0, js-yaml@^3.7.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== From 9dba9b5cf4de244f8cf06e26a44fce28bc7b6bc0 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 7 Feb 2019 15:54:07 +0100 Subject: [PATCH 327/554] Upgraded graphql-shield and graphql-middleware --- package.json | 4 ++-- yarn.lock | 23 ++++++++--------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 9a12ad317..bef0f3480 100644 --- a/package.json +++ b/package.json @@ -47,8 +47,8 @@ "graphql": "~14.1.1", "graphql-custom-directives": "~0.2.14", "graphql-iso-date": "~3.6.1", - "graphql-middleware": "~1.7.8", - "graphql-shield": "~4.1.2", + "graphql-middleware": "~3.0.2", + "graphql-shield": "~5.1.2", "graphql-tag": "~2.10.1", "graphql-yoga": "~1.17.4", "jsonwebtoken": "~8.4.0", diff --git a/yarn.lock b/yarn.lock index da824f1dc..083f5c5b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3507,20 +3507,13 @@ graphql-iso-date@~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@3.0.2: +graphql-middleware@3.0.2, graphql-middleware@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-3.0.2.tgz#c8cdb67615eec02aec237b455e679f5fc973ddc4" integrity sha512-sRqu1sF+77z42z1OVM1QDHKQWnWY5K3nAgqWiZwx3U4tqNZprrDuXxSChPMliV343IrVkpYdejUYq9w24Ot3FA== dependencies: graphql-tools "^4.0.4" -graphql-middleware@~1.7.8: - version "1.7.8" - resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-1.7.8.tgz#617940d3cd462e9553e582d2b6ce86cb0e95a3dd" - integrity sha512-FNl427I9fCZ9ZwuywPHPbpVJCgDiMS+7dbtaEZu7zJiMP8il2+2T0KRKCiXkfLDKefiGkZnl4qVIFbncCDaduA== - dependencies: - graphql-tools "^4.0.2" - graphql-playground-html@1.6.12: version "1.6.12" resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.12.tgz#8b3b34ab6013e2c877f0ceaae478fafc8ca91b85" @@ -3547,12 +3540,12 @@ graphql-request@^1.8.2: dependencies: cross-fetch "2.2.2" -graphql-shield@~4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-4.1.2.tgz#dee5f9118c160cae1b793c443e3550ad7e81e1cb" - integrity sha512-hVzAMtb2dWeCv72A5DypAVHaFVXmA2NNH97wTNXtex4zFIhxWXauOF8WuoAXhWdlzxKF/s5NLthvl31AUxsRyQ== +graphql-shield@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-5.1.2.tgz#fd8b9cb263a06caae8f4d026cc8c6d07a155832a" + integrity sha512-imBBsi2HlbRN+K8ZAp1OCrlp7uosPvpmO0Hp2Qef5sPEdZ6w24goctLIE90Jv76cCDtaYTMVIYBtTHeuL+2gJg== dependencies: - object-hash "^1.3.0" + object-hash "^1.3.1" opencollective "1.0.3" graphql-subscriptions@^0.5.8: @@ -3574,7 +3567,7 @@ graphql-tag@^2.9.2, graphql-tag@~2.10.1: resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02" integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg== -graphql-tools@^4.0.0, graphql-tools@^4.0.2, graphql-tools@^4.0.4: +graphql-tools@^4.0.0, graphql-tools@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.4.tgz#ca08a63454221fdde825fe45fbd315eb2a6d566b" integrity sha512-chF12etTIGVVGy3fCTJ1ivJX2KB7OSG4c6UOJQuqOHCmBQwTyNgCDuejZKvpYxNZiEx7bwIjrodDgDe9RIkjlw== @@ -5670,7 +5663,7 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-hash@^1.3.0: +object-hash@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== From 788566a7e4b8e39cb74f95df0a9373bf67403922 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 7 Feb 2019 15:56:15 +0100 Subject: [PATCH 328/554] Upgraded remaining dependencies --- package.json | 24 +- yarn.lock | 1907 +++++++++++++++++++------------------------------- 2 files changed, 734 insertions(+), 1197 deletions(-) diff --git a/package.json b/package.json index bef0f3480..5768328c9 100644 --- a/package.json +++ b/package.json @@ -34,9 +34,9 @@ ] }, "dependencies": { - "apollo-cache-inmemory": "~1.4.0", - "apollo-client": "~2.4.9", - "apollo-link-http": "~1.5.9", + "apollo-cache-inmemory": "~1.4.2", + "apollo-client": "~2.4.12", + "apollo-link-http": "~1.5.11", "apollo-server": "~2.4.0", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", @@ -52,7 +52,7 @@ "graphql-tag": "~2.10.1", "graphql-yoga": "~1.17.4", "jsonwebtoken": "~8.4.0", - "linkifyjs": "~2.1.7", + "linkifyjs": "~2.1.8", "lodash": "~4.17.11", "ms": "~2.1.1", "neo4j-driver": "~1.7.2", @@ -70,24 +70,24 @@ "@babel/cli": "~7.2.3", "@babel/core": "^7.2.2", "@babel/node": "~7.2.2", - "@babel/preset-env": "~7.2.3", + "@babel/preset-env": "~7.3.1", "@babel/register": "~7.0.0", - "apollo-server-testing": "~2.2.6", + "apollo-server-testing": "~2.4.0", "babel-core": "^7.0.0-0", "babel-eslint": "~10.0.1", - "babel-jest": "^23.6.0", + "babel-jest": "^24.1.0", "chai": "~4.2.0", - "eslint": "~5.12.1", + "eslint": "~5.13.0", "eslint-config-standard": "~12.0.0", - "eslint-plugin-import": "~2.15.0", - "eslint-plugin-jest": "^22.1.3", + "eslint-plugin-import": "~2.16.0", + "eslint-plugin-jest": "^22.2.2", "eslint-plugin-node": "~8.0.1", "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", "graphql-request": "^1.8.2", - "jest": "^23.6.0", + "jest": "^24.1.0", "nodemon": "~1.18.9", - "nyc": "^13.1.0", + "nyc": "^13.2.0", "supertest": "^3.4.2" } } diff --git a/yarn.lock b/yarn.lock index 083f5c5b5..7b7041e87 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,13 +2,6 @@ # yarn lockfile v1 -"@apollographql/apollo-tools@^0.2.6": - version "0.2.9" - resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.2.9.tgz#1e20999d11728ef47f8f812f2be0426b5dde1a51" - integrity sha512-AEIQwPkS0QLbkpb6WyRhV4aOMxuErasp47ABv5niDKOasQH8mrD8JSGKJAHuQxVe4kB8DE9sLRoc5qeQ0KFCHA== - dependencies: - apollo-env "0.2.5" - "@apollographql/apollo-tools@^0.3.0": version "0.3.2" resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.3.2.tgz#415c984955c4ae249550def698cbffab8d27bda4" @@ -16,15 +9,6 @@ dependencies: apollo-env "0.3.2" -"@apollographql/apollo-upload-server@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" - integrity sha512-tGAp3ULNyoA8b5o9LsU2Lq6SwgVPUOKAqKywu2liEtTvrFSGPrObwanhYwArq3GPeOqp2bi+JknSJCIU3oQN1Q== - dependencies: - "@babel/runtime-corejs2" "^7.0.0-rc.1" - busboy "^0.2.14" - object-path "^0.11.4" - "@apollographql/graphql-playground-html@^1.6.6": version "1.6.6" resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz#022209e28a2b547dcde15b219f0c50f47aa5beb3" @@ -47,14 +31,14 @@ optionalDependencies: chokidar "^2.0.3" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35": +"@babel/code-frame@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.2.2": +"@babel/core@^7.1.0", "@babel/core@^7.2.2": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687" integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw== @@ -307,10 +291,10 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-json-strings" "^7.2.0" -"@babel/plugin-proposal-object-rest-spread@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.2.0.tgz#88f5fec3e7ad019014c97f7ee3c992f0adbf7fb8" - integrity sha512-1L5mWLSvR76XYUQJXkd/EEQgjq8HHRP6lQuZTTg0VA4tTGPpGemmCdAfQIz1rzEuWAm+ecP8PyyEm30jC1eQCg== +"@babel/plugin-proposal-object-rest-spread@^7.3.1": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.2.tgz#6d1859882d4d778578e41f82cc5d7bf3d5daf6c1" + integrity sha512-DjeMS+J2+lpANkYLLO+m6GjoTMygYglKmRe6cDTbFv3L9i6mmiE8fe6B8MtCSLZpVXscD5kn7s6SgtHrDoBWoA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -346,7 +330,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-object-rest-spread@^7.2.0": +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== @@ -498,6 +482,13 @@ "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-named-capturing-groups-regex@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.3.0.tgz#140b52985b2d6ef0cb092ef3b29502b990f9cd50" + integrity sha512-NxIoNVhk9ZxS+9lSoAQ/LM0V2UEvARLttEHUrRDGKFaAxOYQcrkN/nLRE+BbbicCAvZPl7wMP0X60HsHE5DtQw== + dependencies: + regexp-tree "^0.1.0" + "@babel/plugin-transform-new-target@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz#ae8fbd89517fa7892d20e6564e641e8770c3aa4a" @@ -583,19 +574,20 @@ core-js "^2.5.7" regenerator-runtime "^0.11.1" -"@babel/preset-env@~7.2.3": - version "7.2.3" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.2.3.tgz#948c8df4d4609c99c7e0130169f052ea6a7a8933" - integrity sha512-AuHzW7a9rbv5WXmvGaPX7wADxFkZIqKlbBh1dmZUQp4iwiPpkE/Qnrji6SC4UQCQzvWY/cpHET29eUhXS9cLPw== +"@babel/preset-env@~7.3.1": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.1.tgz#389e8ca6b17ae67aaf9a2111665030be923515db" + integrity sha512-FHKrD6Dxf30e8xgHQO0zJZpUPfVZg+Xwgz5/RdSWCbza9QLNk4Qbp40ctRoqDxml3O8RMzB1DU55SXeDG6PqHQ== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-async-generator-functions" "^7.2.0" "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.2.0" + "@babel/plugin-proposal-object-rest-spread" "^7.3.1" "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" "@babel/plugin-proposal-unicode-property-regex" "^7.2.0" "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" "@babel/plugin-transform-arrow-functions" "^7.2.0" @@ -615,6 +607,7 @@ "@babel/plugin-transform-modules-commonjs" "^7.2.0" "@babel/plugin-transform-modules-systemjs" "^7.2.0" "@babel/plugin-transform-modules-umd" "^7.2.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.3.0" "@babel/plugin-transform-new-target" "^7.0.0" "@babel/plugin-transform-object-super" "^7.2.0" "@babel/plugin-transform-parameters" "^7.2.0" @@ -643,14 +636,6 @@ pirates "^4.0.0" source-map-support "^0.5.9" -"@babel/runtime-corejs2@^7.0.0-rc.1": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.2.0.tgz#5ccd722b72d2c18c6a7224b5751f4b9816b60ada" - integrity sha512-kPfmKoRI8Hpo5ZJGACWyrc9Eq1j3ZIUpUAQT2yH045OuYpccFJ9kYA/eErwzOM2jeBG1sC8XX1nl1EArtuM8tg== - dependencies: - core-js "^2.5.7" - regenerator-runtime "^0.12.0" - "@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2": version "7.1.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" @@ -777,11 +762,6 @@ dependencies: "@types/node" "*" -"@types/async@2.0.50": - version "2.0.50" - resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.50.tgz#117540e026d64e1846093abbd5adc7e27fda7bcb" - integrity sha512-VMhZMMQgV1zsR+lX/0IBfAk+8Eb7dPVMWiQGFAt3qjo5x7Ml6b77jUo0e1C3ToD+XRDXqtrfw+6AB0uUsPEr3Q== - "@types/body-parser@*", "@types/body-parser@1.17.0": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" @@ -1000,14 +980,6 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -apollo-cache-control@0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.4.tgz#286344a417f5489ab034f9fb22ba106ebafbd666" - integrity sha512-9Z9cAfsTQELGvn0CZ4lEg/Kk5WnjRafU58Q9lMi+XOqSrYyX+MRe5pX4dI6jMVMTWfD0D7lyJZxAzoNrF/yZHA== - dependencies: - apollo-server-env "2.2.0" - graphql-extensions "0.3.7" - apollo-cache-control@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.5.0.tgz#78cfefec57c5c0a9648137e3250b91172998061e" @@ -1023,44 +995,37 @@ apollo-cache-control@^0.1.0: dependencies: graphql-extensions "^0.0.x" -apollo-cache-inmemory@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.4.0.tgz#8bcb1de8d1950dcdbd42f9af6d16fccca8e9e9ca" - integrity sha512-gqwiZCApG+hRXEbtDrNIUtNcKKeO3RTih4mydJZRJpFp+PgBf8AZ2z4/uTJFFijmR9krmUWdCRfW1Aesb5+Ktg== +apollo-cache-inmemory@~1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.4.2.tgz#c91aeb4adff45cdc7872d603cbff055fa9cd5021" + integrity sha512-fDVmj5j1e3W+inyuSwjIcMgbQ4edcFgmiKTBMFAEKAq0jg33X7FrbDX8JT2t5Vuf75Mva50JDlt5wXdu7C6WuA== dependencies: - apollo-cache "^1.1.23" - apollo-utilities "^1.1.0" - optimism "^0.6.8" + apollo-cache "^1.1.25" + apollo-utilities "^1.1.2" + optimism "^0.6.9" + tslib "^1.9.3" -apollo-cache@1.1.23, apollo-cache@^1.1.23: - version "1.1.23" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.23.tgz#4765571223cae756ab7faf29792f1ab9a8450a91" - integrity sha512-9FcavymJQdjaYX6of1xgjFmWp8UUCtlW/S9k5bfMMnMNAAQMDnuOFVEklawdSbyAhM4hh1kSymyt/r23K1tVSA== +apollo-cache@1.1.25, apollo-cache@^1.1.25: + version "1.1.25" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.25.tgz#87a15a2a19993bb07234ccee6839b59d6fb49ac5" + integrity sha512-9HhI/tVEHAeGaJJvi1Vpf6PzXUCA0PqNbigi2G3uOc180JjxbcaBvEbKXMEDb/UyTXkFWzI4PiPDuDQFqmIMSA== dependencies: - apollo-utilities "^1.1.0" + apollo-utilities "^1.1.2" + tslib "^1.9.3" -apollo-client@~2.4.9: - version "2.4.9" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.9.tgz#c5fbd4d04645e228dd6a49f5b03b41cb1c2e5ae7" - integrity sha512-7IoIz+3hAk3166663ioyrsPdlTSAQa24HsJPVWw2QM/UE1wZTommu+uhwj9KugL6vpE/wyhyYgEs/9R7PlCsQA== +apollo-client@~2.4.12: + version "2.4.12" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.12.tgz#9fa15f502d04f8cc788a9fbb825163b437681504" + integrity sha512-E5ClFSB9btJLYibLKwLDSCg+w9tI+25eZgXOM+DClawu7of4d/xhuV/xvpuZpsMP3qwrp0QPacBnfG4tUJs3/w== dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.23" + apollo-cache "1.1.25" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "1.1.0" + apollo-utilities "1.1.2" symbol-observable "^1.0.2" + tslib "^1.9.3" zen-observable "^0.8.0" - optionalDependencies: - "@types/async" "2.0.50" - -apollo-datasource@0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.2.1.tgz#3ecef4efe64f7a04a43862f32027d38ac09e142c" - integrity sha512-r185+JTa5KuF1INeTAk7AEP76zwMN6c8Ph1lmpzJMNwBUEzTGnLClrccCskCBx4SxfnkdKbuQdwn9JwCJUWrdg== - dependencies: - apollo-server-caching "0.2.1" - apollo-server-env "2.2.0" apollo-datasource@0.3.0: version "0.3.0" @@ -1070,13 +1035,6 @@ apollo-datasource@0.3.0: apollo-server-caching "0.3.0" apollo-server-env "2.2.0" -apollo-engine-reporting-protobuf@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.1.1.tgz#016d9ee1a73c6c0c666de975d117797fb8b390ea" - integrity sha512-HoXf7mcz0ZqTiubXLnymPK50iZOyw4h/HlzVETxCwE+PHNBcVBAA+fWram/oW1cqK2JPTQOYWszxHxPwcus+eQ== - dependencies: - protobufjs "^6.8.6" - apollo-engine-reporting-protobuf@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.2.0.tgz#2aaf4d2eddefe7924d469cf1135267bc0deadf73" @@ -1084,17 +1042,6 @@ apollo-engine-reporting-protobuf@0.2.0: dependencies: protobufjs "^6.8.6" -apollo-engine-reporting@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.4.tgz#2fb52f2cf8880f758a4d790a11bb246e7c934492" - integrity sha512-484nvAuwpmm3WHgIFs7FQ1dhHmRClTHqMT0sLsxJBgpd/MwTWBAw8lDxRa+FrJrqegeWc30K8tCa24hZ3+Ifrw== - dependencies: - apollo-engine-reporting-protobuf "0.1.1" - apollo-server-env "2.2.0" - async-retry "^1.2.1" - graphql-extensions "0.3.7" - lodash "^4.17.10" - apollo-engine-reporting@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.0.0.tgz#af93b755482ad5a6c52f9f728f3e24e801aa2385" @@ -1107,14 +1054,6 @@ apollo-engine-reporting@1.0.0: async-retry "^1.2.1" graphql-extensions "0.5.0" -apollo-env@0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.2.5.tgz#162c785bccd2aea69350a7600fab4b7147fc9da5" - integrity sha512-Gc7TEbwCl7jJVutnn8TWfzNSkrrqyoo0DP92BQJFU9pZbJhpidoXf2Sw1YwOJl82rRKH3ujM3C8vdZLOgpFcFA== - dependencies: - core-js "^3.0.0-beta.3" - node-fetch "^2.2.0" - apollo-env@0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.3.2.tgz#7cd9abd7a65cb0e00c4cfc057a999864f6157b55" @@ -1137,22 +1076,22 @@ apollo-link-dedup@^1.0.0: dependencies: apollo-link "^1.2.4" -apollo-link-http-common@^0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.8.tgz#c6deedfc2739db8b11013c3c2d2ccd657152941f" - integrity sha512-gGmXZN8mr7e9zjopzKQfZ7IKnh8H12NxBDzvp9nXI3U82aCVb72p+plgoYLcpMY8w6krvoYjgicFmf8LO20TCQ== +apollo-link-http-common@^0.2.10: + version "0.2.10" + resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.10.tgz#b5bbf502ff40a81cc00281ba3b8543b7ad866dfe" + integrity sha512-KY9nhpAurw3z48OIYV0sCZFXrzWp/wjECsveK+Q9GUhhSe1kEbbUjFfmi+qigg+iELgdp5V8ioRJhinl1vPojw== dependencies: - apollo-link "^1.2.6" + apollo-link "^1.2.8" -apollo-link-http@~1.5.9: - version "1.5.9" - resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.9.tgz#9046f5640a94c8a8b508a39e0f2c628b781baecc" - integrity sha512-9tJy2zGm4Cm/1ycScDNZJe51dgnTSfKx7pKIgPZmcxkdDpgUY2DZitDH6ZBv4yp9z8MC9Xr9wgwc29s6hcadUQ== +apollo-link-http@~1.5.11: + version "1.5.11" + resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.11.tgz#1f72a377d03e874a08bc9eadb1ce7ecb166f1e56" + integrity sha512-wDG+I9UmpfaZRPIvTYBgkvqiCgmz6yWgvuzW/S24Q4r4Xrfe6sLpg2FmarhtdP+hdN+IXTLbFNCZ+Trgfpifow== dependencies: - apollo-link "^1.2.6" - apollo-link-http-common "^0.2.8" + apollo-link "^1.2.8" + apollo-link-http-common "^0.2.10" -apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.6: +apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4: version "1.2.6" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.6.tgz#d9b5676d79c01eb4e424b95c7171697f6ad2b8da" integrity sha512-sUNlA20nqIF3gG3F8eyMD+mO80fmf3dPZX+GUOs3MI9oZR8ug09H3F0UsWJMcpEg6h55Yy5wZ+BMmAjrbenF/Q== @@ -1160,12 +1099,12 @@ apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.6: apollo-utilities "^1.0.0" zen-observable-ts "^0.8.13" -apollo-server-caching@0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.2.1.tgz#7e67f8c8cac829e622b394f0fb82579cabbeadfd" - integrity sha512-+U9F3X297LL8Gqy6ypfDNEv/DfV/tDht9Dr2z3AMaEkNW1bwO6rmdDL01zYxDuVDVq6Z3qSiNCSO2pXE2F0zmA== +apollo-link@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.8.tgz#0f252adefd5047ac1a9f35ba9439d216587dcd84" + integrity sha512-lfzGRxhK9RmiH3HPFi7TIEBhhDY9M5a2ZDnllcfy5QDk7cCQHQ1WQArcw1FK0g1B+mV4Kl72DSrlvZHZJEolrA== dependencies: - lru-cache "^5.0.0" + zen-observable-ts "^0.8.15" apollo-server-caching@0.3.0: version "0.3.0" @@ -1174,32 +1113,6 @@ apollo-server-caching@0.3.0: dependencies: lru-cache "^5.0.0" -apollo-server-core@2.2.7: - version "2.2.7" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.7.tgz#1229f5ed54438bafbf2bb3f1c872d5c551b62833" - integrity sha512-fIdoZGoBtYW9U5NWlCdKNb17TOmrdrYIN/f12ILcysoBxTyAsBImZMLOLvyTV0sUSgx7Q9dV7ddiMufXGdAy5Q== - dependencies: - "@apollographql/apollo-tools" "^0.2.6" - "@apollographql/apollo-upload-server" "^5.0.3" - "@apollographql/graphql-playground-html" "^1.6.6" - "@types/ws" "^6.0.0" - apollo-cache-control "0.3.4" - apollo-datasource "0.2.1" - apollo-engine-reporting "0.1.4" - apollo-server-caching "0.2.1" - apollo-server-env "2.2.0" - apollo-server-errors "2.2.0" - apollo-server-plugin-base "0.1.7" - apollo-tracing "0.3.4" - graphql-extensions "0.3.7" - graphql-subscriptions "^1.0.0" - graphql-tag "^2.9.2" - graphql-tools "^4.0.0" - json-stable-stringify "^1.0.1" - lodash "^4.17.10" - subscriptions-transport-ws "^0.9.11" - ws "^6.0.0" - apollo-server-core@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.4.0.tgz#928c563f68d9f69a4288e7a4bf14ca79f8599f2b" @@ -1287,22 +1200,17 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== -apollo-server-plugin-base@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.7.tgz#fb91a0ba8ff505c01287227c874de6f272e5512a" - integrity sha512-Bfw++UWh0kzoAHqlsiYa/bxQSftCvwsF4KteFArTOKQjquBn1TTCWb64JTR5itZYuC5GDsoXGFQjQA3wWJyDVw== - apollo-server-plugin-base@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.0.tgz#26c7f9c020b2d444de5bebd2e3c406bebd9c302e" integrity sha512-SOwp4cpZwyklvP1MkMcY6+12c1hrb5gwC4vK4a23kL5rr9FC0sENcXo3uVVM4XlDGOXIkY+sCM8ngKFuef2flw== -apollo-server-testing@~2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.2.7.tgz#8210e15ac2d53f174e15f4856a7b47d3a00d8c53" - integrity sha512-S+5yLcbwKe1sJ/mG8tPKSrc9mOCqGq07nCqbzaTwiorkJiKxoChMugHT30CGuNGoa0B7Vfdg2wOq3/zsO1i67w== +apollo-server-testing@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.4.0.tgz#db2c5ee2eddf9031a907a425587303df5e1677df" + integrity sha512-1Dxe19+KP9dulACPN0jLMRVAgHNgD3rey4tljUqtofoxsvchXIG6MARVOHz6VDMNk58jWXr81jMtEBS/x/+XFA== dependencies: - apollo-server-core "2.2.7" + apollo-server-core "2.4.0" apollo-server@~2.4.0: version "2.4.0" @@ -1315,14 +1223,6 @@ apollo-server@~2.4.0: graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" -apollo-tracing@0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.4.tgz#32f1c3dad6a0a5aa1fb442f006bf2ef248a125ae" - integrity sha512-U10mTuCic6Xi7Xez7SZic+nNuwFmZ4OlQnR835qGIkE8tq2GtXfFNcofO8kEDnGAnJasoUng8KIrZkSlUJdUSg== - dependencies: - apollo-server-env "2.2.0" - graphql-extensions "0.3.7" - apollo-tracing@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.5.0.tgz#6eebaf1e840ece99299103def689d39fe49780a3" @@ -1348,20 +1248,21 @@ apollo-upload-server@^7.0.0: http-errors "^1.7.0" object-path "^0.11.4" -apollo-utilities@1.1.0, apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.1.0: +apollo-utilities@1.1.2, apollo-utilities@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.2.tgz#aa5eca9d1f1eb721c381a22e0dde03559d856db3" + integrity sha512-EjDx8vToK+zkWIxc76ZQY/irRX52puNg04xf/w8R0kVTDAgHuVfnFVC01O5vE25kFnIaa5em0pFI0p9b6YMkhQ== + dependencies: + fast-json-stable-stringify "^2.0.0" + tslib "^1.9.3" + +apollo-utilities@^1.0.0, apollo-utilities@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.0.tgz#e7603f834b57e4e109be6b450dc1cc1037aac94c" integrity sha512-D3scmF6vJkCBECMasMEc0J9dNNHVULl6h2d7/oGJxWid1fgcAPHZJN5XLCZisuOfn0Dvvu3Unf/zK00Z3e49Qg== dependencies: fast-json-stable-stringify "^2.0.0" -append-transform@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" - integrity sha1-126/jKlNJ24keja61EpLdKthGZE= - dependencies: - default-require-extensions "^1.0.0" - append-transform@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" @@ -1394,19 +1295,12 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= - dependencies: - arr-flatten "^1.0.1" - arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= -arr-flatten@^1.0.1, arr-flatten@^1.1.0: +arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== @@ -1446,11 +1340,6 @@ array-uniq@^1.0.2: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= - array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" @@ -1515,7 +1404,7 @@ async-retry@^1.2.1: dependencies: retry "0.12.0" -async@^2.1.4, async@^2.5.0: +async@^2.5.0, async@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== @@ -1566,40 +1455,6 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== -babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.0.0, babel-core@^6.26.0: - version "6.26.3" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" - integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.1" - debug "^2.6.9" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.8" - slash "^1.0.0" - source-map "^0.5.7" - babel-core@^7.0.0-0: version "7.0.0-bridge.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" @@ -1617,62 +1472,29 @@ babel-eslint@~10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-generator@^6.18.0, babel-generator@^6.26.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== +babel-jest@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.1.0.tgz#441e23ef75ded3bd547e300ac3194cef87b55190" + integrity sha512-MLcagnVrO9ybQGLEfZUqnOzv36iQzU7Bj4elm39vCukumLVSfoX+tRy3/jW7lUKc7XdpRmB/jech6L/UCsSZjw== dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" + babel-plugin-istanbul "^5.1.0" + babel-preset-jest "^24.1.0" + chalk "^2.4.2" + slash "^2.0.0" -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= +babel-plugin-istanbul@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.0.tgz#6892f529eff65a3e2d33d87dc5888ffa2ecd4a30" + integrity sha512-CLoXPRSUWiR8yao8bShqZUIC6qLfZVVY3X1wj+QPNXu0wfmrRRfarh1LYy+dYMVI+bDj0ghy3tuqFFRFZmL1Nw== dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" + find-up "^3.0.0" + istanbul-lib-instrument "^3.0.0" + test-exclude "^5.0.0" -babel-jest@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.6.0.tgz#a644232366557a2240a0c083da6b25786185a2f1" - integrity sha512-lqKGG6LYXYu+DQh/slrQ8nxXQkEkhugdXsU6St7GmhVS7Ilc/22ArwqXNJrf0QaOBjZB0360qZMwXqDYQHXaew== - dependencies: - babel-plugin-istanbul "^4.1.6" - babel-preset-jest "^23.2.0" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-istanbul@^4.1.6: - version "4.1.6" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" - integrity sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ== - dependencies: - babel-plugin-syntax-object-rest-spread "^6.13.0" - find-up "^2.1.0" - istanbul-lib-instrument "^1.10.1" - test-exclude "^4.2.1" - -babel-plugin-jest-hoist@^23.2.0: - version "23.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167" - integrity sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc= - -babel-plugin-syntax-object-rest-spread@^6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" - integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= +babel-plugin-jest-hoist@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.1.0.tgz#dfecc491fb15e2668abbd690a697a8fd1411a7f8" + integrity sha512-gljYrZz8w1b6fJzKcsfKsipSru2DU2DmQ39aB6nV3xQ0DDv3zpIzKGortA5gknrhNnPN8DweaEgrnZdmbGmhnw== babel-polyfill@6.23.0: version "6.23.0" @@ -1683,26 +1505,13 @@ babel-polyfill@6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-preset-jest@^23.2.0: - version "23.2.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46" - integrity sha1-jsegOhOPABoaj7HoETZSvxpV2kY= +babel-preset-jest@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.1.0.tgz#83bc564fdcd4903641af65ec63f2f5de6b04132e" + integrity sha512-FfNLDxFWsNX9lUmtwY7NheGlANnagvxq8LZdl5PKnVG3umP+S/g0XbVBfwtA4Ai3Ri/IMkWabBz3Tyk9wdspcw== dependencies: - babel-plugin-jest-hoist "^23.2.0" - babel-plugin-syntax-object-rest-spread "^6.13.0" - -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + babel-plugin-jest-hoist "^24.1.0" babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" @@ -1712,47 +1521,6 @@ babel-runtime@^6.22.0, babel-runtime@^6.26.0: core-js "^2.4.0" regenerator-runtime "^0.11.0" -babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.0.0, babel-traverse@^6.18.0, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== - backo2@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" @@ -1847,15 +1615,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - braces@^2.3.0, braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -1952,31 +1711,31 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -caching-transform@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-2.0.0.tgz#e1292bd92d35b6e8b1ed7075726724b3bd64eea0" - integrity sha512-tTfemGmFWe7KZ3KN6VsSgQZbd9Bgo7A40wlp4PTsJJvFu4YAnEC5YnfdiKq6Vh2i9XJLnA9n8OXD46orVpnPMw== +caching-transform@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-3.0.1.tgz#1df89e850803ad15f68dafb2abe9a8b866016c7d" + integrity sha512-Y1KTLNwSPd4ljsDrFOtyXVmm7Gnk42yQitNq43AhE+cwUR/e4T+rmOHs1IPtzBg8066GBJfTOj1rQYFSWSsH2g== dependencies: - make-dir "^1.0.0" - md5-hex "^2.0.0" - package-hash "^2.0.0" - write-file-atomic "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + hasha "^3.0.0" + make-dir "^1.3.0" + package-hash "^3.0.0" + write-file-atomic "^2.3.0" callsites@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3" integrity sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw== -camelcase@^4.0.0, camelcase@^4.1.0: +camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= +camelcase@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" + integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + caniuse-lite@^1.0.30000912: version "1.0.30000916" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000916.tgz#3428d3f529f0a7b2bfaaec65e796037bdd433aab" @@ -2010,7 +1769,7 @@ chai@~4.2.0: pathval "^1.1.0" type-detect "^4.0.5" -chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: +chalk@1.1.3, chalk@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -2030,6 +1789,15 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" @@ -2087,6 +1855,11 @@ ci-info@^1.5.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" @@ -2114,6 +1887,16 @@ cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" +cli-table3@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" + integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== + dependencies: + object-assign "^4.1.0" + string-width "^2.1.1" + optionalDependencies: + colors "^1.1.2" + cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" @@ -2158,6 +1941,11 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +colors@^1.1.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" @@ -2180,6 +1968,11 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= +compare-versions@^3.2.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26" + integrity sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg== + component-emitter@^1.2.0, component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" @@ -2222,7 +2015,7 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1, convert-source-map@^1.6.0: +convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== @@ -2259,11 +2052,6 @@ core-js@^2.4.0: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.0.tgz#1e30793e9ee5782b307e37ffa22da0eacddd84d4" integrity sha512-kLRC6ncVpuEW/1kwrOXYX6KQASCVtrh1gQr/UiaVgFlf9WE5Vp+lNe5+h3LuMr5PAucWnnEXwH0nQHRH/gpGtw== -core-js@^2.5.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042" - integrity sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg== - core-js@^2.5.3: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -2273,11 +2061,6 @@ core-js@^2.5.7: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.2.tgz#267988d7268323b349e20b4588211655f0e83944" integrity sha512-NdBPF/RVwPW6jr0NCILuyN9RiqLo2b1mddWHkUL+VnvcB7dzlnBJ1bXYntjpTGOgkZiiLWj2JxmOr7eGE3qK6g== -core-js@^3.0.0-beta.3: - version "3.0.0-beta.9" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.9.tgz#1897789a5ef0ee1190d54777f35f80c38c077633" - integrity sha512-OGLbGro2f0s8UXVyu2s9kIW42pcuRoNEqJsmn8a4rAOO9G5A2t96l++rf+4mHNw9GKrbdozZ9G5ieDKOBl68zQ== - core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -2331,7 +2114,7 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.5: +cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -2395,11 +2178,6 @@ date-fns@^2.0.0-alpha.26: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.26.tgz#e46afd73a2b50e0359446309ee7cb631d7467227" integrity sha512-UAptCZ53MVimUFR8MXTyHED51AVGIqFlBfWgiS/KIoSYiJGrWScx4PYQVNSWfK2Js+43OlokCW1ttnexBTJ5Bg== -debug-log@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" - integrity sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8= - debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2421,7 +2199,14 @@ debug@^4.0.1, debug@^4.1.0: dependencies: ms "^2.1.1" -decamelize@^1.1.1: +debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -2448,13 +2233,6 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -default-require-extensions@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" - integrity sha1-836hXT4T/9m0N9M+GnW1+5eHTLg= - dependencies: - strip-bom "^2.0.0" - default-require-extensions@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" @@ -2516,13 +2294,6 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= - dependencies: - repeating "^2.0.0" - detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" @@ -2541,10 +2312,10 @@ dicer@0.2.5: readable-stream "1.1.x" streamsearch "0.1.2" -diff@^3.2.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff-sequences@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.0.0.tgz#cdf8e27ed20d8b8d3caccb4e0c0d8fe31a173013" + integrity sha512-46OkIuVGBBnrC0soO/4LHu5LHGHx0uhP65OVz8XOrAJpqiCB2aVIuESvjI1F9oqebuvY8lekS1pt6TN7vt7qsw== doctrine@1.5.0: version "1.5.0" @@ -2668,6 +2439,13 @@ encoding@^0.1.11: dependencies: iconv-lite "~0.4.13" +end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + entities@^1.1.1, entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" @@ -2768,10 +2546,10 @@ eslint-plugin-es@^1.3.1: eslint-utils "^1.3.0" regexpp "^2.0.1" -eslint-plugin-import@~2.15.0: - version "2.15.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.15.0.tgz#d8f3c28b8988ccde5df964706faa7c1e52f0602a" - integrity sha512-LEHqgR+RcnpGqYW7h9WMkPb/tP+ekKxWdQDztfTtZeV43IHF+X8lXU+1HOCcR4oXD24qRgEwNSxIweD5uNKGVg== +eslint-plugin-import@~2.16.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz#97ac3e75d0791c4fac0e15ef388510217be7f66f" + integrity sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A== dependencies: contains-path "^0.1.0" debug "^2.6.9" @@ -2784,10 +2562,10 @@ eslint-plugin-import@~2.15.0: read-pkg-up "^2.0.0" resolve "^1.9.0" -eslint-plugin-jest@^22.1.3: - version "22.1.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.1.3.tgz#4444108dfcddc5d2117ed6dc551f529d7e73a99e" - integrity sha512-JTZTI6WQoNruAugNyCO8fXfTONVcDd5i6dMRFA5g3rUFn1UDDLILY1bTL6alvNXbW2U7Sc2OSpi8m08pInnq0A== +eslint-plugin-jest@^22.2.2: + version "22.2.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.2.2.tgz#2a80d70a20c27dfb1503a6f32cdcb647fe5476df" + integrity sha512-hnWgh9o39VJfz6lJEyQJdTW7dN2yynlGkmPOlU/oMHh+d7WVMsJP1GeDTB520VCDljEdKExCwD5IBpQIUl4mJg== eslint-plugin-node@~8.0.1: version "8.0.1" @@ -2837,10 +2615,10 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@~5.12.1: - version "5.12.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.12.1.tgz#5ca9931fb9029d04e7be92b03ce3b58edfac7e3b" - integrity sha512-54NV+JkTpTu0d8+UYSA8mMKAG4XAsaOrozA9rCW7tgneg1mevcL7wIotPC+fZ0SkWwdhNqoXoxnQCTBp7UvTsg== +eslint@~5.13.0: + version "5.13.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.13.0.tgz#ce71cc529c450eed9504530939aa97527861ede9" + integrity sha512-nqD5WQMisciZC5EHZowejLKQjWGuFS5c70fxqSKlnDME+oz9zmE8KTlX+lHSg+/5wsC/kf9Q9eMkC8qS3oM2fg== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.5.3" @@ -2871,7 +2649,6 @@ eslint@~5.12.1: natural-compare "^1.4.0" optionator "^0.8.2" path-is-inside "^1.0.2" - pluralize "^7.0.0" progress "^2.0.0" regexpp "^2.0.1" semver "^5.5.1" @@ -2958,18 +2735,24 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= - dependencies: - is-posix-bracket "^0.1.0" - expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -2983,24 +2766,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= - dependencies: - fill-range "^2.1.0" - -expect@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98" - integrity sha512-dgSoOHgmtn/aDGRVFWclQyPDKl2CQRq0hmIEoUAuQs/2rn2NcvCWcSCovm6BLeuB/7EZuLGu2QfnR+qRt5OM4w== +expect@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.1.0.tgz#88e73301c4c785cde5f16da130ab407bdaf8c0f2" + integrity sha512-lVcAPhaYkQcIyMS+F8RVwzbm1jro20IG8OkvxQ6f1JfqhVZyyudCwYogQ7wnktlf14iF3ii7ArIUO/mqvrW9Gw== dependencies: ansi-styles "^3.2.0" - jest-diff "^23.6.0" - jest-get-type "^22.1.0" - jest-matcher-utils "^23.6.0" - jest-message-util "^23.4.0" - jest-regex-util "^23.3.0" + jest-get-type "^24.0.0" + jest-matcher-utils "^24.0.0" + jest-message-util "^24.0.0" + jest-regex-util "^24.0.0" express@^4.0.0, express@^4.16.3: version "4.16.4" @@ -3076,13 +2851,6 @@ external-editor@^3.0.0: iconv-lite "^0.4.24" tmp "^0.0.33" -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= - dependencies: - is-extglob "^1.0.0" - extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -3149,12 +2917,7 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= - -fileset@^2.0.2: +fileset@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA= @@ -3162,17 +2925,6 @@ fileset@^2.0.2: glob "^7.0.3" minimatch "^3.0.3" -fill-range@^2.1.0: - version "2.2.4" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" - integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^3.0.0" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -3214,14 +2966,6 @@ find-cache-dir@^2.0.0: make-dir "^1.0.0" pkg-dir "^3.0.0" -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -3246,18 +2990,11 @@ flat-cache@^1.2.1: rimraf "~2.6.2" write "^0.2.1" -for-in@^1.0.1, for-in@^1.0.2: +for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= - dependencies: - for-in "^1.0.1" - foreground-child@^1.5.6: version "1.5.6" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" @@ -3371,6 +3108,13 @@ 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: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -3383,21 +3127,6 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= - dependencies: - is-glob "^2.0.0" - glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -3430,11 +3159,6 @@ globals@^11.1.0, globals@^11.7.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== - got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" @@ -3452,7 +3176,7 @@ got@^6.7.1: unzip-response "^2.0.1" url-parse-lax "^1.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: version "4.1.15" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== @@ -3472,13 +3196,6 @@ graphql-deduplicator@^2.0.1: resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3" integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA== -graphql-extensions@0.3.7: - version "0.3.7" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.7.tgz#1a7bb99a0e29c105dd64d8dccb955ddc8ddc31ad" - integrity sha512-i9Zo1w5uZmHoKP2qlh4PfxD85Ju08lMYrjUL6tROqipWTdrGMc107kUWBsiRvAVipcTyagKhDLF75FIvJiaHBg== - dependencies: - "@apollographql/apollo-tools" "^0.2.6" - graphql-extensions@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.0.tgz#117b9872e5cafbebef5254ad795b41fa97037c14" @@ -3634,7 +3351,7 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= -handlebars@^4.0.11, handlebars@^4.0.3: +handlebars@^4.0.11: version "4.0.12" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== @@ -3665,11 +3382,6 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3723,6 +3435,13 @@ has@^1.0.1, has@^1.0.3: dependencies: function-bind "^1.1.1" +hasha@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hasha/-/hasha-3.0.0.tgz#52a32fab8569d41ca69a61ff1a214f8eb7c8bd39" + integrity sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk= + dependencies: + is-stream "^1.0.1" + he@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" @@ -3738,14 +3457,6 @@ hoek@6.x.x: resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.1.2.tgz#99e6d070561839de74ee427b61aa476bd6bddfd6" integrity sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q== -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - home-or-tmp@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-3.0.0.tgz#57a8fe24cf33cdd524860a15821ddc25c86671fb" @@ -3876,12 +3587,12 @@ import-lazy@^2.1.0: resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= -import-local@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" - integrity sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ== +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== dependencies: - pkg-dir "^2.0.0" + pkg-dir "^3.0.0" resolve-cwd "^2.0.0" imurmurhash@^0.1.4: @@ -3960,10 +3671,10 @@ invariant@^2.2.2, invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== ipaddr.js@1.8.0: version "1.8.0" @@ -4020,6 +3731,13 @@ is-ci@^1.0.10: dependencies: ci-info "^1.5.0" +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -4057,18 +3775,6 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= - dependencies: - is-primitive "^2.0.0" - is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -4081,23 +3787,11 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= - is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= - dependencies: - number-is-nan "^1.0.0" - is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -4110,17 +3804,10 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= -is-generator-fn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" - integrity sha1-lp1J4bszKfa7fwkIm+JleLLd1Go= - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= - dependencies: - is-extglob "^1.0.0" +is-generator-fn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.0.0.tgz#038c31b774709641bda678b1f06a4e3227c10b3e" + integrity sha512-elzyIdM7iKoFHzcrndIqjYomImhxrFRnGP3galODoII4TB9gI7mZ+FnlLQmmjf27SxHS2gKEeyhX5/+YRS6H9g== is-glob@^3.1.0: version "3.1.0" @@ -4149,13 +3836,6 @@ is-npm@^1.0.0: resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= - dependencies: - kind-of "^3.0.2" - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -4163,11 +3843,6 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== - is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -4192,16 +3867,6 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= - is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -4241,11 +3906,6 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - is-windows@^1.0.0, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -4290,60 +3950,42 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-api@^1.3.1: - version "1.3.7" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa" - integrity sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA== +istanbul-api@^2.0.8: + version "2.1.0" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.0.tgz#37ab0c2c3e83065462f5254b94749d6157846c4e" + integrity sha512-+Ygg4t1StoiNlBGc6x0f8q/Bv26FbZqP/+jegzfNpU7Q8o+4ZRoJxJPhBkgE/UonpAjtxnE4zCZIyJX+MwLRMQ== dependencies: - async "^2.1.4" - fileset "^2.0.2" - istanbul-lib-coverage "^1.2.1" - istanbul-lib-hook "^1.2.2" - istanbul-lib-instrument "^1.10.2" - istanbul-lib-report "^1.1.5" - istanbul-lib-source-maps "^1.2.6" - istanbul-reports "^1.5.1" - js-yaml "^3.7.0" - mkdirp "^0.5.1" + async "^2.6.1" + compare-versions "^3.2.1" + fileset "^2.0.3" + istanbul-lib-coverage "^2.0.3" + istanbul-lib-hook "^2.0.3" + istanbul-lib-instrument "^3.1.0" + istanbul-lib-report "^2.0.4" + istanbul-lib-source-maps "^3.0.2" + istanbul-reports "^2.1.0" + js-yaml "^3.12.0" + make-dir "^1.3.0" + minimatch "^3.0.4" once "^1.4.0" -istanbul-lib-coverage@^1.2.0, istanbul-lib-coverage@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" - integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== - istanbul-lib-coverage@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda" integrity sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA== -istanbul-lib-hook@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86" - integrity sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw== - dependencies: - append-transform "^0.4.0" +istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#0b891e5ad42312c2b9488554f603795f9a2211ba" + integrity sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw== -istanbul-lib-hook@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.1.tgz#918a57b75a0f951d552a08487ca1fa5336433d72" - integrity sha512-ufiZoiJ8CxY577JJWEeFuxXZoMqiKpq/RqZtOAYuQLvlkbJWscq9n3gc4xrCGH9n4pW0qnTxOz1oyMmVtk8E1w== +istanbul-lib-hook@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz#e0e581e461c611be5d0e5ef31c5f0109759916fb" + integrity sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA== dependencies: append-transform "^1.0.0" -istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" - integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A== - dependencies: - babel-generator "^6.18.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - babylon "^6.18.0" - istanbul-lib-coverage "^1.2.1" - semver "^5.3.0" - istanbul-lib-instrument@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz#b5f066b2a161f75788be17a9d556f40a0cf2afc9" @@ -4357,58 +3999,43 @@ istanbul-lib-instrument@^3.0.0: istanbul-lib-coverage "^2.0.1" semver "^5.5.0" -istanbul-lib-report@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c" - integrity sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw== +istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz#a2b5484a7d445f1f311e93190813fa56dfb62971" + integrity sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA== dependencies: - istanbul-lib-coverage "^1.2.1" - mkdirp "^0.5.1" - path-parse "^1.0.5" - supports-color "^3.1.2" + "@babel/generator" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + istanbul-lib-coverage "^2.0.3" + semver "^5.5.0" -istanbul-lib-report@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.2.tgz#430a2598519113e1da7af274ba861bd42dd97535" - integrity sha512-rJ8uR3peeIrwAxoDEbK4dJ7cqqtxBisZKCuwkMtMv0xYzaAnsAi3AHrHPAAtNXzG/bcCgZZ3OJVqm1DTi9ap2Q== +istanbul-lib-report@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz#bfd324ee0c04f59119cb4f07dab157d09f24d7e4" + integrity sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA== dependencies: - istanbul-lib-coverage "^2.0.1" + istanbul-lib-coverage "^2.0.3" make-dir "^1.3.0" - supports-color "^5.4.0" + supports-color "^6.0.0" -istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f" - integrity sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg== +istanbul-lib-source-maps@^3.0.1, istanbul-lib-source-maps@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz#f1e817229a9146e8424a28e5d69ba220fda34156" + integrity sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ== dependencies: - debug "^3.1.0" - istanbul-lib-coverage "^1.2.1" - mkdirp "^0.5.1" - rimraf "^2.6.1" - source-map "^0.5.3" - -istanbul-lib-source-maps@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-2.0.1.tgz#ce8b45131d8293fdeaa732f4faf1852d13d0a97e" - integrity sha512-30l40ySg+gvBLcxTrLzR4Z2XTRj3HgRCA/p2rnbs/3OiTaoj054gAbuP5DcLOtwqmy4XW8qXBHzrmP2/bQ9i3A== - dependencies: - debug "^3.1.0" - istanbul-lib-coverage "^2.0.1" + debug "^4.1.1" + istanbul-lib-coverage "^2.0.3" make-dir "^1.3.0" rimraf "^2.6.2" source-map "^0.6.1" -istanbul-reports@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a" - integrity sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw== - dependencies: - handlebars "^4.0.3" - -istanbul-reports@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.0.1.tgz#fb8d6ea850701a3984350b977a969e9a556116a7" - integrity sha512-CT0QgMBJqs6NJLF678ZHcquUAZIoBIUNzdJrRJfpkI9OnzG6MkUfHxbJC3ln981dMswC7/B1mfX3LNkhgJxsuw== +istanbul-reports@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.1.0.tgz#87b8b55cd1901ba1748964c98ddd8900ce306d59" + integrity sha512-azQdSX+dtTtkQEfqq20ICxWi6eOHXyHIgMFw1VOOVi8iIPWeCWRgCyFh/CsBKIhcgskMI8ExXmU7rjXTRCIJ+A== dependencies: handlebars "^4.0.11" @@ -4417,322 +4044,334 @@ iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2: resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== -jest-changed-files@^23.4.2: - version "23.4.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.2.tgz#1eed688370cd5eebafe4ae93d34bb3b64968fe83" - integrity sha512-EyNhTAUWEfwnK0Is/09LxoqNDOn7mU7S3EHskG52djOFS/z+IT0jT3h3Ql61+dklcG7bJJitIWEMB4Sp1piHmA== +jest-changed-files@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.0.0.tgz#c02c09a8cc9ca93f513166bc773741bd39898ff7" + integrity sha512-nnuU510R9U+UX0WNb5XFEcsrMqriSiRLeO9KWDFgPrpToaQm60prfQYpxsXigdClpvNot5bekDY440x9dNGnsQ== dependencies: + execa "^1.0.0" throat "^4.0.0" -jest-cli@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.6.0.tgz#61ab917744338f443ef2baa282ddffdd658a5da4" - integrity sha512-hgeD1zRUp1E1zsiyOXjEn4LzRLWdJBV//ukAHGlx6s5mfCNJTbhbHjgxnDUXA8fsKWN/HqFFF6X5XcCwC/IvYQ== +jest-cli@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.1.0.tgz#f7cc98995f36e7210cce3cbb12974cbf60940843" + integrity sha512-U/iyWPwOI0T1CIxVLtk/2uviOTJ/OiSWJSe8qt6X1VkbbgP+nrtLJlmT9lPBe4lK78VNFJtrJ7pttcNv/s7yCw== dependencies: ansi-escapes "^3.0.0" chalk "^2.0.1" exit "^0.1.2" glob "^7.1.2" - graceful-fs "^4.1.11" - import-local "^1.0.0" - is-ci "^1.0.10" - istanbul-api "^1.3.1" - istanbul-lib-coverage "^1.2.0" - istanbul-lib-instrument "^1.10.1" - istanbul-lib-source-maps "^1.2.4" - jest-changed-files "^23.4.2" - jest-config "^23.6.0" - jest-environment-jsdom "^23.4.0" - jest-get-type "^22.1.0" - jest-haste-map "^23.6.0" - jest-message-util "^23.4.0" - jest-regex-util "^23.3.0" - jest-resolve-dependencies "^23.6.0" - jest-runner "^23.6.0" - jest-runtime "^23.6.0" - jest-snapshot "^23.6.0" - jest-util "^23.4.0" - jest-validate "^23.6.0" - jest-watcher "^23.4.0" - jest-worker "^23.2.0" - micromatch "^2.3.11" + graceful-fs "^4.1.15" + import-local "^2.0.0" + is-ci "^2.0.0" + istanbul-api "^2.0.8" + istanbul-lib-coverage "^2.0.2" + istanbul-lib-instrument "^3.0.1" + istanbul-lib-source-maps "^3.0.1" + jest-changed-files "^24.0.0" + jest-config "^24.1.0" + jest-environment-jsdom "^24.0.0" + jest-get-type "^24.0.0" + jest-haste-map "^24.0.0" + jest-message-util "^24.0.0" + jest-regex-util "^24.0.0" + jest-resolve-dependencies "^24.1.0" + jest-runner "^24.1.0" + jest-runtime "^24.1.0" + jest-snapshot "^24.1.0" + jest-util "^24.0.0" + jest-validate "^24.0.0" + jest-watcher "^24.0.0" + jest-worker "^24.0.0" + micromatch "^3.1.10" node-notifier "^5.2.1" - prompts "^0.1.9" + p-each-series "^1.0.0" + pirates "^4.0.0" + prompts "^2.0.1" realpath-native "^1.0.0" rimraf "^2.5.4" - slash "^1.0.0" + slash "^2.0.0" string-length "^2.0.0" - strip-ansi "^4.0.0" + strip-ansi "^5.0.0" which "^1.2.12" - yargs "^11.0.0" + yargs "^12.0.2" -jest-config@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.6.0.tgz#f82546a90ade2d8c7026fbf6ac5207fc22f8eb1d" - integrity sha512-i8V7z9BeDXab1+VNo78WM0AtWpBRXJLnkT+lyT+Slx/cbP5sZJ0+NDuLcmBE5hXAoK0aUp7vI+MOxR+R4d8SRQ== +jest-config@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.1.0.tgz#6ea6881cfdd299bc86cc144ee36d937c97c3850c" + integrity sha512-FbbRzRqtFC6eGjG5VwsbW4E5dW3zqJKLWYiZWhB0/4E5fgsMw8GODLbGSrY5t17kKOtCWb/Z7nsIThRoDpuVyg== dependencies: - babel-core "^6.0.0" - babel-jest "^23.6.0" + "@babel/core" "^7.1.0" + babel-jest "^24.1.0" chalk "^2.0.1" glob "^7.1.1" - jest-environment-jsdom "^23.4.0" - jest-environment-node "^23.4.0" - jest-get-type "^22.1.0" - jest-jasmine2 "^23.6.0" - jest-regex-util "^23.3.0" - jest-resolve "^23.6.0" - jest-util "^23.4.0" - jest-validate "^23.6.0" - micromatch "^2.3.11" - pretty-format "^23.6.0" + jest-environment-jsdom "^24.0.0" + jest-environment-node "^24.0.0" + jest-get-type "^24.0.0" + jest-jasmine2 "^24.1.0" + jest-regex-util "^24.0.0" + jest-resolve "^24.1.0" + jest-util "^24.0.0" + jest-validate "^24.0.0" + micromatch "^3.1.10" + pretty-format "^24.0.0" + realpath-native "^1.0.2" -jest-diff@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d" - integrity sha512-Gz9l5Ov+X3aL5L37IT+8hoCUsof1CVYBb2QEkOupK64XyRR3h+uRpYIm97K7sY8diFxowR8pIGEdyfMKTixo3g== +jest-diff@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.0.0.tgz#a3e5f573dbac482f7d9513ac9cfa21644d3d6b34" + integrity sha512-XY5wMpRaTsuMoU+1/B2zQSKQ9RdE9gsLkGydx3nvApeyPijLA8GtEvIcPwISRCer+VDf9W1mStTYYq6fPt8ryA== dependencies: chalk "^2.0.1" - diff "^3.2.0" - jest-get-type "^22.1.0" - pretty-format "^23.6.0" + diff-sequences "^24.0.0" + jest-get-type "^24.0.0" + pretty-format "^24.0.0" -jest-docblock@^23.2.0: - version "23.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7" - integrity sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c= +jest-docblock@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.0.0.tgz#54d77a188743e37f62181a91a01eb9222289f94e" + integrity sha512-KfAKZ4SN7CFOZpWg4i7g7MSlY0M+mq7K0aMqENaG2vHuhC9fc3vkpU/iNN9sOus7v3h3Y48uEjqz3+Gdn2iptA== dependencies: detect-newline "^2.1.0" -jest-each@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.6.0.tgz#ba0c3a82a8054387016139c733a05242d3d71575" - integrity sha512-x7V6M/WGJo6/kLoissORuvLIeAoyo2YqLOoCDkohgJ4XOXSqOtyvr8FbInlAWS77ojBsZrafbozWoKVRdtxFCg== +jest-each@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.0.0.tgz#10987a06b21c7ffbfb7706c89d24c52ed864be55" + integrity sha512-gFcbY4Cu55yxExXMkjrnLXov3bWO3dbPAW7HXb31h/DNWdNc/6X8MtxGff8nh3/MjkF9DpVqnj0KsPKuPK0cpA== dependencies: chalk "^2.0.1" - pretty-format "^23.6.0" + jest-get-type "^24.0.0" + jest-util "^24.0.0" + pretty-format "^24.0.0" -jest-environment-jsdom@^23.4.0: - version "23.4.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023" - integrity sha1-BWp5UrP+pROsYqFAosNox52eYCM= +jest-environment-jsdom@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.0.0.tgz#5affa0654d6e44cd798003daa1a8701dbd6e4d11" + integrity sha512-1YNp7xtxajTRaxbylDc2pWvFnfDTH5BJJGyVzyGAKNt/lEULohwEV9zFqTgG4bXRcq7xzdd+sGFws+LxThXXOw== dependencies: - jest-mock "^23.2.0" - jest-util "^23.4.0" + jest-mock "^24.0.0" + jest-util "^24.0.0" jsdom "^11.5.1" -jest-environment-node@^23.4.0: - version "23.4.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10" - integrity sha1-V+gO0IQd6jAxZ8zozXlSHeuv3hA= +jest-environment-node@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.0.0.tgz#330948980656ed8773ce2e04eb597ed91e3c7190" + integrity sha512-62fOFcaEdU0VLaq8JL90TqwI7hLn0cOKOl8vY2n477vRkCJRojiRRtJVRzzCcgFvs6gqU97DNqX5R0BrBP6Rxg== dependencies: - jest-mock "^23.2.0" - jest-util "^23.4.0" + jest-mock "^24.0.0" + jest-util "^24.0.0" -jest-get-type@^22.1.0: - version "22.4.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" - integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== +jest-get-type@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.0.0.tgz#36e72930b78e33da59a4f63d44d332188278940b" + integrity sha512-z6/Eyf6s9ZDGz7eOvl+fzpuJmN9i0KyTt1no37/dHu8galssxz5ZEgnc1KaV8R31q1khxyhB4ui/X5ZjjPk77w== -jest-haste-map@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.6.0.tgz#2e3eb997814ca696d62afdb3f2529f5bbc935e16" - integrity sha512-uyNhMyl6dr6HaXGHp8VF7cK6KpC6G9z9LiMNsst+rJIZ8l7wY0tk8qwjPmEghczojZ2/ZhtEdIabZ0OQRJSGGg== +jest-haste-map@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0.tgz#e9ef51b2c9257384b4d6beb83bd48c65b37b5e6e" + integrity sha512-CcViJyUo41IQqttLxXVdI41YErkzBKbE6cS6dRAploCeutePYfUimWd3C9rQEWhX0YBOQzvNsC0O9nYxK2nnxQ== dependencies: fb-watchman "^2.0.0" - graceful-fs "^4.1.11" + graceful-fs "^4.1.15" invariant "^2.2.4" - jest-docblock "^23.2.0" - jest-serializer "^23.0.1" - jest-worker "^23.2.0" - micromatch "^2.3.11" - sane "^2.0.0" + jest-serializer "^24.0.0" + jest-util "^24.0.0" + jest-worker "^24.0.0" + micromatch "^3.1.10" + sane "^3.0.0" -jest-jasmine2@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz#840e937f848a6c8638df24360ab869cc718592e0" - integrity sha512-pe2Ytgs1nyCs8IvsEJRiRTPC0eVYd8L/dXJGU08GFuBwZ4sYH/lmFDdOL3ZmvJR8QKqV9MFuwlsAi/EWkFUbsQ== +jest-jasmine2@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.1.0.tgz#8377324b967037c440f0a549ee0bbd9912055db6" + integrity sha512-H+o76SdSNyCh9fM5K8upK45YTo/DiFx5w2YAzblQebSQmukDcoVBVeXynyr7DDnxh+0NTHYRCLwJVf3tC518wg== dependencies: - babel-traverse "^6.0.0" + "@babel/traverse" "^7.1.0" chalk "^2.0.1" co "^4.6.0" - expect "^23.6.0" - is-generator-fn "^1.0.0" - jest-diff "^23.6.0" - jest-each "^23.6.0" - jest-matcher-utils "^23.6.0" - jest-message-util "^23.4.0" - jest-snapshot "^23.6.0" - jest-util "^23.4.0" - pretty-format "^23.6.0" + expect "^24.1.0" + is-generator-fn "^2.0.0" + jest-each "^24.0.0" + jest-matcher-utils "^24.0.0" + jest-message-util "^24.0.0" + jest-snapshot "^24.1.0" + jest-util "^24.0.0" + pretty-format "^24.0.0" + throat "^4.0.0" -jest-leak-detector@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz#e4230fd42cf381a1a1971237ad56897de7e171de" - integrity sha512-f/8zA04rsl1Nzj10HIyEsXvYlMpMPcy0QkQilVZDFOaPbv2ur71X5u2+C4ZQJGyV/xvVXtCCZ3wQ99IgQxftCg== +jest-leak-detector@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.0.0.tgz#78280119fd05ee98317daee62cddb3aa537a31c6" + integrity sha512-ZYHJYFeibxfsDSKowjDP332pStuiFT2xfc5R67Rjm/l+HFJWJgNIOCOlQGeXLCtyUn3A23+VVDdiCcnB6dTTrg== dependencies: - pretty-format "^23.6.0" + pretty-format "^24.0.0" -jest-matcher-utils@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80" - integrity sha512-rosyCHQfBcol4NsckTn01cdelzWLU9Cq7aaigDf8VwwpIRvWE/9zLgX2bON+FkEW69/0UuYslUe22SOdEf2nog== +jest-matcher-utils@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.0.0.tgz#fc9c41cfc49b2c3ec14e576f53d519c37729d579" + integrity sha512-LQTDmO+aWRz1Tf9HJg+HlPHhDh1E1c65kVwRFo5mwCVp5aQDzlkz4+vCvXhOKFjitV2f0kMdHxnODrXVoi+rlA== dependencies: chalk "^2.0.1" - jest-get-type "^22.1.0" - pretty-format "^23.6.0" + jest-diff "^24.0.0" + jest-get-type "^24.0.0" + pretty-format "^24.0.0" -jest-message-util@^23.4.0: - version "23.4.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f" - integrity sha1-F2EMUJQjSVCNAaPR4L2iwHkIap8= +jest-message-util@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.0.0.tgz#a07a141433b2c992dbaec68d4cbfe470ba289619" + integrity sha512-J9ROJIwz/IeC+eV1XSwnRK4oAwPuhmxEyYx1+K5UI+pIYwFZDSrfZaiWTdq0d2xYFw4Xiu+0KQWsdsQpgJMf3Q== dependencies: - "@babel/code-frame" "^7.0.0-beta.35" + "@babel/code-frame" "^7.0.0" chalk "^2.0.1" - micromatch "^2.3.11" - slash "^1.0.0" + micromatch "^3.1.10" + slash "^2.0.0" stack-utils "^1.0.1" -jest-mock@^23.2.0: - version "23.2.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134" - integrity sha1-rRxg8p6HGdR8JuETgJi20YsmETQ= +jest-mock@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.0.0.tgz#9a4b53e01d66a0e780f7d857462d063e024c617d" + integrity sha512-sQp0Hu5fcf5NZEh1U9eIW2qD0BwJZjb63Yqd98PQJFvf/zzUTBoUAwv/Dc/HFeNHIw1f3hl/48vNn+j3STaI7A== -jest-regex-util@^23.3.0: - version "23.3.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5" - integrity sha1-X4ZylUfCeFxAAs6qj4Sf6MpHG8U= +jest-regex-util@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.0.0.tgz#4feee8ec4a358f5bee0a654e94eb26163cb9089a" + integrity sha512-Jv/uOTCuC+PY7WpJl2mpoI+WbY2ut73qwwO9ByJJNwOCwr1qWhEW2Lyi2S9ZewUdJqeVpEBisdEVZSI+Zxo58Q== -jest-resolve-dependencies@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz#b4526af24c8540d9a3fab102c15081cf509b723d" - integrity sha512-EkQWkFWjGKwRtRyIwRwI6rtPAEyPWlUC2MpzHissYnzJeHcyCn1Hc8j7Nn1xUVrS5C6W5+ZL37XTem4D4pLZdA== +jest-resolve-dependencies@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.1.0.tgz#78f738a2ec59ff4d00751d9da56f176e3f589f6c" + integrity sha512-2VwPsjd3kRPu7qe2cpytAgowCObk5AKeizfXuuiwgm1a9sijJDZe8Kh1sFj6FKvSaNEfCPlBVkZEJa2482m/Uw== dependencies: - jest-regex-util "^23.3.0" - jest-snapshot "^23.6.0" + jest-regex-util "^24.0.0" + jest-snapshot "^24.1.0" -jest-resolve@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.6.0.tgz#cf1d1a24ce7ee7b23d661c33ba2150f3aebfa0ae" - integrity sha512-XyoRxNtO7YGpQDmtQCmZjum1MljDqUCob7XlZ6jy9gsMugHdN2hY4+Acz9Qvjz2mSsOnPSH7skBmDYCHXVZqkA== +jest-resolve@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.1.0.tgz#42ff0169b0ea47bfdbd0c52a0067ca7d022c7688" + integrity sha512-TPiAIVp3TG6zAxH28u/6eogbwrvZjBMWroSLBDkwkHKrqxB/RIdwkWDye4uqPlZIXWIaHtifY3L0/eO5Z0f2wg== dependencies: browser-resolve "^1.11.3" chalk "^2.0.1" realpath-native "^1.0.0" -jest-runner@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.6.0.tgz#3894bd219ffc3f3cb94dc48a4170a2e6f23a5a38" - integrity sha512-kw0+uj710dzSJKU6ygri851CObtCD9cN8aNkg8jWJf4ewFyEa6kwmiH/r/M1Ec5IL/6VFa0wnAk6w+gzUtjJzA== +jest-runner@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.1.0.tgz#3686a2bb89ce62800da23d7fdc3da2c32792943b" + integrity sha512-CDGOkT3AIFl16BLL/OdbtYgYvbAprwJ+ExKuLZmGSCSldwsuU2dEGauqkpvd9nphVdAnJUcP12e/EIlnTX0QXg== dependencies: + chalk "^2.4.2" exit "^0.1.2" - graceful-fs "^4.1.11" - jest-config "^23.6.0" - jest-docblock "^23.2.0" - jest-haste-map "^23.6.0" - jest-jasmine2 "^23.6.0" - jest-leak-detector "^23.6.0" - jest-message-util "^23.4.0" - jest-runtime "^23.6.0" - jest-util "^23.4.0" - jest-worker "^23.2.0" + graceful-fs "^4.1.15" + jest-config "^24.1.0" + jest-docblock "^24.0.0" + jest-haste-map "^24.0.0" + jest-jasmine2 "^24.1.0" + jest-leak-detector "^24.0.0" + jest-message-util "^24.0.0" + jest-runtime "^24.1.0" + jest-util "^24.0.0" + jest-worker "^24.0.0" source-map-support "^0.5.6" throat "^4.0.0" -jest-runtime@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.6.0.tgz#059e58c8ab445917cd0e0d84ac2ba68de8f23082" - integrity sha512-ycnLTNPT2Gv+TRhnAYAQ0B3SryEXhhRj1kA6hBPSeZaNQkJ7GbZsxOLUkwg6YmvWGdX3BB3PYKFLDQCAE1zNOw== +jest-runtime@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.1.0.tgz#7c157a2e776609e8cf552f956a5a19ec9c985214" + integrity sha512-59/BY6OCuTXxGeDhEMU7+N33dpMQyXq7MLK07cNSIY/QYt2QZgJ7Tjx+rykBI0skAoigFl0A5tmT8UdwX92YuQ== dependencies: - babel-core "^6.0.0" - babel-plugin-istanbul "^4.1.6" + "@babel/core" "^7.1.0" + babel-plugin-istanbul "^5.1.0" chalk "^2.0.1" convert-source-map "^1.4.0" exit "^0.1.2" fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.1.11" - jest-config "^23.6.0" - jest-haste-map "^23.6.0" - jest-message-util "^23.4.0" - jest-regex-util "^23.3.0" - jest-resolve "^23.6.0" - jest-snapshot "^23.6.0" - jest-util "^23.4.0" - jest-validate "^23.6.0" - micromatch "^2.3.11" + glob "^7.1.3" + graceful-fs "^4.1.15" + jest-config "^24.1.0" + jest-haste-map "^24.0.0" + jest-message-util "^24.0.0" + jest-regex-util "^24.0.0" + jest-resolve "^24.1.0" + jest-snapshot "^24.1.0" + jest-util "^24.0.0" + jest-validate "^24.0.0" + micromatch "^3.1.10" realpath-native "^1.0.0" - slash "^1.0.0" - strip-bom "3.0.0" - write-file-atomic "^2.1.0" - yargs "^11.0.0" + slash "^2.0.0" + strip-bom "^3.0.0" + write-file-atomic "2.4.1" + yargs "^12.0.2" -jest-serializer@^23.0.1: - version "23.0.1" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165" - integrity sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU= +jest-serializer@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0.tgz#522c44a332cdd194d8c0531eb06a1ee5afb4256b" + integrity sha512-9FKxQyrFgHtx3ozU+1a8v938ILBE7S8Ko3uiAVjT8Yfi2o91j/fj81jacCQZ/Ihjiff/VsUCXVgQ+iF1XdImOw== -jest-snapshot@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.6.0.tgz#f9c2625d1b18acda01ec2d2b826c0ce58a5aa17a" - integrity sha512-tM7/Bprftun6Cvj2Awh/ikS7zV3pVwjRYU2qNYS51VZHgaAMBs5l4o/69AiDHhQrj5+LA2Lq4VIvK7zYk/bswg== +jest-snapshot@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.1.0.tgz#85e22f810357aa5994ab61f236617dc2205f2f5b" + integrity sha512-th6TDfFqEmXvuViacU1ikD7xFb7lQsPn2rJl7OEmnfIVpnrx3QNY2t3PE88meeg0u/mQ0nkyvmC05PBqO4USFA== dependencies: - babel-types "^6.0.0" + "@babel/types" "^7.0.0" chalk "^2.0.1" - jest-diff "^23.6.0" - jest-matcher-utils "^23.6.0" - jest-message-util "^23.4.0" - jest-resolve "^23.6.0" + jest-diff "^24.0.0" + jest-matcher-utils "^24.0.0" + jest-message-util "^24.0.0" + jest-resolve "^24.1.0" mkdirp "^0.5.1" natural-compare "^1.4.0" - pretty-format "^23.6.0" + pretty-format "^24.0.0" semver "^5.5.0" -jest-util@^23.4.0: - version "23.4.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561" - integrity sha1-TQY8uSe68KI4Mf9hvsLLv0l5NWE= +jest-util@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.0.0.tgz#fd38fcafd6dedbd0af2944d7a227c0d91b68f7d6" + integrity sha512-QxsALc4wguYS7cfjdQSOr5HTkmjzkHgmZvIDkcmPfl1ib8PNV8QUWLwbKefCudWS0PRKioV+VbQ0oCUPC691fQ== dependencies: - callsites "^2.0.0" + callsites "^3.0.0" chalk "^2.0.1" - graceful-fs "^4.1.11" - is-ci "^1.0.10" - jest-message-util "^23.4.0" + graceful-fs "^4.1.15" + is-ci "^2.0.0" + jest-message-util "^24.0.0" mkdirp "^0.5.1" - slash "^1.0.0" + slash "^2.0.0" source-map "^0.6.0" -jest-validate@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" - integrity sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A== +jest-validate@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.0.0.tgz#aa8571a46983a6538328fef20406b4a496b6c020" + integrity sha512-vMrKrTOP4BBFIeOWsjpsDgVXATxCspC9S1gqvbJ3Tnn/b9ACsJmteYeVx9830UMV28Cob1RX55x96Qq3Tfad4g== dependencies: + camelcase "^5.0.0" chalk "^2.0.1" - jest-get-type "^22.1.0" + jest-get-type "^24.0.0" leven "^2.1.0" - pretty-format "^23.6.0" + pretty-format "^24.0.0" -jest-watcher@^23.4.0: - version "23.4.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.4.0.tgz#d2e28ce74f8dad6c6afc922b92cabef6ed05c91c" - integrity sha1-0uKM50+NrWxq/JIrksq+9u0FyRw= +jest-watcher@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.0.0.tgz#20d44244d10b0b7312410aefd256c1c1eef68890" + integrity sha512-GxkW2QrZ4YxmW1GUWER05McjVDunBlKMFfExu+VsGmXJmpej1saTEKvONdx5RJBlVdpPI5x6E3+EDQSIGgl53g== dependencies: ansi-escapes "^3.0.0" chalk "^2.0.1" + jest-util "^24.0.0" string-length "^2.0.0" -jest-worker@^23.2.0: - version "23.2.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-23.2.0.tgz#faf706a8da36fae60eb26957257fa7b5d8ea02b9" - integrity sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk= +jest-worker@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0.tgz#3d3483b077bf04f412f47654a27bba7e947f8b6d" + integrity sha512-s64/OThpfQvoCeHG963MiEZOAAxu8kHsaL/rCMF7lpdzo7vgF0CtPml9hfguOMgykgH/eOm4jFP4ibfHLruytg== dependencies: merge-stream "^1.0.1" + supports-color "^6.1.0" -jest@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-23.6.0.tgz#ad5835e923ebf6e19e7a1d7529a432edfee7813d" - integrity sha512-lWzcd+HSiqeuxyhG+EnZds6iO3Y3ZEnMrfZq/OTGvF/C+Z4fPMCdhWTGSAiO2Oym9rbEXfwddHhh6jqrTF3+Lw== +jest@^24.1.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.1.0.tgz#b1e1135caefcf2397950ecf7f90e395fde866fd2" + integrity sha512-+q91L65kypqklvlRFfXfdzUKyngQLOcwGhXQaLmVHv+d09LkNXuBuGxlofTFW42XMzu3giIcChchTsCNUjQ78A== dependencies: - import-local "^1.0.0" - jest-cli "^23.6.0" + import-local "^2.0.0" + jest-cli "^24.1.0" jmespath@0.15.0: version "0.15.0" @@ -4763,12 +4402,7 @@ js-levenshtein@^1.1.3: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= - -js-yaml@^3.12.0, js-yaml@^3.7.0: +js-yaml@^3.12.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== @@ -4813,11 +4447,6 @@ jsdom@^11.5.1: ws "^5.2.0" xml-name-validator "^3.0.0" -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= - jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -4848,23 +4477,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - json5@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" @@ -4943,10 +4560,10 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== -kleur@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300" - integrity sha512-77XF9iTllATmG9lSlIv0qdQ2BQ/h9t0bJllHlbvsQ0zUWfU7Yi0S8L5JXzPZgkefIiajLmBJJ4BsMJmqcf7oxQ== +kleur@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.1.tgz#4f5b313f5fa315432a400f19a24db78d451ede62" + integrity sha512-P3kRv+B+Ra070ng2VKQqW4qW7gd/v3iD8sy/zOdcYRsfiD+QBokQNOps/AfP6Hr48cBhIIBFWckB9aO+IZhrWg== latest-version@^3.0.0: version "3.1.0" @@ -4955,12 +4572,12 @@ latest-version@^3.0.0: dependencies: package-json "^4.0.0" -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== dependencies: - invert-kv "^1.0.0" + invert-kv "^2.0.0" left-pad@^1.3.0: version "1.3.0" @@ -4989,26 +4606,15 @@ libphonenumber-js@^1.6.4: semver-compare "^1.0.0" xml2js "^0.4.17" -linkifyjs@~2.1.7: - version "2.1.7" - resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-2.1.7.tgz#e5d68d2ae30b9c055e1d74cc40f9a31d3abb4012" - integrity sha512-Cbn77BnYEslpAObZZoP6GVQHF1j5T6RsDydNq5RVxIy4eiZAiADRx7qHfWzfEMQecc1PtZFog1AsCGGX2WjQLA== +linkifyjs@~2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-2.1.8.tgz#2bee2272674dc196cce3740b8436c43df2162f9c" + integrity sha512-j3QpiEr4UYzN5foKhrr9Sr06VI9vSlI4HisDWt+7Mq+TWDwpJ6H/LLpogYsXcyUIJLVhGblXXdUnblHsVNMPpg== optionalDependencies: jquery "^3.3.1" react "^16.4.2" react-dom "^16.4.2" -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" @@ -5161,6 +4767,13 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -5173,34 +4786,19 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -math-random@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" - integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= - -md5-hex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" - integrity sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM= - dependencies: - md5-o-matic "^0.1.1" - -md5-o-matic@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" - integrity sha1-givM1l4RfFFPqxdrJZRdVBAKA8M= - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= +mem@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.1.0.tgz#aeb9be2d21f47e78af29e4ac5978e8afa2ca5b8a" + integrity sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg== dependencies: + map-age-cleaner "^0.1.1" mimic-fn "^1.0.0" + p-is-promise "^2.0.0" memorystream@^0.3.1: version "0.3.1" @@ -5236,25 +4834,6 @@ methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -5539,7 +5118,7 @@ normalize-package-data@^2.3.2: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.0.1, normalize-path@^2.1.1: +normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= @@ -5613,36 +5192,35 @@ nwsapi@^2.0.7: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016" integrity sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ== -nyc@^13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-13.1.0.tgz#463665c7ff6b5798e322624a5eb449a678db90e3" - integrity sha512-3GyY6TpQ58z9Frpv4GMExE1SV2tAgYqC7HSy2omEhNiCT3mhT9NyiOvIE8zkbuJVFzmvvNTnE4h/7/wQae7xLg== +nyc@^13.2.0: + version "13.2.0" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-13.2.0.tgz#6a4a4b3f5f97b63ab491c665567557debcfa23d6" + integrity sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ== dependencies: archy "^1.0.0" arrify "^1.0.1" - caching-transform "^2.0.0" + caching-transform "^3.0.1" convert-source-map "^1.6.0" - debug-log "^1.0.1" find-cache-dir "^2.0.0" find-up "^3.0.0" foreground-child "^1.5.6" glob "^7.1.3" - istanbul-lib-coverage "^2.0.1" - istanbul-lib-hook "^2.0.1" - istanbul-lib-instrument "^3.0.0" - istanbul-lib-report "^2.0.2" - istanbul-lib-source-maps "^2.0.1" - istanbul-reports "^2.0.1" + istanbul-lib-coverage "^2.0.3" + istanbul-lib-hook "^2.0.3" + istanbul-lib-instrument "^3.0.1" + istanbul-lib-report "^2.0.4" + istanbul-lib-source-maps "^3.0.2" + istanbul-reports "^2.1.0" make-dir "^1.3.0" merge-source-map "^1.1.0" resolve-from "^4.0.0" - rimraf "^2.6.2" + rimraf "^2.6.3" signal-exit "^3.0.2" spawn-wrap "^1.4.2" - test-exclude "^5.0.0" + test-exclude "^5.1.0" uuid "^3.3.2" - yargs "11.1.0" - yargs-parser "^9.0.2" + yargs "^12.0.5" + yargs-parser "^11.1.1" oauth-sign@~0.9.0: version "0.9.0" @@ -5693,14 +5271,6 @@ object.getownpropertydescriptors@^2.0.3: define-properties "^1.1.2" es-abstract "^1.5.1" -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -5715,7 +5285,7 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -once@^1.3.0, once@^1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -5749,10 +5319,10 @@ opn@4.0.2: object-assign "^4.0.1" pinkie-promise "^2.0.0" -optimism@^0.6.8: - version "0.6.8" - resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.8.tgz#0780b546da8cd0a72e5207e0c3706c990c8673a6" - integrity sha512-bN5n1KCxSqwBDnmgDnzMtQTHdL+uea2HYFx1smvtE+w2AMl0Uy31g0aXnP/Nt85OINnMJPRpJyfRQLTCqn5Weg== +optimism@^0.6.9: + version "0.6.9" + resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.9.tgz#19258ff8b3be0cea29ac35f06bff818e026e30bb" + integrity sha512-xoQm2lvXbCA9Kd7SCx6y713Y7sZ6fUc5R6VYpoL5M6svKJbTuvtNopexK8sO8K4s0EOUYHuPN2+yAEsNyRggkQ== dependencies: immutable-tuple "^0.4.9" @@ -5781,16 +5351,16 @@ os-homedir@^1.0.0, os-homedir@^1.0.1: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== +os-locale@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= @@ -5812,11 +5382,28 @@ output-file-sync@^2.0.0: is-plain-obj "^1.1.0" mkdirp "^0.5.1" +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-each-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" + integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= + dependencies: + p-reduce "^1.0.0" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= +p-is-promise@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.0.0.tgz#7554e3d572109a87e1f3f53f6a7d85d1b194f4c5" + integrity sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg== + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -5845,6 +5432,11 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -5855,14 +5447,14 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== -package-hash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-2.0.0.tgz#78ae326c89e05a4d813b68601977af05c00d2a0d" - integrity sha1-eK4ybIngWk2BO2hgGXevBcANKg0= +package-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-3.0.0.tgz#50183f2d36c9e3e528ea0a8605dff57ce976f88e" + integrity sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA== dependencies: - graceful-fs "^4.1.11" + graceful-fs "^4.1.15" + hasha "^3.0.0" lodash.flattendeep "^4.4.0" - md5-hex "^2.0.0" release-zalgo "^1.0.0" package-json@^4.0.0: @@ -5882,16 +5474,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -5960,19 +5542,12 @@ path-dirname@^1.0.0: resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: +path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= @@ -5987,7 +5562,7 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.5, path-parse@^1.0.6: +path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== @@ -5997,15 +5572,6 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" @@ -6083,11 +5649,6 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pluralize@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== - pn@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" @@ -6117,20 +5678,15 @@ prepend-http@^1.0.1: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= - -pretty-format@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" - integrity sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw== +pretty-format@^24.0.0: + version "24.0.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0.tgz#cb6599fd73ac088e37ed682f61291e4678f48591" + integrity sha512-LszZaKG665djUcqg5ZQq+XzezHLKrxsA86ZABTozp+oNhkdqa+tG2dX4qa6ERl5c/sRDrAa3lHmwnvKoP+OG/g== dependencies: - ansi-regex "^3.0.0" + ansi-regex "^4.0.0" ansi-styles "^3.2.0" -private@^0.1.6, private@^0.1.8: +private@^0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== @@ -6145,13 +5701,13 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -prompts@^0.1.9: - version "0.1.14" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2" - integrity sha512-rxkyiE9YH6zAz/rZpywySLKkpaj0NMVyNw1qhsubdbjjSgcayjTShDreZGlFMcGSu5sab3bAKPfFk78PB90+8w== +prompts@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.0.1.tgz#201b3718b4276fb407f037db48c0029d6465245c" + integrity sha512-8lnEOSIGQbgbnO47+13S+H204L8ISogGulyi0/NNEFAQ9D1VMNTrJ9SBX2Ra03V4iPn/zt36HQMndRYkaPoWiQ== dependencies: - kleur "^2.0.1" - sisteransi "^0.1.1" + kleur "^3.0.0" + sisteransi "^1.0.0" prop-types@^15.6.2: version "15.6.2" @@ -6208,6 +5764,14 @@ pstree.remy@^1.1.6: resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.6.tgz#73a55aad9e2d95814927131fbf4dc1b62d259f47" integrity sha512-NdF35+QsqD7EgNEI5mkI/X+UwaxVEbQaz9f4IooEmMUv6ZPmlTQYGjBPJGgrlzNdjSvIy4MWMg6Q6vCgBO2K+w== +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" @@ -6238,15 +5802,6 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= -randomatic@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" - integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== - dependencies: - is-number "^4.0.0" - kind-of "^6.0.0" - math-random "^1.0.1" - range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" @@ -6292,14 +5847,6 @@ react@^16.4.2: prop-types "^15.6.2" scheduler "^0.11.2" -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" @@ -6316,15 +5863,6 @@ read-pkg-up@^4.0.0: find-up "^3.0.0" read-pkg "^3.0.0" -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" @@ -6384,7 +5922,7 @@ readdirp@^2.0.0: micromatch "^3.1.10" readable-stream "^2.0.2" -realpath-native@^1.0.0: +realpath-native@^1.0.0, realpath-native@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560" integrity sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g== @@ -6413,11 +5951,6 @@ regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== -regenerator-runtime@^0.12.0: - version "0.12.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" - integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== - regenerator-transform@^0.13.3: version "0.13.3" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb" @@ -6425,13 +5958,6 @@ regenerator-transform@^0.13.3: dependencies: private "^0.1.6" -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== - dependencies: - is-equal-shallow "^0.1.3" - regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -6440,6 +5966,15 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexp-tree@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.1.tgz#27b455f9b138ca2e84c090e9aff1ffe2a04d97fa" + integrity sha512-HwRjOquc9QOwKTgbxvZTcddS5mlNlwePMQ3NFL8broajMLD5CXDAqas8Y5yxJH5QtZp5iRor3YCILd5pz71Cgw== + dependencies: + cli-table3 "^0.5.0" + colors "^1.1.2" + yargs "^12.0.5" + regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" @@ -6501,18 +6036,11 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.5.2, repeat-string@^1.6.1: +repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - request-promise-core@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" @@ -6624,6 +6152,13 @@ rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: dependencies: glob "^7.0.5" +rimraf@^2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + rsvp@^3.3.3: version "3.6.2" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" @@ -6665,14 +6200,15 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sane@^2.0.0: - version "2.5.2" - resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa" - integrity sha1-tNwYYcIbQn6SlQej51HiosuKs/o= +sane@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-3.1.0.tgz#995193b7dc1445ef1fe41ddfca2faf9f111854c6" + integrity sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q== dependencies: anymatch "^2.0.0" capture-exit "^1.2.0" exec-sh "^0.2.0" + execa "^1.0.0" fb-watchman "^2.0.0" micromatch "^3.1.4" minimist "^1.1.1" @@ -6823,15 +6359,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= -sisteransi@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz#5431447d5f7d1675aac667ccd0b865a4994cb3ce" - integrity sha512-PmGOd02bM9YO5ifxpw36nrNMBTptEtfRl4qUYl9SndkolplkrZZOW7PGHjrZL53QvMVj9nQ+TKqUnRsw4tJa4g== - -slash@^1.0.0: +sisteransi@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.0.tgz#77d9622ff909080f1c19e5f4a1df0c1b0a27b88c" + integrity sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ== slash@^2.0.0: version "2.0.0" @@ -6895,13 +6426,6 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== - dependencies: - source-map "^0.5.6" - source-map-support@^0.5.1, source-map-support@^0.5.6, source-map-support@^0.5.9: version "0.5.9" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" @@ -6915,7 +6439,7 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -7105,18 +6629,11 @@ strip-ansi@^5.0.0: dependencies: ansi-regex "^4.0.0" -strip-bom@3.0.0, strip-bom@^3.0.0: +strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -7167,20 +6684,20 @@ supports-color@^2.0.0: resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= -supports-color@^3.1.2: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= - dependencies: - has-flag "^1.0.0" - -supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: +supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" +supports-color@^6.0.0, supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + symbol-observable@^1.0.2, symbol-observable@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" @@ -7221,17 +6738,6 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" -test-exclude@^4.2.1: - version "4.2.3" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20" - integrity sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA== - dependencies: - arrify "^1.0.1" - micromatch "^2.3.11" - object-assign "^4.1.0" - read-pkg-up "^1.0.1" - require-main-filename "^1.0.1" - test-exclude@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.0.0.tgz#cdce7cece785e0e829cd5c2b27baf18bc583cfb7" @@ -7242,6 +6748,16 @@ test-exclude@^5.0.0: read-pkg-up "^4.0.0" require-main-filename "^1.0.1" +test-exclude@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1" + integrity sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA== + dependencies: + arrify "^1.0.1" + minimatch "^3.0.4" + read-pkg-up "^4.0.0" + require-main-filename "^1.0.1" + text-encoding@^0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" @@ -7279,11 +6795,6 @@ tmpl@1.0.x: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -7375,7 +6886,7 @@ trunc-text@1.0.1: resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" integrity sha1-WPh22KxZsiS3mDS7R4uGVuaWIrU= -tslib@^1.9.0: +tslib@^1.9.0, tslib@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== @@ -7722,7 +7233,16 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write-file-atomic@^2.0.0, write-file-atomic@^2.1.0: +write-file-atomic@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" + integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write-file-atomic@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== @@ -7731,6 +7251,15 @@ write-file-atomic@^2.0.0, write-file-atomic@^2.1.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" +write-file-atomic@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9" + integrity sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" @@ -7780,10 +7309,10 @@ xtend@^4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= +"y18n@^3.2.1 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== yallist@^2.1.2: version "2.1.2" @@ -7795,30 +7324,31 @@ yallist@^3.0.0, yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== -yargs-parser@^9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" - integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== dependencies: - camelcase "^4.1.0" + camelcase "^5.0.0" + decamelize "^1.2.0" -yargs@11.1.0, yargs@^11.0.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" - integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A== +yargs@^12.0.2, yargs@^12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== dependencies: cliui "^4.0.0" - decamelize "^1.1.1" - find-up "^2.1.0" + decamelize "^1.2.0" + find-up "^3.0.0" get-caller-file "^1.0.1" - os-locale "^2.0.0" + os-locale "^3.0.0" require-directory "^2.1.1" require-main-filename "^1.0.1" set-blocking "^2.0.0" string-width "^2.0.0" which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^9.0.2" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" zen-observable-ts@^0.8.13: version "0.8.13" @@ -7827,6 +7357,13 @@ zen-observable-ts@^0.8.13: dependencies: zen-observable "^0.8.0" +zen-observable-ts@^0.8.15: + version "0.8.15" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.15.tgz#6cf7df6aa619076e4af2f707ccf8a6290d26699b" + integrity sha512-sXKPWiw6JszNEkRv5dQ+lQCttyjHM2Iks74QU5NP8mMPS/NrzTlHDr780gf/wOBqmHkPO6NCLMlsa+fAQ8VE8w== + dependencies: + zen-observable "^0.8.0" + zen-observable@^0.8.0: version "0.8.11" resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.11.tgz#d3415885eeeb42ee5abb9821c95bb518fcd6d199" From ad51372228ad0c3ebbe724ae64bca5bd99a13700 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Thu, 7 Feb 2019 15:57:41 +0100 Subject: [PATCH 329/554] Upgraded neo4j-graphql-js --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 5768328c9..5a9dd34be 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "lodash": "~4.17.11", "ms": "~2.1.1", "neo4j-driver": "~1.7.2", - "neo4j-graphql-js": "~2.2.0", + "neo4j-graphql-js": "~2.3.0", "node-fetch": "~2.3.0", "npm-run-all": "~4.1.5", "passport": "~0.4.0", diff --git a/yarn.lock b/yarn.lock index 7b7041e87..bd30a01c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5002,10 +5002,10 @@ neo4j-driver@^1.7.2, neo4j-driver@~1.7.2: text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-graphql-js@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.2.0.tgz#f0d934b376e9476ef2aa1600e86eb1f8a74c10a2" - integrity sha512-DyYRE6wAVPKxDAHkRwiZmNYx+Vv3KVFQp2Ul1Ay4f2ahW52mWzwMFe/Rlbau3phFYSZZAeaRCT7XLBy++sg/cQ== +neo4j-graphql-js@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.3.0.tgz#d59193052a27d026a02911bd2686c531bde2caa4" + integrity sha512-rUwi1HRV8DSRuGn6j4yZw11t3NpHEUU9Np6CZf06GCnBEzYVolzzpuTXvUe1RSvD9vyDzQiH1O0uioEg+jp5cQ== dependencies: graphql "^14.0.2" lodash "^4.17.11" From b70eea891995a390481e6a9a68fc1e5bc3d6e88e Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 8 Feb 2019 09:49:22 +0100 Subject: [PATCH 330/554] Fixed eslint --- src/server.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/server.js b/src/server.js index e94ad9a77..1d85cbd00 100644 --- a/src/server.js +++ b/src/server.js @@ -1,6 +1,5 @@ import { GraphQLServer } from 'graphql-yoga' -import { makeExecutableSchema } from 'apollo-server' -import { augmentSchema, makeAugmentedSchema } from 'neo4j-graphql-js' +import { makeAugmentedSchema } from 'neo4j-graphql-js' import { typeDefs, resolvers } from './graphql-schema' import express from 'express' import dotenv from 'dotenv' From 871d8318ce863cd2bd1b3bec4f5608eb3d8635e0 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 8 Feb 2019 09:50:28 +0100 Subject: [PATCH 331/554] Pinned dependencies and upgraded neo4j-graphql-js to 2.3.1 --- package.json | 20 ++++++++++---------- yarn.lock | 26 +++++++++++++------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 5a9dd34be..d81f2444c 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", "cross-env": "~5.2.0", - "date-fns": "^2.0.0-alpha.26", + "date-fns": "2.0.0-alpha.26", "dotenv": "~6.2.0", "faker": "~4.1.0", "graphql": "~14.1.1", @@ -56,7 +56,7 @@ "lodash": "~4.17.11", "ms": "~2.1.1", "neo4j-driver": "~1.7.2", - "neo4j-graphql-js": "~2.3.0", + "neo4j-graphql-js": "~2.3.1", "node-fetch": "~2.3.0", "npm-run-all": "~4.1.5", "passport": "~0.4.0", @@ -68,26 +68,26 @@ }, "devDependencies": { "@babel/cli": "~7.2.3", - "@babel/core": "^7.2.2", + "@babel/core": "~7.2.2", "@babel/node": "~7.2.2", "@babel/preset-env": "~7.3.1", "@babel/register": "~7.0.0", "apollo-server-testing": "~2.4.0", - "babel-core": "^7.0.0-0", + "babel-core": "~7.0.0-0", "babel-eslint": "~10.0.1", - "babel-jest": "^24.1.0", + "babel-jest": "~24.1.0", "chai": "~4.2.0", "eslint": "~5.13.0", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.16.0", - "eslint-plugin-jest": "^22.2.2", + "eslint-plugin-jest": "~22.2.2", "eslint-plugin-node": "~8.0.1", "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", - "graphql-request": "^1.8.2", - "jest": "^24.1.0", + "graphql-request": "~1.8.2", + "jest": "~24.1.0", "nodemon": "~1.18.9", - "nyc": "^13.2.0", - "supertest": "^3.4.2" + "nyc": "~13.2.0", + "supertest": "~3.4.2" } } diff --git a/yarn.lock b/yarn.lock index bd30a01c1..350d53783 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38,7 +38,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.1.0", "@babel/core@^7.2.2": +"@babel/core@^7.1.0", "@babel/core@~7.2.2": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687" integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw== @@ -1455,7 +1455,7 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== -babel-core@^7.0.0-0: +babel-core@~7.0.0-0: version "7.0.0-bridge.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== @@ -1472,7 +1472,7 @@ babel-eslint@~10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-jest@^24.1.0: +babel-jest@^24.1.0, babel-jest@~24.1.0: version "24.1.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.1.0.tgz#441e23ef75ded3bd547e300ac3194cef87b55190" integrity sha512-MLcagnVrO9ybQGLEfZUqnOzv36iQzU7Bj4elm39vCukumLVSfoX+tRy3/jW7lUKc7XdpRmB/jech6L/UCsSZjw== @@ -2173,7 +2173,7 @@ data-urls@^1.0.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" -date-fns@^2.0.0-alpha.26: +date-fns@2.0.0-alpha.26: version "2.0.0-alpha.26" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.26.tgz#e46afd73a2b50e0359446309ee7cb631d7467227" integrity sha512-UAptCZ53MVimUFR8MXTyHED51AVGIqFlBfWgiS/KIoSYiJGrWScx4PYQVNSWfK2Js+43OlokCW1ttnexBTJ5Bg== @@ -2562,7 +2562,7 @@ eslint-plugin-import@~2.16.0: read-pkg-up "^2.0.0" resolve "^1.9.0" -eslint-plugin-jest@^22.2.2: +eslint-plugin-jest@~22.2.2: version "22.2.2" resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.2.2.tgz#2a80d70a20c27dfb1503a6f32cdcb647fe5476df" integrity sha512-hnWgh9o39VJfz6lJEyQJdTW7dN2yynlGkmPOlU/oMHh+d7WVMsJP1GeDTB520VCDljEdKExCwD5IBpQIUl4mJg== @@ -3250,7 +3250,7 @@ graphql-playground-middleware-lambda@1.7.12: dependencies: graphql-playground-html "1.6.12" -graphql-request@^1.8.2: +graphql-request@~1.8.2: version "1.8.2" resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.8.2.tgz#398d10ae15c585676741bde3fc01d5ca948f8fbe" integrity sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg== @@ -4365,7 +4365,7 @@ jest-worker@^24.0.0: merge-stream "^1.0.1" supports-color "^6.1.0" -jest@^24.1.0: +jest@~24.1.0: version "24.1.0" resolved "https://registry.yarnpkg.com/jest/-/jest-24.1.0.tgz#b1e1135caefcf2397950ecf7f90e395fde866fd2" integrity sha512-+q91L65kypqklvlRFfXfdzUKyngQLOcwGhXQaLmVHv+d09LkNXuBuGxlofTFW42XMzu3giIcChchTsCNUjQ78A== @@ -5002,10 +5002,10 @@ neo4j-driver@^1.7.2, neo4j-driver@~1.7.2: text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-graphql-js@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.3.0.tgz#d59193052a27d026a02911bd2686c531bde2caa4" - integrity sha512-rUwi1HRV8DSRuGn6j4yZw11t3NpHEUU9Np6CZf06GCnBEzYVolzzpuTXvUe1RSvD9vyDzQiH1O0uioEg+jp5cQ== +neo4j-graphql-js@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.3.1.tgz#9a5de7e312594d63481e947a0cbe4e08b05ffed3" + integrity sha512-9DExWXD2vFdDJOmqorT1ygFOUEos7KF8KyF8Wt3jYxejWUuq+a5fAFBu7+YDH8QbvA23paKPEX0Pn1nS+Q5C1A== dependencies: graphql "^14.0.2" lodash "^4.17.11" @@ -5192,7 +5192,7 @@ nwsapi@^2.0.7: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016" integrity sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ== -nyc@^13.2.0: +nyc@~13.2.0: version "13.2.0" resolved "https://registry.yarnpkg.com/nyc/-/nyc-13.2.0.tgz#6a4a4b3f5f97b63ab491c665567557debcfa23d6" integrity sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ== @@ -6671,7 +6671,7 @@ superagent@^3.8.3: qs "^6.5.1" readable-stream "^2.3.5" -supertest@^3.4.2: +supertest@~3.4.2: version "3.4.2" resolved "https://registry.yarnpkg.com/supertest/-/supertest-3.4.2.tgz#bad7de2e43d60d27c8caeb8ab34a67c8a5f71aad" integrity sha512-WZWbwceHUo2P36RoEIdXvmqfs47idNNZjCuJOqDz6rvtkk8ym56aU5oglORCpPeXGxT7l9rkJ41+O1lffQXYSA== From c390856027d867389549bf1766a412460e568f1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 11 Feb 2019 04:29:23 +0000 Subject: [PATCH 332/554] Bump nodemon from 1.18.9 to 1.18.10 Bumps [nodemon](https://github.com/remy/nodemon) from 1.18.9 to 1.18.10. - [Release notes](https://github.com/remy/nodemon/releases) - [Commits](https://github.com/remy/nodemon/compare/v1.18.9...v1.18.10) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 70 ++++++++++++++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index d81f2444c..5cb2d90ed 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "eslint-plugin-standard": "~4.0.0", "graphql-request": "~1.8.2", "jest": "~24.1.0", - "nodemon": "~1.18.9", + "nodemon": "~1.18.10", "nyc": "~13.2.0", "supertest": "~3.4.2" } diff --git a/yarn.lock b/yarn.lock index 350d53783..110916c3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1387,7 +1387,7 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== -async-each@^1.0.0: +async-each@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" integrity sha1-GdOGodntxufByF04iu28xW0zYC0= @@ -1615,7 +1615,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^2.3.0, braces@^2.3.1: +braces@^2.3.1, braces@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== @@ -1825,25 +1825,24 @@ cheerio@~1.0.0-rc.2: lodash "^4.15.0" parse5 "^3.0.1" -chokidar@^2.0.3, chokidar@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" - integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== +chokidar@^2.0.3, chokidar@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.0.tgz#5fcb70d0b28ebe0867eb0f09d5f6a08f29a1efa0" + integrity sha512-5t6G2SH8eO6lCvYOoUpaRnF5Qfd//gd7qJAkwRUw9qlGVkiQ13uwQngqbWWaurOsaAm9+kUGbITADxt6H0XFNQ== dependencies: anymatch "^2.0.0" - async-each "^1.0.0" - braces "^2.3.0" + async-each "^1.0.1" + braces "^2.3.2" glob-parent "^3.1.0" - inherits "^2.0.1" + inherits "^2.0.3" is-binary-path "^1.0.0" is-glob "^4.0.0" - lodash.debounce "^4.0.8" - normalize-path "^2.1.1" + normalize-path "^3.0.0" path-is-absolute "^1.0.0" - readdirp "^2.0.0" - upath "^1.0.5" + readdirp "^2.2.1" + upath "^1.1.0" optionalDependencies: - fsevents "^1.2.2" + fsevents "^1.2.7" chownr@^1.1.1: version "1.1.1" @@ -2192,14 +2191,7 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^4.0.1, debug@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" - integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== - dependencies: - ms "^2.1.1" - -debug@^4.1.1: +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -3061,7 +3053,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.2, fsevents@^1.2.3: +fsevents@^1.2.3: version "1.2.4" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== @@ -3069,6 +3061,14 @@ fsevents@^1.2.2, fsevents@^1.2.3: nan "^2.9.2" node-pre-gyp "^0.10.0" +fsevents@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" + integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw== + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + function-bind@^1.0.2, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -4656,11 +4656,6 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= - lodash.escaperegexp@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" @@ -5077,12 +5072,12 @@ node-releases@^1.0.5: dependencies: semver "^5.3.0" -nodemon@~1.18.9: - version "1.18.9" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.9.tgz#90b467efd3b3c81b9453380aeb2a2cba535d0ead" - integrity sha512-oj/eEVTEI47pzYAjGkpcNw0xYwTl4XSTUQv2NPQI6PpN3b75PhpuYk3Vb3U80xHCyM2Jm+1j68ULHXl4OR3Afw== +nodemon@~1.18.10: + version "1.18.10" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.10.tgz#3ba63f64eb4c283cf3e4f75f30817e9d4f393afe" + integrity sha512-we51yBb1TfEvZamFchRgcfLbVYgg0xlGbyXmOtbBzDwxwgewYS/YbZ5tnlnsH51+AoSTTsT3A2E/FloUbtH8cQ== dependencies: - chokidar "^2.0.4" + chokidar "^2.1.0" debug "^3.1.0" ignore-by-default "^1.0.1" minimatch "^3.0.4" @@ -5125,6 +5120,11 @@ normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + npm-bundled@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" @@ -5913,7 +5913,7 @@ readable-stream@^3.0.6: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdirp@^2.0.0: +readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== @@ -7001,7 +7001,7 @@ unzip-response@^2.0.1: resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= -upath@^1.0.5: +upath@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== From 6d86769af615bcab31652e9e91adec9b60593f46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 12 Feb 2019 17:58:12 +0000 Subject: [PATCH 333/554] Bump graphql-shield from 5.1.2 to 5.1.3 Bumps [graphql-shield](https://github.com/maticzav/graphql-shield) from 5.1.2 to 5.1.3. - [Release notes](https://github.com/maticzav/graphql-shield/releases) - [Commits](https://github.com/maticzav/graphql-shield/compare/v5.1.2...v5.1.3) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 152 +++++---------------------------------------------- 2 files changed, 16 insertions(+), 138 deletions(-) diff --git a/package.json b/package.json index 5cb2d90ed..b65292acd 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "graphql-custom-directives": "~0.2.14", "graphql-iso-date": "~3.6.1", "graphql-middleware": "~3.0.2", - "graphql-shield": "~5.1.2", + "graphql-shield": "~5.1.3", "graphql-tag": "~2.10.1", "graphql-yoga": "~1.17.4", "jsonwebtoken": "~8.4.0", diff --git a/yarn.lock b/yarn.lock index 110916c3e..e89d2f383 100644 --- a/yarn.lock +++ b/yarn.lock @@ -935,11 +935,6 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" -ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= - ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" @@ -960,11 +955,6 @@ ansi-regex@^4.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1496,15 +1486,6 @@ babel-plugin-jest-hoist@^24.1.0: resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.1.0.tgz#dfecc491fb15e2668abbd690a697a8fd1411a7f8" integrity sha512-gljYrZz8w1b6fJzKcsfKsipSru2DU2DmQ39aB6nV3xQ0DDv3zpIzKGortA5gknrhNnPN8DweaEgrnZdmbGmhnw== -babel-polyfill@6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" - integrity sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0= - dependencies: - babel-runtime "^6.22.0" - core-js "^2.4.0" - regenerator-runtime "^0.10.0" - babel-preset-jest@^24.1.0: version "24.1.0" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.1.0.tgz#83bc564fdcd4903641af65ec63f2f5de6b04132e" @@ -1513,7 +1494,7 @@ babel-preset-jest@^24.1.0: "@babel/plugin-syntax-object-rest-spread" "^7.0.0" babel-plugin-jest-hoist "^24.1.0" -babel-runtime@^6.22.0, babel-runtime@^6.26.0: +babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= @@ -1769,17 +1750,6 @@ chai@~4.2.0: pathval "^1.1.0" type-detect "^4.0.5" -chalk@1.1.3, chalk@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" @@ -1798,11 +1768,6 @@ chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chardet@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" - integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= - chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -2424,13 +2389,6 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= - dependencies: - iconv-lite "~0.4.13" - end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" @@ -2492,7 +2450,7 @@ escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -2825,15 +2783,6 @@ extend@^3.0.0, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" - integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== - dependencies: - chardet "^0.4.0" - iconv-lite "^0.4.17" - tmp "^0.0.33" - external-editor@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" @@ -3257,13 +3206,13 @@ graphql-request@~1.8.2: dependencies: cross-fetch "2.2.2" -graphql-shield@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-5.1.2.tgz#fd8b9cb263a06caae8f4d026cc8c6d07a155832a" - integrity sha512-imBBsi2HlbRN+K8ZAp1OCrlp7uosPvpmO0Hp2Qef5sPEdZ6w24goctLIE90Jv76cCDtaYTMVIYBtTHeuL+2gJg== +graphql-shield@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-5.1.3.tgz#c3301842775c22eb10ada21d42c6b87f3d6b7428" + integrity sha512-UwjUBhSaHXKh+L9FFi2nHV7GLcWbvPqbXpQ3I6Kz/u1MMxo3r1DBFlabeTgnrV4PLeppOsQPSX7t6Wyf9/CEfQ== dependencies: + lightercollective "^0.2.0" object-hash "^1.3.1" - opencollective "1.0.3" graphql-subscriptions@^0.5.8: version "0.5.8" @@ -3375,13 +3324,6 @@ har-validator@~5.1.0: ajv "^6.5.5" har-schema "^2.0.0" -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3530,7 +3472,7 @@ iconv-lite@0.4.23: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -3618,25 +3560,6 @@ ini@^1.3.4, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== -inquirer@3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" - integrity sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c= - dependencies: - ansi-escapes "^1.1.0" - chalk "^1.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.0.1" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rx "^4.1.0" - string-width "^2.0.0" - strip-ansi "^3.0.0" - through "^2.3.6" - inquirer@^6.1.0: version "6.2.1" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52" @@ -4606,6 +4529,11 @@ libphonenumber-js@^1.6.4: semver-compare "^1.0.0" xml2js "^0.4.17" +lightercollective@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/lightercollective/-/lightercollective-0.2.0.tgz#4f10cd53ec50405d7da03ee81233067993ca8e67" + integrity sha512-zgFCDiUQQOjislj+1tX7zDxZbgVB6Qi9BSmos41oZcxHdkTveVDzHW0Y3TisNZCWuBN1h0e0xrjkNoLtPkLsUg== + linkifyjs@~2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-2.1.8.tgz#2bee2272674dc196cce3740b8436c43df2162f9c" @@ -4711,7 +4639,7 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.11: +lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.11: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -4887,7 +4815,7 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@1.2.0, minimist@^1.1.1, minimist@^1.2.0: +minimist@^1.1.1, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= @@ -5011,14 +4939,6 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -node-fetch@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" - integrity sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ= - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - node-fetch@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" @@ -5299,26 +5219,6 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -opencollective@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/opencollective/-/opencollective-1.0.3.tgz#aee6372bc28144583690c3ca8daecfc120dd0ef1" - integrity sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE= - dependencies: - babel-polyfill "6.23.0" - chalk "1.1.3" - inquirer "3.0.6" - minimist "1.2.0" - node-fetch "1.6.3" - opn "4.0.2" - -opn@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" - integrity sha1-erwi5kTf9jsKltWrfyeQwPAavJU= - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" - optimism@^0.6.9: version "0.6.9" resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.6.9.tgz#19258ff8b3be0cea29ac35f06bff818e026e30bb" @@ -5616,18 +5516,6 @@ pify@^3.0.0: resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - pirates@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.0.tgz#850b18781b4ac6ec58a43c9ed9ec5fe6796addbd" @@ -5941,11 +5829,6 @@ regenerate@^1.4.0: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== -regenerator-runtime@^0.10.0: - version "0.10.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" - integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= - regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" @@ -6679,11 +6562,6 @@ supertest@~3.4.2: methods "^1.1.2" superagent "^3.8.3" -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" From 4f8f0debbee1b766aa7c49d8212f97bc1d66ae05 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 13 Feb 2019 16:02:25 +0100 Subject: [PATCH 334/554] Added findPost query --- src/schema.graphql | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/schema.graphql b/src/schema.graphql index 55f23d5ca..95e7b3d48 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -1,6 +1,16 @@ type Query { isLoggedIn: Boolean! statistics: Statistics! + findPosts(filter: String!, limit: Int = 10): [Post]! @cypher( + statement: """ + CALL db.index.fulltext.queryNodes( + 'postTitleAndContent', $filter+'~') + YIELD node AS node + RETURN node + ORDER BY node.createdAt DESC + LIMIT $limit + """ + ) } type Mutation { login(email: String!, password: String!): LoggedInUser From 56936c403831b9b624711ca60c6a1a94d6121b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 14 Feb 2019 16:05:30 +0100 Subject: [PATCH 335/554] Setup a routine how to create indices initially In order to create the indices programmatically we need to change the default password for security concerns. To create the user we need to start the neo4j database. So I decided to provide a bash script that let us do it once the container are started. In production we must change the NEO4J_PASSWORD. --- README.md | 2 +- docker-compose.override.yml | 7 +++++++ docker-compose.prod.yml | 9 +++++++++ docker-compose.yml | 7 ------- neo4j/Dockerfile | 1 + neo4j/migrate.sh | 4 ++++ src/bootstrap/neo4j.js | 2 +- src/graphql-schema.js | 2 +- src/schema.graphql | 2 +- 9 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 docker-compose.prod.yml create mode 100755 neo4j/migrate.sh diff --git a/README.md b/README.md index 1b12562d2..b1363a293 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ _.env_ ```yaml NEO4J_URI=bolt://localhost:7687 -NEO4J_USER=neo4j +NEO4J_USERNAME=neo4j NEO4J_PASSWORD=letmein ``` diff --git a/docker-compose.override.yml b/docker-compose.override.yml index ef7d52c7e..b972c31f6 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -11,6 +11,13 @@ services: - /nitro-backend/node_modules command: yarn run dev neo4j: + environment: + - NEO4J_AUTH=none ports: - 7687:7687 - 7474:7474 + volumes: + - neo4j-data:/data + +volumes: + neo4j-data: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 000000000..c4f5dc4f5 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,9 @@ +version: "3.7" + +services: + neo4j: + environment: + - NEO4J_PASSWORD=letmein + backend: + environment: + - NEO4J_PASSWORD=letmein diff --git a/docker-compose.yml b/docker-compose.yml index 6905bb893..1e8c9158c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,14 +27,7 @@ services: context: neo4j networks: - hc-network - volumes: - - neo4j-data:/data - environment: - - NEO4J_AUTH=none networks: hc-network: name: hc-network - -volumes: - neo4j-data: diff --git a/neo4j/Dockerfile b/neo4j/Dockerfile index cb7fd228f..f6e71811b 100644 --- a/neo4j/Dockerfile +++ b/neo4j/Dockerfile @@ -1,2 +1,3 @@ FROM neo4j:3.5.0 RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.1/apoc-3.5.0.1-all.jar -P plugins/ +COPY migrate.sh /usr/local/bin/migrate diff --git a/neo4j/migrate.sh b/neo4j/migrate.sh new file mode 100755 index 000000000..30a58c306 --- /dev/null +++ b/neo4j/migrate.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +echo "CALL dbms.security.changePassword('${NEO4J_PASSWORD}');" | cypher-shell --username neo4j --password neo4j +echo 'CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);' | cypher-shell --username neo4j --password $NEO4J_PASSWORD diff --git a/src/bootstrap/neo4j.js b/src/bootstrap/neo4j.js index 766c12065..929e62f23 100644 --- a/src/bootstrap/neo4j.js +++ b/src/bootstrap/neo4j.js @@ -9,7 +9,7 @@ export default function () { driver = neo4j.driver( process.env.NEO4J_URI || 'bolt://localhost:7687', neo4j.auth.basic( - process.env.NEO4J_USER || 'neo4j', + process.env.NEO4J_USERNAME || 'neo4j', process.env.NEO4J_PASSWORD || 'neo4j' ) ) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 8b5f369e0..c525d67d7 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -34,7 +34,7 @@ export const query = (cypher, session) => { }) }) } -const queryOne = (cypher, session) => { +export const queryOne = (cypher, session) => { return new Promise((resolve, reject) => { query(cypher, session) .then(res => { diff --git a/src/schema.graphql b/src/schema.graphql index 95e7b3d48..472b345d7 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -4,7 +4,7 @@ type Query { findPosts(filter: String!, limit: Int = 10): [Post]! @cypher( statement: """ CALL db.index.fulltext.queryNodes( - 'postTitleAndContent', $filter+'~') + 'full_text_search', $filter+'~') YIELD node AS node RETURN node ORDER BY node.createdAt DESC From d579d19ad24764f0de3f6ab87da809a0b2e8bbef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 14 Feb 2019 17:30:17 +0100 Subject: [PATCH 336/554] Modify migrate for development environment --- neo4j/migrate.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/neo4j/migrate.sh b/neo4j/migrate.sh index 30a58c306..cdb9ec46c 100755 --- a/neo4j/migrate.sh +++ b/neo4j/migrate.sh @@ -1,4 +1,8 @@ #!/usr/bin/env bash set -e -echo "CALL dbms.security.changePassword('${NEO4J_PASSWORD}');" | cypher-shell --username neo4j --password neo4j -echo 'CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);' | cypher-shell --username neo4j --password $NEO4J_PASSWORD +if [[ -z "${NEO4J_PASSWORD}" ]]; then + echo 'CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);' | cypher-shell +else + echo "CALL dbms.security.changePassword('${NEO4J_PASSWORD}');" | cypher-shell --username neo4j --password neo4j + echo 'CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);' | cypher-shell --username neo4j --password $NEO4J_PASSWORD +fi From e87dae4efdb2b7b473239d03ff85802063cd50bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 00:16:43 +0100 Subject: [PATCH 337/554] Provide README --- README.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b1363a293..7f4676a6c 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,15 @@ > This Prototype tries to resolve the biggest hurdle of connecting > our services together. This is not possible in a sane way using -> our current approach. -> -> With this Prototype we can explore using the combination of +> our current approach. +> +> With this Prototype we can explore using the combination of > GraphQL and the Neo4j Graph Database for achieving the connected > nature of a social graph with better development experience as we > do not need to connect data by our own any more through weird table > structures etc. -> +> > #### Advantages: > - easer data structure > - better connected data @@ -19,10 +19,10 @@ > - more performant and better to understand API > - better API client that uses caching > -> We still need to evaluate the drawbacks and estimate the development +> We still need to evaluate the drawbacks and estimate the development > cost of such an approach -## How to get in touch +## How to get in touch Connect with other developers over [Discord](https://discord.gg/6ub73U3) ## Quick Start @@ -35,6 +35,10 @@ Before you start, fork the repository using the fork button above, then clone it Run: ```sh docker-compose up + +# create indices etc. +docker-compose exec neo4j migrate + # if you want seed data # open another terminal and run docker-compose exec backend yarn run db:seed @@ -116,7 +120,7 @@ Just set `MOCK=true` inside `.env` or pass it on application start. ## Seed and Reset the Database -Optionally you can seed the GraphQL service by executing mutations that +Optionally you can seed the GraphQL service by executing mutations that will write sample data to the database: ```bash @@ -152,5 +156,5 @@ npm run test - [x] check if sorting is working - [x] check if pagination is working - [ ] check if upload is working (using graphql-yoga?) -- [x] evaluate middleware +- [x] evaluate middleware - [ ] ignore Posts and Comments by blacklisted Users From 2715f940b5e787c2e4e3f46b057ad8412b1631ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 00:50:37 +0100 Subject: [PATCH 338/554] Sketch a test --- src/schema.graphql.spec.js | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/schema.graphql.spec.js diff --git a/src/schema.graphql.spec.js b/src/schema.graphql.spec.js new file mode 100644 index 000000000..304fdf557 --- /dev/null +++ b/src/schema.graphql.spec.js @@ -0,0 +1,51 @@ +import { request } from 'graphql-request' +import { create, cleanDatabase } from './seed/factories' +import { host } from './jest/helpers' + +describe('filter for searchQuery', () => { + const query = (searchQuery) => { + return ` + { + findPosts(filter: "${searchQuery}", limit: 10) { + title + } + } + ` + } + + describe('given some posts', () => { + beforeEach(async () => { + await create('post', { + title: 'Hamlet', + content: 'To be, or not to be: that is the question' + }) + await create('post', { + title: 'Threepenny Opera', + content: 'And the shark, it has teeth, And it wears them in the face.' + }) + }) + + afterEach(async () => { + await cleanDatabase() + }) + + describe('result set', () => { + describe('includes posts if search term', () => { + it('matches title', async () => { + const data = await request(host, query('Hamlet')) + expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) + }) + + it('matches a part of the title', async () => { + const data = await request(host, query('let')) + expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) + }) + + it('matches a part of the content', async () => { + const data = await request(host, query('shark')) + expect(data).toEqual({findPosts: [{title: 'Threepenny Opera'}]}) + }) + }) + }) + }) +}) From 6b5d329759fc6958a05311796fda02decb3a5cf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 01:46:33 +0100 Subject: [PATCH 339/554] Implement test for search @appinteractive could you have a look if sanitization of search queries work? I created a test and I see "unterminated string" exceptions. This is not what we want! All user input should be escaped. --- src/schema.graphql | 3 +-- src/schema.graphql.spec.js | 18 +++++++++++++++--- src/seed/factories/index.js | 3 ++- src/seed/factories/posts.js | 22 ++++++++++++++++++++++ 4 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 src/seed/factories/posts.js diff --git a/src/schema.graphql b/src/schema.graphql index 472b345d7..ee519fff3 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -3,8 +3,7 @@ type Query { statistics: Statistics! findPosts(filter: String!, limit: Int = 10): [Post]! @cypher( statement: """ - CALL db.index.fulltext.queryNodes( - 'full_text_search', $filter+'~') + CALL db.index.fulltext.queryNodes('full_text_search', $filter+'~') YIELD node AS node RETURN node ORDER BY node.createdAt DESC diff --git a/src/schema.graphql.spec.js b/src/schema.graphql.spec.js index 304fdf557..5fdc67d0c 100644 --- a/src/schema.graphql.spec.js +++ b/src/schema.graphql.spec.js @@ -21,7 +21,7 @@ describe('filter for searchQuery', () => { }) await create('post', { title: 'Threepenny Opera', - content: 'And the shark, it has teeth, And it wears them in the face.' + content: 'And the shark, it has teeth, And it wears them in the face.' }) }) @@ -29,6 +29,18 @@ describe('filter for searchQuery', () => { await cleanDatabase() }) + describe('sanitization', () => { + it('escapes cypher statement', async () => { + await request(host, query(`''); + MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r; + CALL db.index.fulltext.queryNodes('full_text_search', '' + `)) + console.log(data) + const data = await request(host, query('the')) + expect(data).toEqual({findPosts: [{title: 'Hamlet'}, {title: 'Threepenny Opera'}]}) + }) + }) + describe('result set', () => { describe('includes posts if search term', () => { it('matches title', async () => { @@ -36,8 +48,8 @@ describe('filter for searchQuery', () => { expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) }) - it('matches a part of the title', async () => { - const data = await request(host, query('let')) + it('matches mistyped title', async () => { + const data = await request(host, query('amlet')) expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) }) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index e62e98869..9c6d4116c 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -20,7 +20,8 @@ const client = new ApolloClient({ const driver = neo4j().getDriver() const builders = { - 'user': require('./users.js').default + 'user': require('./users.js').default, + 'post': require('./posts.js').default } const buildMutation = (model, parameters) => { diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js new file mode 100644 index 000000000..366b64155 --- /dev/null +++ b/src/seed/factories/posts.js @@ -0,0 +1,22 @@ +import faker from 'faker' + +export default function (params) { + const { + id = Array.from({length: 3}, () => faker.lorem.word()).join(''), + title = faker.lorem.sentence(), + content = Array.from({length: 10}, () => faker.lorem.sentence()).join(' ') + } = params + return ` + mutation { + ${id}: CreatePost( + id: "${id}", + title: "${title}", + content: "${content}", + image: "https://picsum.photos/1280/1024?image=424", + visibility: public, + disabled: false, + deleted: false + ) { title } + } + ` +} From cadb309ecfadfa671fb1befd47f1eaf661d7c6c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 02:05:08 +0100 Subject: [PATCH 340/554] Fix lint --- src/schema.graphql.spec.js | 13 ++++++------- src/seed/factories/posts.js | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/schema.graphql.spec.js b/src/schema.graphql.spec.js index 5fdc67d0c..12abdd3c2 100644 --- a/src/schema.graphql.spec.js +++ b/src/schema.graphql.spec.js @@ -16,11 +16,11 @@ describe('filter for searchQuery', () => { describe('given some posts', () => { beforeEach(async () => { await create('post', { - title: 'Hamlet', + title: 'Hamlet', content: 'To be, or not to be: that is the question' }) await create('post', { - title: 'Threepenny Opera', + title: 'Threepenny Opera', content: 'And the shark, it has teeth, And it wears them in the face.' }) }) @@ -35,9 +35,8 @@ describe('filter for searchQuery', () => { MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r; CALL db.index.fulltext.queryNodes('full_text_search', '' `)) - console.log(data) const data = await request(host, query('the')) - expect(data).toEqual({findPosts: [{title: 'Hamlet'}, {title: 'Threepenny Opera'}]}) + expect(data).toEqual({ findPosts: [{ title: 'Hamlet' }, { title: 'Threepenny Opera' }] }) }) }) @@ -45,17 +44,17 @@ describe('filter for searchQuery', () => { describe('includes posts if search term', () => { it('matches title', async () => { const data = await request(host, query('Hamlet')) - expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) + expect(data).toEqual({ findPosts: [{ title: 'Hamlet' }] }) }) it('matches mistyped title', async () => { const data = await request(host, query('amlet')) - expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) + expect(data).toEqual({ findPosts: [{ title: 'Hamlet' }] }) }) it('matches a part of the content', async () => { const data = await request(host, query('shark')) - expect(data).toEqual({findPosts: [{title: 'Threepenny Opera'}]}) + expect(data).toEqual({ findPosts: [{ title: 'Threepenny Opera' }] }) }) }) }) diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index 366b64155..d3cd46c9a 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -2,9 +2,9 @@ import faker from 'faker' export default function (params) { const { - id = Array.from({length: 3}, () => faker.lorem.word()).join(''), + id = Array.from({ length: 3 }, () => faker.lorem.word()).join(''), title = faker.lorem.sentence(), - content = Array.from({length: 10}, () => faker.lorem.sentence()).join(' ') + content = Array.from({ length: 10 }, () => faker.lorem.sentence()).join(' ') } = params return ` mutation { From d3a925cc3b1ec5560256df5437cb0faadeba3c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 02:10:30 +0100 Subject: [PATCH 341/554] Create indices before testing --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index f4a01b147..f106ed5e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,10 +16,12 @@ before_install: - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose - chmod +x docker-compose - sudo mv docker-compose /usr/local/bin + - yarn global add wait-on install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-backend:latest . - docker-compose -f docker-compose.yml -f docker-compose.travis.yml up -d + - wait-on tcp:7687 && docker-compose exec neo4j migrate script: - docker-compose exec backend yarn run lint From af536fac61faf96ee4470a04e52d8a0c9cb7023b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 02:20:28 +0100 Subject: [PATCH 342/554] On Travis we have to expose the port ...to be able to wait for it. --- docker-compose.travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml index 761a2aa64..bc26a2a34 100644 --- a/docker-compose.travis.yml +++ b/docker-compose.travis.yml @@ -1,6 +1,9 @@ version: "3.7" services: + neo4j: + ports: + - 7687:7687 backend: image: humanconnection/nitro-backend:builder build: From 3cc19800c9b10085182b1a039107b34aa87a6bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 02:29:09 +0100 Subject: [PATCH 343/554] Do we need to wait until the web client is up? --- .travis.yml | 2 +- docker-compose.travis.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f106ed5e8..e699197cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ before_install: install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-backend:latest . - docker-compose -f docker-compose.yml -f docker-compose.travis.yml up -d - - wait-on tcp:7687 && docker-compose exec neo4j migrate + - wait-on http://localhost:7474 && docker-compose exec neo4j migrate script: - docker-compose exec backend yarn run lint diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml index bc26a2a34..1553347fa 100644 --- a/docker-compose.travis.yml +++ b/docker-compose.travis.yml @@ -4,6 +4,7 @@ services: neo4j: ports: - 7687:7687 + - 7474:7474 backend: image: humanconnection/nitro-backend:builder build: From 55ee112dfa11096a8aa61aa9331e39c1869f7692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 02:36:07 +0100 Subject: [PATCH 344/554] Disable authentication on Travis --- docker-compose.travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml index 1553347fa..e1998f6dd 100644 --- a/docker-compose.travis.yml +++ b/docker-compose.travis.yml @@ -2,6 +2,8 @@ version: "3.7" services: neo4j: + environment: + - NEO4J_AUTH=none ports: - 7687:7687 - 7474:7474 From a8dd16f35ba54f6bfb3a607df7cff98b191e7d51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 15 Feb 2019 04:21:08 +0000 Subject: [PATCH 345/554] Bump nyc from 13.2.0 to 13.3.0 Bumps [nyc](https://github.com/istanbuljs/nyc) from 13.2.0 to 13.3.0. - [Release notes](https://github.com/istanbuljs/nyc/releases) - [Changelog](https://github.com/istanbuljs/nyc/blob/master/CHANGELOG.md) - [Commits](https://github.com/istanbuljs/nyc/compare/v13.2.0...v13.3.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 73 ++++++++++++++-------------------------------------- 2 files changed, 20 insertions(+), 55 deletions(-) diff --git a/package.json b/package.json index b65292acd..e2590c5ca 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "graphql-request": "~1.8.2", "jest": "~24.1.0", "nodemon": "~1.18.10", - "nyc": "~13.2.0", + "nyc": "~13.3.0", "supertest": "~3.4.2" } } diff --git a/yarn.lock b/yarn.lock index e89d2f383..eee4ab815 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3084,7 +3084,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: +glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== @@ -3300,10 +3300,10 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= -handlebars@^4.0.11: - version "4.0.12" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" - integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== +handlebars@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.0.tgz#0d6a6f34ff1f63cecec8423aa4169827bf787c3a" + integrity sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w== dependencies: async "^2.5.0" optimist "^0.6.1" @@ -3892,11 +3892,6 @@ istanbul-api@^2.0.8: minimatch "^3.0.4" once "^1.4.0" -istanbul-lib-coverage@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda" - integrity sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA== - istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#0b891e5ad42312c2b9488554f603795f9a2211ba" @@ -3909,20 +3904,7 @@ istanbul-lib-hook@^2.0.3: dependencies: append-transform "^1.0.0" -istanbul-lib-instrument@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz#b5f066b2a161f75788be17a9d556f40a0cf2afc9" - integrity sha512-eQY9vN9elYjdgN9Iv6NS/00bptm02EBBk70lRMaVjeA6QYocQgenVrSgC28TJurdnZa80AGO3ASdFN+w/njGiQ== - dependencies: - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - istanbul-lib-coverage "^2.0.1" - semver "^5.5.0" - -istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.1.0: +istanbul-lib-instrument@^3.0.0, istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz#a2b5484a7d445f1f311e93190813fa56dfb62971" integrity sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA== @@ -3955,12 +3937,12 @@ istanbul-lib-source-maps@^3.0.1, istanbul-lib-source-maps@^3.0.2: rimraf "^2.6.2" source-map "^0.6.1" -istanbul-reports@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.1.0.tgz#87b8b55cd1901ba1748964c98ddd8900ce306d59" - integrity sha512-azQdSX+dtTtkQEfqq20ICxWi6eOHXyHIgMFw1VOOVi8iIPWeCWRgCyFh/CsBKIhcgskMI8ExXmU7rjXTRCIJ+A== +istanbul-reports@^2.1.0, istanbul-reports@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.1.1.tgz#72ef16b4ecb9a4a7bd0e2001e00f95d1eec8afa9" + integrity sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw== dependencies: - handlebars "^4.0.11" + handlebars "^4.1.0" iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2: version "1.2.2" @@ -5112,10 +5094,10 @@ nwsapi@^2.0.7: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016" integrity sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ== -nyc@~13.2.0: - version "13.2.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-13.2.0.tgz#6a4a4b3f5f97b63ab491c665567557debcfa23d6" - integrity sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ== +nyc@~13.3.0: + version "13.3.0" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-13.3.0.tgz#da4dbe91a9c8b9ead3f4f3344c76f353e3c78c75" + integrity sha512-P+FwIuro2aFG6B0Esd9ZDWUd51uZrAEoGutqZxzrVmYl3qSfkLgcQpBPBjtDFsUQLFY1dvTQJPOyeqr8S9GF8w== dependencies: archy "^1.0.0" arrify "^1.0.1" @@ -5127,10 +5109,10 @@ nyc@~13.2.0: glob "^7.1.3" istanbul-lib-coverage "^2.0.3" istanbul-lib-hook "^2.0.3" - istanbul-lib-instrument "^3.0.1" + istanbul-lib-instrument "^3.1.0" istanbul-lib-report "^2.0.4" istanbul-lib-source-maps "^3.0.2" - istanbul-reports "^2.1.0" + istanbul-reports "^2.1.1" make-dir "^1.3.0" merge-source-map "^1.1.0" resolve-from "^4.0.0" @@ -6028,14 +6010,7 @@ retry@0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== - dependencies: - glob "^7.0.5" - -rimraf@^2.6.3: +rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -6616,17 +6591,7 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" -test-exclude@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.0.0.tgz#cdce7cece785e0e829cd5c2b27baf18bc583cfb7" - integrity sha512-bO3Lj5+qFa9YLfYW2ZcXMOV1pmQvw+KS/DpjqhyX6Y6UZ8zstpZJ+mA2ERkXfpOqhxsJlQiLeVXD3Smsrs6oLw== - dependencies: - arrify "^1.0.1" - minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^1.0.1" - -test-exclude@^5.1.0: +test-exclude@^5.0.0, test-exclude@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1" integrity sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA== From 99c2f9e2729e27d72b22299cfd1308db052d7007 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 15 Feb 2019 16:34:32 +0000 Subject: [PATCH 346/554] Bump apollo-cache-inmemory from 1.4.2 to 1.4.3 Bumps [apollo-cache-inmemory](https://github.com/apollographql/apollo-client) from 1.4.2 to 1.4.3. - [Release notes](https://github.com/apollographql/apollo-client/releases) - [Changelog](https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-client/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 33 +++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index e2590c5ca..924a2b78e 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ ] }, "dependencies": { - "apollo-cache-inmemory": "~1.4.2", + "apollo-cache-inmemory": "~1.4.3", "apollo-client": "~2.4.12", "apollo-link-http": "~1.5.11", "apollo-server": "~2.4.0", diff --git a/yarn.lock b/yarn.lock index eee4ab815..30a2fd508 100644 --- a/yarn.lock +++ b/yarn.lock @@ -985,17 +985,17 @@ apollo-cache-control@^0.1.0: dependencies: graphql-extensions "^0.0.x" -apollo-cache-inmemory@~1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.4.2.tgz#c91aeb4adff45cdc7872d603cbff055fa9cd5021" - integrity sha512-fDVmj5j1e3W+inyuSwjIcMgbQ4edcFgmiKTBMFAEKAq0jg33X7FrbDX8JT2t5Vuf75Mva50JDlt5wXdu7C6WuA== +apollo-cache-inmemory@~1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.4.3.tgz#aded4fb8b3de9e2fb2573a6c03591b07ef98ed36" + integrity sha512-p9KGtEZ9Mlb+FS0UEaxR8WvKOijYV0c+TXlhC/XZ3/ltYvP1zL3b1ozSOLGR9SawN2895Fc7QDV5nzPpihV0rA== dependencies: - apollo-cache "^1.1.25" - apollo-utilities "^1.1.2" + apollo-cache "^1.1.26" + apollo-utilities "^1.1.3" optimism "^0.6.9" tslib "^1.9.3" -apollo-cache@1.1.25, apollo-cache@^1.1.25: +apollo-cache@1.1.25: version "1.1.25" resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.25.tgz#87a15a2a19993bb07234ccee6839b59d6fb49ac5" integrity sha512-9HhI/tVEHAeGaJJvi1Vpf6PzXUCA0PqNbigi2G3uOc180JjxbcaBvEbKXMEDb/UyTXkFWzI4PiPDuDQFqmIMSA== @@ -1003,6 +1003,14 @@ apollo-cache@1.1.25, apollo-cache@^1.1.25: apollo-utilities "^1.1.2" tslib "^1.9.3" +apollo-cache@^1.1.26: + version "1.1.26" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.26.tgz#5afe023270effbc2063d90f51d8e56bce274ab37" + integrity sha512-JKFHijwkhXpcQ3jOat+ctwiXyjDhQgy0p6GSaj7zG+or+ZSalPqUnPzFRgRwFLVbYxBKJgHCkWX+2VkxWTZzQQ== + dependencies: + apollo-utilities "^1.1.3" + tslib "^1.9.3" + apollo-client@~2.4.12: version "2.4.12" resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.12.tgz#9fa15f502d04f8cc788a9fbb825163b437681504" @@ -1238,7 +1246,7 @@ apollo-upload-server@^7.0.0: http-errors "^1.7.0" object-path "^0.11.4" -apollo-utilities@1.1.2, apollo-utilities@^1.1.2: +apollo-utilities@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.2.tgz#aa5eca9d1f1eb721c381a22e0dde03559d856db3" integrity sha512-EjDx8vToK+zkWIxc76ZQY/irRX52puNg04xf/w8R0kVTDAgHuVfnFVC01O5vE25kFnIaa5em0pFI0p9b6YMkhQ== @@ -1246,12 +1254,13 @@ apollo-utilities@1.1.2, apollo-utilities@^1.1.2: fast-json-stable-stringify "^2.0.0" tslib "^1.9.3" -apollo-utilities@^1.0.0, apollo-utilities@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.0.tgz#e7603f834b57e4e109be6b450dc1cc1037aac94c" - integrity sha512-D3scmF6vJkCBECMasMEc0J9dNNHVULl6h2d7/oGJxWid1fgcAPHZJN5XLCZisuOfn0Dvvu3Unf/zK00Z3e49Qg== +apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.1.2, apollo-utilities@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.3.tgz#a8883c0392f6b46eac0d366204ebf34be9307c87" + integrity sha512-pF9abhiClX5gfj/WFWZh8DiI33nOLGxRhXH9ZMquaM1V8bhq1WLFPt2QjShWH3kGQVeIGUK+FQefnhe+ZaaAYg== dependencies: fast-json-stable-stringify "^2.0.0" + tslib "^1.9.3" append-transform@^1.0.0: version "1.0.0" From 357ac42411659a41f2e29eb240697aa98c026a45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 15 Feb 2019 16:48:40 +0000 Subject: [PATCH 347/554] Bump apollo-client from 2.4.12 to 2.4.13 Bumps [apollo-client](https://github.com/apollographql/apollo-client) from 2.4.12 to 2.4.13. - [Release notes](https://github.com/apollographql/apollo-client/releases) - [Changelog](https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-client/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 49 +++++++++---------------------------------------- 2 files changed, 10 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index 924a2b78e..232d08c15 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "dependencies": { "apollo-cache-inmemory": "~1.4.3", - "apollo-client": "~2.4.12", + "apollo-client": "~2.4.13", "apollo-link-http": "~1.5.11", "apollo-server": "~2.4.0", "bcryptjs": "~2.4.3", diff --git a/yarn.lock b/yarn.lock index 30a2fd508..459080799 100644 --- a/yarn.lock +++ b/yarn.lock @@ -995,15 +995,7 @@ apollo-cache-inmemory@~1.4.3: optimism "^0.6.9" tslib "^1.9.3" -apollo-cache@1.1.25: - version "1.1.25" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.25.tgz#87a15a2a19993bb07234ccee6839b59d6fb49ac5" - integrity sha512-9HhI/tVEHAeGaJJvi1Vpf6PzXUCA0PqNbigi2G3uOc180JjxbcaBvEbKXMEDb/UyTXkFWzI4PiPDuDQFqmIMSA== - dependencies: - apollo-utilities "^1.1.2" - tslib "^1.9.3" - -apollo-cache@^1.1.26: +apollo-cache@1.1.26, apollo-cache@^1.1.26: version "1.1.26" resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.26.tgz#5afe023270effbc2063d90f51d8e56bce274ab37" integrity sha512-JKFHijwkhXpcQ3jOat+ctwiXyjDhQgy0p6GSaj7zG+or+ZSalPqUnPzFRgRwFLVbYxBKJgHCkWX+2VkxWTZzQQ== @@ -1011,16 +1003,16 @@ apollo-cache@^1.1.26: apollo-utilities "^1.1.3" tslib "^1.9.3" -apollo-client@~2.4.12: - version "2.4.12" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.12.tgz#9fa15f502d04f8cc788a9fbb825163b437681504" - integrity sha512-E5ClFSB9btJLYibLKwLDSCg+w9tI+25eZgXOM+DClawu7of4d/xhuV/xvpuZpsMP3qwrp0QPacBnfG4tUJs3/w== +apollo-client@~2.4.13: + version "2.4.13" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.13.tgz#09829fcbd68e069de9840d0a10764d7c6a3d0787" + integrity sha512-7mBdW/CW1qHB8Mj4EFAG3MTtbRc6S8aUUntUdrKfRWV1rZdWa0NovxsgVD/R4HZWZjRQ2UOM4ENsHdM5g1uXOQ== dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.25" + apollo-cache "1.1.26" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "1.1.2" + apollo-utilities "1.1.3" symbol-observable "^1.0.2" tslib "^1.9.3" zen-observable "^0.8.0" @@ -1089,15 +1081,7 @@ apollo-link-http@~1.5.11: apollo-link "^1.2.8" apollo-link-http-common "^0.2.10" -apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4: - version "1.2.6" - resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.6.tgz#d9b5676d79c01eb4e424b95c7171697f6ad2b8da" - integrity sha512-sUNlA20nqIF3gG3F8eyMD+mO80fmf3dPZX+GUOs3MI9oZR8ug09H3F0UsWJMcpEg6h55Yy5wZ+BMmAjrbenF/Q== - dependencies: - apollo-utilities "^1.0.0" - zen-observable-ts "^0.8.13" - -apollo-link@^1.2.8: +apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.8.tgz#0f252adefd5047ac1a9f35ba9439d216587dcd84" integrity sha512-lfzGRxhK9RmiH3HPFi7TIEBhhDY9M5a2ZDnllcfy5QDk7cCQHQ1WQArcw1FK0g1B+mV4Kl72DSrlvZHZJEolrA== @@ -1246,15 +1230,7 @@ apollo-upload-server@^7.0.0: http-errors "^1.7.0" object-path "^0.11.4" -apollo-utilities@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.2.tgz#aa5eca9d1f1eb721c381a22e0dde03559d856db3" - integrity sha512-EjDx8vToK+zkWIxc76ZQY/irRX52puNg04xf/w8R0kVTDAgHuVfnFVC01O5vE25kFnIaa5em0pFI0p9b6YMkhQ== - dependencies: - fast-json-stable-stringify "^2.0.0" - tslib "^1.9.3" - -apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.1.2, apollo-utilities@^1.1.3: +apollo-utilities@1.1.3, apollo-utilities@^1.0.1, apollo-utilities@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.3.tgz#a8883c0392f6b46eac0d366204ebf34be9307c87" integrity sha512-pF9abhiClX5gfj/WFWZh8DiI33nOLGxRhXH9ZMquaM1V8bhq1WLFPt2QjShWH3kGQVeIGUK+FQefnhe+ZaaAYg== @@ -7202,13 +7178,6 @@ yargs@^12.0.2, yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -zen-observable-ts@^0.8.13: - version "0.8.13" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.13.tgz#ae1fd77c84ef95510188b1f8bca579d7a5448fc2" - integrity sha512-WDb8SM0tHCb6c0l1k60qXWlm1ok3zN9U4VkLdnBKQwIYwUoB9psH7LIFgR+JVCCMmBxUgOjskIid8/N02k/2Bg== - dependencies: - zen-observable "^0.8.0" - zen-observable-ts@^0.8.15: version "0.8.15" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.15.tgz#6cf7df6aa619076e4af2f707ccf8a6290d26699b" From da804e26ae44b34383e0eb096a49983b165c6f12 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 17 Feb 2019 17:32:14 +0100 Subject: [PATCH 348/554] Fix search --- src/schema.graphql | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index ee519fff3..e9b5d5106 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -3,10 +3,9 @@ type Query { statistics: Statistics! findPosts(filter: String!, limit: Int = 10): [Post]! @cypher( statement: """ - CALL db.index.fulltext.queryNodes('full_text_search', $filter+'~') - YIELD node AS node + CALL db.index.fulltext.queryNodes('full_text_search', $filter) + YIELD node RETURN node - ORDER BY node.createdAt DESC LIMIT $limit """ ) From f17242b8245c4edc52262aad26a489962144de29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 18 Feb 2019 12:56:38 +0100 Subject: [PATCH 349/554] Transfer relevant changes from branch `neode` --- .travis.yml | 2 ++ README.md | 22 +++++++++++++--------- docker-compose.override.yml | 7 +++++++ docker-compose.prod.yml | 9 +++++++++ docker-compose.travis.yml | 6 ++++++ docker-compose.yml | 7 ------- neo4j/Dockerfile | 1 + neo4j/migrate.sh | 11 +++++++++++ src/bootstrap/neo4j.js | 2 +- src/middleware/slugify/uniqueSlug.js | 15 +++++++++++++++ src/middleware/slugify/uniqueSlug.spec.js | 18 ++++++++++++++++++ 11 files changed, 83 insertions(+), 17 deletions(-) create mode 100644 docker-compose.prod.yml create mode 100755 neo4j/migrate.sh create mode 100644 src/middleware/slugify/uniqueSlug.js create mode 100644 src/middleware/slugify/uniqueSlug.spec.js diff --git a/.travis.yml b/.travis.yml index f4a01b147..e699197cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,10 +16,12 @@ before_install: - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose - chmod +x docker-compose - sudo mv docker-compose /usr/local/bin + - yarn global add wait-on install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-backend:latest . - docker-compose -f docker-compose.yml -f docker-compose.travis.yml up -d + - wait-on http://localhost:7474 && docker-compose exec neo4j migrate script: - docker-compose exec backend yarn run lint diff --git a/README.md b/README.md index 1b12562d2..7f4676a6c 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,15 @@ > This Prototype tries to resolve the biggest hurdle of connecting > our services together. This is not possible in a sane way using -> our current approach. -> -> With this Prototype we can explore using the combination of +> our current approach. +> +> With this Prototype we can explore using the combination of > GraphQL and the Neo4j Graph Database for achieving the connected > nature of a social graph with better development experience as we > do not need to connect data by our own any more through weird table > structures etc. -> +> > #### Advantages: > - easer data structure > - better connected data @@ -19,10 +19,10 @@ > - more performant and better to understand API > - better API client that uses caching > -> We still need to evaluate the drawbacks and estimate the development +> We still need to evaluate the drawbacks and estimate the development > cost of such an approach -## How to get in touch +## How to get in touch Connect with other developers over [Discord](https://discord.gg/6ub73U3) ## Quick Start @@ -35,6 +35,10 @@ Before you start, fork the repository using the fork button above, then clone it Run: ```sh docker-compose up + +# create indices etc. +docker-compose exec neo4j migrate + # if you want seed data # open another terminal and run docker-compose exec backend yarn run db:seed @@ -94,7 +98,7 @@ _.env_ ```yaml NEO4J_URI=bolt://localhost:7687 -NEO4J_USER=neo4j +NEO4J_USERNAME=neo4j NEO4J_PASSWORD=letmein ``` @@ -116,7 +120,7 @@ Just set `MOCK=true` inside `.env` or pass it on application start. ## Seed and Reset the Database -Optionally you can seed the GraphQL service by executing mutations that +Optionally you can seed the GraphQL service by executing mutations that will write sample data to the database: ```bash @@ -152,5 +156,5 @@ npm run test - [x] check if sorting is working - [x] check if pagination is working - [ ] check if upload is working (using graphql-yoga?) -- [x] evaluate middleware +- [x] evaluate middleware - [ ] ignore Posts and Comments by blacklisted Users diff --git a/docker-compose.override.yml b/docker-compose.override.yml index ef7d52c7e..b972c31f6 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -11,6 +11,13 @@ services: - /nitro-backend/node_modules command: yarn run dev neo4j: + environment: + - NEO4J_AUTH=none ports: - 7687:7687 - 7474:7474 + volumes: + - neo4j-data:/data + +volumes: + neo4j-data: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 000000000..c4f5dc4f5 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,9 @@ +version: "3.7" + +services: + neo4j: + environment: + - NEO4J_PASSWORD=letmein + backend: + environment: + - NEO4J_PASSWORD=letmein diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml index 761a2aa64..e1998f6dd 100644 --- a/docker-compose.travis.yml +++ b/docker-compose.travis.yml @@ -1,6 +1,12 @@ version: "3.7" services: + neo4j: + environment: + - NEO4J_AUTH=none + ports: + - 7687:7687 + - 7474:7474 backend: image: humanconnection/nitro-backend:builder build: diff --git a/docker-compose.yml b/docker-compose.yml index 6905bb893..1e8c9158c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,14 +27,7 @@ services: context: neo4j networks: - hc-network - volumes: - - neo4j-data:/data - environment: - - NEO4J_AUTH=none networks: hc-network: name: hc-network - -volumes: - neo4j-data: diff --git a/neo4j/Dockerfile b/neo4j/Dockerfile index cb7fd228f..f6e71811b 100644 --- a/neo4j/Dockerfile +++ b/neo4j/Dockerfile @@ -1,2 +1,3 @@ FROM neo4j:3.5.0 RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.1/apoc-3.5.0.1-all.jar -P plugins/ +COPY migrate.sh /usr/local/bin/migrate diff --git a/neo4j/migrate.sh b/neo4j/migrate.sh new file mode 100755 index 000000000..c659909fa --- /dev/null +++ b/neo4j/migrate.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -e +if [[ -z "${NEO4J_PASSWORD}" ]]; then + echo 'CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);' | cypher-shell +else + echo "CALL dbms.security.changePassword('${NEO4J_PASSWORD}');" | cypher-shell --username neo4j --password neo4j + echo "CREATE CONSTRAINT ON (p:Post) ASSERT p.slug IS UNIQUE;" | cypher-shell + echo "CREATE CONSTRAINT ON (c:Category) ASSERT c.slug IS UNIQUE;" | cypher-shell + echo "CREATE CONSTRAINT ON (u:User) ASSERT u.slug IS UNIQUE;" | cypher-shell + echo "CREATE CONSTRAINT ON (o:Organization) ASSERT o.slug IS UNIQUE;" | cypher-shell +fi diff --git a/src/bootstrap/neo4j.js b/src/bootstrap/neo4j.js index 766c12065..929e62f23 100644 --- a/src/bootstrap/neo4j.js +++ b/src/bootstrap/neo4j.js @@ -9,7 +9,7 @@ export default function () { driver = neo4j.driver( process.env.NEO4J_URI || 'bolt://localhost:7687', neo4j.auth.basic( - process.env.NEO4J_USER || 'neo4j', + process.env.NEO4J_USERNAME || 'neo4j', process.env.NEO4J_PASSWORD || 'neo4j' ) ) diff --git a/src/middleware/slugify/uniqueSlug.js b/src/middleware/slugify/uniqueSlug.js new file mode 100644 index 000000000..0f5b264a7 --- /dev/null +++ b/src/middleware/slugify/uniqueSlug.js @@ -0,0 +1,15 @@ +import slugify from 'slug' +export default function uniqueSlug(string, isUnique) { + let slug = slugify(string, { + lower: true + }) + if (isUnique(slug)) return slug; + + let count = 0 + let uniqueSlug + do { + count += 1 + uniqueSlug = `${slug}-${count}` + } while(!isUnique(uniqueSlug)); + return uniqueSlug; +} diff --git a/src/middleware/slugify/uniqueSlug.spec.js b/src/middleware/slugify/uniqueSlug.spec.js new file mode 100644 index 000000000..3d379bafb --- /dev/null +++ b/src/middleware/slugify/uniqueSlug.spec.js @@ -0,0 +1,18 @@ +import uniqueSlug from './uniqueSlug' + +describe('uniqueSlug', () => { + it('slugifies given string', () => { + const string = 'Hello World' + const isUnique = () => true + expect(uniqueSlug(string, isUnique)).toEqual('hello-world') + }) + + it('increments slugified string until unique', () => { + const string = 'Hello World' + const isUnique = jest.fn() + isUnique + .mockReturnValueOnce(false) + .mockReturnValueOnce(true) + expect(uniqueSlug(string, isUnique)).toEqual('hello-world-1') + }) +}) From f024bd3821dadab120c9e483f1a9f10c7902ad09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 18 Feb 2019 13:25:11 +0100 Subject: [PATCH 350/554] Remove redundancy --- src/seed/data/index.js | 27 +----------------------- src/seed/factories/index.js | 10 ++++----- src/seed/seed-db.js | 41 ++++++++++++++++++++++--------------- 3 files changed, 30 insertions(+), 48 deletions(-) diff --git a/src/seed/data/index.js b/src/seed/data/index.js index d3f5d15d7..5df9ee404 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -1,7 +1,4 @@ -import gql from 'graphql-tag' -import asyncForEach from '../../helpers/asyncForEach' - -const seed = { +export default { Badge: require('./badges.js').default, Category: require('./categories.js').default, Tags: require('./tags.js').default, @@ -19,25 +16,3 @@ const seed = { // Reports: require('./reports.js').default } - -let data = {} - -export default async function (client) { - // iterate through seeds - await asyncForEach(Object.keys(seed), async key => { - const mutations = seed[key] - try { - const res = await client - .mutate({ - mutation: gql(mutations(data)) - }) - data[key] = Object.assign(data[key] || {}, res.data) - } catch (err) { - /* eslint-disable-next-line no-console */ - console.error(err) - process.exit(1) - } - }) - /* eslint-disable-next-line no-console */ - console.log('Seeded Data...') -} diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index e62e98869..74076872b 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -8,11 +8,7 @@ import fetch from 'node-fetch' dotenv.config() -if (process.env.NODE_ENV === 'production') { - throw new Error('YOU CAN`T RUN FACTORIES IN PRODUCTION MODE') -} - -const client = new ApolloClient({ +const apolloClient = new ApolloClient({ link: new HttpLink({ uri: 'http://localhost:4001', fetch }), cache: new InMemoryCache() }) @@ -28,7 +24,7 @@ const buildMutation = (model, parameters) => { } const create = (model, parameters) => { - return client.mutate({ mutation: gql(buildMutation(model, parameters)) }) + return apolloClient.mutate({ mutation: gql(buildMutation(model, parameters)) }) } const cleanDatabase = async () => { @@ -44,6 +40,8 @@ const cleanDatabase = async () => { } export { + driver, + apolloClient, create, buildMutation, cleanDatabase diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 3e7e6e9c4..e6adbe1a2 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,19 +1,28 @@ -import ApolloClient from 'apollo-client' -import dotenv from 'dotenv' -import fetch from 'node-fetch' -import { HttpLink } from 'apollo-link-http' -import { InMemoryCache } from 'apollo-cache-inmemory' -import Seed from './data/index' +import { apolloClient } from './factories' +import gql from 'graphql-tag' +import asyncForEach from '../helpers/asyncForEach' +import seed from './data' -dotenv.config() +(async function () { -if (process.env.NODE_ENV === 'production') { - throw new Error('YOU CAN`T SEED IN PRODUCTION MODE') -} + // prefer factories +let data = {} + // legacy seeds + await asyncForEach(Object.keys(seed), async key => { + const mutations = seed[key] + try { + const res = await apolloClient + .mutate({ + mutation: gql(mutations(data)) + }) + data[key] = Object.assign(data[key] || {}, res.data) + } catch (err) { + /* eslint-disable-next-line no-console */ + console.error(err) + process.exit(1) + } + }) + /* eslint-disable-next-line no-console */ + console.log('Seeded Data...') +})() -const client = new ApolloClient({ - link: new HttpLink({ uri: process.env.GRAPHQL_URI, fetch }), - cache: new InMemoryCache() -}) - -Seed(client) From 1734554a88741fae67e343511fa1625e556cf115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 18 Feb 2019 15:35:45 +0100 Subject: [PATCH 351/554] Fix seeds without the use of neode @appinteractive ping --- src/graphql-schema.spec.js | 2 +- src/jest/helpers.js | 4 +-- src/middleware/permissionsMiddleware.spec.js | 2 +- src/seed/data/index.js | 2 -- src/seed/factories/index.js | 14 +++++--- src/seed/factories/posts.js | 34 ++++++++++++++++++++ src/seed/factories/users.js | 16 +++++---- src/seed/seed-db.js | 29 ++++++++++++++++- 8 files changed, 86 insertions(+), 17 deletions(-) create mode 100644 src/seed/factories/posts.js diff --git a/src/graphql-schema.spec.js b/src/graphql-schema.spec.js index 69073444c..21b3f3d61 100644 --- a/src/graphql-schema.spec.js +++ b/src/graphql-schema.spec.js @@ -1,7 +1,7 @@ import { request } from 'graphql-request' import { create, cleanDatabase } from './seed/factories' import jwt from 'jsonwebtoken' -import { host } from './jest/helpers' +import { testServerHost as host } from './jest/helpers' describe('login', () => { const mutation = (params) => { diff --git a/src/jest/helpers.js b/src/jest/helpers.js index 01a26e9d3..cb86bf785 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -1,8 +1,8 @@ import { request } from 'graphql-request' -export const host = 'http://127.0.0.1:4123' +export const testServerHost = 'http://127.0.0.1:4123' -export async function authenticatedHeaders ({ email, password }) { +export async function authenticatedHeaders ({ email, password }, host = testServerHost) { const mutation = ` mutation { login(email:"${email}", password:"${password}"){ diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index cf86d11c9..481e340cb 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,5 +1,5 @@ import { create, cleanDatabase } from '../seed/factories' -import { host, authenticatedHeaders } from '../jest/helpers' +import { testServerHost as host, authenticatedHeaders } from '../jest/helpers' import { GraphQLClient } from 'graphql-request' describe('authorization', () => { diff --git a/src/seed/data/index.js b/src/seed/data/index.js index 5df9ee404..483ad065a 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -3,14 +3,12 @@ export default { Category: require('./categories.js').default, Tags: require('./tags.js').default, - User: require('./users.js').default, UserBadges: require('./users-badges.js').default, UserBlacklist: require('./users-blacklist.js').default, UserFollows: require('./users-follows.js').default, UserFriends: require('./users-friends.js').default, Organization: require('./organizations.js').default, - Post: require('./posts.js').default, Comment: require('./comments.js').default, UserShouts: require('./users-shouts.js').default diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 74076872b..faf2b93cc 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -1,3 +1,4 @@ +import { GraphQLClient } from 'graphql-request' import ApolloClient from 'apollo-client' import gql from 'graphql-tag' import dotenv from 'dotenv' @@ -6,25 +7,30 @@ import { InMemoryCache } from 'apollo-cache-inmemory' import neo4j from '../../bootstrap/neo4j' import fetch from 'node-fetch' +export const seedServerHost = 'http://127.0.0.1:4001' + dotenv.config() const apolloClient = new ApolloClient({ - link: new HttpLink({ uri: 'http://localhost:4001', fetch }), + link: new HttpLink({ uri: seedServerHost, fetch }), cache: new InMemoryCache() }) const driver = neo4j().getDriver() const builders = { - 'user': require('./users.js').default + 'user': require('./users.js').default, + 'post': require('./posts.js').default } const buildMutation = (model, parameters) => { return builders[model](parameters) } -const create = (model, parameters) => { - return apolloClient.mutate({ mutation: gql(buildMutation(model, parameters)) }) +const create = (model, parameters, options) => { + const graphQLClient = new GraphQLClient(seedServerHost, options) + const mutation = buildMutation(model, parameters) + return graphQLClient.request(mutation) } const cleanDatabase = async () => { diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js new file mode 100644 index 000000000..3dc240d9f --- /dev/null +++ b/src/seed/factories/posts.js @@ -0,0 +1,34 @@ + +import faker from 'faker' + +export default function (params) { + const { + id = `u${faker.random.number()}`, + title = faker.lorem.sentence(), + content = [ + faker.lorem.sentence(), + faker.lorem.sentence(), + faker.lorem.sentence(), + faker.lorem.sentence(), + faker.lorem.sentence(), + ].join('. '), + image = faker.image.imageUrl(), + visibility = 'public', + disabled = false, + deleted = false + } = params + + return ` + mutation { + CreatePost( + id: "${id}", + title: "${title}", + content: "${content}", + image: "${image}", + visibility: ${visibility}, + disabled: ${disabled}, + deleted: ${deleted} + ) { id, title } + } + ` +} diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index 452059a73..7ead2d9f0 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -2,23 +2,27 @@ import faker from 'faker' export default function (params) { const { + id = `u${faker.random.number()}`, name = faker.name.findName(), email = faker.internet.email(), password = '1234', - avatar = faker.internet.avatar() + role = 'user', + avatar = faker.internet.avatar(), + disabled = false, + deleted = false } = params return ` mutation { - u1: CreateUser( - id: "u1", + CreateUser( + id: "${id}", name: "${name}", password: "${password}", email: "${email}", avatar: "${avatar}", - role: admin, - disabled: false, - deleted: false) { + role: ${role}, + disabled: ${disabled}, + deleted: ${deleted}) { id name email diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index e6adbe1a2..7b9f3b775 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,4 +1,5 @@ -import { apolloClient } from './factories' +import { create, apolloClient, seedServerHost as host } from './factories' +import { authenticatedHeaders } from '../jest/helpers.js' import gql from 'graphql-tag' import asyncForEach from '../helpers/asyncForEach' import seed from './data' @@ -6,6 +7,32 @@ import seed from './data' (async function () { // prefer factories + try { + const [admin, moderator, user, ...otherUsers] = await Promise.all([ + create('user', {id: 'u1', name: 'Peter Lustig' , role: 'admin' , email: 'admin@example.org', password: '1234'}), + create('user', {id: 'u2', name: 'Bob der Baumeister', role: 'moderator', email: 'moderator@example.org'}), + create('user', {id: 'u3', name: 'Jenny Rostock' , role: 'user' , email: 'user@example.org'}), + create('user', {id: 'u4', name: 'Angie Banjie' , role: 'user' , email: 'angie@example.org'}), + ]) + + // TODO: other users, not only admin, are authors of a post + const headers = await authenticatedHeaders({ + email: 'admin@example.org', + password: '1234' + }, host) + await create('post', {id: 'p1'}, { headers } ) + await create('post', {id: 'p2'}, { headers } ) + await create('post', {id: 'p3'}, { headers } ) + await create('post', {id: 'p4'}, { headers } ) + await create('post', {id: 'p5'}, { headers } ) + await create('post', {id: 'p6'}, { headers } ) + } catch(err) { + /* eslint-disable-next-line no-console */ + console.error(err) + process.exit(1) + } + + let data = {} // legacy seeds await asyncForEach(Object.keys(seed), async key => { From cbbd33301f04c2052d0faf2a3545e294bf8be1da Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 18 Feb 2019 16:57:17 +0100 Subject: [PATCH 352/554] Improved search query --- src/schema.graphql | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index e9b5d5106..1e09768cb 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -4,8 +4,12 @@ type Query { findPosts(filter: String!, limit: Int = 10): [Post]! @cypher( statement: """ CALL db.index.fulltext.queryNodes('full_text_search', $filter) - YIELD node - RETURN node + YIELD node as post, score + MATCH (post)<-[:WROTE]-(user:User) + WHERE score >= 0.2 + AND NOT user.deleted = true AND NOT user.disabled = true + AND NOT post.deleted = true AND NOT post.disabled = true + RETURN post LIMIT $limit """ ) From 9dba02cf091a36f43c36d0f07713e895a115e5fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 18 Feb 2019 17:23:12 +0100 Subject: [PATCH 353/554] Create posts by multiple authors --- src/seed/factories/posts.js | 2 +- src/seed/seed-db.js | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index 3dc240d9f..679649c88 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -12,7 +12,7 @@ export default function (params) { faker.lorem.sentence(), faker.lorem.sentence(), ].join('. '), - image = faker.image.imageUrl(), + image = faker.image.image(), visibility = 'public', disabled = false, deleted = false diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 7b9f3b775..981764062 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -15,17 +15,24 @@ import seed from './data' create('user', {id: 'u4', name: 'Angie Banjie' , role: 'user' , email: 'angie@example.org'}), ]) - // TODO: other users, not only admin, are authors of a post - const headers = await authenticatedHeaders({ + const asAdmin = await authenticatedHeaders({ email: 'admin@example.org', password: '1234' }, host) - await create('post', {id: 'p1'}, { headers } ) - await create('post', {id: 'p2'}, { headers } ) - await create('post', {id: 'p3'}, { headers } ) - await create('post', {id: 'p4'}, { headers } ) - await create('post', {id: 'p5'}, { headers } ) - await create('post', {id: 'p6'}, { headers } ) + const asModerator = await authenticatedHeaders({ + email: 'moderator@example.org', + password: '1234' + }, host) + const asUser = await authenticatedHeaders({ + email: 'user@example.org', + password: '1234' + }, host) + await create('post', {id: 'p1'}, { headers: asAdmin } ) + await create('post', {id: 'p2'}, { headers: asModerator } ) + await create('post', {id: 'p3'}, { headers: asUser } ) + await create('post', {id: 'p4'}, { headers: asAdmin } ) + await create('post', {id: 'p5'}, { headers: asModerator } ) + await create('post', {id: 'p6'}, { headers: asUser } ) } catch(err) { /* eslint-disable-next-line no-console */ console.error(err) From 437e8589f877e3a522c828df4fc85990b9d6ed9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 18 Feb 2019 18:07:07 +0100 Subject: [PATCH 354/554] Categories posts in seeding --- src/seed/data/categories.js | 22 --------------------- src/seed/data/index.js | 1 - src/seed/factories/categories.js | 21 ++++++++++++++++++++ src/seed/factories/index.js | 3 ++- src/seed/factories/posts.js | 14 ++++++++++++-- src/seed/seed-db.js | 33 ++++++++++++++++++++++++++------ 6 files changed, 62 insertions(+), 32 deletions(-) delete mode 100644 src/seed/data/categories.js create mode 100644 src/seed/factories/categories.js diff --git a/src/seed/data/categories.js b/src/seed/data/categories.js deleted file mode 100644 index a21f0f3d6..000000000 --- a/src/seed/data/categories.js +++ /dev/null @@ -1,22 +0,0 @@ -export default function (data) { - return ` - mutation { - cat1: CreateCategory( id: "cat1", name: "Just For Fun", slug: "justforfun", icon: "smile" ) { name } - cat2: CreateCategory( id: "cat2", name: "Happyness & Values", slug: "happyness-values", icon: "heart-o" ) { name } - cat3: CreateCategory( id: "cat3", name: "Health & Wellbeing", slug: "health-wellbeing", icon: "medkit" ) { name } - cat4: CreateCategory( id: "cat4", name: "Environment & Nature", slug: "environment-nature", icon: "tree" ) { name } - cat5: CreateCategory( id: "cat5", name: "Animal Protection", slug: "animalprotection", icon: "paw" ) { name } - cat6: CreateCategory( id: "cat6", name: "Humanrights Justice", slug: "humanrights-justice", icon: "balance-scale" ) { name } - cat7: CreateCategory( id: "cat7", name: "Education & Sciences", slug: "education-sciences", icon: "graduation-cap" ) { name } - cat8: CreateCategory( id: "cat8", name: "Cooperation & Development", slug: "cooperation-development", icon: "users" ) { name } - cat9: CreateCategory( id: "cat9", name: "Democracy & Politics", slug: "democracy-politics", icon: "university" ) { name } - cat10: CreateCategory( id: "cat10", name: "Economy & Finances", slug: "economy-finances", icon: "money" ) { name } - cat11: CreateCategory( id: "cat11", name: "Energy & Technology", slug: "energy-technology", icon: "flash" ) { name } - cat12: CreateCategory( id: "cat12", name: "IT, Internet & Data Privacy", slug: "it-internet-dataprivacy", icon: "mouse-pointer" ) { name } - cat13: CreateCategory( id: "cat13", name: "Art, Curlure & Sport", slug: "art-culture-sport", icon: "paint-brush" ) { name } - cat14: CreateCategory( id: "cat14", name: "Freedom of Speech", slug: "freedomofspeech", icon: "bullhorn" ) { name } - cat15: CreateCategory( id: "cat15", name: "Consumption & Sustainability", slug: "consumption-sustainability", icon: "shopping-cart" ) { name } - cat16: CreateCategory( id: "cat16", name: "Global Peace & Nonviolence", slug: "globalpeace-nonviolence", icon: "angellist" ) { name } - } - ` -} diff --git a/src/seed/data/index.js b/src/seed/data/index.js index 483ad065a..329aa7c03 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -1,6 +1,5 @@ export default { Badge: require('./badges.js').default, - Category: require('./categories.js').default, Tags: require('./tags.js').default, UserBadges: require('./users-badges.js').default, diff --git a/src/seed/factories/categories.js b/src/seed/factories/categories.js new file mode 100644 index 000000000..287aac5e0 --- /dev/null +++ b/src/seed/factories/categories.js @@ -0,0 +1,21 @@ +import faker from 'faker' + +export default function (params) { + const { + id = `cat${faker.random.number()}`, + name, + slug, + icon + } = params + + return ` + mutation { + CreateCategory( + id: "${id}", + name: "${name}", + slug: "${slug}", + icon: "${icon}" + ) { id, name } + } + ` +} diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index faf2b93cc..c7a00a145 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -20,7 +20,8 @@ const driver = neo4j().getDriver() const builders = { 'user': require('./users.js').default, - 'post': require('./posts.js').default + 'post': require('./posts.js').default, + 'category': require('./categories.js').default } const buildMutation = (model, parameters) => { diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index 679649c88..ca25f69e9 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -15,12 +15,21 @@ export default function (params) { image = faker.image.image(), visibility = 'public', disabled = false, - deleted = false + deleted = false, + tagIds = [], + categoryIds = [] } = params + const categoryRelations = categoryIds.map((categoryId) => { + return `${id}_${categoryId}: AddPostCategories( + from: {id: "${id}"}, + to: {id: "${categoryId}"} + ) { from { id } }` + }) + return ` mutation { - CreatePost( + ${id}: CreatePost( id: "${id}", title: "${title}", content: "${content}", @@ -29,6 +38,7 @@ export default function (params) { disabled: ${disabled}, deleted: ${deleted} ) { id, title } + ${categoryRelations.join('\n')} } ` } diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 981764062..187dacec6 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -27,12 +27,33 @@ import seed from './data' email: 'user@example.org', password: '1234' }, host) - await create('post', {id: 'p1'}, { headers: asAdmin } ) - await create('post', {id: 'p2'}, { headers: asModerator } ) - await create('post', {id: 'p3'}, { headers: asUser } ) - await create('post', {id: 'p4'}, { headers: asAdmin } ) - await create('post', {id: 'p5'}, { headers: asModerator } ) - await create('post', {id: 'p6'}, { headers: asUser } ) + + const categories = await Promise.all([ + create('category', { id: "cat1", name: "Just For Fun", slug: "justforfun", icon: "smile" }), + create('category', { id: "cat2", name: "Happyness & Values", slug: "happyness-values", icon: "heart-o" }), + create('category', { id: "cat3", name: "Health & Wellbeing", slug: "health-wellbeing", icon: "medkit" }), + create('category', { id: "cat4", name: "Environment & Nature", slug: "environment-nature", icon: "tree" }), + create('category', { id: "cat5", name: "Animal Protection", slug: "animalprotection", icon: "paw" }), + create('category', { id: "cat6", name: "Humanrights Justice", slug: "humanrights-justice", icon: "balance-scale" }), + create('category', { id: "cat7", name: "Education & Sciences", slug: "education-sciences", icon: "graduation-cap" }), + create('category', { id: "cat8", name: "Cooperation & Development", slug: "cooperation-development", icon: "users" }), + create('category', { id: "cat9", name: "Democracy & Politics", slug: "democracy-politics", icon: "university" }), + create('category', { id: "cat10", name: "Economy & Finances", slug: "economy-finances", icon: "money" }), + create('category', { id: "cat11", name: "Energy & Technology", slug: "energy-technology", icon: "flash" }), + create('category', { id: "cat12", name: "IT, Internet & Data Privacy", slug: "it-internet-dataprivacy", icon: "mouse-pointer" }), + create('category', { id: "cat13", name: "Art, Curlure & Sport", slug: "art-culture-sport", icon: "paint-brush" }), + create('category', { id: "cat14", name: "Freedom of Speech", slug: "freedomofspeech", icon: "bullhorn" }), + create('category', { id: "cat15", name: "Consumption & Sustainability", slug: "consumption-sustainability", icon: "shopping-cart" }), + create('category', { id: "cat16", name: "Global Peace & Nonviolence", slug: "globalpeace-nonviolence", icon: "angellist" }) + ]) + + + await create('post', {id: 'p1', categoryIds: ['cat1']}, { headers: asAdmin } ) + await create('post', {id: 'p2', categoryIds: ['cat2']}, { headers: asModerator } ) + await create('post', {id: 'p3', categoryIds: ['cat3']}, { headers: asUser } ) + await create('post', {id: 'p4', categoryIds: ['cat4']}, { headers: asAdmin } ) + await create('post', {id: 'p5', categoryIds: ['cat5']}, { headers: asModerator } ) + await create('post', {id: 'p6', categoryIds: ['cat6']}, { headers: asUser } ) } catch(err) { /* eslint-disable-next-line no-console */ console.error(err) From 924a57a7ca021e8b20882d3246aa944276ea1bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 18 Feb 2019 18:33:30 +0100 Subject: [PATCH 355/554] Seed badges and tags --- src/middleware/slugify/uniqueSlug.js | 8 +-- src/seed/data/badges.js | 12 ---- src/seed/data/index.js | 2 - src/seed/factories/badges.js | 22 +++++++ src/seed/factories/index.js | 5 +- src/seed/factories/posts.js | 10 +++- src/seed/factories/tags.js | 17 ++++++ src/seed/seed-db.js | 89 +++++++++++++++++----------- 8 files changed, 111 insertions(+), 54 deletions(-) delete mode 100644 src/seed/data/badges.js create mode 100644 src/seed/factories/badges.js create mode 100644 src/seed/factories/tags.js diff --git a/src/middleware/slugify/uniqueSlug.js b/src/middleware/slugify/uniqueSlug.js index 0f5b264a7..0f66fac5f 100644 --- a/src/middleware/slugify/uniqueSlug.js +++ b/src/middleware/slugify/uniqueSlug.js @@ -1,15 +1,15 @@ import slugify from 'slug' -export default function uniqueSlug(string, isUnique) { +export default function uniqueSlug (string, isUnique) { let slug = slugify(string, { lower: true }) - if (isUnique(slug)) return slug; + if (isUnique(slug)) return slug let count = 0 let uniqueSlug do { count += 1 uniqueSlug = `${slug}-${count}` - } while(!isUnique(uniqueSlug)); - return uniqueSlug; + } while (!isUnique(uniqueSlug)) + return uniqueSlug } diff --git a/src/seed/data/badges.js b/src/seed/data/badges.js deleted file mode 100644 index bb3ad06c7..000000000 --- a/src/seed/data/badges.js +++ /dev/null @@ -1,12 +0,0 @@ -export default function (data) { - return ` - mutation { - b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_racoon.svg") { id } - b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_rabbit.svg") { id } - b3: CreateBadge(id: "b3", key: "indiegogo_en_wolf", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_wolf.svg") { id } - b4: CreateBadge(id: "b4", key: "indiegogo_en_bear", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_bear.svg") { id } - b5: CreateBadge(id: "b5", key: "indiegogo_en_turtle", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_turtle.svg") { id } - b6: CreateBadge(id: "b6", key: "indiegogo_en_rhino", type: crowdfunding, status: permanent, icon: "/img/badges/indiegogo_en_rhino.svg") { id } - } - ` -} diff --git a/src/seed/data/index.js b/src/seed/data/index.js index 329aa7c03..d9706a6a9 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -1,6 +1,4 @@ export default { - Badge: require('./badges.js').default, - Tags: require('./tags.js').default, UserBadges: require('./users-badges.js').default, UserBlacklist: require('./users-blacklist.js').default, diff --git a/src/seed/factories/badges.js b/src/seed/factories/badges.js new file mode 100644 index 000000000..2aabe2014 --- /dev/null +++ b/src/seed/factories/badges.js @@ -0,0 +1,22 @@ +import faker from 'faker' + +export default function (params) { + const { + id = `cat${faker.random.number()}`, + key, + type = 'crowdfunding', + status = 'permanent', + icon + } = params + + return ` + mutation { + ${id}: CreateBadge( + id: "${id}", + key: "${key}", + type: ${type}, + status: ${status}, + icon: "${icon}") { id } + } + ` +} diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index c7a00a145..886dd2ad9 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -1,6 +1,5 @@ import { GraphQLClient } from 'graphql-request' import ApolloClient from 'apollo-client' -import gql from 'graphql-tag' import dotenv from 'dotenv' import { HttpLink } from 'apollo-link-http' import { InMemoryCache } from 'apollo-cache-inmemory' @@ -19,9 +18,11 @@ const apolloClient = new ApolloClient({ const driver = neo4j().getDriver() const builders = { + 'badge': require('./badges.js').default, 'user': require('./users.js').default, 'post': require('./posts.js').default, - 'category': require('./categories.js').default + 'category': require('./categories.js').default, + 'tag': require('./tags.js').default } const buildMutation = (model, parameters) => { diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index ca25f69e9..4b15ee359 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -10,7 +10,7 @@ export default function (params) { faker.lorem.sentence(), faker.lorem.sentence(), faker.lorem.sentence(), - faker.lorem.sentence(), + faker.lorem.sentence() ].join('. '), image = faker.image.image(), visibility = 'public', @@ -27,6 +27,13 @@ export default function (params) { ) { from { id } }` }) + const tagRelations = tagIds.map((tagId) => { + return `${id}_${tagId}: AddPostTags( + from: {id: "${id}"}, + to: {id: "${tagId}"} + ) { from { id } }` + }) + return ` mutation { ${id}: CreatePost( @@ -39,6 +46,7 @@ export default function (params) { deleted: ${deleted} ) { id, title } ${categoryRelations.join('\n')} + ${tagRelations.join('\n')} } ` } diff --git a/src/seed/factories/tags.js b/src/seed/factories/tags.js new file mode 100644 index 000000000..0854cc0cd --- /dev/null +++ b/src/seed/factories/tags.js @@ -0,0 +1,17 @@ +import faker from 'faker' + +export default function (params) { + const { + id = `t${faker.random.number()}`, + name + } = params + + return ` + mutation { + CreateTag( + id: "${id}", + name: "${name}", + ) { name } + } + ` +} diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 187dacec6..9f6c994ba 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -5,14 +5,13 @@ import asyncForEach from '../helpers/asyncForEach' import seed from './data' (async function () { - // prefer factories try { - const [admin, moderator, user, ...otherUsers] = await Promise.all([ - create('user', {id: 'u1', name: 'Peter Lustig' , role: 'admin' , email: 'admin@example.org', password: '1234'}), - create('user', {id: 'u2', name: 'Bob der Baumeister', role: 'moderator', email: 'moderator@example.org'}), - create('user', {id: 'u3', name: 'Jenny Rostock' , role: 'user' , email: 'user@example.org'}), - create('user', {id: 'u4', name: 'Angie Banjie' , role: 'user' , email: 'angie@example.org'}), + await Promise.all([ + create('user', { id: 'u1', name: 'Peter Lustig', role: 'admin', email: 'admin@example.org', password: '1234' }), + create('user', { id: 'u2', name: 'Bob der Baumeister', role: 'moderator', email: 'moderator@example.org' }), + create('user', { id: 'u3', name: 'Jenny Rostock', role: 'user', email: 'user@example.org' }), + create('user', { id: 'u4', name: 'Angie Banjie', role: 'user', email: 'angie@example.org' }) ]) const asAdmin = await authenticatedHeaders({ @@ -28,40 +27,65 @@ import seed from './data' password: '1234' }, host) - const categories = await Promise.all([ - create('category', { id: "cat1", name: "Just For Fun", slug: "justforfun", icon: "smile" }), - create('category', { id: "cat2", name: "Happyness & Values", slug: "happyness-values", icon: "heart-o" }), - create('category', { id: "cat3", name: "Health & Wellbeing", slug: "health-wellbeing", icon: "medkit" }), - create('category', { id: "cat4", name: "Environment & Nature", slug: "environment-nature", icon: "tree" }), - create('category', { id: "cat5", name: "Animal Protection", slug: "animalprotection", icon: "paw" }), - create('category', { id: "cat6", name: "Humanrights Justice", slug: "humanrights-justice", icon: "balance-scale" }), - create('category', { id: "cat7", name: "Education & Sciences", slug: "education-sciences", icon: "graduation-cap" }), - create('category', { id: "cat8", name: "Cooperation & Development", slug: "cooperation-development", icon: "users" }), - create('category', { id: "cat9", name: "Democracy & Politics", slug: "democracy-politics", icon: "university" }), - create('category', { id: "cat10", name: "Economy & Finances", slug: "economy-finances", icon: "money" }), - create('category', { id: "cat11", name: "Energy & Technology", slug: "energy-technology", icon: "flash" }), - create('category', { id: "cat12", name: "IT, Internet & Data Privacy", slug: "it-internet-dataprivacy", icon: "mouse-pointer" }), - create('category', { id: "cat13", name: "Art, Curlure & Sport", slug: "art-culture-sport", icon: "paint-brush" }), - create('category', { id: "cat14", name: "Freedom of Speech", slug: "freedomofspeech", icon: "bullhorn" }), - create('category', { id: "cat15", name: "Consumption & Sustainability", slug: "consumption-sustainability", icon: "shopping-cart" }), - create('category', { id: "cat16", name: "Global Peace & Nonviolence", slug: "globalpeace-nonviolence", icon: "angellist" }) + await Promise.all([ + create('category', { id: 'cat1', name: 'Just For Fun', slug: 'justforfun', icon: 'smile' }), + create('category', { id: 'cat2', name: 'Happyness & Values', slug: 'happyness-values', icon: 'heart-o' }), + create('category', { id: 'cat3', name: 'Health & Wellbeing', slug: 'health-wellbeing', icon: 'medkit' }), + create('category', { id: 'cat4', name: 'Environment & Nature', slug: 'environment-nature', icon: 'tree' }), + create('category', { id: 'cat5', name: 'Animal Protection', slug: 'animalprotection', icon: 'paw' }), + create('category', { id: 'cat6', name: 'Humanrights Justice', slug: 'humanrights-justice', icon: 'balance-scale' }), + create('category', { id: 'cat7', name: 'Education & Sciences', slug: 'education-sciences', icon: 'graduation-cap' }), + create('category', { id: 'cat8', name: 'Cooperation & Development', slug: 'cooperation-development', icon: 'users' }), + create('category', { id: 'cat9', name: 'Democracy & Politics', slug: 'democracy-politics', icon: 'university' }), + create('category', { id: 'cat10', name: 'Economy & Finances', slug: 'economy-finances', icon: 'money' }), + create('category', { id: 'cat11', name: 'Energy & Technology', slug: 'energy-technology', icon: 'flash' }), + create('category', { id: 'cat12', name: 'IT, Internet & Data Privacy', slug: 'it-internet-dataprivacy', icon: 'mouse-pointer' }), + create('category', { id: 'cat13', name: 'Art, Curlure & Sport', slug: 'art-culture-sport', icon: 'paint-brush' }), + create('category', { id: 'cat14', name: 'Freedom of Speech', slug: 'freedomofspeech', icon: 'bullhorn' }), + create('category', { id: 'cat15', name: 'Consumption & Sustainability', slug: 'consumption-sustainability', icon: 'shopping-cart' }), + create('category', { id: 'cat16', name: 'Global Peace & Nonviolence', slug: 'globalpeace-nonviolence', icon: 'angellist' }) ]) + await Promise.all([ + create('tag', { id: 't1', name: 'Umwelt' }), + create('tag', { id: 't2', name: 'Naturschutz' }), + create('tag', { id: 't3', name: 'Demokratie' }), + create('tag', { id: 't4', name: 'Freiheit' }) + ]) - await create('post', {id: 'p1', categoryIds: ['cat1']}, { headers: asAdmin } ) - await create('post', {id: 'p2', categoryIds: ['cat2']}, { headers: asModerator } ) - await create('post', {id: 'p3', categoryIds: ['cat3']}, { headers: asUser } ) - await create('post', {id: 'p4', categoryIds: ['cat4']}, { headers: asAdmin } ) - await create('post', {id: 'p5', categoryIds: ['cat5']}, { headers: asModerator } ) - await create('post', {id: 'p6', categoryIds: ['cat6']}, { headers: asUser } ) - } catch(err) { + await Promise.all([ + create('badge', { id: 'b1', key: 'indiegogo_en_racoon', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_racoon.svg' }), + create('badge', { id: 'b2', key: 'indiegogo_en_rabbit', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rabbit.svg' }), + create('badge', { id: 'b3', key: 'indiegogo_en_wolf', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_wolf.svg' }), + create('badge', { id: 'b4', key: 'indiegogo_en_bear', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_bear.svg' }), + create('badge', { id: 'b5', key: 'indiegogo_en_turtle', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_turtle.svg' }), + create('badge', { id: 'b6', key: 'indiegogo_en_rhino', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rhino.svg' }) + ]) + + await Promise.all([ + create('post', { id: 'p0', categoryIds: ['cat1'], tagIds: ['t1', 't4'] }, { headers: asAdmin }), + create('post', { id: 'p1', categoryIds: ['cat2'], tagIds: ['t2', 't3'] }, { headers: asModerator }), + create('post', { id: 'p2', categoryIds: ['cat3'], tagIds: ['t3', 't4'] }, { headers: asUser }), + create('post', { id: 'p3', categoryIds: ['cat4'], tagIds: ['t4', 't2'] }, { headers: asAdmin }), + create('post', { id: 'p4', categoryIds: ['cat5'], tagIds: ['t1', 't2'] }, { headers: asModerator }), + create('post', { id: 'p5', categoryIds: ['cat6'], tagIds: ['t2', 't4'] }, { headers: asUser }), + create('post', { id: 'p6', categoryIds: ['cat7'], tagIds: ['t1', 't4'] }, { headers: asAdmin }), + create('post', { id: 'p7', categoryIds: ['cat8'], tagIds: ['t2', 't3'] }, { headers: asModerator }), + create('post', { id: 'p8', categoryIds: ['cat9'], tagIds: ['t3', 't4'] }, { headers: asUser }), + create('post', { id: 'p10', categoryIds: ['cat11'], tagIds: ['t4', 't2'] }, { headers: asAdmin }), + create('post', { id: 'p11', categoryIds: ['cat12'], tagIds: ['t1', 't2'] }, { headers: asModerator }), + create('post', { id: 'p12', categoryIds: ['cat13'], tagIds: ['t2', 't4'] }, { headers: asUser }), + create('post', { id: 'p13', categoryIds: ['cat14'], tagIds: ['t4', 't2'] }, { headers: asAdmin }), + create('post', { id: 'p14', categoryIds: ['cat15'], tagIds: ['t1', 't2'] }, { headers: asModerator }), + create('post', { id: 'p15', categoryIds: ['cat16'], tagIds: ['t2', 't4'] }, { headers: asUser }) + ]) + } catch (err) { /* eslint-disable-next-line no-console */ console.error(err) process.exit(1) } - -let data = {} + let data = {} // legacy seeds await asyncForEach(Object.keys(seed), async key => { const mutations = seed[key] @@ -80,4 +104,3 @@ let data = {} /* eslint-disable-next-line no-console */ console.log('Seeded Data...') })() - From aa2ce1f639fcb44433f85f9d9d843bf116b24469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 18 Feb 2019 23:02:52 +0100 Subject: [PATCH 356/554] Remove redundancy in database cleaner --- src/seed/factories/index.js | 8 ++++---- src/seed/reset-db.js | 33 +++++++++++---------------------- src/seed/seed-db.js | 3 ++- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 886dd2ad9..33d2e8f44 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -37,13 +37,13 @@ const create = (model, parameters, options) => { const cleanDatabase = async () => { const session = driver.session() - const cypher = 'MATCH (n) DETACH DELETE n' + const cypher = 'MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r' try { - const result = await session.run(cypher) - session.close() - return result + return await session.run(cypher) } catch (error) { console.log(error) + } finally { + session.close() } } diff --git a/src/seed/reset-db.js b/src/seed/reset-db.js index 7d7c4f3f9..4075489f9 100644 --- a/src/seed/reset-db.js +++ b/src/seed/reset-db.js @@ -1,30 +1,19 @@ -import { query } from '../graphql-schema' +import { cleanDatabase } from './factories' import dotenv from 'dotenv' -import neo4j from '../bootstrap/neo4j' dotenv.config() if (process.env.NODE_ENV === 'production') { - throw new Error('YOU CAN`T UNSEED IN PRODUCTION MODE') + throw new Error(`YOU CAN'T CLEAN THE DATABASE WITH NODE_ENV=${process.env.NODE_ENV}`) } -const driver = neo4j().getDriver() -const session = driver.session() - -const deleteAll = ` -MATCH (n) -OPTIONAL MATCH (n)-[r]-() -DELETE n,r -` -query(deleteAll, session).then(() => { - /* eslint-disable-next-line no-console */ - console.log('Successfully deleted all nodes and relations!') -}).catch((err) => { - /* eslint-disable-next-line no-console */ - console.log(`Error occurred deleting the nodes and relations (reset the db)\n\n${err}`) -}).finally(() => { - if (session) { - session.close() +(async function () { + try { + await cleanDatabase() + console.log('Successfully deleted all nodes and relations!') + process.exit(0) + } catch (err) { + console.log(`Error occurred deleting the nodes and relations (reset the db)\n\n${err}`) + process.exit(1) } - process.exit(0) -}) +})() diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 9f6c994ba..2b1151e0d 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -4,8 +4,8 @@ import gql from 'graphql-tag' import asyncForEach from '../helpers/asyncForEach' import seed from './data' +/* eslint-disable no-multi-spaces */ (async function () { - // prefer factories try { await Promise.all([ create('user', { id: 'u1', name: 'Peter Lustig', role: 'admin', email: 'admin@example.org', password: '1234' }), @@ -104,3 +104,4 @@ import seed from './data' /* eslint-disable-next-line no-console */ console.log('Seeded Data...') })() +/* eslint-enable no-multi-spaces */ From dd8fe73e6d561e02e03e175c906812ac3dc26c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 18 Feb 2019 23:25:43 +0100 Subject: [PATCH 357/554] Create more posts, connect users with badges --- src/seed/data/index.js | 1 - src/seed/data/users-badges.js | 12 ------ src/seed/factories/users.js | 13 +++++- src/seed/seed-db.js | 77 +++++++++++++++++------------------ 4 files changed, 50 insertions(+), 53 deletions(-) delete mode 100644 src/seed/data/users-badges.js diff --git a/src/seed/data/index.js b/src/seed/data/index.js index d9706a6a9..d00d55d9f 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -1,6 +1,5 @@ export default { - UserBadges: require('./users-badges.js').default, UserBlacklist: require('./users-blacklist.js').default, UserFollows: require('./users-follows.js').default, UserFriends: require('./users-friends.js').default, diff --git a/src/seed/data/users-badges.js b/src/seed/data/users-badges.js deleted file mode 100644 index 1a8bc1fe1..000000000 --- a/src/seed/data/users-badges.js +++ /dev/null @@ -1,12 +0,0 @@ -export default function (data) { - return ` - mutation { - b1_u1: AddUserBadges(from: {id: "b1"}, to: {id: "u1"}) { from { id } } - b2_u1: AddUserBadges(from: {id: "b2"}, to: {id: "u1"}) { from { id } } - b3_u1: AddUserBadges(from: {id: "b3"}, to: {id: "u1"}) { from { id } } - b6_u2: AddUserBadges(from: {id: "b6"}, to: {id: "u2"}) { from { id } } - b3_u3: AddUserBadges(from: {id: "b3"}, to: {id: "u3"}) { from { id } } - b5_u4: AddUserBadges(from: {id: "b5"}, to: {id: "u4"}) { from { id } } - } - ` -} diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index 7ead2d9f0..a4320b341 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -8,13 +8,23 @@ export default function (params) { password = '1234', role = 'user', avatar = faker.internet.avatar(), + badgeIds = [], disabled = false, deleted = false } = params + const badgeRelations = badgeIds.map((badgeId) => { + return ` + ${id}_${badgeId}: AddUserBadges( + from: {id: "${badgeId}"}, + to: {id: "${id}"} + ) { from { id } } + ` + }) + return ` mutation { - CreateUser( + ${id}: CreateUser( id: "${id}", name: "${name}", password: "${password}", @@ -29,6 +39,7 @@ export default function (params) { avatar role } + ${badgeRelations.join('\n')} } ` } diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 2b1151e0d..32ff7b0ab 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -8,24 +8,31 @@ import seed from './data' (async function () { try { await Promise.all([ - create('user', { id: 'u1', name: 'Peter Lustig', role: 'admin', email: 'admin@example.org', password: '1234' }), - create('user', { id: 'u2', name: 'Bob der Baumeister', role: 'moderator', email: 'moderator@example.org' }), - create('user', { id: 'u3', name: 'Jenny Rostock', role: 'user', email: 'user@example.org' }), - create('user', { id: 'u4', name: 'Angie Banjie', role: 'user', email: 'angie@example.org' }) + create('badge', { id: 'b1', key: 'indiegogo_en_racoon', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_racoon.svg' }), + create('badge', { id: 'b2', key: 'indiegogo_en_rabbit', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rabbit.svg' }), + create('badge', { id: 'b3', key: 'indiegogo_en_wolf', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_wolf.svg' }), + create('badge', { id: 'b4', key: 'indiegogo_en_bear', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_bear.svg' }), + create('badge', { id: 'b5', key: 'indiegogo_en_turtle', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_turtle.svg' }), + create('badge', { id: 'b6', key: 'indiegogo_en_rhino', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rhino.svg' }) ]) - const asAdmin = await authenticatedHeaders({ - email: 'admin@example.org', - password: '1234' - }, host) - const asModerator = await authenticatedHeaders({ - email: 'moderator@example.org', - password: '1234' - }, host) - const asUser = await authenticatedHeaders({ - email: 'user@example.org', - password: '1234' - }, host) + await Promise.all([ + create('user', { id: 'u1', name: 'Peter Lustig', role: 'admin', badgeIds: ['b6'], email: 'admin@example.org' }), + create('user', { id: 'u2', name: 'Bob der Baumeister', role: 'moderator', badgeIds: ['b5'], email: 'moderator@example.org' }), + create('user', { id: 'u3', name: 'Jenny Rostock', role: 'user', badgeIds: ['b4'], email: 'user@example.org' }), + create('user', { id: 'u4', name: 'Tick', role: 'user', badgeIds: ['b3'], email: 'tick@example.org' }), + create('user', { id: 'u5', name: 'Trick', role: 'user', badgeIds: ['b2'], email: 'trick@example.org' }), + create('user', { id: 'u6', name: 'Track', role: 'user', badgeIds: ['b1'], email: 'track@example.org' }) + ]) + + const headers = await Promise.all([ + authenticatedHeaders({ email: 'admin@example.org', password: '1234' }, host), + authenticatedHeaders({ email: 'moderator@example.org', password: '1234' }, host), + authenticatedHeaders({ email: 'user@example.org', password: '1234' }, host), + authenticatedHeaders({ email: 'tick@example.org', password: '1234' }, host), + authenticatedHeaders({ email: 'trick@example.org', password: '1234' }, host), + authenticatedHeaders({ email: 'track@example.org', password: '1234' }, host), + ]) await Promise.all([ create('category', { id: 'cat1', name: 'Just For Fun', slug: 'justforfun', icon: 'smile' }), @@ -53,31 +60,23 @@ import seed from './data' create('tag', { id: 't4', name: 'Freiheit' }) ]) - await Promise.all([ - create('badge', { id: 'b1', key: 'indiegogo_en_racoon', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_racoon.svg' }), - create('badge', { id: 'b2', key: 'indiegogo_en_rabbit', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rabbit.svg' }), - create('badge', { id: 'b3', key: 'indiegogo_en_wolf', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_wolf.svg' }), - create('badge', { id: 'b4', key: 'indiegogo_en_bear', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_bear.svg' }), - create('badge', { id: 'b5', key: 'indiegogo_en_turtle', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_turtle.svg' }), - create('badge', { id: 'b6', key: 'indiegogo_en_rhino', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rhino.svg' }) - ]) await Promise.all([ - create('post', { id: 'p0', categoryIds: ['cat1'], tagIds: ['t1', 't4'] }, { headers: asAdmin }), - create('post', { id: 'p1', categoryIds: ['cat2'], tagIds: ['t2', 't3'] }, { headers: asModerator }), - create('post', { id: 'p2', categoryIds: ['cat3'], tagIds: ['t3', 't4'] }, { headers: asUser }), - create('post', { id: 'p3', categoryIds: ['cat4'], tagIds: ['t4', 't2'] }, { headers: asAdmin }), - create('post', { id: 'p4', categoryIds: ['cat5'], tagIds: ['t1', 't2'] }, { headers: asModerator }), - create('post', { id: 'p5', categoryIds: ['cat6'], tagIds: ['t2', 't4'] }, { headers: asUser }), - create('post', { id: 'p6', categoryIds: ['cat7'], tagIds: ['t1', 't4'] }, { headers: asAdmin }), - create('post', { id: 'p7', categoryIds: ['cat8'], tagIds: ['t2', 't3'] }, { headers: asModerator }), - create('post', { id: 'p8', categoryIds: ['cat9'], tagIds: ['t3', 't4'] }, { headers: asUser }), - create('post', { id: 'p10', categoryIds: ['cat11'], tagIds: ['t4', 't2'] }, { headers: asAdmin }), - create('post', { id: 'p11', categoryIds: ['cat12'], tagIds: ['t1', 't2'] }, { headers: asModerator }), - create('post', { id: 'p12', categoryIds: ['cat13'], tagIds: ['t2', 't4'] }, { headers: asUser }), - create('post', { id: 'p13', categoryIds: ['cat14'], tagIds: ['t4', 't2'] }, { headers: asAdmin }), - create('post', { id: 'p14', categoryIds: ['cat15'], tagIds: ['t1', 't2'] }, { headers: asModerator }), - create('post', { id: 'p15', categoryIds: ['cat16'], tagIds: ['t2', 't4'] }, { headers: asUser }) + create('post', { id: 'p0', categoryIds: ['cat1'], tagIds: ['t1', 't4'] }, { headers: headers[0]}), + create('post', { id: 'p1', categoryIds: ['cat2'], tagIds: ['t2', 't3'] }, { headers: headers[1]}), + create('post', { id: 'p2', categoryIds: ['cat3'], tagIds: ['t3', 't4'] }, { headers: headers[2]}), + create('post', { id: 'p3', categoryIds: ['cat4'], tagIds: ['t4', 't2'] }, { headers: headers[3]}), + create('post', { id: 'p4', categoryIds: ['cat5'], tagIds: ['t1', 't2'] }, { headers: headers[4]}), + create('post', { id: 'p5', categoryIds: ['cat6'], tagIds: ['t2', 't4'] }, { headers: headers[5]}), + create('post', { id: 'p6', categoryIds: ['cat7'], tagIds: ['t1', 't4'] }, { headers: headers[0]}), + create('post', { id: 'p7', categoryIds: ['cat8'], tagIds: ['t2', 't3'] }, { headers: headers[1]}), + create('post', { id: 'p8', categoryIds: ['cat9'], tagIds: ['t3', 't4'] }, { headers: headers[2]}), + create('post', { id: 'p10', categoryIds: ['cat11'], tagIds: ['t4', 't2'] }, { headers: headers[3]}), + create('post', { id: 'p11', categoryIds: ['cat12'], tagIds: ['t1', 't2'] }, { headers: headers[4]}), + create('post', { id: 'p12', categoryIds: ['cat13'], tagIds: ['t2', 't4'] }, { headers: headers[5]}), + create('post', { id: 'p13', categoryIds: ['cat14'], tagIds: ['t4', 't2'] }, { headers: headers[0]}), + create('post', { id: 'p14', categoryIds: ['cat15'], tagIds: ['t1', 't2'] }, { headers: headers[1]}), + create('post', { id: 'p15', categoryIds: ['cat16'], tagIds: ['t2', 't4'] }, { headers: headers[2]}) ]) } catch (err) { /* eslint-disable-next-line no-console */ From df9b4b9b8b8472ebb631a35e38010624e64eb81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 18 Feb 2019 23:37:44 +0100 Subject: [PATCH 358/554] Seed blacklisted relationships between users --- src/seed/data/index.js | 1 - src/seed/data/users-blacklist.js | 7 ------- src/seed/factories/users.js | 11 +++++++++++ src/seed/seed-db.js | 3 ++- 4 files changed, 13 insertions(+), 9 deletions(-) delete mode 100644 src/seed/data/users-blacklist.js diff --git a/src/seed/data/index.js b/src/seed/data/index.js index d00d55d9f..12008ccda 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -1,6 +1,5 @@ export default { - UserBlacklist: require('./users-blacklist.js').default, UserFollows: require('./users-follows.js').default, UserFriends: require('./users-friends.js').default, diff --git a/src/seed/data/users-blacklist.js b/src/seed/data/users-blacklist.js deleted file mode 100644 index e303c6157..000000000 --- a/src/seed/data/users-blacklist.js +++ /dev/null @@ -1,7 +0,0 @@ -export default function (data) { - return ` - mutation { - u1_blacklist_u4: AddUserBlacklisted(from: { id: "u1" }, to: { id: "u4" }) { from { id } } - } - ` -} diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index a4320b341..efea9a413 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -9,6 +9,7 @@ export default function (params) { role = 'user', avatar = faker.internet.avatar(), badgeIds = [], + blacklistedUserIds = [], disabled = false, deleted = false } = params @@ -22,6 +23,15 @@ export default function (params) { ` }) + const blacklistedUserRelations = blacklistedUserIds.map((blacklistedUserId) => { + return ` + ${id}_blacklist_${blacklistedUserId}: AddUserBlacklisted( + from: { id: "${id}" }, + to: { id: "${blacklistedUserId}" } + ) { from { id } } + ` + }) + return ` mutation { ${id}: CreateUser( @@ -40,6 +50,7 @@ export default function (params) { role } ${badgeRelations.join('\n')} + ${blacklistedUserRelations.join('\n')} } ` } diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 32ff7b0ab..78b26eb21 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -22,7 +22,8 @@ import seed from './data' create('user', { id: 'u3', name: 'Jenny Rostock', role: 'user', badgeIds: ['b4'], email: 'user@example.org' }), create('user', { id: 'u4', name: 'Tick', role: 'user', badgeIds: ['b3'], email: 'tick@example.org' }), create('user', { id: 'u5', name: 'Trick', role: 'user', badgeIds: ['b2'], email: 'trick@example.org' }), - create('user', { id: 'u6', name: 'Track', role: 'user', badgeIds: ['b1'], email: 'track@example.org' }) + create('user', { id: 'u6', name: 'Track', role: 'user', badgeIds: ['b1'], email: 'track@example.org' }), + create('user', { id: 'u7', name: 'Dagobert', role: 'user', badgeIds: ['b1', 'b2'], blacklistedUserIds: ['u4', 'u5', 'u6'], email: 'dagobert@example.org' }) ]) const headers = await Promise.all([ From f9083c8d4b1636abb4758fe8113d4a3e677fa36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 18 Feb 2019 23:39:06 +0100 Subject: [PATCH 359/554] Remove obsolete legacy seeds --- src/seed/data/tags.js | 22 ------------- src/seed/data/users.js | 70 ------------------------------------------ 2 files changed, 92 deletions(-) delete mode 100644 src/seed/data/tags.js delete mode 100644 src/seed/data/users.js diff --git a/src/seed/data/tags.js b/src/seed/data/tags.js deleted file mode 100644 index be4b3da90..000000000 --- a/src/seed/data/tags.js +++ /dev/null @@ -1,22 +0,0 @@ -export default function (data) { - return ` - mutation { - t1: CreateTag( - id: "t1", - name: "Umwelt" - ) { name } - t2: CreateTag( - id: "t2", - name: "Naturschutz" - ) { name } - t3: CreateTag( - id: "t3", - name: "Demokratie" - ) { name } - t4: CreateTag( - id: "t4", - name: "Freiheit" - ) { name } - } - ` -} diff --git a/src/seed/data/users.js b/src/seed/data/users.js deleted file mode 100644 index 8106a75f4..000000000 --- a/src/seed/data/users.js +++ /dev/null @@ -1,70 +0,0 @@ -import faker from 'faker' - -export default function (data) { - return ` - mutation { - u1: CreateUser( - id: "u1", - name: "Peter Lustig", - password: "1234", - email: "admin@example.org", - avatar: "${faker.internet.avatar()}", - locationName: "Hamburg, Germany", - role: admin, - disabled: false, - deleted: false) { - id - name - email - avatar - role - } - u2: CreateUser( - id: "u2", - name: "Bob der Bausmeister", - password: "1234", - email: "moderator@example.org", - avatar: "${faker.internet.avatar()}", - locationName: "USA", - role: moderator, - disabled: false, - deleted: false) { - id - name - email - avatar - role - } - u3: CreateUser( - id: "u3", - name: "Jenny Rostock", - password: "1234", - email: "user@example.org", - avatar: "${faker.internet.avatar()}", - role: user, - disabled: false, - deleted: false) { - id - name - email - avatar - role - } - u4: CreateUser( - id: "u4", - name: "Angie Banjie", - password: "1234", - email: "angie@example.org", - avatar: "${faker.internet.avatar()}", - role: user, - disabled: false, - deleted: false) { - id - name - email - avatar - role - } - } - ` -} From e51817c849520892519296f458e92b9ab3585fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 18 Feb 2019 23:49:54 +0100 Subject: [PATCH 360/554] Seed follow relations between users --- src/seed/data/index.js | 1 - src/seed/data/users-follows.js | 26 -------------------------- src/seed/factories/users.js | 11 +++++++++++ src/seed/seed-db.js | 12 ++++++------ 4 files changed, 17 insertions(+), 33 deletions(-) delete mode 100644 src/seed/data/users-follows.js diff --git a/src/seed/data/index.js b/src/seed/data/index.js index 12008ccda..d4a99817e 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -1,6 +1,5 @@ export default { - UserFollows: require('./users-follows.js').default, UserFriends: require('./users-friends.js').default, Organization: require('./organizations.js').default, diff --git a/src/seed/data/users-follows.js b/src/seed/data/users-follows.js deleted file mode 100644 index af6467e7f..000000000 --- a/src/seed/data/users-follows.js +++ /dev/null @@ -1,26 +0,0 @@ -export default function (data) { - return ` - mutation { - u1_follow_u2: AddUserFollowing( - from: { id: "u1" }, - to: { id: "u2" } - ) { from { id } } - u2_follow_u1: AddUserFollowing( - from: { id: "u2" }, - to: { id: "u1" } - ) { from { id } } - u2_follow_u3: AddUserFollowing( - from: { id: "u2" }, - to: { id: "u3" } - ) { from { id } } - u2_follow_u4: AddUserFollowing( - from: { id: "u2" }, - to: { id: "u4" } - ) { from { id } } - u4_follow_u2: AddUserFollowing( - from: { id: "u4" }, - to: { id: "u2" } - ) { from { id } } - } - ` -} diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index efea9a413..c9659f72c 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -10,6 +10,7 @@ export default function (params) { avatar = faker.internet.avatar(), badgeIds = [], blacklistedUserIds = [], + followedUserIds = [], disabled = false, deleted = false } = params @@ -32,6 +33,15 @@ export default function (params) { ` }) + const followedUserRelations = followedUserIds.map((followedUserId) => { + return ` + ${id}_follow_${followedUserId}: AddUserFollowing( + from: { id: "${id}" }, + to: { id: "${followedUserId}" } + ) { from { id } } + ` + }); + return ` mutation { ${id}: CreateUser( @@ -51,6 +61,7 @@ export default function (params) { } ${badgeRelations.join('\n')} ${blacklistedUserRelations.join('\n')} + ${followedUserRelations.join('\n')} } ` } diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 78b26eb21..8943c1406 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -17,12 +17,12 @@ import seed from './data' ]) await Promise.all([ - create('user', { id: 'u1', name: 'Peter Lustig', role: 'admin', badgeIds: ['b6'], email: 'admin@example.org' }), - create('user', { id: 'u2', name: 'Bob der Baumeister', role: 'moderator', badgeIds: ['b5'], email: 'moderator@example.org' }), - create('user', { id: 'u3', name: 'Jenny Rostock', role: 'user', badgeIds: ['b4'], email: 'user@example.org' }), - create('user', { id: 'u4', name: 'Tick', role: 'user', badgeIds: ['b3'], email: 'tick@example.org' }), - create('user', { id: 'u5', name: 'Trick', role: 'user', badgeIds: ['b2'], email: 'trick@example.org' }), - create('user', { id: 'u6', name: 'Track', role: 'user', badgeIds: ['b1'], email: 'track@example.org' }), + create('user', { id: 'u1', name: 'Peter Lustig', role: 'admin', followedUserIds: [ ], badgeIds: ['b6'], email: 'admin@example.org' }), + create('user', { id: 'u2', name: 'Bob der Baumeister', role: 'moderator', followedUserIds: ['u1'], badgeIds: ['b5'], email: 'moderator@example.org' }), + create('user', { id: 'u3', name: 'Jenny Rostock', role: 'user', followedUserIds: ['u2'], badgeIds: ['b4'], email: 'user@example.org' }), + create('user', { id: 'u4', name: 'Tick', role: 'user', followedUserIds: ['u3'], badgeIds: ['b3'], email: 'tick@example.org' }), + create('user', { id: 'u5', name: 'Trick', role: 'user', followedUserIds: ['u4'], badgeIds: ['b2'], email: 'trick@example.org' }), + create('user', { id: 'u6', name: 'Track', role: 'user', followedUserIds: ['u5'], badgeIds: ['b1'], email: 'track@example.org' }), create('user', { id: 'u7', name: 'Dagobert', role: 'user', badgeIds: ['b1', 'b2'], blacklistedUserIds: ['u4', 'u5', 'u6'], email: 'dagobert@example.org' }) ]) From eb22555797c658bf39085ad85619d9043f961a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Feb 2019 00:15:40 +0100 Subject: [PATCH 361/554] Change API: create/relate Separating the relations from mere properties removes boilerplate code. --- src/seed/factories/index.js | 18 +++++++++++++++++- src/seed/factories/users.js | 17 ++++++++++++++++- src/seed/seed-db.js | 8 +++++++- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 33d2e8f44..ed1ecf330 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -25,16 +25,30 @@ const builders = { 'tag': require('./tags.js').default } +const relationBuilders = { + 'user': require('./users.js').relate +} + const buildMutation = (model, parameters) => { return builders[model](parameters) } +const buildRelationMutation = (model, type, parameters) => { + return relationBuilders[model](type, parameters) +} + const create = (model, parameters, options) => { const graphQLClient = new GraphQLClient(seedServerHost, options) const mutation = buildMutation(model, parameters) return graphQLClient.request(mutation) } +const relate = (model, type, parameters, options) => { + const graphQLClient = new GraphQLClient(seedServerHost, options) + const mutation = buildRelationMutation(model, type, parameters) + return graphQLClient.request(mutation) +} + const cleanDatabase = async () => { const session = driver.session() const cypher = 'MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r' @@ -50,7 +64,9 @@ const cleanDatabase = async () => { export { driver, apolloClient, - create, buildMutation, + buildRelationMutation, + create, + relate, cleanDatabase } diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index c9659f72c..7b0f1316b 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -1,6 +1,6 @@ import faker from 'faker' -export default function (params) { +export default function create (params) { const { id = `u${faker.random.number()}`, name = faker.name.findName(), @@ -65,3 +65,18 @@ export default function (params) { } ` } + +export function relate(type, params) { + switch(type){ + case 'friends': + const { from, to } = params + return ` + mutation { + ${from}_friends_${to}: AddUserFriends( + from: { id: "${from}" }, + to: { id: "${to}" } + ) { from { id } } + } + ` + } +} diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 8943c1406..79058f0d4 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,4 +1,4 @@ -import { create, apolloClient, seedServerHost as host } from './factories' +import { create, relate, apolloClient, seedServerHost as host } from './factories' import { authenticatedHeaders } from '../jest/helpers.js' import gql from 'graphql-tag' import asyncForEach from '../helpers/asyncForEach' @@ -26,6 +26,12 @@ import seed from './data' create('user', { id: 'u7', name: 'Dagobert', role: 'user', badgeIds: ['b1', 'b2'], blacklistedUserIds: ['u4', 'u5', 'u6'], email: 'dagobert@example.org' }) ]) + await Promise.all([ + relate('user', 'friends', { from: 'u1', to: 'u2' }), + relate('user', 'friends', { from: 'u1', to: 'u3' }), + relate('user', 'friends', { from: 'u2', to: 'u3' }) + ]) + const headers = await Promise.all([ authenticatedHeaders({ email: 'admin@example.org', password: '1234' }, host), authenticatedHeaders({ email: 'moderator@example.org', password: '1234' }, host), From 62d450ef684ee6bb5670775b653086346353ca76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Feb 2019 00:54:21 +0100 Subject: [PATCH 362/554] Remove boilerplate code with method relate() --- src/seed/factories/index.js | 3 +- src/seed/factories/posts.js | 31 +++++------ src/seed/factories/users.js | 54 ++++--------------- src/seed/seed-db.js | 104 +++++++++++++++++++++++++++--------- 4 files changed, 103 insertions(+), 89 deletions(-) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index ed1ecf330..849d77dc1 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -26,7 +26,8 @@ const builders = { } const relationBuilders = { - 'user': require('./users.js').relate + 'user': require('./users.js').relate, + 'post': require('./posts.js').relate } const buildMutation = (model, parameters) => { diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index 4b15ee359..e96eb61f2 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -15,24 +15,9 @@ export default function (params) { image = faker.image.image(), visibility = 'public', disabled = false, - deleted = false, - tagIds = [], - categoryIds = [] + deleted = false } = params - const categoryRelations = categoryIds.map((categoryId) => { - return `${id}_${categoryId}: AddPostCategories( - from: {id: "${id}"}, - to: {id: "${categoryId}"} - ) { from { id } }` - }) - - const tagRelations = tagIds.map((tagId) => { - return `${id}_${tagId}: AddPostTags( - from: {id: "${id}"}, - to: {id: "${tagId}"} - ) { from { id } }` - }) return ` mutation { @@ -45,8 +30,18 @@ export default function (params) { disabled: ${disabled}, deleted: ${deleted} ) { id, title } - ${categoryRelations.join('\n')} - ${tagRelations.join('\n')} + } + ` +} + +export function relate(type, params) { + const { from, to } = params + return ` + mutation { + ${from}_${type}_${to}: AddPost${type}( + from: { id: "${from}" }, + to: { id: "${to}" } + ) { from { id } } } ` } diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index 7b0f1316b..f1198cb7a 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -8,40 +8,10 @@ export default function create (params) { password = '1234', role = 'user', avatar = faker.internet.avatar(), - badgeIds = [], - blacklistedUserIds = [], - followedUserIds = [], disabled = false, deleted = false } = params - const badgeRelations = badgeIds.map((badgeId) => { - return ` - ${id}_${badgeId}: AddUserBadges( - from: {id: "${badgeId}"}, - to: {id: "${id}"} - ) { from { id } } - ` - }) - - const blacklistedUserRelations = blacklistedUserIds.map((blacklistedUserId) => { - return ` - ${id}_blacklist_${blacklistedUserId}: AddUserBlacklisted( - from: { id: "${id}" }, - to: { id: "${blacklistedUserId}" } - ) { from { id } } - ` - }) - - const followedUserRelations = followedUserIds.map((followedUserId) => { - return ` - ${id}_follow_${followedUserId}: AddUserFollowing( - from: { id: "${id}" }, - to: { id: "${followedUserId}" } - ) { from { id } } - ` - }); - return ` mutation { ${id}: CreateUser( @@ -59,24 +29,18 @@ export default function create (params) { avatar role } - ${badgeRelations.join('\n')} - ${blacklistedUserRelations.join('\n')} - ${followedUserRelations.join('\n')} } ` } export function relate(type, params) { - switch(type){ - case 'friends': - const { from, to } = params - return ` - mutation { - ${from}_friends_${to}: AddUserFriends( - from: { id: "${from}" }, - to: { id: "${to}" } - ) { from { id } } - } - ` - } + const { from, to } = params + return ` + mutation { + ${from}_${type}_${to}: AddUser${type}( + from: { id: "${from}" }, + to: { id: "${to}" } + ) { from { id } } + } + ` } diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 79058f0d4..4ef55bec6 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -7,6 +7,7 @@ import seed from './data' /* eslint-disable no-multi-spaces */ (async function () { try { + await Promise.all([ create('badge', { id: 'b1', key: 'indiegogo_en_racoon', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_racoon.svg' }), create('badge', { id: 'b2', key: 'indiegogo_en_rabbit', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rabbit.svg' }), @@ -17,19 +18,34 @@ import seed from './data' ]) await Promise.all([ - create('user', { id: 'u1', name: 'Peter Lustig', role: 'admin', followedUserIds: [ ], badgeIds: ['b6'], email: 'admin@example.org' }), - create('user', { id: 'u2', name: 'Bob der Baumeister', role: 'moderator', followedUserIds: ['u1'], badgeIds: ['b5'], email: 'moderator@example.org' }), - create('user', { id: 'u3', name: 'Jenny Rostock', role: 'user', followedUserIds: ['u2'], badgeIds: ['b4'], email: 'user@example.org' }), - create('user', { id: 'u4', name: 'Tick', role: 'user', followedUserIds: ['u3'], badgeIds: ['b3'], email: 'tick@example.org' }), - create('user', { id: 'u5', name: 'Trick', role: 'user', followedUserIds: ['u4'], badgeIds: ['b2'], email: 'trick@example.org' }), - create('user', { id: 'u6', name: 'Track', role: 'user', followedUserIds: ['u5'], badgeIds: ['b1'], email: 'track@example.org' }), - create('user', { id: 'u7', name: 'Dagobert', role: 'user', badgeIds: ['b1', 'b2'], blacklistedUserIds: ['u4', 'u5', 'u6'], email: 'dagobert@example.org' }) + create('user', { id: 'u1', name: 'Peter Lustig', role: 'admin', email: 'admin@example.org' }), + create('user', { id: 'u2', name: 'Bob der Baumeister', role: 'moderator', email: 'moderator@example.org' }), + create('user', { id: 'u3', name: 'Jenny Rostock', role: 'user', email: 'user@example.org' }), + create('user', { id: 'u4', name: 'Tick', role: 'user', email: 'tick@example.org' }), + create('user', { id: 'u5', name: 'Trick', role: 'user', email: 'trick@example.org' }), + create('user', { id: 'u6', name: 'Track', role: 'user', email: 'track@example.org' }), + create('user', { id: 'u7', name: 'Dagobert', role: 'user', email: 'dagobert@example.org' }) ]) await Promise.all([ - relate('user', 'friends', { from: 'u1', to: 'u2' }), - relate('user', 'friends', { from: 'u1', to: 'u3' }), - relate('user', 'friends', { from: 'u2', to: 'u3' }) + relate('user', 'Badges', { from: 'b6', to: 'u1' }), + relate('user', 'Badges', { from: 'b5', to: 'u2' }), + relate('user', 'Badges', { from: 'b4', to: 'u3' }), + relate('user', 'Badges', { from: 'b3', to: 'u4' }), + relate('user', 'Badges', { from: 'b2', to: 'u5' }), + relate('user', 'Badges', { from: 'b1', to: 'u6' }), + relate('user', 'Following', { from: 'u1', to: 'u2' }), + relate('user', 'Following', { from: 'u2', to: 'u3' }), + relate('user', 'Following', { from: 'u3', to: 'u4' }), + relate('user', 'Following', { from: 'u4', to: 'u5' }), + relate('user', 'Following', { from: 'u5', to: 'u6' }), + relate('user', 'Following', { from: 'u6', to: 'u7' }), + relate('user', 'Friends', { from: 'u1', to: 'u2' }), + relate('user', 'Friends', { from: 'u1', to: 'u3' }), + relate('user', 'Friends', { from: 'u2', to: 'u3' }), + relate('user', 'Blacklisted', { from: 'u7', to: 'u4' }), + relate('user', 'Blacklisted', { from: 'u7', to: 'u5' }), + relate('user', 'Blacklisted', { from: 'u7', to: 'u6' }) ]) const headers = await Promise.all([ @@ -69,22 +85,60 @@ import seed from './data' await Promise.all([ - create('post', { id: 'p0', categoryIds: ['cat1'], tagIds: ['t1', 't4'] }, { headers: headers[0]}), - create('post', { id: 'p1', categoryIds: ['cat2'], tagIds: ['t2', 't3'] }, { headers: headers[1]}), - create('post', { id: 'p2', categoryIds: ['cat3'], tagIds: ['t3', 't4'] }, { headers: headers[2]}), - create('post', { id: 'p3', categoryIds: ['cat4'], tagIds: ['t4', 't2'] }, { headers: headers[3]}), - create('post', { id: 'p4', categoryIds: ['cat5'], tagIds: ['t1', 't2'] }, { headers: headers[4]}), - create('post', { id: 'p5', categoryIds: ['cat6'], tagIds: ['t2', 't4'] }, { headers: headers[5]}), - create('post', { id: 'p6', categoryIds: ['cat7'], tagIds: ['t1', 't4'] }, { headers: headers[0]}), - create('post', { id: 'p7', categoryIds: ['cat8'], tagIds: ['t2', 't3'] }, { headers: headers[1]}), - create('post', { id: 'p8', categoryIds: ['cat9'], tagIds: ['t3', 't4'] }, { headers: headers[2]}), - create('post', { id: 'p10', categoryIds: ['cat11'], tagIds: ['t4', 't2'] }, { headers: headers[3]}), - create('post', { id: 'p11', categoryIds: ['cat12'], tagIds: ['t1', 't2'] }, { headers: headers[4]}), - create('post', { id: 'p12', categoryIds: ['cat13'], tagIds: ['t2', 't4'] }, { headers: headers[5]}), - create('post', { id: 'p13', categoryIds: ['cat14'], tagIds: ['t4', 't2'] }, { headers: headers[0]}), - create('post', { id: 'p14', categoryIds: ['cat15'], tagIds: ['t1', 't2'] }, { headers: headers[1]}), - create('post', { id: 'p15', categoryIds: ['cat16'], tagIds: ['t2', 't4'] }, { headers: headers[2]}) + create('post', { id: 'p0', tagIds: ['t1', 't4'] }, { headers: headers[0]}), + create('post', { id: 'p1', tagIds: ['t2', 't3'] }, { headers: headers[1]}), + create('post', { id: 'p2', tagIds: ['t3', 't4'] }, { headers: headers[2]}), + create('post', { id: 'p3', tagIds: ['t4', 't2'] }, { headers: headers[3]}), + create('post', { id: 'p4', tagIds: ['t1', 't2'] }, { headers: headers[4]}), + create('post', { id: 'p5', tagIds: ['t2', 't4'] }, { headers: headers[5]}), + create('post', { id: 'p6', tagIds: ['t1', 't4'] }, { headers: headers[0]}), + create('post', { id: 'p7', tagIds: ['t2', 't3'] }, { headers: headers[1]}), + create('post', { id: 'p8', tagIds: ['t3', 't4'] }, { headers: headers[2]}), + create('post', { id: 'p9', tagIds: ['t3', 't4'] }, { headers: headers[3]}), + create('post', { id: 'p10', tagIds: ['t4', 't2'] }, { headers: headers[4]}), + create('post', { id: 'p11', tagIds: ['t1', 't2'] }, { headers: headers[5]}), + create('post', { id: 'p12', tagIds: ['t2', 't4'] }, { headers: headers[0]}), + create('post', { id: 'p13', tagIds: ['t4', 't2'] }, { headers: headers[1]}), + create('post', { id: 'p14', tagIds: ['t1', 't2'] }, { headers: headers[2]}), + create('post', { id: 'p15', tagIds: ['t2', 't4'] }, { headers: headers[3]}) ]) + + await Promise.all([ + relate('post', 'Categories', { from: 'p0', to: 'cat16' }), + relate('post', 'Categories', { from: 'p1', to: 'cat1' }), + relate('post', 'Categories', { from: 'p2', to: 'cat2' }), + relate('post', 'Categories', { from: 'p3', to: 'cat3' }), + relate('post', 'Categories', { from: 'p4', to: 'cat4' }), + relate('post', 'Categories', { from: 'p5', to: 'cat5' }), + relate('post', 'Categories', { from: 'p6', to: 'cat6' }), + relate('post', 'Categories', { from: 'p7', to: 'cat7' }), + relate('post', 'Categories', { from: 'p8', to: 'cat8' }), + relate('post', 'Categories', { from: 'p9', to: 'cat9' }), + relate('post', 'Categories', { from: 'p10', to: 'cat10' }), + relate('post', 'Categories', { from: 'p11', to: 'cat11' }), + relate('post', 'Categories', { from: 'p12', to: 'cat12' }), + relate('post', 'Categories', { from: 'p13', to: 'cat13' }), + relate('post', 'Categories', { from: 'p14', to: 'cat14' }), + relate('post', 'Categories', { from: 'p15', to: 'cat15' }), + + relate('post', 'Tags', { from: 'p0', to: 't4' }), + relate('post', 'Tags', { from: 'p1', to: 't1' }), + relate('post', 'Tags', { from: 'p2', to: 't2' }), + relate('post', 'Tags', { from: 'p3', to: 't3' }), + relate('post', 'Tags', { from: 'p4', to: 't4' }), + relate('post', 'Tags', { from: 'p5', to: 't1' }), + relate('post', 'Tags', { from: 'p6', to: 't2' }), + relate('post', 'Tags', { from: 'p7', to: 't3' }), + relate('post', 'Tags', { from: 'p8', to: 't4' }), + relate('post', 'Tags', { from: 'p9', to: 't1' }), + relate('post', 'Tags', { from: 'p10', to: 't2' }), + relate('post', 'Tags', { from: 'p11', to: 't3' }), + relate('post', 'Tags', { from: 'p12', to: 't4' }), + relate('post', 'Tags', { from: 'p13', to: 't1' }), + relate('post', 'Tags', { from: 'p14', to: 't2' }), + relate('post', 'Tags', { from: 'p15', to: 't3' }), + ]) + } catch (err) { /* eslint-disable-next-line no-console */ console.error(err) From a981181e94adef6fdb634d18eb55110a9fc29117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Feb 2019 01:04:05 +0100 Subject: [PATCH 363/554] Seed user shouts --- src/seed/data/index.js | 2 -- src/seed/data/users-friends.js | 14 -------------- src/seed/data/users-shouts.js | 30 ------------------------------ src/seed/seed-db.js | 8 ++++++++ 4 files changed, 8 insertions(+), 46 deletions(-) delete mode 100644 src/seed/data/users-friends.js delete mode 100644 src/seed/data/users-shouts.js diff --git a/src/seed/data/index.js b/src/seed/data/index.js index d4a99817e..4bf0669ff 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -1,10 +1,8 @@ export default { - UserFriends: require('./users-friends.js').default, Organization: require('./organizations.js').default, Comment: require('./comments.js').default, - UserShouts: require('./users-shouts.js').default // Reports: require('./reports.js').default } diff --git a/src/seed/data/users-friends.js b/src/seed/data/users-friends.js deleted file mode 100644 index 33d7db7e4..000000000 --- a/src/seed/data/users-friends.js +++ /dev/null @@ -1,14 +0,0 @@ -export default function (data) { - return ` - mutation { - u1_friends_u2: AddUserFriends( - from: { id: "u1" }, - to: { id: "u2" } - ) { from { id } } - u1_friends_u3: AddUserFriends( - from: { id: "u1" }, - to: { id: "u3" } - ) { from { id } } - } - ` -} diff --git a/src/seed/data/users-shouts.js b/src/seed/data/users-shouts.js deleted file mode 100644 index 9c0f2d1bf..000000000 --- a/src/seed/data/users-shouts.js +++ /dev/null @@ -1,30 +0,0 @@ -export default function (data) { - return ` - mutation { - u1s2: AddUserShouted( - from: { id: "u1" }, - to: { id: "p2" } - ) { from { id } } - u1s3: AddUserShouted( - from: { id: "u1" }, - to: { id: "p3" } - ) { from { id } } - u2s1: AddUserShouted( - from: { id: "u2" }, - to: { id: "p1" } - ) { from { id } } - u3s1: AddUserShouted( - from: { id: "u3" }, - to: { id: "p1" } - ) { from { id } } - u3s4: AddUserShouted( - from: { id: "u3" }, - to: { id: "p4" } - ) { from { id } } - u4s1: AddUserShouted( - from: { id: "u4" }, - to: { id: "p1" } - ) { from { id } } - } - ` -} diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 4ef55bec6..917298569 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -138,6 +138,14 @@ import seed from './data' relate('post', 'Tags', { from: 'p14', to: 't2' }), relate('post', 'Tags', { from: 'p15', to: 't3' }), ]) + await Promise.all([ + relate('user', 'Shouted', { from: 'u1', to: 'p2' }), + relate('user', 'Shouted', { from: 'u1', to: 'p3' }), + relate('user', 'Shouted', { from: 'u2', to: 'p1' }), + relate('user', 'Shouted', { from: 'u3', to: 'p1' }), + relate('user', 'Shouted', { from: 'u3', to: 'p4' }), + relate('user', 'Shouted', { from: 'u4', to: 'p1' }) + ]) } catch (err) { /* eslint-disable-next-line no-console */ From 1afcb4b0c976ee7f2166abdba5a20a7ecec4047e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Feb 2019 01:17:38 +0100 Subject: [PATCH 364/554] Seed organizations --- src/seed/data/index.js | 2 -- src/seed/data/organizations.js | 51 ----------------------------- src/seed/factories/index.js | 2 ++ src/seed/factories/organizations.js | 35 ++++++++++++++++++++ src/seed/seed-db.js | 15 +++++++++ 5 files changed, 52 insertions(+), 53 deletions(-) delete mode 100644 src/seed/data/organizations.js create mode 100644 src/seed/factories/organizations.js diff --git a/src/seed/data/index.js b/src/seed/data/index.js index 4bf0669ff..a77c6e6fb 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -1,7 +1,5 @@ export default { - - Organization: require('./organizations.js').default, Comment: require('./comments.js').default, // Reports: require('./reports.js').default diff --git a/src/seed/data/organizations.js b/src/seed/data/organizations.js deleted file mode 100644 index b8b9075d4..000000000 --- a/src/seed/data/organizations.js +++ /dev/null @@ -1,51 +0,0 @@ -export default () => { - return `mutation { - o1: CreateOrganization( - id: "o1", - name: "Democracy Deutschland", - description: "Description for democracy-deutschland.", - disabled: false, - deleted: false - ) { name } - o2: CreateOrganization( - id: "o2", - name: "Human-Connection", - description: "Description for human-connection.", - disabled: false, - deleted: false - ) { name } - o3: CreateOrganization( - id: "o3", - name: "Pro Veg", - description: "Description for pro-veg.", - disabled: false, - deleted: false - ) { name } - o4: CreateOrganization( - id: "o4", - name: "Greenpeace", - description: "Description for greenpeace.", - disabled: false, - deleted: false - ) { name } - - u1_c_o1: AddOrganizationCreatedBy( - from: { id: "u1" }, - to: { id: "o1" } - ) { from { id } } - u1_c_o2: AddOrganizationCreatedBy( - from: { id: "u1" }, - to: { id: "o2" } - ) { from { id } } - - u2_o_o1: AddOrganizationOwnedBy( - from: { id: "u2" }, - to: { id: "o2" } - ) { from { id } } - u2_c_o3: AddOrganizationOwnedBy( - from: { id: "u2" }, - to: { id: "o3" } - ) { from { id } } - } -` -} diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 849d77dc1..93916f376 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -20,6 +20,7 @@ const driver = neo4j().getDriver() const builders = { 'badge': require('./badges.js').default, 'user': require('./users.js').default, + 'organization': require('./organizations.js').default, 'post': require('./posts.js').default, 'category': require('./categories.js').default, 'tag': require('./tags.js').default @@ -27,6 +28,7 @@ const builders = { const relationBuilders = { 'user': require('./users.js').relate, + 'organization': require('./organizations.js').relate, 'post': require('./posts.js').relate } diff --git a/src/seed/factories/organizations.js b/src/seed/factories/organizations.js new file mode 100644 index 000000000..047398eb0 --- /dev/null +++ b/src/seed/factories/organizations.js @@ -0,0 +1,35 @@ +import faker from 'faker' + +export default function create (params) { + const { + id = `o${faker.random.number()}`, + name = faker.comany.companyName(), + description = faker.company.catchPhrase(), + disabled = false, + deleted = false + } = params + + return ` + mutation { + ${id}: CreateOrganization( + id: "${id}", + name: "${name}", + description: "${description}", + disabled: ${disabled}, + deleted: ${deleted} + ) { name } + } + ` +} + +export function relate(type, params) { + const { from, to } = params + return ` + mutation { + ${from}_${type}_${to}: AddOrganization${type}( + from: { id: "${from}" }, + to: { id: "${to}" } + ) { from { id } } + } + ` +} diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 917298569..1a259f4cc 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -147,6 +147,21 @@ import seed from './data' relate('user', 'Shouted', { from: 'u4', to: 'p1' }) ]) + await Promise.all([ + create('organization', { id: "o1", name: "Democracy Deutschland", description: "Description for democracy-deutschland."}), + create('organization', { id: "o2", name: "Human-Connection", description: "Description for human-connection." }), + create('organization', { id: "o3", name: "Pro Veg", description: "Description for pro-veg." }), + create('organization', { id: "o4", name: "Greenpeace", description: "Description for greenpeace." }) + ]) + + await Promise.all([ + relate('organization', 'CreatedBy', {from: 'u1', to: 'o1'}), + relate('organization', 'CreatedBy', {from: 'u1', to: 'o2'}), + relate('organization', 'OwnedBy', {from: 'u2', to: 'o2'}), + relate('organization', 'OwnedBy', {from: 'u2', to: 'o3'}) + ]) + + } catch (err) { /* eslint-disable-next-line no-console */ console.error(err) From 4488cc9864acad6839b33da84b9fe59f3e72a4fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Feb 2019 01:43:11 +0100 Subject: [PATCH 365/554] Seed comments --- src/seed/data/comments.js | 80 ----------------------- src/seed/data/index.js | 6 -- src/seed/data/posts.js | 112 --------------------------------- src/seed/factories/comments.js | 37 +++++++++++ src/seed/factories/index.js | 4 +- src/seed/factories/posts.js | 1 - src/seed/seed-db.js | 52 ++++++++------- 7 files changed, 69 insertions(+), 223 deletions(-) delete mode 100644 src/seed/data/comments.js delete mode 100644 src/seed/data/index.js delete mode 100644 src/seed/data/posts.js create mode 100644 src/seed/factories/comments.js diff --git a/src/seed/data/comments.js b/src/seed/data/comments.js deleted file mode 100644 index ac1849b86..000000000 --- a/src/seed/data/comments.js +++ /dev/null @@ -1,80 +0,0 @@ -import faker from 'faker' - -/** - * TODO: add a comment automatically to the correct post and relate it to the current user - */ -export default function (data) { - return ` - mutation { - c1: CreateComment( - id: "c1", - content: "

da stimm ich dir zu. Mir ging das auch nie in den kopf, und hatte jesus nie als gott gesehen

" - ) { id } - c1_u1: AddCommentAuthor(from: { id: "u3" }, to: { id: "c1" }) { from { id } } - c1_p1: AddCommentPost( - from: { id: "c1" }, - to: { id: "p1" } - ) { from { id } } - - c2: CreateComment( - id: "c2", - content: "

Schön das es dich gibt ❤️❤️❤️❤️❤️❤️❤️❤️❤️

" - ) { id } - c2_u1: AddCommentAuthor(from: { id: "u1" }, to: { id: "c2" }) { from { id } } - c2_p1: AddCommentPost( - from: { id: "c2" }, - to: { id: "p1" } - ) { from { id } } - - c3: CreateComment( - id: "c3", - content: "

Hi Dieter,

danke fĂźr Deine Info. Hast Du mal ein Foto von Deinem Cabrio mit dem Logo drauf?

" - ) { id } - c3_u2: AddCommentAuthor(from: { id: "u1" }, to: { id: "c3" }) { from { id } } - c3_p3: AddCommentPost( - from: { id: "c3" }, - to: { id: "p3" } - ) { from { id } } - - c4: CreateComment( - id: "c4", - content: "

Das ZusammenfĂźhren aller Gruppen, die mit uns am gleichen Strang in die gleiche Richtung ziehen, in eine gemeinsame Adressenstruktur sehe ich auch als Haupt - Aufgabe fĂźr unsere neue Netzwerkbildung an.

" - ) { id } - c4_u3: AddCommentAuthor(from: { id: "u4" }, to: { id: "c4" }) { from { id } } - c4_p2: AddCommentPost( - from: { id: "c4" }, - to: { id: "p2" } - ) { from { id } } - - c5: CreateComment( - id: "c5", - content: "${faker.lorem.paragraph()}" - ) { id } - c5_u4: AddCommentAuthor(from: { id: "u4" }, to: { id: "c5" }) { from { id } } - c5_p3: AddCommentPost( - from: { id: "c5" }, - to: { id: "p3" } - ) { from { id } } - - c6: CreateComment( - id: "c6", - content: "${faker.lorem.paragraph()}" - ) { id } - c6_u3: AddCommentAuthor(from: { id: "u3" }, to: { id: "c6" }) { from { id } } - c6_p4: AddCommentPost( - from: { id: "c6" }, - to: { id: "p4" } - ) { from { id } } - - c7: CreateComment( - id: "c7", - content: "${faker.lorem.paragraph()}" - ) { id } - c7_u2: AddCommentAuthor(from: { id: "u2" }, to: { id: "c7" }) { from { id } } - c7_p2: AddCommentPost( - from: { id: "c7" }, - to: { id: "p2" } - ) { from { id } } - } - ` -} diff --git a/src/seed/data/index.js b/src/seed/data/index.js deleted file mode 100644 index a77c6e6fb..000000000 --- a/src/seed/data/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - - Comment: require('./comments.js').default, - - // Reports: require('./reports.js').default -} diff --git a/src/seed/data/posts.js b/src/seed/data/posts.js deleted file mode 100644 index 8624c422d..000000000 --- a/src/seed/data/posts.js +++ /dev/null @@ -1,112 +0,0 @@ -import faker from 'faker' - -export default function (data) { - return ` - mutation { - p1: CreatePost( - id: "p1", - title: "Gedanken eines Polizisten zum Einsatz im Hambacher Forst", - content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :)


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION❤️

", - image: "https://picsum.photos/1280/1024?image=352", - visibility: public, - disabled: false, - deleted: false - ) { title } - p1_cat1: AddPostCategories(from: {id: "p1"}, to: {id: "cat1"}) { from { id } } - p1_cat2: AddPostCategories(from: {id: "p1"}, to: {id: "cat2"}) { from { id } } - ur1: AddUserContributions(from: { id: "u1" }, to: { id: "p1" }) { from { id } } - p1_t1: AddPostTags( - from: { id: "p1" } - to: { id: "t1" } - ) { from { id } } - p1_t2: AddPostTags( - from: { id: "p1" } - to: { id: "t2" } - ) { from { id } } - p1_t3: AddPostTags( - from: { id: "p1" } - to: { id: "t3" } - ) { from { id } } - - p2: CreatePost( - id: "p2", - title: "Julian Assange", - content: "

Diese Zukunftsstadt ist real und keine Computer-Animation – sondern sie ist das Lebenswerk des mittlerweile über 100 Jahre alten Futuristen und Architekten Jacque Fresco aus Florida. In 35 Jahren (seit seinem 13. Lebensjahr) hat dieser zusammen mit seiner Frau seinen futuristischen Traum von einer besonderen Zukunftsstadt auf 85.000 Quadratmetern realisiert. In den Gebäuden und Gärten befinden sich u.a. ein Forschungszentrum, Vortragsräume und unzählige seiner Modelle & Architekturentwürfe.


Sein zentrales Anliegen ist eine resourcenbasierte Wirtschaft und die Abschaffung von Geld und Privatbesitz. Mit Hilfe von Roboterarbeit und dem Bedingungslosen Grundeinkommen (da nach seiner Ansicht in den kommenden Jahren fast alle Jobs automatisiert werden), möchte er eine ökologische Landwirtschaft mit Permakulturen etc. und eine effiziente Energiegewinnung (ausschließlich durch regenerative Energien) schaffen. Wenige kompatible Formen in einer sparsamen Modulbauweise (in die u.a. bereits variable Service- und Reparaturelemente integriert sind) sollen insgesamt eine soziale & ökologische Utopie im Einklang mit der Natur ermöglichen.


Nachfolgend der Direkt-Link auf den interessanten Artikel von Zoltan Istvan, der den Architekten und seine Frau in Florida besuchen durfte und seinen Artikel Ende 2016 auf „MOTHERBOARD“ veröffentlicht hatte:


https://motherboard.vice.com/de/article/vv34nb/ich-habe-die-zukunft-besucht-in-der-wir-ohne-geld-steuern-und-besitz-leben


Da soll noch jemand behaupten, es gäbe keine Utopien mehr bzw. keine Futuristen, die ihre kreativen und zukunftsfähigen Ideen (auch in ganz großem Stil) selbst in die Tat umsetzen. LG @all :)


Wir sind eine Menschheitsfamilie. • Wir sind eins. • Wir sind HUMAN CONNECTION❤️

", - image: "https://picsum.photos/1280/1024?image=72", - visibility: public, - disabled: false, - deleted: false - ) { title } - p2_cat1: AddPostCategories(from: {id: "p2"}, to: {id: "cat1"}) { from { id } } - p2_cat16: AddPostCategories(from: {id: "p2"}, to: {id: "cat16"}) { from { id } } - ur2: AddUserContributions(from: { id: "u2" }, to: { id: "p2" }) { from { id } } - p2_t4: AddPostTags( - from: { id: "p2" } - to: { id: "t4" } - ) { from { id } } - - p3: CreatePost( - id: "p3", - title: "Hacker, Freaks und Funktionäre...Der CCC", - content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", - image: "https://picsum.photos/1280/1024?image=121", - visibility: public, - disabled: false, - deleted: false - ) { title } - p3_cat1: AddPostCategories(from: {id: "p3"}, to: {id: "cat1"}) { from { id } } - p3_cat3: AddPostCategories(from: {id: "p3"}, to: {id: "cat3"}) { from { id } } - p3_cat14: AddPostCategories(from: {id: "p3"}, to: {id: "cat14"}) { from { id } } - ur3: AddUserContributions(from: { id: "u3" }, to: { id: "p3" }) { from { id } } - p3_t2: AddPostTags( - from: { id: "p3" } - to: { id: "t2" } - ) { from { id } } - p3_t4: AddPostTags( - from: { id: "p3" } - to: { id: "t4" } - ) { from { id } } - - p4: CreatePost( - id: "p4", - title: "Lebensmittel (?)", - content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", - image: "https://picsum.photos/1280/1024?image=142", - visibility: public, - disabled: false, - deleted: false - ) { title } - p4_cat1: AddPostCategories(from: {id: "p4"}, to: {id: "cat1"}) { from { id } } - p4_cat9: AddPostCategories(from: {id: "p4"}, to: {id: "cat9"}) { from { id } } - p4_cat4: AddPostCategories(from: {id: "p4"}, to: {id: "cat4"}) { from { id } } - ur4: AddUserContributions(from: { id: "u4" }, to: { id: "p4" }) { from { id } } - - p5: CreatePost( - id: "p5", - title: "${faker.lorem.sentence()}", - content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", - image: "https://picsum.photos/1280/1024?image=231", - visibility: public, - disabled: false, - deleted: false - ) { title } - p5_cat8: AddPostCategories(from: {id: "p5"}, to: {id: "cat8"}) { from { id } } - p5_cat12: AddPostCategories(from: {id: "p5"}, to: {id: "cat12"}) { from { id } } - ur5: AddUserContributions(from: { id: "u2" }, to: { id: "p5" }) { from { id } } - - p6: CreatePost( - id: "p6", - title: "${faker.lorem.sentence()}", - content: "${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()} ${faker.lorem.sentence()}", - image: "https://picsum.photos/1280/1024?image=424", - visibility: public, - disabled: false, - deleted: false - ) { title } - p6_cat1: AddPostCategories(from: {id: "p6"}, to: {id: "cat1"}) { from { id } } - p6_cat2: AddPostCategories(from: {id: "p6"}, to: {id: "cat2"}) { from { id } } - p6_cat5: AddPostCategories(from: {id: "p6"}, to: {id: "cat5"}) { from { id } } - ur6: AddUserContributions(from: { id: "u4" }, to: { id: "p6" }) { from { id } } - } - ` -} diff --git a/src/seed/factories/comments.js b/src/seed/factories/comments.js new file mode 100644 index 000000000..184b06bf0 --- /dev/null +++ b/src/seed/factories/comments.js @@ -0,0 +1,37 @@ +import faker from 'faker' + +export default function (params) { + const { + id = `c${faker.random.number()}`, + content = [ + faker.lorem.sentence(), + faker.lorem.sentence() + ].join('. '), + disabled = false, + deleted = false + } = params + + + return ` + mutation { + ${id}: CreateComment( + id: "${id}", + content: "${content}", + disabled: ${disabled}, + deleted: ${deleted} + ) { id } + } + ` +} + +export function relate(type, params) { + const { from, to } = params + return ` + mutation { + ${from}_${type}_${to}: AddComment${type}( + from: { id: "${from}" }, + to: { id: "${to}" } + ) { from { id } } + } + ` +} diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 93916f376..89fa6144e 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -22,6 +22,7 @@ const builders = { 'user': require('./users.js').default, 'organization': require('./organizations.js').default, 'post': require('./posts.js').default, + 'comment': require('./comments.js').default, 'category': require('./categories.js').default, 'tag': require('./tags.js').default } @@ -29,7 +30,8 @@ const builders = { const relationBuilders = { 'user': require('./users.js').relate, 'organization': require('./organizations.js').relate, - 'post': require('./posts.js').relate + 'post': require('./posts.js').relate, + 'comment': require('./comments.js').relate } const buildMutation = (model, parameters) => { diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index e96eb61f2..e547efb01 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -1,4 +1,3 @@ - import faker from 'faker' export default function (params) { diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 1a259f4cc..bab59a966 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,8 +1,5 @@ import { create, relate, apolloClient, seedServerHost as host } from './factories' import { authenticatedHeaders } from '../jest/helpers.js' -import gql from 'graphql-tag' -import asyncForEach from '../helpers/asyncForEach' -import seed from './data' /* eslint-disable no-multi-spaces */ (async function () { @@ -147,6 +144,33 @@ import seed from './data' relate('user', 'Shouted', { from: 'u4', to: 'p1' }) ]) + await Promise.all([ + create('comment', { id: "c1"}), + create('comment', { id: "c2"}), + create('comment', { id: "c3"}), + create('comment', { id: "c4"}), + create('comment', { id: "c5"}), + create('comment', { id: "c6"}), + create('comment', { id: "c7"}), + ]) + + await Promise.all([ + relate('comment', 'Author', { from: 'u3', to: 'c1'}), + relate('comment', 'Post', { from: 'c1', to: 'p1'}), + relate('comment', 'Author', { from: 'u1', to: 'c2'}), + relate('comment', 'Post', { from: 'c2', to: 'p1'}), + relate('comment', 'Author', { from: 'u1', to: 'c3'}), + relate('comment', 'Post', { from: 'c3', to: 'p3'}), + relate('comment', 'Author', { from: 'u4', to: 'c4'}), + relate('comment', 'Post', { from: 'c4', to: 'p2'}), + relate('comment', 'Author', { from: 'u4', to: 'c5'}), + relate('comment', 'Post', { from: 'c5', to: 'p3'}), + relate('comment', 'Author', { from: 'u3', to: 'c6'}), + relate('comment', 'Post', { from: 'c6', to: 'p4'}), + relate('comment', 'Author', { from: 'u2', to: 'c7'}), + relate('comment', 'Post', { from: 'c7', to: 'p2'}), + ]) + await Promise.all([ create('organization', { id: "o1", name: "Democracy Deutschland", description: "Description for democracy-deutschland."}), create('organization', { id: "o2", name: "Human-Connection", description: "Description for human-connection." }), @@ -160,31 +184,13 @@ import seed from './data' relate('organization', 'OwnedBy', {from: 'u2', to: 'o2'}), relate('organization', 'OwnedBy', {from: 'u2', to: 'o3'}) ]) - - + /* eslint-disable-next-line no-console */ + console.log('Seeded Data...') } catch (err) { /* eslint-disable-next-line no-console */ console.error(err) process.exit(1) } - let data = {} - // legacy seeds - await asyncForEach(Object.keys(seed), async key => { - const mutations = seed[key] - try { - const res = await apolloClient - .mutate({ - mutation: gql(mutations(data)) - }) - data[key] = Object.assign(data[key] || {}, res.data) - } catch (err) { - /* eslint-disable-next-line no-console */ - console.error(err) - process.exit(1) - } - }) - /* eslint-disable-next-line no-console */ - console.log('Seeded Data...') })() /* eslint-enable no-multi-spaces */ From f7831dbbb7966755a30610410635be147d6951fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Feb 2019 01:44:30 +0100 Subject: [PATCH 366/554] Simplify package.json We don't have to wait for a seedServer if we access the database directly. --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index b65292acd..9525c3673 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,8 @@ "test:jest:debug": "run-p --race test:before:* 'test:jest:cmd:debug {@}' --", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", - "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", - "db:seed": "$npm_package_config_no_auth run-p --race dev db:script:seed", - "db:reset": "$npm_package_config_no_auth run-p --race dev db:script:reset" + "db:reset": "babel-node src/seed/reset-db.js", + "db:seed": "$npm_package_config_no_auth run-p --race dev db:script:seed" }, "author": "Human Connection gGmbH", "license": "MIT", From 8a7435ebb7f22876ad9c948cfe36f90e67aaf5b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Feb 2019 01:51:04 +0100 Subject: [PATCH 367/554] Clean up seed-db.js --- src/seed/factories/comments.js | 3 +- src/seed/factories/index.js | 10 --- src/seed/factories/organizations.js | 2 +- src/seed/factories/posts.js | 3 +- src/seed/factories/users.js | 2 +- src/seed/seed-db.js | 109 ++++++++++++++-------------- 6 files changed, 57 insertions(+), 72 deletions(-) diff --git a/src/seed/factories/comments.js b/src/seed/factories/comments.js index 184b06bf0..b4e25c482 100644 --- a/src/seed/factories/comments.js +++ b/src/seed/factories/comments.js @@ -11,7 +11,6 @@ export default function (params) { deleted = false } = params - return ` mutation { ${id}: CreateComment( @@ -24,7 +23,7 @@ export default function (params) { ` } -export function relate(type, params) { +export function relate (type, params) { const { from, to } = params return ` mutation { diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 89fa6144e..81d07978b 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -1,20 +1,11 @@ import { GraphQLClient } from 'graphql-request' -import ApolloClient from 'apollo-client' import dotenv from 'dotenv' -import { HttpLink } from 'apollo-link-http' -import { InMemoryCache } from 'apollo-cache-inmemory' import neo4j from '../../bootstrap/neo4j' -import fetch from 'node-fetch' export const seedServerHost = 'http://127.0.0.1:4001' dotenv.config() -const apolloClient = new ApolloClient({ - link: new HttpLink({ uri: seedServerHost, fetch }), - cache: new InMemoryCache() -}) - const driver = neo4j().getDriver() const builders = { @@ -68,7 +59,6 @@ const cleanDatabase = async () => { export { driver, - apolloClient, buildMutation, buildRelationMutation, create, diff --git a/src/seed/factories/organizations.js b/src/seed/factories/organizations.js index 047398eb0..c0329d55d 100644 --- a/src/seed/factories/organizations.js +++ b/src/seed/factories/organizations.js @@ -22,7 +22,7 @@ export default function create (params) { ` } -export function relate(type, params) { +export function relate (type, params) { const { from, to } = params return ` mutation { diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index e547efb01..bd095dd20 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -17,7 +17,6 @@ export default function (params) { deleted = false } = params - return ` mutation { ${id}: CreatePost( @@ -33,7 +32,7 @@ export default function (params) { ` } -export function relate(type, params) { +export function relate (type, params) { const { from, to } = params return ` mutation { diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index f1198cb7a..2e94b5ebe 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -33,7 +33,7 @@ export default function create (params) { ` } -export function relate(type, params) { +export function relate (type, params) { const { from, to } = params return ` mutation { diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index bab59a966..a8b886455 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,10 +1,9 @@ -import { create, relate, apolloClient, seedServerHost as host } from './factories' +import { create, relate, seedServerHost as host } from './factories' import { authenticatedHeaders } from '../jest/helpers.js' /* eslint-disable no-multi-spaces */ (async function () { try { - await Promise.all([ create('badge', { id: 'b1', key: 'indiegogo_en_racoon', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_racoon.svg' }), create('badge', { id: 'b2', key: 'indiegogo_en_rabbit', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rabbit.svg' }), @@ -46,12 +45,12 @@ import { authenticatedHeaders } from '../jest/helpers.js' ]) const headers = await Promise.all([ - authenticatedHeaders({ email: 'admin@example.org', password: '1234' }, host), - authenticatedHeaders({ email: 'moderator@example.org', password: '1234' }, host), - authenticatedHeaders({ email: 'user@example.org', password: '1234' }, host), - authenticatedHeaders({ email: 'tick@example.org', password: '1234' }, host), - authenticatedHeaders({ email: 'trick@example.org', password: '1234' }, host), - authenticatedHeaders({ email: 'track@example.org', password: '1234' }, host), + authenticatedHeaders({ email: 'admin@example.org', password: '1234' }, host), + authenticatedHeaders({ email: 'moderator@example.org', password: '1234' }, host), + authenticatedHeaders({ email: 'user@example.org', password: '1234' }, host), + authenticatedHeaders({ email: 'tick@example.org', password: '1234' }, host), + authenticatedHeaders({ email: 'trick@example.org', password: '1234' }, host), + authenticatedHeaders({ email: 'track@example.org', password: '1234' }, host) ]) await Promise.all([ @@ -80,24 +79,23 @@ import { authenticatedHeaders } from '../jest/helpers.js' create('tag', { id: 't4', name: 'Freiheit' }) ]) - await Promise.all([ - create('post', { id: 'p0', tagIds: ['t1', 't4'] }, { headers: headers[0]}), - create('post', { id: 'p1', tagIds: ['t2', 't3'] }, { headers: headers[1]}), - create('post', { id: 'p2', tagIds: ['t3', 't4'] }, { headers: headers[2]}), - create('post', { id: 'p3', tagIds: ['t4', 't2'] }, { headers: headers[3]}), - create('post', { id: 'p4', tagIds: ['t1', 't2'] }, { headers: headers[4]}), - create('post', { id: 'p5', tagIds: ['t2', 't4'] }, { headers: headers[5]}), - create('post', { id: 'p6', tagIds: ['t1', 't4'] }, { headers: headers[0]}), - create('post', { id: 'p7', tagIds: ['t2', 't3'] }, { headers: headers[1]}), - create('post', { id: 'p8', tagIds: ['t3', 't4'] }, { headers: headers[2]}), - create('post', { id: 'p9', tagIds: ['t3', 't4'] }, { headers: headers[3]}), - create('post', { id: 'p10', tagIds: ['t4', 't2'] }, { headers: headers[4]}), - create('post', { id: 'p11', tagIds: ['t1', 't2'] }, { headers: headers[5]}), - create('post', { id: 'p12', tagIds: ['t2', 't4'] }, { headers: headers[0]}), - create('post', { id: 'p13', tagIds: ['t4', 't2'] }, { headers: headers[1]}), - create('post', { id: 'p14', tagIds: ['t1', 't2'] }, { headers: headers[2]}), - create('post', { id: 'p15', tagIds: ['t2', 't4'] }, { headers: headers[3]}) + create('post', { id: 'p0' }, { headers: headers[0] }), + create('post', { id: 'p1' }, { headers: headers[1] }), + create('post', { id: 'p2' }, { headers: headers[2] }), + create('post', { id: 'p3' }, { headers: headers[3] }), + create('post', { id: 'p4' }, { headers: headers[4] }), + create('post', { id: 'p5' }, { headers: headers[5] }), + create('post', { id: 'p6' }, { headers: headers[0] }), + create('post', { id: 'p7' }, { headers: headers[1] }), + create('post', { id: 'p8' }, { headers: headers[2] }), + create('post', { id: 'p9' }, { headers: headers[3] }), + create('post', { id: 'p10' }, { headers: headers[4] }), + create('post', { id: 'p11' }, { headers: headers[5] }), + create('post', { id: 'p12' }, { headers: headers[0] }), + create('post', { id: 'p13' }, { headers: headers[1] }), + create('post', { id: 'p14' }, { headers: headers[2] }), + create('post', { id: 'p15' }, { headers: headers[3] }) ]) await Promise.all([ @@ -133,7 +131,7 @@ import { authenticatedHeaders } from '../jest/helpers.js' relate('post', 'Tags', { from: 'p12', to: 't4' }), relate('post', 'Tags', { from: 'p13', to: 't1' }), relate('post', 'Tags', { from: 'p14', to: 't2' }), - relate('post', 'Tags', { from: 'p15', to: 't3' }), + relate('post', 'Tags', { from: 'p15', to: 't3' }) ]) await Promise.all([ relate('user', 'Shouted', { from: 'u1', to: 'p2' }), @@ -145,44 +143,44 @@ import { authenticatedHeaders } from '../jest/helpers.js' ]) await Promise.all([ - create('comment', { id: "c1"}), - create('comment', { id: "c2"}), - create('comment', { id: "c3"}), - create('comment', { id: "c4"}), - create('comment', { id: "c5"}), - create('comment', { id: "c6"}), - create('comment', { id: "c7"}), + create('comment', { id: 'c1' }), + create('comment', { id: 'c2' }), + create('comment', { id: 'c3' }), + create('comment', { id: 'c4' }), + create('comment', { id: 'c5' }), + create('comment', { id: 'c6' }), + create('comment', { id: 'c7' }) ]) await Promise.all([ - relate('comment', 'Author', { from: 'u3', to: 'c1'}), - relate('comment', 'Post', { from: 'c1', to: 'p1'}), - relate('comment', 'Author', { from: 'u1', to: 'c2'}), - relate('comment', 'Post', { from: 'c2', to: 'p1'}), - relate('comment', 'Author', { from: 'u1', to: 'c3'}), - relate('comment', 'Post', { from: 'c3', to: 'p3'}), - relate('comment', 'Author', { from: 'u4', to: 'c4'}), - relate('comment', 'Post', { from: 'c4', to: 'p2'}), - relate('comment', 'Author', { from: 'u4', to: 'c5'}), - relate('comment', 'Post', { from: 'c5', to: 'p3'}), - relate('comment', 'Author', { from: 'u3', to: 'c6'}), - relate('comment', 'Post', { from: 'c6', to: 'p4'}), - relate('comment', 'Author', { from: 'u2', to: 'c7'}), - relate('comment', 'Post', { from: 'c7', to: 'p2'}), + relate('comment', 'Author', { from: 'u3', to: 'c1' }), + relate('comment', 'Post', { from: 'c1', to: 'p1' }), + relate('comment', 'Author', { from: 'u1', to: 'c2' }), + relate('comment', 'Post', { from: 'c2', to: 'p1' }), + relate('comment', 'Author', { from: 'u1', to: 'c3' }), + relate('comment', 'Post', { from: 'c3', to: 'p3' }), + relate('comment', 'Author', { from: 'u4', to: 'c4' }), + relate('comment', 'Post', { from: 'c4', to: 'p2' }), + relate('comment', 'Author', { from: 'u4', to: 'c5' }), + relate('comment', 'Post', { from: 'c5', to: 'p3' }), + relate('comment', 'Author', { from: 'u3', to: 'c6' }), + relate('comment', 'Post', { from: 'c6', to: 'p4' }), + relate('comment', 'Author', { from: 'u2', to: 'c7' }), + relate('comment', 'Post', { from: 'c7', to: 'p2' }) ]) await Promise.all([ - create('organization', { id: "o1", name: "Democracy Deutschland", description: "Description for democracy-deutschland."}), - create('organization', { id: "o2", name: "Human-Connection", description: "Description for human-connection." }), - create('organization', { id: "o3", name: "Pro Veg", description: "Description for pro-veg." }), - create('organization', { id: "o4", name: "Greenpeace", description: "Description for greenpeace." }) + create('organization', { id: 'o1', name: 'Democracy Deutschland', description: 'Description for democracy-deutschland.' }), + create('organization', { id: 'o2', name: 'Human-Connection', description: 'Description for human-connection.' }), + create('organization', { id: 'o3', name: 'Pro Veg', description: 'Description for pro-veg.' }), + create('organization', { id: 'o4', name: 'Greenpeace', description: 'Description for greenpeace.' }) ]) await Promise.all([ - relate('organization', 'CreatedBy', {from: 'u1', to: 'o1'}), - relate('organization', 'CreatedBy', {from: 'u1', to: 'o2'}), - relate('organization', 'OwnedBy', {from: 'u2', to: 'o2'}), - relate('organization', 'OwnedBy', {from: 'u2', to: 'o3'}) + relate('organization', 'CreatedBy', { from: 'u1', to: 'o1' }), + relate('organization', 'CreatedBy', { from: 'u1', to: 'o2' }), + relate('organization', 'OwnedBy', { from: 'u2', to: 'o2' }), + relate('organization', 'OwnedBy', { from: 'u2', to: 'o3' }) ]) /* eslint-disable-next-line no-console */ console.log('Seeded Data...') @@ -191,6 +189,5 @@ import { authenticatedHeaders } from '../jest/helpers.js' console.error(err) process.exit(1) } - })() /* eslint-enable no-multi-spaces */ From 4de6265baa538fcd0cbefbd63e752bcf9429e223 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 19 Feb 2019 04:17:52 +0000 Subject: [PATCH 368/554] Bump graphql-shield from 5.1.3 to 5.3.0 Bumps [graphql-shield](https://github.com/maticzav/graphql-shield) from 5.1.3 to 5.3.0. - [Release notes](https://github.com/maticzav/graphql-shield/releases) - [Commits](https://github.com/maticzav/graphql-shield/compare/v5.1.3...v5.3.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 53 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 232d08c15..61a0f4838 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "graphql-custom-directives": "~0.2.14", "graphql-iso-date": "~3.6.1", "graphql-middleware": "~3.0.2", - "graphql-shield": "~5.1.3", + "graphql-shield": "~5.3.0", "graphql-tag": "~2.10.1", "graphql-yoga": "~1.17.4", "jsonwebtoken": "~8.4.0", diff --git a/yarn.lock b/yarn.lock index 459080799..4545543aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -636,6 +636,13 @@ pirates "^4.0.0" source-map-support "^0.5.9" +"@babel/runtime@7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c" + integrity sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA== + dependencies: + regenerator-runtime "^0.12.0" + "@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2": version "7.1.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" @@ -2916,6 +2923,11 @@ flat-cache@^1.2.1: rimraf "~2.6.2" write "^0.2.1" +fn-name@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" + integrity sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc= + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -3191,13 +3203,14 @@ graphql-request@~1.8.2: dependencies: cross-fetch "2.2.2" -graphql-shield@~5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-5.1.3.tgz#c3301842775c22eb10ada21d42c6b87f3d6b7428" - integrity sha512-UwjUBhSaHXKh+L9FFi2nHV7GLcWbvPqbXpQ3I6Kz/u1MMxo3r1DBFlabeTgnrV4PLeppOsQPSX7t6Wyf9/CEfQ== +graphql-shield@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-5.3.0.tgz#095bdaa383025785e11e60ff55bf470015b15f9a" + integrity sha512-gPxOamyCgez0KgG9WcxoEa0vohsZz4yQw+vKwmnGJbYg9+1yR9CN3DYDA7EwaQcpRHEhRXClAzDvbdM3I+KZOw== dependencies: lightercollective "^0.2.0" object-hash "^1.3.1" + yup "^0.26.10" graphql-subscriptions@^0.5.8: version "0.5.8" @@ -5572,6 +5585,11 @@ prop-types@^15.6.2: loose-envify "^1.3.1" object-assign "^4.1.1" +property-expr@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-1.5.1.tgz#22e8706894a0c8e28d58735804f6ba3a3673314f" + integrity sha512-CGuc0VUTGthpJXL36ydB6jnbyOf/rAHFvmVrJlH+Rg0DqqLFQGAP6hIaxD/G0OAmBJPhXDHuEJigrp0e0wFV6g== + protobufjs@^6.8.6: version "6.8.8" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" @@ -5801,6 +5819,11 @@ regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" + integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== + regenerator-transform@^0.13.3: version "0.13.3" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb" @@ -6546,6 +6569,11 @@ symbol-tree@^3.2.2: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY= +synchronous-promise@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.6.tgz#de76e0ea2b3558c1e673942e47e714a930fa64aa" + integrity sha512-TyOuWLwkmtPL49LHCX1caIwHjRzcVd62+GF6h8W/jHOeZUFHpnd2XJDVuUlaTaLPH1nuu2M69mfHr5XbQJnf/g== + table@^5.0.2: version "5.1.1" resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837" @@ -6665,6 +6693,11 @@ topo@3.x.x: dependencies: hoek "6.x.x" +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA= + touch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" @@ -7178,6 +7211,18 @@ yargs@^12.0.2, yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" +yup@^0.26.10: + version "0.26.10" + resolved "https://registry.yarnpkg.com/yup/-/yup-0.26.10.tgz#3545839663289038faf25facfc07e11fd67c0cb1" + integrity sha512-keuNEbNSnsOTOuGCt3UJW69jDE3O4P+UHAakO7vSeFMnjaitcmlbij/a3oNb9g1Y1KvSKH/7O1R2PQ4m4TRylw== + dependencies: + "@babel/runtime" "7.0.0" + fn-name "~2.0.1" + lodash "^4.17.10" + property-expr "^1.5.0" + synchronous-promise "^2.0.5" + toposort "^2.0.2" + zen-observable-ts@^0.8.15: version "0.8.15" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.15.tgz#6cf7df6aa619076e4af2f707ccf8a6290d26699b" From f703164f1db7663f860729e78c7719875b7bdf27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Feb 2019 13:36:02 +0100 Subject: [PATCH 369/554] Expose cannot read property id of null error CC @appinteractive --- src/middleware/slugifyMiddleware.spec.js | 65 ++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/middleware/slugifyMiddleware.spec.js diff --git a/src/middleware/slugifyMiddleware.spec.js b/src/middleware/slugifyMiddleware.spec.js new file mode 100644 index 000000000..d1d35d96f --- /dev/null +++ b/src/middleware/slugifyMiddleware.spec.js @@ -0,0 +1,65 @@ +import { create, cleanDatabase } from '../seed/factories' +import { testServerHost as host, authenticatedHeaders } from '../jest/helpers' +import { GraphQLClient } from 'graphql-request' + +let client +let headers +beforeEach(async () => { + await create('user', {email: 'user@example.org', password: '1234'}) + headers = authenticatedHeaders({email: 'user@example.org', password: '1234'}) + client = new GraphQLClient(host, { headers }) +}) + +afterEach(async () => { + await cleanDatabase() +}) + +describe('slugify', () => { + describe('CreatePost', () => { + it('generates a slug based on the title', async () => { + const response = await client.request(`mutation { + CreatePost( + title: "I am a brand new post", + content: "Some content" + ) { slug } + }`) + expect(response).toEqual({ CreatePost: { slug: 'i-am-a-brand-new-post' } }) + }) + + describe('if slug exists', () => { + beforeEach(async () => { + await create('post', { + title: 'Pre-existing post', + slug: 'pre-existing-post' + }, { headers }) + }) + + it('chooses another slug', async () => { + const response = await client.request(`mutation { + CreatePost( + title: "Pre-existing post", + content: "Some content" + ) { slug } + }`) + expect(response).toEqual({ CreatePost: { slug: 'pre-existing-post-1' } }) + }) + + describe('but if the client requested a slug', () => { + it('rejects CreatePost', async () => { + try { + await client.request(`mutation { + CreatePost( + title: "Pre-existing post", + content: "Some content", + slug: "pre-existing-post" + ) { slug } + }`) + } catch (error) { + expect(error.response.errors[0].message).toEqual('Not Authorised!') + expect(error.response.data).toEqual({ User: [ { email: null } ] }) + } + }) + }) + }) + }) +}) From a7149dffc91fe16d1af374bd0e1efda963704573 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 19 Feb 2019 14:14:33 +0000 Subject: [PATCH 370/554] Bump apollo-server from 2.4.0 to 2.4.2 Bumps [apollo-server](https://github.com/apollographql/apollo-server) from 2.4.0 to 2.4.2. - [Release notes](https://github.com/apollographql/apollo-server/releases) - [Changelog](https://github.com/apollographql/apollo-server/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-server/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 145 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 135 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 61a0f4838..11137cc95 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "apollo-cache-inmemory": "~1.4.3", "apollo-client": "~2.4.13", "apollo-link-http": "~1.5.11", - "apollo-server": "~2.4.0", + "apollo-server": "~2.4.2", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", "cross-env": "~5.2.0", diff --git a/yarn.lock b/yarn.lock index 4545543aa..29b7ac029 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,6 +9,13 @@ dependencies: apollo-env "0.3.2" +"@apollographql/apollo-tools@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.3.3.tgz#7ec7af07021336ab6947e21e290dd06cb705233e" + integrity sha512-/vLzZjloWB4xzgw2MRs9TUDIdCzS+No1hEClkEKqcnH86c2EgE/W0Dv2nkCTH9WxDrfryziJWbNMurYYkm61Zw== + dependencies: + apollo-env "0.3.3" + "@apollographql/graphql-playground-html@^1.6.6": version "1.6.6" resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz#022209e28a2b547dcde15b219f0c50f47aa5beb3" @@ -985,6 +992,14 @@ apollo-cache-control@0.5.0: apollo-server-env "2.2.0" graphql-extensions "0.5.0" +apollo-cache-control@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.5.1.tgz#db7e86cd7ede6cad0a2e0ea97488d9fb5c33d913" + integrity sha512-82hzX7/fFiu5dODLS8oGieEE4jLjMIhIkQ4JTsWj9drv8PZJltl0xqORtU2jA/FottjxfYab8+ebi3BgGPOaqw== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.5.2" + apollo-cache-control@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz#173d14ceb3eb9e7cb53de7eb8b61bee6159d4171" @@ -1032,6 +1047,14 @@ apollo-datasource@0.3.0: apollo-server-caching "0.3.0" apollo-server-env "2.2.0" +apollo-datasource@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.3.1.tgz#4b7ec4c2dd7d08eb7edc865b95fd46b83a4679fd" + integrity sha512-qdEUeonc9pPZvYwXK36h2NZoT7Pddmy0HYOzdV0ON5pcG1YtNmUyyYi83Q60V5wTWjuaCjyJ9hOY6wr0BMvQuA== + dependencies: + apollo-server-caching "0.3.1" + apollo-server-env "2.2.0" + apollo-engine-reporting-protobuf@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.2.0.tgz#2aaf4d2eddefe7924d469cf1135267bc0deadf73" @@ -1039,6 +1062,13 @@ apollo-engine-reporting-protobuf@0.2.0: dependencies: protobufjs "^6.8.6" +apollo-engine-reporting-protobuf@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.2.1.tgz#8547efcb4078a501ddf606cbfe01a2e8c3ba1afd" + integrity sha512-5pYR84uWeylRS2OJowtkTczT3bWTwOErWtfnkRKccUi/wZ/AZJBP+D5HKNzM7xoFcz9XvrJyS+wBTz1oBi0Jiw== + dependencies: + protobufjs "^6.8.6" + apollo-engine-reporting@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.0.0.tgz#af93b755482ad5a6c52f9f728f3e24e801aa2385" @@ -1051,6 +1081,18 @@ apollo-engine-reporting@1.0.0: async-retry "^1.2.1" graphql-extensions "0.5.0" +apollo-engine-reporting@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.0.2.tgz#5dd5411f17d76e6788a1166367a2ab7b52794224" + integrity sha512-g6JkO5WaMuqXfn3WoZMQyyFzpxfHsw/f7P7XTHSEqTSd/M4uk7/uih/xcqmgBGt4ET30KbaGFz2l4FJzO06A5w== + dependencies: + apollo-engine-reporting-protobuf "0.2.1" + apollo-graphql "^0.1.0" + apollo-server-core "2.4.2" + apollo-server-env "2.2.0" + async-retry "^1.2.1" + graphql-extensions "0.5.2" + apollo-env@0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.3.2.tgz#7cd9abd7a65cb0e00c4cfc057a999864f6157b55" @@ -1059,6 +1101,14 @@ apollo-env@0.3.2: core-js "3.0.0-beta.3" node-fetch "^2.2.0" +apollo-env@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.3.3.tgz#e758ece2fbc4f81abc6f07442680ed9e314ecf6c" + integrity sha512-VsUX14bfQCJpKmTyYNBTeLrdeFabjmpSPVQ2y4IKnwqaxVqZuRca3WFE8ercszO1tLwS6HMM7mFw+IIbtQXo/w== + dependencies: + core-js "3.0.0-beta.13" + node-fetch "^2.2.0" + apollo-graphql@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.1.0.tgz#e453b133daa8b686644da05ec8e556cf31c57037" @@ -1066,6 +1116,13 @@ apollo-graphql@0.1.0: dependencies: lodash.sortby "^4.7.0" +apollo-graphql@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.1.1.tgz#dc5eac3062abf9f063ac9869f0ef5c54fdc136e5" + integrity sha512-UImgDIeB0n0fryYqtdz0CwJ9uDtXwg/3Q6rXzRAqgqBYz46VkmWa7nu2LX9GmDtiXB5VUOVCtyMEnvFwC3o27g== + dependencies: + lodash.sortby "^4.7.0" + apollo-link-dedup@^1.0.0: version "1.0.11" resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.11.tgz#6f34ea748d2834850329ad03111ef18445232b05" @@ -1102,6 +1159,13 @@ apollo-server-caching@0.3.0: dependencies: lru-cache "^5.0.0" +apollo-server-caching@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.3.1.tgz#63fcb2aaa176e1e101b36a8450e6b4c593d2767a" + integrity sha512-mfxzikYXbB/OoEms77AGYwRh7FF3Oim5v5XWAL+VL49FrkbZt5lopVa4bABi7Mz8Nt3Htl9EBJN8765s/yh8IA== + dependencies: + lru-cache "^5.0.0" + apollo-server-core@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.4.0.tgz#928c563f68d9f69a4288e7a4bf14ca79f8599f2b" @@ -1128,6 +1192,32 @@ apollo-server-core@2.4.0: subscriptions-transport-ws "^0.9.11" ws "^6.0.0" +apollo-server-core@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.4.2.tgz#916d98636b1bf576a84b4a469006c1c73741e03a" + integrity sha512-IOWhqjjI1sH38sj7ycjke0dXXEgaqOkb2hDpLBTSiVWKBIqFfo4gchWK5wcWW9jReDpf/+G2wogH+UvONs2ejg== + dependencies: + "@apollographql/apollo-tools" "^0.3.3" + "@apollographql/graphql-playground-html" "^1.6.6" + "@types/ws" "^6.0.0" + apollo-cache-control "0.5.1" + apollo-datasource "0.3.1" + apollo-engine-reporting "1.0.2" + apollo-server-caching "0.3.1" + apollo-server-env "2.2.0" + apollo-server-errors "2.2.0" + apollo-server-plugin-base "0.3.2" + apollo-tracing "0.5.1" + fast-json-stable-stringify "^2.0.0" + graphql-extensions "0.5.2" + graphql-subscriptions "^1.0.0" + graphql-tag "^2.9.2" + graphql-tools "^4.0.0" + graphql-upload "^8.0.2" + sha.js "^2.4.11" + subscriptions-transport-ws "^0.9.11" + ws "^6.0.0" + apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592" @@ -1150,10 +1240,10 @@ apollo-server-errors@2.2.0: resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== -apollo-server-express@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.4.0.tgz#fe8e748f07f01a837d1449e4c28ab27ae7b7d054" - integrity sha512-uDS7OZJ3EwFr4eZ9k1MiBtUTaqKgCXUUTCknPTdCbTzBel7TjNsa6PNKrSQk+jrLja2H8VwNjbra8uBF5z70Pw== +apollo-server-express@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.4.2.tgz#870daf04fd9b727a54b1339cdb55066450b3e05a" + integrity sha512-Q5/unCAi6a2dT39LQaIiLC1d8O4fmBDU2CrRhVhPWP8I344xPgNOcrs7MsNN7Ecb56UGbgDKxBoWowFG65ulKw== dependencies: "@apollographql/graphql-playground-html" "^1.6.6" "@types/accepts" "^1.3.5" @@ -1161,7 +1251,7 @@ apollo-server-express@2.4.0: "@types/cors" "^2.8.4" "@types/express" "4.16.1" accepts "^1.3.5" - apollo-server-core "2.4.0" + apollo-server-core "2.4.2" body-parser "^1.18.3" cors "^2.8.4" graphql-subscriptions "^1.0.0" @@ -1194,6 +1284,11 @@ apollo-server-plugin-base@0.3.0: resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.0.tgz#26c7f9c020b2d444de5bebd2e3c406bebd9c302e" integrity sha512-SOwp4cpZwyklvP1MkMcY6+12c1hrb5gwC4vK4a23kL5rr9FC0sENcXo3uVVM4XlDGOXIkY+sCM8ngKFuef2flw== +apollo-server-plugin-base@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.2.tgz#4609c9a9d154568401d84b7ac17d1e30e3529104" + integrity sha512-yzXrkVSPBoux2uPgbTGROGh7W0axRWopMZM+KT9aF9H/+yMCwtt0EhGOGyNUDMOFA4rT3z+cLVvYuZr1rSQWcg== + apollo-server-testing@~2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.4.0.tgz#db2c5ee2eddf9031a907a425587303df5e1677df" @@ -1201,13 +1296,13 @@ apollo-server-testing@~2.4.0: dependencies: apollo-server-core "2.4.0" -apollo-server@~2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.4.0.tgz#cfcf0431001451d7cda0d89f5ea8f7116aa1a1f4" - integrity sha512-dEc2lGA1qkvffnArlNXDtJ74+gh4dNKbtTYsnoTveve3ML96DK8G2u5yNqwRqxZHUQmLrx3jiehFaPBqk+Cuhw== +apollo-server@~2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.4.2.tgz#6ca42906664918c32d8be391db1178c6eaa8dc54" + integrity sha512-oFwHUhJtJedIPCtZ2ftvRWrVA3KpmeWsgDBs4e5jW/7f5ozkUF22h7L3iy8rEljppiEa2X/GgSi11SVxIOL8gw== dependencies: - apollo-server-core "2.4.0" - apollo-server-express "2.4.0" + apollo-server-core "2.4.2" + apollo-server-express "2.4.2" express "^4.0.0" graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" @@ -1220,6 +1315,14 @@ apollo-tracing@0.5.0: apollo-server-env "2.2.0" graphql-extensions "0.5.0" +apollo-tracing@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.5.1.tgz#16be201bc276120f0f8b7aa180201ee89d57e3bd" + integrity sha512-5gb8OWzkGaJFsmQdyMyZnOjcq6weMTkqJSGj0hfR7uX99X4SBFAzZV4nTeK4z0XkXO2I12xSTJoS4gxbFjgeaA== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.5.2" + apollo-tracing@^0.1.0: version "0.1.4" resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" @@ -1998,6 +2101,11 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +core-js@3.0.0-beta.13: + version "3.0.0-beta.13" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.13.tgz#7732c69be5e4758887917235fe7c0352c4cb42a1" + integrity sha512-16Q43c/3LT9NyePUJKL8nRIQgYWjcBhjJSMWg96PVSxoS0PeE0NHitPI3opBrs9MGGHjte1KoEVr9W63YKlTXQ== + core-js@3.0.0-beta.3: version "3.0.0-beta.3" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.3.tgz#b0f22009972b8c6c04550ebf38513ca4b3cc9559" @@ -3149,6 +3257,13 @@ graphql-extensions@0.5.0: dependencies: "@apollographql/apollo-tools" "^0.3.0" +graphql-extensions@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.2.tgz#cdced94c1931c9983fffcc144e336d6cd4d8b02b" + integrity sha512-D/FAvjYEZ8GM3vfALxRvItozy5iLUfzyoauE2lli+0OuUBCAZDLP0fgqeTFK93NnQX/XSjBVGhcuDWBB7JesEw== + dependencies: + "@apollographql/apollo-tools" "^0.3.3" + graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: version "0.0.10" resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" @@ -6193,6 +6308,14 @@ setprototypeof@1.1.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== +sha.js@^2.4.11: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" From cb666117fc6e3720e97b003292485eb7cc846565 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 19 Feb 2019 14:25:00 +0000 Subject: [PATCH 371/554] Bump eslint-plugin-jest from 22.2.2 to 22.3.0 Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 22.2.2 to 22.3.0. - [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases) - [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v22.2.2...v22.3.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 11137cc95..2d52c3878 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "eslint": "~5.13.0", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.16.0", - "eslint-plugin-jest": "~22.2.2", + "eslint-plugin-jest": "~22.3.0", "eslint-plugin-node": "~8.0.1", "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", diff --git a/yarn.lock b/yarn.lock index 29b7ac029..7be479e07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2612,10 +2612,10 @@ eslint-plugin-import@~2.16.0: read-pkg-up "^2.0.0" resolve "^1.9.0" -eslint-plugin-jest@~22.2.2: - version "22.2.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.2.2.tgz#2a80d70a20c27dfb1503a6f32cdcb647fe5476df" - integrity sha512-hnWgh9o39VJfz6lJEyQJdTW7dN2yynlGkmPOlU/oMHh+d7WVMsJP1GeDTB520VCDljEdKExCwD5IBpQIUl4mJg== +eslint-plugin-jest@~22.3.0: + version "22.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.3.0.tgz#a10f10dedfc92def774ec9bb5bfbd2fb8e1c96d2" + integrity sha512-P1mYVRNlOEoO5T9yTqOfucjOYf1ktmJ26NjwjH8sxpCFQa6IhBGr5TpKl3hcAAT29hOsRJVuMWmTsHoUVo9FoA== eslint-plugin-node@~8.0.1: version "8.0.1" From f55d9aa0bb5a1d3b1fc2fe221aa3bdaef867eedb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 19 Feb 2019 14:55:44 +0000 Subject: [PATCH 372/554] Bump apollo-server-testing from 2.4.0 to 2.4.2 Bumps [apollo-server-testing](https://github.com/apollographql/apollo-server) from 2.4.0 to 2.4.2. - [Release notes](https://github.com/apollographql/apollo-server/releases) - [Changelog](https://github.com/apollographql/apollo-server/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-server/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 125 +++------------------------------------------------ 2 files changed, 6 insertions(+), 121 deletions(-) diff --git a/package.json b/package.json index 2d52c3878..d6da2f3cf 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "@babel/node": "~7.2.2", "@babel/preset-env": "~7.3.1", "@babel/register": "~7.0.0", - "apollo-server-testing": "~2.4.0", + "apollo-server-testing": "~2.4.2", "babel-core": "~7.0.0-0", "babel-eslint": "~10.0.1", "babel-jest": "~24.1.0", diff --git a/yarn.lock b/yarn.lock index 7be479e07..5c5bb4a23 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,13 +2,6 @@ # yarn lockfile v1 -"@apollographql/apollo-tools@^0.3.0": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.3.2.tgz#415c984955c4ae249550def698cbffab8d27bda4" - integrity sha512-IiuO1XaxxvbZa19gGHBOEgQKmMHB+ghXaNjSbY5dWqCEQgBDgJBA/2a1Oq9tMPhEPAmEY2FOuhaWRxxKxmVdlQ== - dependencies: - apollo-env "0.3.2" - "@apollographql/apollo-tools@^0.3.3": version "0.3.3" resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.3.3.tgz#7ec7af07021336ab6947e21e290dd06cb705233e" @@ -984,14 +977,6 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -apollo-cache-control@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.5.0.tgz#78cfefec57c5c0a9648137e3250b91172998061e" - integrity sha512-zu26CFj7CboxLB6cckZQEiSUGXIr8MViEGIC5Vesz2yd37sjtevMfRwQhxFuK0HinR0T/WC3dz2k5cj+33vQQQ== - dependencies: - apollo-server-env "2.2.0" - graphql-extensions "0.5.0" - apollo-cache-control@0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.5.1.tgz#db7e86cd7ede6cad0a2e0ea97488d9fb5c33d913" @@ -1039,14 +1024,6 @@ apollo-client@~2.4.13: tslib "^1.9.3" zen-observable "^0.8.0" -apollo-datasource@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.3.0.tgz#88c680edd63a2f7ea05fc25da290a430632d39f4" - integrity sha512-+jWs3ezhx4lcAAPIHtlj0Zoiv2tvwfzn7feHuhxub3xFwkJm39T8hPjb3aMQCsuS7TukBD+F5ndgVob5hL/5Nw== - dependencies: - apollo-server-caching "0.3.0" - apollo-server-env "2.2.0" - apollo-datasource@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.3.1.tgz#4b7ec4c2dd7d08eb7edc865b95fd46b83a4679fd" @@ -1055,13 +1032,6 @@ apollo-datasource@0.3.1: apollo-server-caching "0.3.1" apollo-server-env "2.2.0" -apollo-engine-reporting-protobuf@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.2.0.tgz#2aaf4d2eddefe7924d469cf1135267bc0deadf73" - integrity sha512-qI+GJKN78UMJ9Aq/ORdiM2qymZ5yswem+/VDdVFocq+/e1QqxjnpKjQWISkswci5+WtpJl9SpHBNxG98uHDKkA== - dependencies: - protobufjs "^6.8.6" - apollo-engine-reporting-protobuf@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.2.1.tgz#8547efcb4078a501ddf606cbfe01a2e8c3ba1afd" @@ -1069,18 +1039,6 @@ apollo-engine-reporting-protobuf@0.2.1: dependencies: protobufjs "^6.8.6" -apollo-engine-reporting@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.0.0.tgz#af93b755482ad5a6c52f9f728f3e24e801aa2385" - integrity sha512-9gZSME9ggZwL1nBBvfgSehwc+PtcvZC1/3NYrBOFgidJbrEFita2w5A0jM8Brjo+N2FMKNYWGj8WQ1ywO21JPg== - dependencies: - apollo-engine-reporting-protobuf "0.2.0" - apollo-graphql "0.1.0" - apollo-server-core "2.4.0" - apollo-server-env "2.2.0" - async-retry "^1.2.1" - graphql-extensions "0.5.0" - apollo-engine-reporting@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.0.2.tgz#5dd5411f17d76e6788a1166367a2ab7b52794224" @@ -1093,14 +1051,6 @@ apollo-engine-reporting@1.0.2: async-retry "^1.2.1" graphql-extensions "0.5.2" -apollo-env@0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.3.2.tgz#7cd9abd7a65cb0e00c4cfc057a999864f6157b55" - integrity sha512-r6nrOw5Pyk6YLNKEtvBiTguJK+oPI1sthKogd7tp6jfkJ+q8SR/9sOoTxyV3vsmR/mMENuBHF89BGLLo9rxDiA== - dependencies: - core-js "3.0.0-beta.3" - node-fetch "^2.2.0" - apollo-env@0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.3.3.tgz#e758ece2fbc4f81abc6f07442680ed9e314ecf6c" @@ -1109,13 +1059,6 @@ apollo-env@0.3.3: core-js "3.0.0-beta.13" node-fetch "^2.2.0" -apollo-graphql@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.1.0.tgz#e453b133daa8b686644da05ec8e556cf31c57037" - integrity sha512-Mi5GqZJz1A/0i8SEm9EVHWe/LkGbYzV5wzobUY+1Q0SI1NdFtRgqHZUdHU0hz1jDnL+dpRqK1huVmtOO/DGa/A== - dependencies: - lodash.sortby "^4.7.0" - apollo-graphql@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.1.1.tgz#dc5eac3062abf9f063ac9869f0ef5c54fdc136e5" @@ -1152,13 +1095,6 @@ apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.8: dependencies: zen-observable-ts "^0.8.15" -apollo-server-caching@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.3.0.tgz#96669b5e3bf693e6a54683edfab4b9495deb17d8" - integrity sha512-dHwWUsRZu7I1yUfzTwPJgOigMsftgp8w3X96Zdch1ICWN7cM6aNxks9tTnLd+liUSEzdYLlTmEy5VUturF2IAw== - dependencies: - lru-cache "^5.0.0" - apollo-server-caching@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.3.1.tgz#63fcb2aaa176e1e101b36a8450e6b4c593d2767a" @@ -1166,32 +1102,6 @@ apollo-server-caching@0.3.1: dependencies: lru-cache "^5.0.0" -apollo-server-core@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.4.0.tgz#928c563f68d9f69a4288e7a4bf14ca79f8599f2b" - integrity sha512-rTFJa12NzTWC9IJrXDr8AZMs1Slbes9YxbyaI+cMC5fs8O9wkCkb34C/1Tp7xKX0fgauXrKZpXv7yPTSm+4YFg== - dependencies: - "@apollographql/apollo-tools" "^0.3.0" - "@apollographql/graphql-playground-html" "^1.6.6" - "@types/ws" "^6.0.0" - apollo-cache-control "0.5.0" - apollo-datasource "0.3.0" - apollo-engine-reporting "1.0.0" - apollo-server-caching "0.3.0" - apollo-server-env "2.2.0" - apollo-server-errors "2.2.0" - apollo-server-plugin-base "0.3.0" - apollo-tracing "0.5.0" - fast-json-stable-stringify "^2.0.0" - graphql-extensions "0.5.0" - graphql-subscriptions "^1.0.0" - graphql-tag "^2.9.2" - graphql-tools "^4.0.0" - graphql-upload "^8.0.2" - lodash "^4.17.10" - subscriptions-transport-ws "^0.9.11" - ws "^6.0.0" - apollo-server-core@2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.4.2.tgz#916d98636b1bf576a84b4a469006c1c73741e03a" @@ -1279,22 +1189,17 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== -apollo-server-plugin-base@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.0.tgz#26c7f9c020b2d444de5bebd2e3c406bebd9c302e" - integrity sha512-SOwp4cpZwyklvP1MkMcY6+12c1hrb5gwC4vK4a23kL5rr9FC0sENcXo3uVVM4XlDGOXIkY+sCM8ngKFuef2flw== - apollo-server-plugin-base@0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.2.tgz#4609c9a9d154568401d84b7ac17d1e30e3529104" integrity sha512-yzXrkVSPBoux2uPgbTGROGh7W0axRWopMZM+KT9aF9H/+yMCwtt0EhGOGyNUDMOFA4rT3z+cLVvYuZr1rSQWcg== -apollo-server-testing@~2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.4.0.tgz#db2c5ee2eddf9031a907a425587303df5e1677df" - integrity sha512-1Dxe19+KP9dulACPN0jLMRVAgHNgD3rey4tljUqtofoxsvchXIG6MARVOHz6VDMNk58jWXr81jMtEBS/x/+XFA== +apollo-server-testing@~2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.4.2.tgz#5c87b34b0b6a1a3e5a1784cadc16bc495dded2e1" + integrity sha512-WZ901nh7uG75342lMukJvuxFF/w3W5JDyWElY8KDhXfaDLbMKqhRqaWRIiEEX4YvciO5ACSzqKt+957/y1yUUQ== dependencies: - apollo-server-core "2.4.0" + apollo-server-core "2.4.2" apollo-server@~2.4.2: version "2.4.2" @@ -1307,14 +1212,6 @@ apollo-server@~2.4.2: graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" -apollo-tracing@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.5.0.tgz#6eebaf1e840ece99299103def689d39fe49780a3" - integrity sha512-j0icEhLYf0xS6Q/iCXA2j9KfpYw0a/XvLSUio7fm5yUwtXP2Pp11x5BtK1dI8sLMiaOqUrREz2XjV4PKLzQPuA== - dependencies: - apollo-server-env "2.2.0" - graphql-extensions "0.5.0" - apollo-tracing@0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.5.1.tgz#16be201bc276120f0f8b7aa180201ee89d57e3bd" @@ -2106,11 +2003,6 @@ core-js@3.0.0-beta.13: resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.13.tgz#7732c69be5e4758887917235fe7c0352c4cb42a1" integrity sha512-16Q43c/3LT9NyePUJKL8nRIQgYWjcBhjJSMWg96PVSxoS0PeE0NHitPI3opBrs9MGGHjte1KoEVr9W63YKlTXQ== -core-js@3.0.0-beta.3: - version "3.0.0-beta.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.3.tgz#b0f22009972b8c6c04550ebf38513ca4b3cc9559" - integrity sha512-kM/OfrnMThP5PwGAj5HhQLdjUqzjrllqN2EVnk/X9qrLsfYjR2hzZ+E/8CzH0xuosexZtqMTLQrk//BULrBj9w== - core-js@^2.4.0: version "2.6.0" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.0.tgz#1e30793e9ee5782b307e37ffa22da0eacddd84d4" @@ -3250,13 +3142,6 @@ graphql-deduplicator@^2.0.1: resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3" integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA== -graphql-extensions@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.0.tgz#117b9872e5cafbebef5254ad795b41fa97037c14" - integrity sha512-2i0rpe4/D8jZj6XmxXGLFDAsGLhkFrSdpS5WfvTAzoXOc52hUAxNdsbgRQGeKMFhmanqA6FDXxO/s+BtPHChVA== - dependencies: - "@apollographql/apollo-tools" "^0.3.0" - graphql-extensions@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.2.tgz#cdced94c1931c9983fffcc144e336d6cd4d8b02b" From 7d0463ac9734284c1b7185a97fa2ae226300d153 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 19 Feb 2019 15:14:52 +0000 Subject: [PATCH 373/554] Bump @babel/core from 7.2.2 to 7.3.3 Bumps [@babel/core](https://github.com/babel/babel) from 7.2.2 to 7.3.3. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.2.2...v7.3.3) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 99 +++++++++++++--------------------------------------- 2 files changed, 26 insertions(+), 75 deletions(-) diff --git a/package.json b/package.json index d6da2f3cf..135429c66 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ }, "devDependencies": { "@babel/cli": "~7.2.3", - "@babel/core": "~7.2.2", + "@babel/core": "~7.3.3", "@babel/node": "~7.2.2", "@babel/preset-env": "~7.3.1", "@babel/register": "~7.0.0", diff --git a/yarn.lock b/yarn.lock index 5c5bb4a23..42193a585 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38,45 +38,34 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.1.0", "@babel/core@~7.2.2": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687" - integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw== +"@babel/core@^7.1.0", "@babel/core@~7.3.3": + version "7.3.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.3.tgz#d090d157b7c5060d05a05acaebc048bd2b037947" + integrity sha512-w445QGI2qd0E0GlSnq6huRZWPMmQGCp5gd5ZWS4hagn0EiwzxD5QMFkpchyusAyVC1n27OKXzQ0/88aVU9n4xQ== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.2.2" + "@babel/generator" "^7.3.3" "@babel/helpers" "^7.2.0" - "@babel/parser" "^7.2.2" + "@babel/parser" "^7.3.3" "@babel/template" "^7.2.2" "@babel/traverse" "^7.2.2" - "@babel/types" "^7.2.2" + "@babel/types" "^7.3.3" convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" - lodash "^4.17.10" + lodash "^4.17.11" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.1.6": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.0.tgz#eaf3821fa0301d9d4aef88e63d4bcc19b73ba16c" - integrity sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg== +"@babel/generator@^7.0.0", "@babel/generator@^7.2.2", "@babel/generator@^7.3.3": + version "7.3.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.3.tgz#185962ade59a52e00ca2bdfcfd1d58e528d4e39e" + integrity sha512-aEADYwRRZjJyMnKN7llGIlircxTCofm3dtV5pmY6ob18MSIuipHpA2yZWkPlycwu5HJcx/pADS3zssd8eY7/6A== dependencies: - "@babel/types" "^7.2.0" + "@babel/types" "^7.3.3" jsesc "^2.5.1" - lodash "^4.17.10" - source-map "^0.5.0" - trim-right "^1.0.1" - -"@babel/generator@^7.2.2": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.2.tgz#18c816c70962640eab42fe8cae5f3947a5c65ccc" - integrity sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg== - dependencies: - "@babel/types" "^7.2.2" - jsesc "^2.5.1" - lodash "^4.17.10" + lodash "^4.17.11" source-map "^0.5.0" trim-right "^1.0.1" @@ -264,15 +253,10 @@ lodash "^4.17.10" v8flags "^3.1.1" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.6": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.2.0.tgz#02d01dbc330b6cbf36b76ac93c50752c69027065" - integrity sha512-M74+GvK4hn1eejD9lZ7967qAwvqTZayQa3g10ag4s9uewgR7TKjeaT0YMyoq+gVfKYABiWZ4MQD701/t5e1Jhg== - -"@babel/parser@^7.2.2", "@babel/parser@^7.2.3": - version "7.2.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.2.3.tgz#32f5df65744b70888d17872ec106b02434ba1489" - integrity sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA== +"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.2.3", "@babel/parser@^7.3.3": + version "7.3.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.3.tgz#092d450db02bdb6ccb1ca8ffd47d8774a91aef87" + integrity sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg== "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.2.0" @@ -643,16 +627,7 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" - integrity sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.1.2" - "@babel/types" "^7.1.2" - -"@babel/template@^7.2.2": +"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g== @@ -661,22 +636,7 @@ "@babel/parser" "^7.2.2" "@babel/types" "^7.2.2" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.6.tgz#c8db9963ab4ce5b894222435482bd8ea854b7b5c" - integrity sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.1.6" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/parser" "^7.1.6" - "@babel/types" "^7.1.6" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.10" - -"@babel/traverse@^7.2.2": +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.2.2": version "7.2.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8" integrity sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw== @@ -691,22 +651,13 @@ globals "^11.1.0" lodash "^4.17.10" -"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.6", "@babel/types@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.0.tgz#7941c5b2d8060e06f9601d6be7c223eef906d5d8" - integrity sha512-b4v7dyfApuKDvmPb+O488UlGuR1WbwMXFsO/cyqMrnfvRAChZKJAYeeglWTjUO1b9UghKKgepAQM5tsvBJca6A== +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.3": + version "7.3.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.3.tgz#6c44d1cdac2a7625b624216657d5bc6c107ab436" + integrity sha512-2tACZ80Wg09UnPg5uGAOUvvInaqLk3l/IAhQzlxLQOIXacr6bMsra5SH6AWw/hIDRCSbCdHP2KzSOD+cT7TzMQ== dependencies: esutils "^2.0.2" - lodash "^4.17.10" - to-fast-properties "^2.0.0" - -"@babel/types@^7.2.2": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.2.tgz#44e10fc24e33af524488b716cdaee5360ea8ed1e" - integrity sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg== - dependencies: - esutils "^2.0.2" - lodash "^4.17.10" + lodash "^4.17.11" to-fast-properties "^2.0.0" "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": From e6a996e0ddb8bcb3748e98ad56bc149317128bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Feb 2019 22:55:23 +0100 Subject: [PATCH 374/554] Harden permissions spec If we expect an error to be thrown, the test should fail if no error was raised. --- src/middleware/permissionsMiddleware.spec.js | 23 ++++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 481e340cb..ea488df28 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -33,11 +33,14 @@ describe('authorization', () => { } describe('not logged in', async () => { + it('rejects', async () => { + await expect(action(headers)).rejects.toThrow('Not Authorised!') + }) + it('does not expose the owner\'s email address', async () => { - try { + try{ await action(headers) - } catch (error) { - expect(error.response.errors[0].message).toEqual('Not Authorised!') + } catch(error) { expect(error.response.data).toEqual({ User: [ { email: null } ] }) } }) @@ -54,15 +57,21 @@ describe('authorization', () => { }) describe('as someone else', () => { - it('does not expose the owner\'s email address', async () => { + beforeEach(async () => { headers = await authenticatedHeaders({ email: 'someone@example.org', password: 'else' }) - try { + }) + + it('rejects', async () => { + await expect(action(headers)).rejects.toThrow('Not Authorised!') + }) + + it('does not expose the owner\'s email address', async () => { + try{ await action(headers) - } catch (error) { - expect(error.response.errors[0].message).toEqual('Not Authorised!') + } catch(error) { expect(error.response.data).toEqual({ User: [ { email: null } ] }) } }) From 30bb54c6fafc1a852521ed1483832aad2f974f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Feb 2019 23:00:59 +0100 Subject: [PATCH 375/554] Fix slugify test --- src/middleware/slugifyMiddleware.spec.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/middleware/slugifyMiddleware.spec.js b/src/middleware/slugifyMiddleware.spec.js index d1d35d96f..31ddc78f7 100644 --- a/src/middleware/slugifyMiddleware.spec.js +++ b/src/middleware/slugifyMiddleware.spec.js @@ -6,7 +6,7 @@ let client let headers beforeEach(async () => { await create('user', {email: 'user@example.org', password: '1234'}) - headers = authenticatedHeaders({email: 'user@example.org', password: '1234'}) + headers = await authenticatedHeaders({email: 'user@example.org', password: '1234'}) client = new GraphQLClient(host, { headers }) }) @@ -22,7 +22,7 @@ describe('slugify', () => { title: "I am a brand new post", content: "Some content" ) { slug } - }`) + }`, { headers }) expect(response).toEqual({ CreatePost: { slug: 'i-am-a-brand-new-post' } }) }) @@ -46,18 +46,14 @@ describe('slugify', () => { describe('but if the client requested a slug', () => { it('rejects CreatePost', async () => { - try { - await client.request(`mutation { + await expect(client.request(`mutation { CreatePost( title: "Pre-existing post", content: "Some content", slug: "pre-existing-post" ) { slug } }`) - } catch (error) { - expect(error.response.errors[0].message).toEqual('Not Authorised!') - expect(error.response.data).toEqual({ User: [ { email: null } ] }) - } + ).rejects.toThrow('Unique constraint error') }) }) }) From 9c4e599ff1485ed3de8adc849d3a1cf2d28c2268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Feb 2019 23:25:28 +0100 Subject: [PATCH 376/554] Separate middleware for ids --- src/middleware/idMiddleware.js | 32 ++++++++++++++++++++ src/middleware/index.js | 4 ++- src/middleware/permissionsMiddleware.spec.js | 8 ++--- src/middleware/slugifyMiddleware.spec.js | 4 +-- src/middleware/userMiddleware.js | 24 --------------- 5 files changed, 41 insertions(+), 31 deletions(-) create mode 100644 src/middleware/idMiddleware.js diff --git a/src/middleware/idMiddleware.js b/src/middleware/idMiddleware.js new file mode 100644 index 000000000..59224bd64 --- /dev/null +++ b/src/middleware/idMiddleware.js @@ -0,0 +1,32 @@ +import find from 'lodash/find' + +const includeId = async (resolve, root, args, context, info) => { + let isIdPresent + let removeIdFromResult + isIdPresent = find(info.fieldNodes[0].selectionSet.selections, item => item.name.value === 'id') + if (!isIdPresent) { + // add id to request as the user did not ask but we need it + info.fieldNodes[0].selectionSet.selections.unshift({ + kind: 'Field', + name: { kind: 'Name', value: 'id' } + }) + removeIdFromResult = true + } + + const result = await resolve(root, args, context, info) + + if (!isIdPresent && removeIdFromResult) { + // remove id if the user did not ask for it + info.fieldNodes[0].selectionSet.selections.shift() + } + return result +} + +export default { + Query: (resolve, root, args, context, info) => { + return includeId(resolve, root, args, context, info) + }, + Mutation: (resolve, root, args, context, info) => { + return includeId(resolve, root, args, context, info) + } +} diff --git a/src/middleware/index.js b/src/middleware/index.js index bd95f0e93..5cc20f969 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -7,6 +7,7 @@ import dateTimeMiddleware from './dateTimeMiddleware' import xssMiddleware from './xssMiddleware' import permissionsMiddleware from './permissionsMiddleware' import userMiddleware from './userMiddleware' +import idMiddleware from './idMiddleware' export default schema => { let middleware = [ @@ -17,7 +18,8 @@ export default schema => { xssMiddleware, fixImageUrlsMiddleware, softDeleteMiddleware, - userMiddleware + userMiddleware, + idMiddleware ] // add permisions middleware at the first position (unless we're seeding) diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index ea488df28..7a5eacfce 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -38,9 +38,9 @@ describe('authorization', () => { }) it('does not expose the owner\'s email address', async () => { - try{ + try { await action(headers) - } catch(error) { + } catch (error) { expect(error.response.data).toEqual({ User: [ { email: null } ] }) } }) @@ -69,9 +69,9 @@ describe('authorization', () => { }) it('does not expose the owner\'s email address', async () => { - try{ + try { await action(headers) - } catch(error) { + } catch (error) { expect(error.response.data).toEqual({ User: [ { email: null } ] }) } }) diff --git a/src/middleware/slugifyMiddleware.spec.js b/src/middleware/slugifyMiddleware.spec.js index 31ddc78f7..00382ffb9 100644 --- a/src/middleware/slugifyMiddleware.spec.js +++ b/src/middleware/slugifyMiddleware.spec.js @@ -5,8 +5,8 @@ import { GraphQLClient } from 'graphql-request' let client let headers beforeEach(async () => { - await create('user', {email: 'user@example.org', password: '1234'}) - headers = await authenticatedHeaders({email: 'user@example.org', password: '1234'}) + await create('user', { email: 'user@example.org', password: '1234' }) + headers = await authenticatedHeaders({ email: 'user@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) }) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index cf42709e9..3af9ce294 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -1,5 +1,4 @@ import createOrUpdateLocations from './nodes/locations' -import find from 'lodash/find' export default { Mutation: { @@ -26,29 +25,6 @@ export default { }) session.close() - return result - } - }, - Query: { - User: async (resolve, root, args, context, info) => { - let isIdPresent - let removeIdFromResult - try { - isIdPresent = find(info.fieldNodes[0].selectionSet.selections, item => item.name.value === 'id') - if (!isIdPresent) { - // add id to request as the user did not ask but we need it - info.fieldNodes[0].selectionSet.selections.unshift({ - kind: 'Field', - name: { kind: 'Name', value: 'id' } - }) - removeIdFromResult = true - } - } catch (err) {} - const result = await resolve(root, args, context, info) - if (!isIdPresent && removeIdFromResult) { - // remove id if the user did not ask for it - info.fieldNodes[0].selectionSet.selections.shift() - } return result } } From f1dd52f5791c2889cda0ac1f2eace85c4543edc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Feb 2019 00:38:48 +0100 Subject: [PATCH 377/554] Expose yet another bug in the authorization Cannot read property id of null CC @appinteractive --- src/graphql-schema.js | 17 +++++ src/graphql-schema.spec.js | 121 +++++++++++++++++++++---------- src/middleware/userMiddleware.js | 15 ---- 3 files changed, 99 insertions(+), 54 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 8b5f369e0..521ac97bd 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -6,6 +6,7 @@ import generateJwt from './jwt/generateToken' import uuid from 'uuid/v4' import { fixUrl } from './middleware/fixImageUrlsMiddleware' import { AuthenticationError } from 'apollo-server' +import { neo4jgraphql } from 'neo4j-graphql-js' export const typeDefs = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, 'schema.graphql')) @@ -161,6 +162,22 @@ export const resolvers = { // TODO: output Report compatible object return data + }, + CreatePost: async (object, params, ctx, resolveInfo) => { + const result = await neo4jgraphql(object, params, ctx, resolveInfo, false) + + const session = ctx.driver.session() + await session.run( + 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + + 'MERGE (post)<-[:WROTE]-(author) ' + + 'RETURN author', { + userId: ctx.user.id, + postId: result.id + }) + session.close() + + return result } + } } diff --git a/src/graphql-schema.spec.js b/src/graphql-schema.spec.js index 21b3f3d61..e61130fe3 100644 --- a/src/graphql-schema.spec.js +++ b/src/graphql-schema.spec.js @@ -1,7 +1,18 @@ -import { request } from 'graphql-request' import { create, cleanDatabase } from './seed/factories' import jwt from 'jsonwebtoken' -import { testServerHost as host } from './jest/helpers' +import { testServerHost as host, authenticatedHeaders } from './jest/helpers' +import { GraphQLClient, request } from 'graphql-request' + +beforeEach(async () => { + await create('user', { + email: 'test@example.org', + password: '1234' + }) +}) + +afterEach(async () => { + await cleanDatabase() +}) describe('login', () => { const mutation = (params) => { @@ -14,48 +25,80 @@ describe('login', () => { }` } - describe('given an existing user', () => { - beforeEach(async () => { - await create('user', { - email: 'test@example.org', - password: '1234' + describe('ask for a `token`', () => { + describe('with valid email/password combination', () => { + it('responds with a JWT token', async () => { + const data = await request(host, mutation({ email: 'test@example.org', password: '1234' })) + const { token } = data.login + jwt.verify(token, process.env.JWT_SECRET, (err, data) => { + expect(data.email).toEqual('test@example.org') + expect(err).toBeNull() + }) }) }) - afterEach(async () => { - await cleanDatabase() + describe('with a valid email but incorrect password', () => { + it('responds with "Incorrect email address or password."', async () => { + try { + await request(host, mutation({ email: 'test@example.org', password: 'wrong' })) + } catch (error) { + expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') + } + }) }) - describe('asking for a `token`', () => { - describe('with valid email/password combination', () => { - it('responds with a JWT token', async () => { - const data = await request(host, mutation({ email: 'test@example.org', password: '1234' })) - const { token } = data.login - jwt.verify(token, process.env.JWT_SECRET, (err, data) => { - expect(data.email).toEqual('test@example.org') - expect(err).toBeNull() - }) - }) - }) - - describe('with a valid email but incorrect password', () => { - it('responds with "Incorrect email address or password."', async () => { - try { - await request(host, mutation({ email: 'test@example.org', password: 'wrong' })) - } catch (error) { - expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') - } - }) - }) - - describe('with a non-existing email', () => { - it('responds with "Incorrect email address or password."', async () => { - try { - await request(host, mutation({ email: 'non-existent@example.org', password: 'wrong' })) - } catch (error) { - expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') - } - }) + describe('with a non-existing email', () => { + it('responds with "Incorrect email address or password."', async () => { + try { + await request(host, mutation({ email: 'non-existent@example.org', password: 'wrong' })) + } catch (error) { + expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') + } + }) + }) + }) +}) + +describe('CreatePost', () => { + describe('unauthenticated', () => { + let client + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect(client.request(`mutation { + CreatePost( + title: "I am a post", + content: "Some content" + ) { slug } + }`)).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { + let headers + let response + beforeEach(async () => { + headers = await authenticatedHeaders({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + response = await client.request(`mutation { + CreatePost( + title: "A title", + content: "Some content" + ) { title, content } + }`, { headers }) + }) + + it('creates a post', () => { + expect(response).toEqual({ CreatePost: { title: 'A title', content: 'Some content' } }) + }) + + it('assigns the authenticated user as author', async () => { + const { User } = await client.request(`{ + User(email:"test@example.org") { + contributions { + title + } + } + }`, { headers }) + expect(User).toEqual([ { contributions: [ { title: 'A title' } ] } ]) }) }) }) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 3af9ce294..55b181bc9 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -10,21 +10,6 @@ export default { UpdateUser: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) await createOrUpdateLocations(args.id, args.locationName, context.driver) - return result - }, - CreatePost: async (resolve, root, args, context, info) => { - const result = await resolve(root, args, context, info) - - const session = context.driver.session() - await session.run( - 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + - 'MERGE (post)<-[:WROTE]-(author) ' + - 'RETURN author', { - userId: context.user.id, - postId: result.id - }) - session.close() - return result } } From 7a70b9ece4ebee4f862e4c2b5ba953886fdd13a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Feb 2019 00:46:27 +0100 Subject: [PATCH 378/554] Implement authorization on Post mutations --- src/middleware/permissionsMiddleware.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 0dd4a9a86..7db516e11 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -16,7 +16,7 @@ const isModerator = rule()(async (parent, args, ctx, info) => { }) */ -const isOwner = rule({ cache: 'no_cache' })(async (parent, args, ctx, info) => { +const myself = rule({ cache: 'no_cache' })(async (parent, args, ctx, info) => { return ctx.user.id === parent.id }) @@ -28,13 +28,16 @@ const permissions = shield({ // customers: and(isAuthenticated, isAdmin) }, Mutation: { - report: isAuthenticated + CreatePost: isAuthenticated, + // TODO UpdatePost: isOwner, + // TODO DeletePost: isOwner, + report: isAuthenticated, // addFruitToBasket: isAuthenticated // CreateUser: allow, }, User: { - email: isOwner, - password: isOwner + email: myself, + password: myself } // Post: isAuthenticated }) From 3532b473eeaa2dcfa12e50de5a25cd00c4fda75a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Feb 2019 01:30:32 +0100 Subject: [PATCH 379/554] Choose another slug is green --- src/middleware/sluggifyMiddleware.js | 17 ++++++++++++++--- src/middleware/slugify/uniqueSlug.js | 6 +++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/middleware/sluggifyMiddleware.js b/src/middleware/sluggifyMiddleware.js index f059cb680..e187aa797 100644 --- a/src/middleware/sluggifyMiddleware.js +++ b/src/middleware/sluggifyMiddleware.js @@ -1,11 +1,22 @@ +import uniqueSlug from './slugify/uniqueSlug' import slug from 'slug' +const isUniqueFor = (context, type) => { + return async (slug) => { + const session = context.driver.session() + const response = await session.run( + `MATCH(p:${type} {slug: $slug }) return p.slug`, { + slug + }) + session.close() + return response.records.length === 0 + } +} + export default { Mutation: { CreatePost: async (resolve, root, args, context, info) => { - args.slug = slug(args.title, { - lower: true - }) + args.slug = await uniqueSlug(args.title, isUniqueFor(context, 'Post')) const result = await resolve(root, args, context, info) return result }, diff --git a/src/middleware/slugify/uniqueSlug.js b/src/middleware/slugify/uniqueSlug.js index 0f66fac5f..8b04edc6f 100644 --- a/src/middleware/slugify/uniqueSlug.js +++ b/src/middleware/slugify/uniqueSlug.js @@ -1,15 +1,15 @@ import slugify from 'slug' -export default function uniqueSlug (string, isUnique) { +export default async function uniqueSlug (string, isUnique) { let slug = slugify(string, { lower: true }) - if (isUnique(slug)) return slug + if (await isUnique(slug)) return slug let count = 0 let uniqueSlug do { count += 1 uniqueSlug = `${slug}-${count}` - } while (!isUnique(uniqueSlug)) + } while (!await isUnique(uniqueSlug)) return uniqueSlug } From ba26c0e1887ae9abe1bd159b71fc331b36b3c53a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Feb 2019 11:23:03 +0100 Subject: [PATCH 380/554] Seed reported comments, posts and users --- src/middleware/permissionsMiddleware.js | 2 +- src/seed/data/reports.js | 45 ------------------------- src/seed/factories/index.js | 3 +- src/seed/factories/reports.js | 23 +++++++++++++ src/seed/seed-db.js | 6 ++++ 5 files changed, 32 insertions(+), 47 deletions(-) delete mode 100644 src/seed/data/reports.js create mode 100644 src/seed/factories/reports.js diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 7db516e11..0bd88b274 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -31,7 +31,7 @@ const permissions = shield({ CreatePost: isAuthenticated, // TODO UpdatePost: isOwner, // TODO DeletePost: isOwner, - report: isAuthenticated, + report: isAuthenticated // addFruitToBasket: isAuthenticated // CreateUser: allow, }, diff --git a/src/seed/data/reports.js b/src/seed/data/reports.js deleted file mode 100644 index 9cecc4f9a..000000000 --- a/src/seed/data/reports.js +++ /dev/null @@ -1,45 +0,0 @@ -export default function (data) { - return ` - mutation { - r1: CreateReport(id: "r1", type: contribution, description: "Bad Stuff") { - id - } - r2: CreateReport(id: "r2", type: comment, description: "Please remove this sh**") { - id - } - r3: CreateReport(id: "r3", type: user, description: "The user have misbehaved!") { - id - } - ra1: AddReportReporter(from: { id: "u1" }, to: { id: "r1" }) { - from { - id - } - } - ra2: AddReportReporter(from: { id: "u2" }, to: { id: "r2" }) { - from { - id - } - } - ra3: AddReportReporter(from: { id: "u3" }, to: { id: "r3" }) { - from { - id - } - } - rc1: AddReportContribution(from: { id: "r1" }, to: { id: "p2" }) { - from { - id - } - } - rc2: AddReportComment(from: { id: "r2" }, to: { id: "c2" }) { - from { - id - } - } - rc3: AddReportUser(from: { id: "r3" }, to: { id: "u4" }) { - from { - id - } - } - } - ` -} diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 81d07978b..04b1817ca 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -15,7 +15,8 @@ const builders = { 'post': require('./posts.js').default, 'comment': require('./comments.js').default, 'category': require('./categories.js').default, - 'tag': require('./tags.js').default + 'tag': require('./tags.js').default, + 'report': require('./reports.js').default } const relationBuilders = { diff --git a/src/seed/factories/reports.js b/src/seed/factories/reports.js new file mode 100644 index 000000000..4dcd479f1 --- /dev/null +++ b/src/seed/factories/reports.js @@ -0,0 +1,23 @@ +import faker from 'faker' + +export default function create (params) { + const { + description = faker.lorem.sentence(), + resource: { id: resourceId, type } + } = params + + return ` + mutation { + report( + description: "${description}", + resource: { + id: "${resourceId}", + type: ${type} + } + ) { + id, + createdAt + } + } + ` +} diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index a8b886455..21cb543a8 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -169,6 +169,12 @@ import { authenticatedHeaders } from '../jest/helpers.js' relate('comment', 'Post', { from: 'c7', to: 'p2' }) ]) + await Promise.all([ + create('report', { description: 'I don\'t like this comment', resource: { id: 'c1', type: 'comment' } }, { headers: headers[3] }), + create('report', { description: 'I don\'t like this post', resource: { id: 'p1', type: 'contribution' } }, { headers: headers[4] }), + create('report', { description: 'I don\'t like this user', resource: { id: 'u1', type: 'user' } }, { headers: headers[5] }) + ]) + await Promise.all([ create('organization', { id: 'o1', name: 'Democracy Deutschland', description: 'Description for democracy-deutschland.' }), create('organization', { id: 'o2', name: 'Human-Connection', description: 'Description for human-connection.' }), From a61362b2693c26a303d36dded3fe48a654f0475a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Feb 2019 11:48:06 +0100 Subject: [PATCH 381/554] Fix slugify unit test with async mock functions --- src/middleware/slugify/uniqueSlug.spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/middleware/slugify/uniqueSlug.spec.js b/src/middleware/slugify/uniqueSlug.spec.js index 3d379bafb..190899795 100644 --- a/src/middleware/slugify/uniqueSlug.spec.js +++ b/src/middleware/slugify/uniqueSlug.spec.js @@ -3,16 +3,16 @@ import uniqueSlug from './uniqueSlug' describe('uniqueSlug', () => { it('slugifies given string', () => { const string = 'Hello World' - const isUnique = () => true - expect(uniqueSlug(string, isUnique)).toEqual('hello-world') + const isUnique = jest.fn() + .mockResolvedValue(true) + expect(uniqueSlug(string, isUnique)).resolves.toEqual('hello-world') }) it('increments slugified string until unique', () => { const string = 'Hello World' const isUnique = jest.fn() - isUnique - .mockReturnValueOnce(false) - .mockReturnValueOnce(true) - expect(uniqueSlug(string, isUnique)).toEqual('hello-world-1') + .mockResolvedValueOnce(false) + .mockResolvedValueOnce(true) + expect(uniqueSlug(string, isUnique)).resolves.toEqual('hello-world-1') }) }) From c30548d1e82365685287057cead029bb2b68448e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Feb 2019 12:53:56 +0100 Subject: [PATCH 382/554] Fix bugs in migration script for neo4j Only change the password, if we are the default user. Everything else should be executed. --- neo4j/migrate.sh | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/neo4j/migrate.sh b/neo4j/migrate.sh index c659909fa..1ec5212ad 100755 --- a/neo4j/migrate.sh +++ b/neo4j/migrate.sh @@ -1,11 +1,18 @@ #!/usr/bin/env bash -set -e -if [[ -z "${NEO4J_PASSWORD}" ]]; then - echo 'CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);' | cypher-shell -else - echo "CALL dbms.security.changePassword('${NEO4J_PASSWORD}');" | cypher-shell --username neo4j --password neo4j - echo "CREATE CONSTRAINT ON (p:Post) ASSERT p.slug IS UNIQUE;" | cypher-shell - echo "CREATE CONSTRAINT ON (c:Category) ASSERT c.slug IS UNIQUE;" | cypher-shell - echo "CREATE CONSTRAINT ON (u:User) ASSERT u.slug IS UNIQUE;" | cypher-shell - echo "CREATE CONSTRAINT ON (o:Organization) ASSERT o.slug IS UNIQUE;" | cypher-shell + +# If the user has the password `neo4j` this is a strong indicator, that we are +# the initial default user. Before we can create constraints, we have to change +# the default password. This is a security feature of neo4j. +if echo ":exit" | cypher-shell --password neo4j 2> /dev/null ; then + echo "CALL dbms.security.changePassword('${NEO4J_PASSWORD}');" | cypher-shell --password neo4j fi + +set -e + +echo ' +CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]); +CREATE CONSTRAINT ON (p:Post) ASSERT p.slug IS UNIQUE; +CREATE CONSTRAINT ON (c:Category) ASSERT c.slug IS UNIQUE; +CREATE CONSTRAINT ON (u:User) ASSERT u.slug IS UNIQUE; +CREATE CONSTRAINT ON (o:Organization) ASSERT o.slug IS UNIQUE; +' | cypher-shell From bfc5603fa8603a72ae017a180438c2b64f1b00fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Feb 2019 12:56:57 +0100 Subject: [PATCH 383/554] All tests are passing! --- src/middleware/sluggifyMiddleware.js | 2 +- src/middleware/slugifyMiddleware.spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/middleware/sluggifyMiddleware.js b/src/middleware/sluggifyMiddleware.js index e187aa797..2276e6373 100644 --- a/src/middleware/sluggifyMiddleware.js +++ b/src/middleware/sluggifyMiddleware.js @@ -16,7 +16,7 @@ const isUniqueFor = (context, type) => { export default { Mutation: { CreatePost: async (resolve, root, args, context, info) => { - args.slug = await uniqueSlug(args.title, isUniqueFor(context, 'Post')) + args.slug = args.slug || await uniqueSlug(args.title, isUniqueFor(context, 'Post')) const result = await resolve(root, args, context, info) return result }, diff --git a/src/middleware/slugifyMiddleware.spec.js b/src/middleware/slugifyMiddleware.spec.js index 00382ffb9..0088d7d11 100644 --- a/src/middleware/slugifyMiddleware.spec.js +++ b/src/middleware/slugifyMiddleware.spec.js @@ -53,7 +53,7 @@ describe('slugify', () => { slug: "pre-existing-post" ) { slug } }`) - ).rejects.toThrow('Unique constraint error') + ).rejects.toThrow('already exists') }) }) }) From 7abc1583dc91d9ab43820d4b3576b8d98517dc55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Feb 2019 14:03:36 +0100 Subject: [PATCH 384/554] Implement + test unique slugs for user I put the relevant line on categories and organizations too, but I didn't test it separately. I could have tested it but found it unnecessary repeating --- src/middleware/sluggifyMiddleware.js | 30 +++++-------------- src/middleware/slugifyMiddleware.spec.js | 38 ++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/middleware/sluggifyMiddleware.js b/src/middleware/sluggifyMiddleware.js index 2276e6373..50883d216 100644 --- a/src/middleware/sluggifyMiddleware.js +++ b/src/middleware/sluggifyMiddleware.js @@ -17,35 +17,19 @@ export default { Mutation: { CreatePost: async (resolve, root, args, context, info) => { args.slug = args.slug || await uniqueSlug(args.title, isUniqueFor(context, 'Post')) - const result = await resolve(root, args, context, info) - return result + return resolve(root, args, context, info) }, CreateUser: async (resolve, root, args, context, info) => { - if (!args.slug) { - args.slug = slug(args.name, { - lower: true - }) - } - const result = await resolve(root, args, context, info) - return result + args.slug = args.slug || await uniqueSlug(args.name, isUniqueFor(context, 'User')) + return resolve(root, args, context, info) }, CreateOrganization: async (resolve, root, args, context, info) => { - if (!args.slug) { - args.slug = slug(args.name, { - lower: true - }) - } - const result = await resolve(root, args, context, info) - return result + args.slug = args.slug || await uniqueSlug(args.name, isUniqueFor(context, 'Organization')) + return resolve(root, args, context, info) }, CreateCategory: async (resolve, root, args, context, info) => { - if (!args.slug) { - args.slug = slug(args.name, { - lower: true - }) - } - const result = await resolve(root, args, context, info) - return result + args.slug = args.slug || await uniqueSlug(args.name, isUniqueFor(context, 'Category')) + return resolve(root, args, context, info) } } } diff --git a/src/middleware/slugifyMiddleware.spec.js b/src/middleware/slugifyMiddleware.spec.js index 0088d7d11..b8e74cd7f 100644 --- a/src/middleware/slugifyMiddleware.spec.js +++ b/src/middleware/slugifyMiddleware.spec.js @@ -16,7 +16,7 @@ afterEach(async () => { describe('slugify', () => { describe('CreatePost', () => { - it('generates a slug based on the title', async () => { + it('generates a slug based on title', async () => { const response = await client.request(`mutation { CreatePost( title: "I am a brand new post", @@ -44,7 +44,7 @@ describe('slugify', () => { expect(response).toEqual({ CreatePost: { slug: 'pre-existing-post-1' } }) }) - describe('but if the client requested a slug', () => { + describe('but if the client specifies a slug', () => { it('rejects CreatePost', async () => { await expect(client.request(`mutation { CreatePost( @@ -58,4 +58,38 @@ describe('slugify', () => { }) }) }) + + describe('CreateUser', () => { + const action = async (mutation, params) => { + return client.request(`mutation { + ${mutation}(password: "yo", ${params}) { slug } + }`, { headers }) + } + it('generates a slug based on name', async () => { + await expect(action('CreateUser', 'name: "I am a user"')) + .resolves.toEqual({ CreateUser: { slug: 'i-am-a-user' } }) + }) + + describe('if slug exists', () => { + beforeEach(async () => { + await action('CreateUser', 'name: "Pre-existing user", slug: "pre-existing-user"') + }) + + it('chooses another slug', async () => { + await expect(action( + 'CreateUser', + 'name: "pre-existing-user"' + )).resolves.toEqual({ CreateUser: { slug: 'pre-existing-user-1' } }) + }) + + describe('but if the client specifies a slug', () => { + it('rejects CreateUser', async () => { + await expect(action( + 'CreateUser', + 'name: "Pre-existing user", slug: "pre-existing-user"' + )).rejects.toThrow('already exists') + }) + }) + }) + }) }) From 4a1e06402aa38205fea2fae541212c9dc54e9bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Feb 2019 15:26:49 +0100 Subject: [PATCH 385/554] Fix lint --- src/middleware/sluggifyMiddleware.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/middleware/sluggifyMiddleware.js b/src/middleware/sluggifyMiddleware.js index 50883d216..1a9177daa 100644 --- a/src/middleware/sluggifyMiddleware.js +++ b/src/middleware/sluggifyMiddleware.js @@ -1,5 +1,4 @@ import uniqueSlug from './slugify/uniqueSlug' -import slug from 'slug' const isUniqueFor = (context, type) => { return async (slug) => { @@ -25,11 +24,11 @@ export default { }, CreateOrganization: async (resolve, root, args, context, info) => { args.slug = args.slug || await uniqueSlug(args.name, isUniqueFor(context, 'Organization')) - return resolve(root, args, context, info) + return resolve(root, args, context, info) }, CreateCategory: async (resolve, root, args, context, info) => { args.slug = args.slug || await uniqueSlug(args.name, isUniqueFor(context, 'Category')) - return resolve(root, args, context, info) + return resolve(root, args, context, info) } } } From d4a999ee91d98b592a5ca5093327159fb4c66f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 21 Feb 2019 00:27:26 +0100 Subject: [PATCH 386/554] Configure factories#cleanDatabase easier --- src/bootstrap/neo4j.js | 26 +++++++++--------- src/seed/factories/index.js | 53 ++++++++++++++----------------------- src/server.js | 4 +-- 3 files changed, 34 insertions(+), 49 deletions(-) diff --git a/src/bootstrap/neo4j.js b/src/bootstrap/neo4j.js index 929e62f23..24a0cd4dd 100644 --- a/src/bootstrap/neo4j.js +++ b/src/bootstrap/neo4j.js @@ -1,20 +1,18 @@ import { v1 as neo4j } from 'neo4j-driver' +import dotenv from 'dotenv' + +dotenv.config() let driver -export default function () { - return { - getDriver () { - if (!driver) { - driver = neo4j.driver( - process.env.NEO4J_URI || 'bolt://localhost:7687', - neo4j.auth.basic( - process.env.NEO4J_USERNAME || 'neo4j', - process.env.NEO4J_PASSWORD || 'neo4j' - ) - ) - } - return driver - } +export function getDriver (options = {}) { + const { + uri = process.env.NEO4J_URI || 'bolt://localhost:7687', + username = process.env.NEO4J_USERNAME || 'neo4j', + password = process.env.NEO4J_PASSWORD || 'neo4j' + } = options + if (!driver) { + driver = neo4j.driver(uri, neo4j.auth.basic(username, password)) } + return driver } diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 04b1817ca..650071f2e 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -1,67 +1,54 @@ import { GraphQLClient } from 'graphql-request' -import dotenv from 'dotenv' -import neo4j from '../../bootstrap/neo4j' +import { getDriver } from '../../bootstrap/neo4j' export const seedServerHost = 'http://127.0.0.1:4001' -dotenv.config() - -const driver = neo4j().getDriver() - -const builders = { - 'badge': require('./badges.js').default, - 'user': require('./users.js').default, +const factories = { + 'badge': require('./badges.js').default, + 'user': require('./users.js').default, 'organization': require('./organizations.js').default, - 'post': require('./posts.js').default, - 'comment': require('./comments.js').default, - 'category': require('./categories.js').default, - 'tag': require('./tags.js').default, - 'report': require('./reports.js').default + 'post': require('./posts.js').default, + 'comment': require('./comments.js').default, + 'category': require('./categories.js').default, + 'tag': require('./tags.js').default, + 'report': require('./reports.js').default } -const relationBuilders = { - 'user': require('./users.js').relate, +const relationFactories = { + 'user': require('./users.js').relate, 'organization': require('./organizations.js').relate, - 'post': require('./posts.js').relate, - 'comment': require('./comments.js').relate -} - -const buildMutation = (model, parameters) => { - return builders[model](parameters) -} - -const buildRelationMutation = (model, type, parameters) => { - return relationBuilders[model](type, parameters) + 'post': require('./posts.js').relate, + 'comment': require('./comments.js').relate } const create = (model, parameters, options) => { const graphQLClient = new GraphQLClient(seedServerHost, options) - const mutation = buildMutation(model, parameters) + const mutation = factories[model](parameters) return graphQLClient.request(mutation) } const relate = (model, type, parameters, options) => { const graphQLClient = new GraphQLClient(seedServerHost, options) - const mutation = buildRelationMutation(model, type, parameters) + const mutation = relationFactories[model](type, parameters) return graphQLClient.request(mutation) } -const cleanDatabase = async () => { +const cleanDatabase = async (options = {}) => { + const { + driver = getDriver() + } = options const session = driver.session() const cypher = 'MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r' try { return await session.run(cypher) } catch (error) { - console.log(error) + throw(error) } finally { session.close() } } export { - driver, - buildMutation, - buildRelationMutation, create, relate, cleanDatabase diff --git a/src/server.js b/src/server.js index 1d85cbd00..5867e6952 100644 --- a/src/server.js +++ b/src/server.js @@ -7,7 +7,7 @@ import mocks from './mocks' import middleware from './middleware' import applyDirectives from './bootstrap/directives' import applyScalars from './bootstrap/scalars' -import neo4j from './bootstrap/neo4j' +import { getDriver } from './bootstrap/neo4j' import passport from 'passport' import jwtStrategy from './jwt/strategy' @@ -22,7 +22,7 @@ requiredEnvVars.forEach(env => { } }) -const driver = neo4j().getDriver() +const driver = getDriver() const debug = process.env.NODE_ENV !== 'production' && process.env.DEBUG === 'true' let schema = makeAugmentedSchema({ From b3e476e039d5ec1eaaec6c19280eeed43910a4e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 21 Feb 2019 00:30:46 +0100 Subject: [PATCH 387/554] Create a yarn script to the backend for testing --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 9525c3673..2578052d3 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", + "test:cypress": "run-p --race test:before:*", "test:before:server": "cross-env GRAPHQL_URI=http://localhost:4123 GRAPHQL_PORT=4123 babel-node src/ 2> /dev/null", "test:before:seeder": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 PERMISSIONS=disabled babel-node src/ 2> /dev/null", "test:jest:cmd": "wait-on tcp:4001 tcp:4123 && jest --forceExit --detectOpenHandles --runInBand", From 91a13593dcb535111821cb69a8d99559a879b2b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 21 Feb 2019 02:09:07 +0100 Subject: [PATCH 388/554] Provide a better interface for factories You can now run graphql mutations *from the point of view* of a user. @mattwr18 @Tirokk Do you have a better idea how to name the factory builder? --- src/seed/factories/index.js | 65 +++++++++++++++++++++++++++++++++---- src/seed/factories/posts.js | 4 +-- src/seed/seed-db.js | 59 +++++++++++++++++---------------- 3 files changed, 89 insertions(+), 39 deletions(-) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 650071f2e..efbf7b248 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -1,7 +1,22 @@ import { GraphQLClient } from 'graphql-request' import { getDriver } from '../../bootstrap/neo4j' +import { request } from 'graphql-request' export const seedServerHost = 'http://127.0.0.1:4001' +export const testServerHost = 'http://127.0.0.1:4123' + +const authenticatedHeaders = async ({ email, password }, host = testServerHost) => { + const mutation = ` + mutation { + login(email:"${email}", password:"${password}"){ + token + } + }` + const response = await request(host, mutation) + return { + authorization: `Bearer ${response.login.token}` + } +} const factories = { 'badge': require('./badges.js').default, @@ -21,19 +36,19 @@ const relationFactories = { 'comment': require('./comments.js').relate } -const create = (model, parameters, options) => { +export const create = (model, parameters, options) => { const graphQLClient = new GraphQLClient(seedServerHost, options) const mutation = factories[model](parameters) return graphQLClient.request(mutation) } -const relate = (model, type, parameters, options) => { +export const relate = (model, type, parameters, options) => { const graphQLClient = new GraphQLClient(seedServerHost, options) const mutation = relationFactories[model](type, parameters) return graphQLClient.request(mutation) } -const cleanDatabase = async (options = {}) => { +export const cleanDatabase = async (options = {}) => { const { driver = getDriver() } = options @@ -48,8 +63,44 @@ const cleanDatabase = async (options = {}) => { } } -export { - create, - relate, - cleanDatabase +export default function factoryFun (options = {}) { + const { + neo4jDriver = getDriver(), + seedServerHost = 'http://127.0.0.1:4001', + testServerHost = 'http://127.0.0.1:4123' + } = options + + const graphQLClient = new GraphQLClient(seedServerHost) + + const result = { + neo4jDriver, + seedServerHost, + graphQLClient, + lastResponse: null, + async authenticateAs({email, password}) { + const headers = await authenticatedHeaders({email, password}, seedServerHost) + this.lastResponse = headers + this.graphQLClient = new GraphQLClient(seedServerHost, { headers }) + return this + }, + async create(node, properties) { + const mutation = factories[node](properties) + this.lastResponse = await this.graphQLClient.request(mutation) + return this + }, + async relate(node, relationship, properties) { + const mutation = relationFactories[node](relationship, properties) + this.lastResponse = await this.graphQLClient.request(mutation) + return this + }, + async cleanDatabase() { + this.lastResponse = await cleanDatabase({driver: this.neo4jDriver}) + return this + } + } + result.authenticateAs.bind(result) + result.create.bind(result) + result.relate.bind(result) + result.cleanDatabase.bind(result) + return result } diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index bd095dd20..eaa616b2b 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -2,7 +2,7 @@ import faker from 'faker' export default function (params) { const { - id = `u${faker.random.number()}`, + id = `p${faker.random.number()}`, title = faker.lorem.sentence(), content = [ faker.lorem.sentence(), @@ -27,7 +27,7 @@ export default function (params) { visibility: ${visibility}, disabled: ${disabled}, deleted: ${deleted} - ) { id, title } + ) { title, content } } ` } diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 21cb543a8..1075c61d6 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,5 +1,4 @@ -import { create, relate, seedServerHost as host } from './factories' -import { authenticatedHeaders } from '../jest/helpers.js' +import factoryFun, { create, relate, seedServerHost as host } from './factories' /* eslint-disable no-multi-spaces */ (async function () { @@ -44,15 +43,6 @@ import { authenticatedHeaders } from '../jest/helpers.js' relate('user', 'Blacklisted', { from: 'u7', to: 'u6' }) ]) - const headers = await Promise.all([ - authenticatedHeaders({ email: 'admin@example.org', password: '1234' }, host), - authenticatedHeaders({ email: 'moderator@example.org', password: '1234' }, host), - authenticatedHeaders({ email: 'user@example.org', password: '1234' }, host), - authenticatedHeaders({ email: 'tick@example.org', password: '1234' }, host), - authenticatedHeaders({ email: 'trick@example.org', password: '1234' }, host), - authenticatedHeaders({ email: 'track@example.org', password: '1234' }, host) - ]) - await Promise.all([ create('category', { id: 'cat1', name: 'Just For Fun', slug: 'justforfun', icon: 'smile' }), create('category', { id: 'cat2', name: 'Happyness & Values', slug: 'happyness-values', icon: 'heart-o' }), @@ -79,23 +69,32 @@ import { authenticatedHeaders } from '../jest/helpers.js' create('tag', { id: 't4', name: 'Freiheit' }) ]) + const [ asAdmin, asModerator, asUser, asTick, asTrick, asTrack ] = await Promise.all([ + factoryFun().authenticateAs({ email: 'admin@example.org', password: '1234' }), + factoryFun().authenticateAs({ email: 'moderator@example.org', password: '1234' }), + factoryFun().authenticateAs({ email: 'user@example.org', password: '1234' }), + factoryFun().authenticateAs({ email: 'tick@example.org', password: '1234' }), + factoryFun().authenticateAs({ email: 'trick@example.org', password: '1234' }), + factoryFun().authenticateAs({ email: 'track@example.org', password: '1234' }) + ]) + await Promise.all([ - create('post', { id: 'p0' }, { headers: headers[0] }), - create('post', { id: 'p1' }, { headers: headers[1] }), - create('post', { id: 'p2' }, { headers: headers[2] }), - create('post', { id: 'p3' }, { headers: headers[3] }), - create('post', { id: 'p4' }, { headers: headers[4] }), - create('post', { id: 'p5' }, { headers: headers[5] }), - create('post', { id: 'p6' }, { headers: headers[0] }), - create('post', { id: 'p7' }, { headers: headers[1] }), - create('post', { id: 'p8' }, { headers: headers[2] }), - create('post', { id: 'p9' }, { headers: headers[3] }), - create('post', { id: 'p10' }, { headers: headers[4] }), - create('post', { id: 'p11' }, { headers: headers[5] }), - create('post', { id: 'p12' }, { headers: headers[0] }), - create('post', { id: 'p13' }, { headers: headers[1] }), - create('post', { id: 'p14' }, { headers: headers[2] }), - create('post', { id: 'p15' }, { headers: headers[3] }) + asAdmin .create('post', { id: 'p0' }), + asModerator.create('post', { id: 'p1' }), + asUser .create('post', { id: 'p2' }), + asTick .create('post', { id: 'p3' }), + asTrick .create('post', { id: 'p4' }), + asTrack .create('post', { id: 'p5' }), + asAdmin .create('post', { id: 'p6' }), + asModerator.create('post', { id: 'p7' }), + asUser .create('post', { id: 'p8' }), + asTick .create('post', { id: 'p9' }), + asTrick .create('post', { id: 'p10' }), + asTrack .create('post', { id: 'p11' }), + asAdmin .create('post', { id: 'p12' }), + asModerator.create('post', { id: 'p13' }), + asUser .create('post', { id: 'p14' }), + asTick .create('post', { id: 'p15' }) ]) await Promise.all([ @@ -170,9 +169,9 @@ import { authenticatedHeaders } from '../jest/helpers.js' ]) await Promise.all([ - create('report', { description: 'I don\'t like this comment', resource: { id: 'c1', type: 'comment' } }, { headers: headers[3] }), - create('report', { description: 'I don\'t like this post', resource: { id: 'p1', type: 'contribution' } }, { headers: headers[4] }), - create('report', { description: 'I don\'t like this user', resource: { id: 'u1', type: 'user' } }, { headers: headers[5] }) + asTick .create('report', { description: 'I don\'t like this comment', resource: { id: 'c1', type: 'comment' } }), + asTrick.create('report', { description: 'I don\'t like this post', resource: { id: 'p1', type: 'contribution' } }), + asTrack.create('report', { description: 'I don\'t like this user', resource: { id: 'u1', type: 'user' } }) ]) await Promise.all([ From e5be51257a85ceafbf482030361632ae0fa6f9da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 21 Feb 2019 04:17:07 +0000 Subject: [PATCH 389/554] Bump jsonwebtoken from 8.4.0 to 8.5.0 Bumps [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) from 8.4.0 to 8.5.0. - [Release notes](https://github.com/auth0/node-jsonwebtoken/releases) - [Changelog](https://github.com/auth0/node-jsonwebtoken/blob/master/CHANGELOG.md) - [Commits](https://github.com/auth0/node-jsonwebtoken/compare/v8.4.0...v8.5.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 41 +++++++++++++++++++++-------------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 135429c66..8954de8f1 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "graphql-shield": "~5.3.0", "graphql-tag": "~2.10.1", "graphql-yoga": "~1.17.4", - "jsonwebtoken": "~8.4.0", + "jsonwebtoken": "~8.5.0", "linkifyjs": "~2.1.8", "lodash": "~4.17.11", "ms": "~2.1.1", diff --git a/yarn.lock b/yarn.lock index 42193a585..ff7dffeb0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2310,10 +2310,10 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -ecdsa-sig-formatter@1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz#1c595000f04a8897dfb85000892a0f4c33af86c3" - integrity sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM= +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== dependencies: safe-buffer "^5.0.1" @@ -4348,12 +4348,12 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= -jsonwebtoken@^8.2.0, jsonwebtoken@~8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz#8757f7b4cb7440d86d5e2f3becefa70536c8e46a" - integrity sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg== +jsonwebtoken@^8.2.0, jsonwebtoken@~8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#ebd0ca2a69797816e1c5af65b6c759787252947e" + integrity sha512-IqEycp0znWHNA11TpYi77bVgyBO/pGESDh7Ajhas+u0ttkGkKYIIAjniL4Bw5+oVejVF+SYkaI7XKfwCCyeTuA== dependencies: - jws "^3.1.5" + jws "^3.2.1" lodash.includes "^4.3.0" lodash.isboolean "^3.0.3" lodash.isinteger "^4.0.4" @@ -4362,6 +4362,7 @@ jsonwebtoken@^8.2.0, jsonwebtoken@~8.4.0: lodash.isstring "^4.0.1" lodash.once "^4.0.0" ms "^2.1.1" + semver "^5.6.0" jsprim@^1.2.2: version "1.4.1" @@ -4373,21 +4374,21 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jwa@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.6.tgz#87240e76c9808dbde18783cf2264ef4929ee50e6" - integrity sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw== +jwa@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.3.0.tgz#061a7c3bb8ab2b3434bb2f432005a8bb7fca0efa" + integrity sha512-SxObIyzv9a6MYuZYaSN6DhSm9j3+qkokwvCB0/OTSV5ylPq1wUQiygZQcHT5Qlux0I5kmISx3J86TxKhuefItg== dependencies: buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.10" + ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" -jws@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.5.tgz#80d12d05b293d1e841e7cb8b4e69e561adcf834f" - integrity sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ== +jws@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.1.tgz#d79d4216a62c9afa0a3d5e8b5356d75abdeb2be5" + integrity sha512-bGA2omSrFUkd72dhh05bIAN832znP4wOU3lfuXtRBuGTbsmNmDXMQg28f0Vsxaxgk4myF5YkKQpz6qeRpMgX9g== dependencies: - jwa "^1.1.5" + jwa "^1.2.0" safe-buffer "^5.0.1" kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: @@ -6080,7 +6081,7 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1: +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== From 98983bb575e67c3e5f1dd41cc6485374dda41040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 21 Feb 2019 10:32:07 +0100 Subject: [PATCH 390/554] Fix lint --- src/bootstrap/neo4j.js | 2 +- src/seed/factories/index.js | 43 +++++++++++++++++-------------------- src/seed/seed-db.js | 30 +++++++++++++------------- 3 files changed, 36 insertions(+), 39 deletions(-) diff --git a/src/bootstrap/neo4j.js b/src/bootstrap/neo4j.js index 24a0cd4dd..935449a0a 100644 --- a/src/bootstrap/neo4j.js +++ b/src/bootstrap/neo4j.js @@ -7,7 +7,7 @@ let driver export function getDriver (options = {}) { const { - uri = process.env.NEO4J_URI || 'bolt://localhost:7687', + uri = process.env.NEO4J_URI || 'bolt://localhost:7687', username = process.env.NEO4J_USERNAME || 'neo4j', password = process.env.NEO4J_PASSWORD || 'neo4j' } = options diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index efbf7b248..6eed8a397 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -1,11 +1,9 @@ -import { GraphQLClient } from 'graphql-request' +import { GraphQLClient, request } from 'graphql-request' import { getDriver } from '../../bootstrap/neo4j' -import { request } from 'graphql-request' export const seedServerHost = 'http://127.0.0.1:4001' -export const testServerHost = 'http://127.0.0.1:4123' -const authenticatedHeaders = async ({ email, password }, host = testServerHost) => { +const authenticatedHeaders = async ({ email, password }, host) => { const mutation = ` mutation { login(email:"${email}", password:"${password}"){ @@ -19,21 +17,21 @@ const authenticatedHeaders = async ({ email, password }, host = testServerHost) } const factories = { - 'badge': require('./badges.js').default, - 'user': require('./users.js').default, + 'badge': require('./badges.js').default, + 'user': require('./users.js').default, 'organization': require('./organizations.js').default, - 'post': require('./posts.js').default, - 'comment': require('./comments.js').default, - 'category': require('./categories.js').default, - 'tag': require('./tags.js').default, - 'report': require('./reports.js').default + 'post': require('./posts.js').default, + 'comment': require('./comments.js').default, + 'category': require('./categories.js').default, + 'tag': require('./tags.js').default, + 'report': require('./reports.js').default } const relationFactories = { - 'user': require('./users.js').relate, + 'user': require('./users.js').relate, 'organization': require('./organizations.js').relate, - 'post': require('./posts.js').relate, - 'comment': require('./comments.js').relate + 'post': require('./posts.js').relate, + 'comment': require('./comments.js').relate } export const create = (model, parameters, options) => { @@ -57,7 +55,7 @@ export const cleanDatabase = async (options = {}) => { try { return await session.run(cypher) } catch (error) { - throw(error) + throw (error) } finally { session.close() } @@ -66,8 +64,7 @@ export const cleanDatabase = async (options = {}) => { export default function factoryFun (options = {}) { const { neo4jDriver = getDriver(), - seedServerHost = 'http://127.0.0.1:4001', - testServerHost = 'http://127.0.0.1:4123' + seedServerHost = 'http://127.0.0.1:4001' } = options const graphQLClient = new GraphQLClient(seedServerHost) @@ -77,24 +74,24 @@ export default function factoryFun (options = {}) { seedServerHost, graphQLClient, lastResponse: null, - async authenticateAs({email, password}) { - const headers = await authenticatedHeaders({email, password}, seedServerHost) + async authenticateAs ({ email, password }) { + const headers = await authenticatedHeaders({ email, password }, seedServerHost) this.lastResponse = headers this.graphQLClient = new GraphQLClient(seedServerHost, { headers }) return this }, - async create(node, properties) { + async create (node, properties) { const mutation = factories[node](properties) this.lastResponse = await this.graphQLClient.request(mutation) return this }, - async relate(node, relationship, properties) { + async relate (node, relationship, properties) { const mutation = relationFactories[node](relationship, properties) this.lastResponse = await this.graphQLClient.request(mutation) return this }, - async cleanDatabase() { - this.lastResponse = await cleanDatabase({driver: this.neo4jDriver}) + async cleanDatabase () { + this.lastResponse = await cleanDatabase({ driver: this.neo4jDriver }) return this } } diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 1075c61d6..df5126329 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,4 +1,4 @@ -import factoryFun, { create, relate, seedServerHost as host } from './factories' +import factoryFun, { create, relate } from './factories' /* eslint-disable no-multi-spaces */ (async function () { @@ -79,22 +79,22 @@ import factoryFun, { create, relate, seedServerHost as host } from './factories' ]) await Promise.all([ - asAdmin .create('post', { id: 'p0' }), + asAdmin.create('post', { id: 'p0' }), asModerator.create('post', { id: 'p1' }), - asUser .create('post', { id: 'p2' }), - asTick .create('post', { id: 'p3' }), - asTrick .create('post', { id: 'p4' }), - asTrack .create('post', { id: 'p5' }), - asAdmin .create('post', { id: 'p6' }), + asUser.create('post', { id: 'p2' }), + asTick.create('post', { id: 'p3' }), + asTrick.create('post', { id: 'p4' }), + asTrack.create('post', { id: 'p5' }), + asAdmin.create('post', { id: 'p6' }), asModerator.create('post', { id: 'p7' }), - asUser .create('post', { id: 'p8' }), - asTick .create('post', { id: 'p9' }), - asTrick .create('post', { id: 'p10' }), - asTrack .create('post', { id: 'p11' }), - asAdmin .create('post', { id: 'p12' }), + asUser.create('post', { id: 'p8' }), + asTick.create('post', { id: 'p9' }), + asTrick.create('post', { id: 'p10' }), + asTrack.create('post', { id: 'p11' }), + asAdmin.create('post', { id: 'p12' }), asModerator.create('post', { id: 'p13' }), - asUser .create('post', { id: 'p14' }), - asTick .create('post', { id: 'p15' }) + asUser.create('post', { id: 'p14' }), + asTick.create('post', { id: 'p15' }) ]) await Promise.all([ @@ -169,7 +169,7 @@ import factoryFun, { create, relate, seedServerHost as host } from './factories' ]) await Promise.all([ - asTick .create('report', { description: 'I don\'t like this comment', resource: { id: 'c1', type: 'comment' } }), + asTick.create('report', { description: 'I don\'t like this comment', resource: { id: 'c1', type: 'comment' } }), asTrick.create('report', { description: 'I don\'t like this post', resource: { id: 'p1', type: 'contribution' } }), asTrack.create('report', { description: 'I don\'t like this user', resource: { id: 'u1', type: 'user' } }) ]) From aa07a2a6167cac5e06d3267745209dc787ec489b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 21 Feb 2019 10:45:34 +0100 Subject: [PATCH 391/554] Refactor Id Middleware I found a way to cleanly request additional attributes in our middleware. We can use this pattern if we e.g. require the author of posts and comments to check if the user is the author and therefore authorized to update or delete the post. CC @mattwr18 @appinteractive @tirokk --- src/middleware/idMiddleware.js | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/middleware/idMiddleware.js b/src/middleware/idMiddleware.js index 59224bd64..d6dac0580 100644 --- a/src/middleware/idMiddleware.js +++ b/src/middleware/idMiddleware.js @@ -1,25 +1,17 @@ -import find from 'lodash/find' +import cloneDeep from 'lodash/cloneDeep' -const includeId = async (resolve, root, args, context, info) => { - let isIdPresent - let removeIdFromResult - isIdPresent = find(info.fieldNodes[0].selectionSet.selections, item => item.name.value === 'id') - if (!isIdPresent) { - // add id to request as the user did not ask but we need it - info.fieldNodes[0].selectionSet.selections.unshift({ - kind: 'Field', - name: { kind: 'Name', value: 'id' } - }) - removeIdFromResult = true - } +const includeId = async (resolve, root, args, context, resolveInfo) => { + // Keeping the graphql resolveInfo untouched ensures that we don't add the + // following attributes to the result set returned to the graphQL client. + // We only want to pass these attributes to our resolver for internal + // purposes e.g. authorization. + const copy = cloneDeep(resolveInfo) - const result = await resolve(root, args, context, info) - - if (!isIdPresent && removeIdFromResult) { - // remove id if the user did not ask for it - info.fieldNodes[0].selectionSet.selections.shift() - } - return result + copy.fieldNodes[0].selectionSet.selections.unshift({ + kind: 'Field', + name: { kind: 'Name', value: 'id' } + }) + return resolve(root, args, context, copy) } export default { From 132dba04dd1f28a169c669fb6b318827cad3f775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 21 Feb 2019 15:40:31 +0100 Subject: [PATCH 392/554] Refactor tests with the new factory API --- src/graphql-schema.spec.js | 39 +++++++++------- src/jest/helpers.js | 6 ++- src/middleware/permissionsMiddleware.spec.js | 49 +++++++++++--------- src/middleware/slugifyMiddleware.spec.js | 37 +++++++++------ src/seed/factories/index.js | 2 +- src/seed/seed-db.js | 14 +++--- 6 files changed, 84 insertions(+), 63 deletions(-) diff --git a/src/graphql-schema.spec.js b/src/graphql-schema.spec.js index e61130fe3..463d91af2 100644 --- a/src/graphql-schema.spec.js +++ b/src/graphql-schema.spec.js @@ -1,17 +1,19 @@ -import { create, cleanDatabase } from './seed/factories' +import Factory from './seed/factories' import jwt from 'jsonwebtoken' -import { testServerHost as host, authenticatedHeaders } from './jest/helpers' +import { host, login } from './jest/helpers' import { GraphQLClient, request } from 'graphql-request' +const factory = Factory() + beforeEach(async () => { - await create('user', { + await factory.create('user', { email: 'test@example.org', password: '1234' }) }) afterEach(async () => { - await cleanDatabase() + await factory.cleanDatabase() }) describe('login', () => { @@ -28,7 +30,10 @@ describe('login', () => { describe('ask for a `token`', () => { describe('with valid email/password combination', () => { it('responds with a JWT token', async () => { - const data = await request(host, mutation({ email: 'test@example.org', password: '1234' })) + const data = await request(host, mutation({ + email: 'test@example.org', + password: '1234' + })) const { token } = data.login jwt.verify(token, process.env.JWT_SECRET, (err, data) => { expect(data.email).toEqual('test@example.org') @@ -39,21 +44,23 @@ describe('login', () => { describe('with a valid email but incorrect password', () => { it('responds with "Incorrect email address or password."', async () => { - try { - await request(host, mutation({ email: 'test@example.org', password: 'wrong' })) - } catch (error) { - expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') - } + await expect( + request(host, mutation({ + email: 'test@example.org', + password: 'wrong' + })) + ).rejects.toThrow('Incorrect email address or password.') }) }) describe('with a non-existing email', () => { it('responds with "Incorrect email address or password."', async () => { - try { - await request(host, mutation({ email: 'non-existent@example.org', password: 'wrong' })) - } catch (error) { - expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') - } + await expect( + request(host, mutation({ + email: 'non-existent@example.org', + password: 'wrong' + })) + ).rejects.toThrow('Incorrect email address or password.') }) }) }) @@ -76,7 +83,7 @@ describe('CreatePost', () => { let headers let response beforeEach(async () => { - headers = await authenticatedHeaders({ email: 'test@example.org', password: '1234' }) + headers = await login({ email: 'test@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) response = await client.request(`mutation { CreatePost( diff --git a/src/jest/helpers.js b/src/jest/helpers.js index cb86bf785..ff6a535e2 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -1,8 +1,10 @@ import { request } from 'graphql-request' -export const testServerHost = 'http://127.0.0.1:4123' +// this is the to-be-tested server host +// not to be confused with the seeder host +export const host = 'http://127.0.0.1:4123' -export async function authenticatedHeaders ({ email, password }, host = testServerHost) { +export async function login ({ email, password }) { const mutation = ` mutation { login(email:"${email}", password:"${password}"){ diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 7a5eacfce..a22f2bb72 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,16 +1,18 @@ -import { create, cleanDatabase } from '../seed/factories' -import { testServerHost as host, authenticatedHeaders } from '../jest/helpers' +import Factory from '../seed/factories' +import { host, login } from '../jest/helpers' import { GraphQLClient } from 'graphql-request' +const factory = Factory() + describe('authorization', () => { describe('given two existing users', () => { beforeEach(async () => { - await create('user', { + await factory.create('user', { email: 'owner@example.org', name: 'Owner', password: 'iamtheowner' }) - await create('user', { + await factory.create('user', { email: 'someone@example.org', name: 'Someone else', password: 'else' @@ -18,28 +20,28 @@ describe('authorization', () => { }) afterEach(async () => { - await cleanDatabase() + await factory.cleanDatabase() }) describe('access email address', () => { let headers = {} - const action = async (headers) => { + let loginCredentials = null + const action = async () => { + if (loginCredentials) { + headers = await login(loginCredentials) + } const graphQLClient = new GraphQLClient(host, { headers }) - return graphQLClient.request(`{ - User(name: "Owner") { - email - } - }`) + return graphQLClient.request('{User(name: "Owner") { email } }') } describe('not logged in', async () => { it('rejects', async () => { - await expect(action(headers)).rejects.toThrow('Not Authorised!') + await expect(action()).rejects.toThrow('Not Authorised!') }) it('does not expose the owner\'s email address', async () => { try { - await action(headers) + await action() } catch (error) { expect(error.response.data).toEqual({ User: [ { email: null } ] }) } @@ -47,30 +49,33 @@ describe('authorization', () => { }) describe('as owner', () => { - it('exposes the owner\'s email address', async () => { - headers = await authenticatedHeaders({ + beforeEach(() => { + loginCredentials = { email: 'owner@example.org', password: 'iamtheowner' - }) - expect(await action(headers)).toEqual({ User: [ { email: 'owner@example.org' } ] }) + } + }) + + it('exposes the owner\'s email address', async () => { + await expect(action()).resolves.toEqual({ User: [ { email: 'owner@example.org' } ] }) }) }) - describe('as someone else', () => { + describe('authenticated as another user', () => { beforeEach(async () => { - headers = await authenticatedHeaders({ + loginCredentials = { email: 'someone@example.org', password: 'else' - }) + } }) it('rejects', async () => { - await expect(action(headers)).rejects.toThrow('Not Authorised!') + await expect(action()).rejects.toThrow('Not Authorised!') }) it('does not expose the owner\'s email address', async () => { try { - await action(headers) + await action() } catch (error) { expect(error.response.data).toEqual({ User: [ { email: null } ] }) } diff --git a/src/middleware/slugifyMiddleware.spec.js b/src/middleware/slugifyMiddleware.spec.js index b8e74cd7f..aaa09d29a 100644 --- a/src/middleware/slugifyMiddleware.spec.js +++ b/src/middleware/slugifyMiddleware.spec.js @@ -1,41 +1,48 @@ -import { create, cleanDatabase } from '../seed/factories' -import { testServerHost as host, authenticatedHeaders } from '../jest/helpers' +import Factory from '../seed/factories' +import { host, login } from '../jest/helpers' import { GraphQLClient } from 'graphql-request' -let client +let authenticatedClient let headers +const factory = Factory() + beforeEach(async () => { - await create('user', { email: 'user@example.org', password: '1234' }) - headers = await authenticatedHeaders({ email: 'user@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) + await factory.create('user', { email: 'user@example.org', password: '1234' }) + await factory.create('user', { email: 'someone@example.org', password: '1234' }) + headers = await login({ email: 'user@example.org', password: '1234' }) + authenticatedClient = new GraphQLClient(host, { headers }) }) afterEach(async () => { - await cleanDatabase() + await factory.cleanDatabase() }) describe('slugify', () => { describe('CreatePost', () => { it('generates a slug based on title', async () => { - const response = await client.request(`mutation { + const response = await authenticatedClient.request(`mutation { CreatePost( title: "I am a brand new post", content: "Some content" ) { slug } - }`, { headers }) + }`) expect(response).toEqual({ CreatePost: { slug: 'i-am-a-brand-new-post' } }) }) describe('if slug exists', () => { beforeEach(async () => { - await create('post', { + const asSomeoneElse = await Factory().authenticateAs({ + email: 'someone@example.org', + password: '1234' + }) + await asSomeoneElse.create('post', { title: 'Pre-existing post', slug: 'pre-existing-post' - }, { headers }) + }) }) it('chooses another slug', async () => { - const response = await client.request(`mutation { + const response = await authenticatedClient.request(`mutation { CreatePost( title: "Pre-existing post", content: "Some content" @@ -46,7 +53,7 @@ describe('slugify', () => { describe('but if the client specifies a slug', () => { it('rejects CreatePost', async () => { - await expect(client.request(`mutation { + await expect(authenticatedClient.request(`mutation { CreatePost( title: "Pre-existing post", content: "Some content", @@ -61,9 +68,9 @@ describe('slugify', () => { describe('CreateUser', () => { const action = async (mutation, params) => { - return client.request(`mutation { + return authenticatedClient.request(`mutation { ${mutation}(password: "yo", ${params}) { slug } - }`, { headers }) + }`) } it('generates a slug based on name', async () => { await expect(action('CreateUser', 'name: "I am a user"')) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 6eed8a397..fef83ff55 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -61,7 +61,7 @@ export const cleanDatabase = async (options = {}) => { } } -export default function factoryFun (options = {}) { +export default function Factory (options = {}) { const { neo4jDriver = getDriver(), seedServerHost = 'http://127.0.0.1:4001' diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index df5126329..58984b12a 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,4 +1,4 @@ -import factoryFun, { create, relate } from './factories' +import Factory, { create, relate } from './factories' /* eslint-disable no-multi-spaces */ (async function () { @@ -70,12 +70,12 @@ import factoryFun, { create, relate } from './factories' ]) const [ asAdmin, asModerator, asUser, asTick, asTrick, asTrack ] = await Promise.all([ - factoryFun().authenticateAs({ email: 'admin@example.org', password: '1234' }), - factoryFun().authenticateAs({ email: 'moderator@example.org', password: '1234' }), - factoryFun().authenticateAs({ email: 'user@example.org', password: '1234' }), - factoryFun().authenticateAs({ email: 'tick@example.org', password: '1234' }), - factoryFun().authenticateAs({ email: 'trick@example.org', password: '1234' }), - factoryFun().authenticateAs({ email: 'track@example.org', password: '1234' }) + Factory().authenticateAs({ email: 'admin@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'moderator@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'user@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'tick@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'trick@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'track@example.org', password: '1234' }) ]) await Promise.all([ From eda2ea34fcb00d12f9879a97e9b3baf4dcd67b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 21 Feb 2019 20:00:35 +0100 Subject: [PATCH 393/554] Incorporate @appinteractive's feedback @appinteractive can we merge this soon? --- src/middleware/permissionsMiddleware.js | 6 +++--- src/seed/factories/badges.js | 17 +++++++++-------- src/seed/factories/categories.js | 12 ++++++------ src/seed/factories/comments.js | 5 +++-- src/seed/factories/index.js | 2 +- src/seed/factories/organizations.js | 5 +++-- src/seed/factories/posts.js | 5 +++-- src/seed/factories/tags.js | 4 ++-- src/seed/factories/users.js | 9 +++++---- 9 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 0bd88b274..1a3f04ceb 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -16,7 +16,7 @@ const isModerator = rule()(async (parent, args, ctx, info) => { }) */ -const myself = rule({ cache: 'no_cache' })(async (parent, args, ctx, info) => { +const isMyOwn = rule({ cache: 'no_cache' })(async (parent, args, ctx, info) => { return ctx.user.id === parent.id }) @@ -36,8 +36,8 @@ const permissions = shield({ // CreateUser: allow, }, User: { - email: myself, - password: myself + email: isMyOwn, + password: isMyOwn } // Post: isAuthenticated }) diff --git a/src/seed/factories/badges.js b/src/seed/factories/badges.js index 2aabe2014..b34442521 100644 --- a/src/seed/factories/badges.js +++ b/src/seed/factories/badges.js @@ -1,8 +1,8 @@ -import faker from 'faker' +import uuid from 'uuid/v4' export default function (params) { const { - id = `cat${faker.random.number()}`, + id = uuid(), key, type = 'crowdfunding', status = 'permanent', @@ -11,12 +11,13 @@ export default function (params) { return ` mutation { - ${id}: CreateBadge( - id: "${id}", - key: "${key}", - type: ${type}, - status: ${status}, - icon: "${icon}") { id } + CreateBadge( + id: "${id}", + key: "${key}", + type: ${type}, + status: ${status}, + icon: "${icon}" + ) { id } } ` } diff --git a/src/seed/factories/categories.js b/src/seed/factories/categories.js index 287aac5e0..a4b448f4b 100644 --- a/src/seed/factories/categories.js +++ b/src/seed/factories/categories.js @@ -1,8 +1,8 @@ -import faker from 'faker' +import uuid from 'uuid/v4' export default function (params) { const { - id = `cat${faker.random.number()}`, + id = uuid(), name, slug, icon @@ -11,10 +11,10 @@ export default function (params) { return ` mutation { CreateCategory( - id: "${id}", - name: "${name}", - slug: "${slug}", - icon: "${icon}" + id: "${id}", + name: "${name}", + slug: "${slug}", + icon: "${icon}" ) { id, name } } ` diff --git a/src/seed/factories/comments.js b/src/seed/factories/comments.js index b4e25c482..acf493f6d 100644 --- a/src/seed/factories/comments.js +++ b/src/seed/factories/comments.js @@ -1,8 +1,9 @@ import faker from 'faker' +import uuid from 'uuid/v4' export default function (params) { const { - id = `c${faker.random.number()}`, + id = uuid(), content = [ faker.lorem.sentence(), faker.lorem.sentence() @@ -13,7 +14,7 @@ export default function (params) { return ` mutation { - ${id}: CreateComment( + CreateComment( id: "${id}", content: "${content}", disabled: ${disabled}, diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index fef83ff55..a107fc6b7 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -51,7 +51,7 @@ export const cleanDatabase = async (options = {}) => { driver = getDriver() } = options const session = driver.session() - const cypher = 'MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r' + const cypher = 'MATCH (n) DETACH DELETE n' try { return await session.run(cypher) } catch (error) { diff --git a/src/seed/factories/organizations.js b/src/seed/factories/organizations.js index c0329d55d..0ab73beb8 100644 --- a/src/seed/factories/organizations.js +++ b/src/seed/factories/organizations.js @@ -1,8 +1,9 @@ import faker from 'faker' +import uuid from 'uuid/v4' export default function create (params) { const { - id = `o${faker.random.number()}`, + id = uuid(), name = faker.comany.companyName(), description = faker.company.catchPhrase(), disabled = false, @@ -11,7 +12,7 @@ export default function create (params) { return ` mutation { - ${id}: CreateOrganization( + CreateOrganization( id: "${id}", name: "${name}", description: "${description}", diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index eaa616b2b..80f5e289d 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -1,8 +1,9 @@ import faker from 'faker' +import uuid from 'uuid/v4' export default function (params) { const { - id = `p${faker.random.number()}`, + id = uuid(), title = faker.lorem.sentence(), content = [ faker.lorem.sentence(), @@ -19,7 +20,7 @@ export default function (params) { return ` mutation { - ${id}: CreatePost( + CreatePost( id: "${id}", title: "${title}", content: "${content}", diff --git a/src/seed/factories/tags.js b/src/seed/factories/tags.js index 0854cc0cd..c603c5629 100644 --- a/src/seed/factories/tags.js +++ b/src/seed/factories/tags.js @@ -1,8 +1,8 @@ -import faker from 'faker' +import uuid from 'uuid/v4' export default function (params) { const { - id = `t${faker.random.number()}`, + id = uuid(), name } = params diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index 2e94b5ebe..b3a6e83c1 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -1,8 +1,9 @@ import faker from 'faker' +import uuid from 'uuid/v4' export default function create (params) { const { - id = `u${faker.random.number()}`, + id = uuid(), name = faker.name.findName(), email = faker.internet.email(), password = '1234', @@ -14,7 +15,7 @@ export default function create (params) { return ` mutation { - ${id}: CreateUser( + CreateUser( id: "${id}", name: "${name}", password: "${password}", @@ -22,8 +23,8 @@ export default function create (params) { avatar: "${avatar}", role: ${role}, disabled: ${disabled}, - deleted: ${deleted}) { - id + deleted: ${deleted} + ) { name email avatar From d8af7cb2e57b4623baa719c181899f4d72f7b185 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 21 Feb 2019 21:25:16 +0000 Subject: [PATCH 394/554] Bump neo4j-graphql-js from 2.3.1 to 2.4.0 Bumps [neo4j-graphql-js](https://github.com/neo4j-graphql/neo4j-graphql-js) from 2.3.1 to 2.4.0. - [Release notes](https://github.com/neo4j-graphql/neo4j-graphql-js/releases) - [Changelog](https://github.com/neo4j-graphql/neo4j-graphql-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/neo4j-graphql/neo4j-graphql-js/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 61 +++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 8954de8f1..0cf71cddd 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "lodash": "~4.17.11", "ms": "~2.1.1", "neo4j-driver": "~1.7.2", - "neo4j-graphql-js": "~2.3.1", + "neo4j-graphql-js": "~2.4.0", "node-fetch": "~2.3.0", "npm-run-all": "~4.1.5", "passport": "~0.4.0", diff --git a/yarn.lock b/yarn.lock index ff7dffeb0..f77e60551 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1010,6 +1010,14 @@ apollo-env@0.3.3: core-js "3.0.0-beta.13" node-fetch "^2.2.0" +apollo-errors@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/apollo-errors/-/apollo-errors-1.9.0.tgz#f1ed0ca0a6be5cd2f24e2eaa7b0860a10146ff51" + integrity sha512-XVukHd0KLvgY6tNjsPS3/Re3U6RQlTKrTbIpqqeTMo2N34uQMr+H1UheV21o8hOZBAFosvBORVricJiP5vfmrw== + dependencies: + assert "^1.4.1" + extendable-error "^0.1.5" + apollo-graphql@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.1.1.tgz#dc5eac3062abf9f063ac9869f0ef5c54fdc136e5" @@ -1295,6 +1303,13 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +assert@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + dependencies: + util "0.10.3" + assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -2726,6 +2741,11 @@ extend@^3.0.0, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +extendable-error@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/extendable-error/-/extendable-error-0.1.5.tgz#122308a7097bc89a263b2c4fbf089c78140e3b6d" + integrity sha1-EiMIpwl7yJomOyxPvwiceBQOO20= + external-editor@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" @@ -3078,6 +3098,15 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== +graphql-auth-directives@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/graphql-auth-directives/-/graphql-auth-directives-2.0.0.tgz#8e8c5118d362d19e99f9a2ae6d854c563d9da293" + integrity sha512-bqKXJjjf2pXnZRAJiqzemXAc3Wp5fUjnKb/w5bZvJLBxN4doSeVfnSQFMjnoSUKyd8eayyuPyjZj/+PXUO99Yg== + dependencies: + apollo-errors "^1.9.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" @@ -3230,14 +3259,7 @@ graphql-yoga@~1.17.4: graphql-tools "^4.0.0" subscriptions-transport-ws "^0.9.8" -"graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0", graphql@^14.0.2: - version "14.0.2" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.0.2.tgz#7dded337a4c3fd2d075692323384034b357f5650" - integrity sha512-gUC4YYsaiSJT1h40krG3J+USGlwhzNTXSb4IOZljn9ag5Tj+RkoXrWp+Kh7WyE3t1NCfab5kzCuxBIvOMERMXw== - dependencies: - iterall "^1.2.2" - -graphql@~14.1.1: +"graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0", graphql@^14.0.2, graphql@~14.1.1: version "14.1.1" resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.1.1.tgz#d5d77df4b19ef41538d7215d1e7a28834619fac0" integrity sha512-C5zDzLqvfPAgTtP8AUPIt9keDabrdRAqSWjj2OPRKrKxI9Fb65I36s1uCs1UUBFnSWTdO7hyHi7z1ZbwKMKF6Q== @@ -3504,6 +3526,11 @@ inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, i resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" @@ -4348,7 +4375,7 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= -jsonwebtoken@^8.2.0, jsonwebtoken@~8.5.0: +jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0, jsonwebtoken@~8.5.0: version "8.5.0" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#ebd0ca2a69797816e1c5af65b6c759787252947e" integrity sha512-IqEycp0znWHNA11TpYi77bVgyBO/pGESDh7Ajhas+u0ttkGkKYIIAjniL4Bw5+oVejVF+SYkaI7XKfwCCyeTuA== @@ -4857,12 +4884,13 @@ neo4j-driver@^1.7.2, neo4j-driver@~1.7.2: text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-graphql-js@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.3.1.tgz#9a5de7e312594d63481e947a0cbe4e08b05ffed3" - integrity sha512-9DExWXD2vFdDJOmqorT1ygFOUEos7KF8KyF8Wt3jYxejWUuq+a5fAFBu7+YDH8QbvA23paKPEX0Pn1nS+Q5C1A== +neo4j-graphql-js@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.4.0.tgz#6e87f57bd5f4892ada66c3c4b31aac9eba9c8c64" + integrity sha512-lFerSRsUXVwEr8AWUpQ7rWN7Cabn6RCAvymZPTltVaQR2gS/jZoKbJsVUmXurtNQCBJbDg9YWguNQy8uloLjZg== dependencies: graphql "^14.0.2" + graphql-auth-directives "^2.0.0" lodash "^4.17.11" neo4j-driver "^1.7.2" @@ -6888,6 +6916,13 @@ util.promisify@^1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" From 40c210a0ce61107482d0f281e134259f9c6a0b2c Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Thu, 21 Feb 2019 21:09:33 -0300 Subject: [PATCH 395/554] Start unit testing report feature --- src/graphql-schema.spec.js | 61 +++++++++++++++++++- src/jest/helpers.js | 6 +- src/middleware/permissionsMiddleware.spec.js | 6 +- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/graphql-schema.spec.js b/src/graphql-schema.spec.js index 69073444c..d425b0114 100644 --- a/src/graphql-schema.spec.js +++ b/src/graphql-schema.spec.js @@ -1,7 +1,7 @@ -import { request } from 'graphql-request' +import { GraphQLClient, request } from 'graphql-request' import { create, cleanDatabase } from './seed/factories' import jwt from 'jsonwebtoken' -import { host } from './jest/helpers' +import { host, login } from './jest/helpers' describe('login', () => { const mutation = (params) => { @@ -60,3 +60,60 @@ describe('login', () => { }) }) }) + +describe('report', () => { + beforeEach(async () => { + await create('user', { + email: 'test@example.org', + password: '1234' + }) + }) + + afterEach(async () => { + await cleanDatabase() + }) + + describe('unauthenticated', () => { + let client + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect( + client.request(`mutation { + report( + description: "I don't like this user", + resource: { + id: "u1", + type: user + } + ) { id, createdAt } + }`) + ).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { + let headers + let response + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + response = await client.request(`mutation { + report( + description: "I don't like this user", + resource: { + id: "u1", + type: user + } + ) { id, createdAt } + }`, + { headers } + ) + }) + it('creates a report', () => { + let { id, createdAt } = response.report + expect(response).toEqual({ + report: { id, createdAt } + }) + }) + }) + }) +}) diff --git a/src/jest/helpers.js b/src/jest/helpers.js index 01a26e9d3..12cb63335 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -1,8 +1,10 @@ import { request } from 'graphql-request' +// this is the to-be-tested server host +// not to be confused with the seeder host export const host = 'http://127.0.0.1:4123' -export async function authenticatedHeaders ({ email, password }) { +export async function login ({ email, password }) { const mutation = ` mutation { login(email:"${email}", password:"${password}"){ @@ -13,4 +15,4 @@ export async function authenticatedHeaders ({ email, password }) { return { authorization: `Bearer ${response.login.token}` } -} +} \ No newline at end of file diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index cf86d11c9..9b115eae3 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,5 +1,5 @@ import { create, cleanDatabase } from '../seed/factories' -import { host, authenticatedHeaders } from '../jest/helpers' +import { host, login } from '../jest/helpers' import { GraphQLClient } from 'graphql-request' describe('authorization', () => { @@ -45,7 +45,7 @@ describe('authorization', () => { describe('as owner', () => { it('exposes the owner\'s email address', async () => { - headers = await authenticatedHeaders({ + headers = await login({ email: 'owner@example.org', password: 'iamtheowner' }) @@ -55,7 +55,7 @@ describe('authorization', () => { describe('as someone else', () => { it('does not expose the owner\'s email address', async () => { - headers = await authenticatedHeaders({ + headers = await login({ email: 'someone@example.org', password: 'else' }) From 4a43583c6b982fd72b2041dd35894c3bc59815c0 Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Thu, 21 Feb 2019 22:43:51 -0300 Subject: [PATCH 396/554] Create abusive-user to report, PR review suggestions --- src/bootstrap/neo4j.js | 26 +++-- src/graphql-schema.spec.js | 32 ++++--- src/jest/helpers.js | 2 +- src/seed/factories/badges.js | 23 +++++ src/seed/factories/categories.js | 21 +++++ src/seed/factories/comments.js | 37 ++++++++ src/seed/factories/index.js | 141 +++++++++++++++++++--------- src/seed/factories/organizations.js | 36 +++++++ src/seed/factories/posts.js | 46 +++++++++ src/seed/factories/reports.js | 23 +++++ src/seed/factories/tags.js | 17 ++++ src/seed/factories/users.js | 33 +++++-- src/server.js | 4 +- 13 files changed, 360 insertions(+), 81 deletions(-) create mode 100644 src/seed/factories/badges.js create mode 100644 src/seed/factories/categories.js create mode 100644 src/seed/factories/comments.js create mode 100644 src/seed/factories/organizations.js create mode 100644 src/seed/factories/posts.js create mode 100644 src/seed/factories/reports.js create mode 100644 src/seed/factories/tags.js diff --git a/src/bootstrap/neo4j.js b/src/bootstrap/neo4j.js index 766c12065..935449a0a 100644 --- a/src/bootstrap/neo4j.js +++ b/src/bootstrap/neo4j.js @@ -1,20 +1,18 @@ import { v1 as neo4j } from 'neo4j-driver' +import dotenv from 'dotenv' + +dotenv.config() let driver -export default function () { - return { - getDriver () { - if (!driver) { - driver = neo4j.driver( - process.env.NEO4J_URI || 'bolt://localhost:7687', - neo4j.auth.basic( - process.env.NEO4J_USER || 'neo4j', - process.env.NEO4J_PASSWORD || 'neo4j' - ) - ) - } - return driver - } +export function getDriver (options = {}) { + const { + uri = process.env.NEO4J_URI || 'bolt://localhost:7687', + username = process.env.NEO4J_USERNAME || 'neo4j', + password = process.env.NEO4J_PASSWORD || 'neo4j' + } = options + if (!driver) { + driver = neo4j.driver(uri, neo4j.auth.basic(username, password)) } + return driver } diff --git a/src/graphql-schema.spec.js b/src/graphql-schema.spec.js index d425b0114..cedecac26 100644 --- a/src/graphql-schema.spec.js +++ b/src/graphql-schema.spec.js @@ -1,8 +1,10 @@ import { GraphQLClient, request } from 'graphql-request' -import { create, cleanDatabase } from './seed/factories' +import Factory from './seed/factories' import jwt from 'jsonwebtoken' import { host, login } from './jest/helpers' +const factory = Factory() + describe('login', () => { const mutation = (params) => { const { email, password } = params @@ -16,14 +18,14 @@ describe('login', () => { describe('given an existing user', () => { beforeEach(async () => { - await create('user', { + await factory.create('user', { email: 'test@example.org', password: '1234' }) }) afterEach(async () => { - await cleanDatabase() + await factory.cleanDatabase() }) describe('asking for a `token`', () => { @@ -63,16 +65,22 @@ describe('login', () => { describe('report', () => { beforeEach(async () => { - await create('user', { + await factory.create('user', { email: 'test@example.org', password: '1234' }) + await factory.create('user', { + id: 'u2', + name: 'abusive-user', + role: 'user', + email: 'abusive-user@example.org' + }) }) afterEach(async () => { - await cleanDatabase() + await factory.cleanDatabase() }) - + describe('unauthenticated', () => { let client it('throws authorization error', async () => { @@ -82,14 +90,14 @@ describe('report', () => { report( description: "I don't like this user", resource: { - id: "u1", + id: "u2", type: user } ) { id, createdAt } }`) ).rejects.toThrow('Not Authorised') }) - + describe('authenticated', () => { let headers let response @@ -100,14 +108,14 @@ describe('report', () => { report( description: "I don't like this user", resource: { - id: "u1", + id: "u2", type: user } ) { id, createdAt } }`, - { headers } - ) - }) + { headers } + ) + }) it('creates a report', () => { let { id, createdAt } = response.report expect(response).toEqual({ diff --git a/src/jest/helpers.js b/src/jest/helpers.js index 12cb63335..ff6a535e2 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -15,4 +15,4 @@ export async function login ({ email, password }) { return { authorization: `Bearer ${response.login.token}` } -} \ No newline at end of file +} diff --git a/src/seed/factories/badges.js b/src/seed/factories/badges.js new file mode 100644 index 000000000..b34442521 --- /dev/null +++ b/src/seed/factories/badges.js @@ -0,0 +1,23 @@ +import uuid from 'uuid/v4' + +export default function (params) { + const { + id = uuid(), + key, + type = 'crowdfunding', + status = 'permanent', + icon + } = params + + return ` + mutation { + CreateBadge( + id: "${id}", + key: "${key}", + type: ${type}, + status: ${status}, + icon: "${icon}" + ) { id } + } + ` +} diff --git a/src/seed/factories/categories.js b/src/seed/factories/categories.js new file mode 100644 index 000000000..a4b448f4b --- /dev/null +++ b/src/seed/factories/categories.js @@ -0,0 +1,21 @@ +import uuid from 'uuid/v4' + +export default function (params) { + const { + id = uuid(), + name, + slug, + icon + } = params + + return ` + mutation { + CreateCategory( + id: "${id}", + name: "${name}", + slug: "${slug}", + icon: "${icon}" + ) { id, name } + } + ` +} diff --git a/src/seed/factories/comments.js b/src/seed/factories/comments.js new file mode 100644 index 000000000..acf493f6d --- /dev/null +++ b/src/seed/factories/comments.js @@ -0,0 +1,37 @@ +import faker from 'faker' +import uuid from 'uuid/v4' + +export default function (params) { + const { + id = uuid(), + content = [ + faker.lorem.sentence(), + faker.lorem.sentence() + ].join('. '), + disabled = false, + deleted = false + } = params + + return ` + mutation { + CreateComment( + id: "${id}", + content: "${content}", + disabled: ${disabled}, + deleted: ${deleted} + ) { id } + } + ` +} + +export function relate (type, params) { + const { from, to } = params + return ` + mutation { + ${from}_${type}_${to}: AddComment${type}( + from: { id: "${from}" }, + to: { id: "${to}" } + ) { from { id } } + } + ` +} diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index e62e98869..a107fc6b7 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -1,50 +1,103 @@ -import ApolloClient from 'apollo-client' -import gql from 'graphql-tag' -import dotenv from 'dotenv' -import { HttpLink } from 'apollo-link-http' -import { InMemoryCache } from 'apollo-cache-inmemory' -import neo4j from '../../bootstrap/neo4j' -import fetch from 'node-fetch' +import { GraphQLClient, request } from 'graphql-request' +import { getDriver } from '../../bootstrap/neo4j' -dotenv.config() +export const seedServerHost = 'http://127.0.0.1:4001' -if (process.env.NODE_ENV === 'production') { - throw new Error('YOU CAN`T RUN FACTORIES IN PRODUCTION MODE') -} - -const client = new ApolloClient({ - link: new HttpLink({ uri: 'http://localhost:4001', fetch }), - cache: new InMemoryCache() -}) - -const driver = neo4j().getDriver() - -const builders = { - 'user': require('./users.js').default -} - -const buildMutation = (model, parameters) => { - return builders[model](parameters) -} - -const create = (model, parameters) => { - return client.mutate({ mutation: gql(buildMutation(model, parameters)) }) -} - -const cleanDatabase = async () => { - const session = driver.session() - const cypher = 'MATCH (n) DETACH DELETE n' - try { - const result = await session.run(cypher) - session.close() - return result - } catch (error) { - console.log(error) +const authenticatedHeaders = async ({ email, password }, host) => { + const mutation = ` + mutation { + login(email:"${email}", password:"${password}"){ + token + } + }` + const response = await request(host, mutation) + return { + authorization: `Bearer ${response.login.token}` } } -export { - create, - buildMutation, - cleanDatabase +const factories = { + 'badge': require('./badges.js').default, + 'user': require('./users.js').default, + 'organization': require('./organizations.js').default, + 'post': require('./posts.js').default, + 'comment': require('./comments.js').default, + 'category': require('./categories.js').default, + 'tag': require('./tags.js').default, + 'report': require('./reports.js').default +} + +const relationFactories = { + 'user': require('./users.js').relate, + 'organization': require('./organizations.js').relate, + 'post': require('./posts.js').relate, + 'comment': require('./comments.js').relate +} + +export const create = (model, parameters, options) => { + const graphQLClient = new GraphQLClient(seedServerHost, options) + const mutation = factories[model](parameters) + return graphQLClient.request(mutation) +} + +export const relate = (model, type, parameters, options) => { + const graphQLClient = new GraphQLClient(seedServerHost, options) + const mutation = relationFactories[model](type, parameters) + return graphQLClient.request(mutation) +} + +export const cleanDatabase = async (options = {}) => { + const { + driver = getDriver() + } = options + const session = driver.session() + const cypher = 'MATCH (n) DETACH DELETE n' + try { + return await session.run(cypher) + } catch (error) { + throw (error) + } finally { + session.close() + } +} + +export default function Factory (options = {}) { + const { + neo4jDriver = getDriver(), + seedServerHost = 'http://127.0.0.1:4001' + } = options + + const graphQLClient = new GraphQLClient(seedServerHost) + + const result = { + neo4jDriver, + seedServerHost, + graphQLClient, + lastResponse: null, + async authenticateAs ({ email, password }) { + const headers = await authenticatedHeaders({ email, password }, seedServerHost) + this.lastResponse = headers + this.graphQLClient = new GraphQLClient(seedServerHost, { headers }) + return this + }, + async create (node, properties) { + const mutation = factories[node](properties) + this.lastResponse = await this.graphQLClient.request(mutation) + return this + }, + async relate (node, relationship, properties) { + const mutation = relationFactories[node](relationship, properties) + this.lastResponse = await this.graphQLClient.request(mutation) + return this + }, + async cleanDatabase () { + this.lastResponse = await cleanDatabase({ driver: this.neo4jDriver }) + return this + } + } + result.authenticateAs.bind(result) + result.create.bind(result) + result.relate.bind(result) + result.cleanDatabase.bind(result) + return result } diff --git a/src/seed/factories/organizations.js b/src/seed/factories/organizations.js new file mode 100644 index 000000000..0ab73beb8 --- /dev/null +++ b/src/seed/factories/organizations.js @@ -0,0 +1,36 @@ +import faker from 'faker' +import uuid from 'uuid/v4' + +export default function create (params) { + const { + id = uuid(), + name = faker.comany.companyName(), + description = faker.company.catchPhrase(), + disabled = false, + deleted = false + } = params + + return ` + mutation { + CreateOrganization( + id: "${id}", + name: "${name}", + description: "${description}", + disabled: ${disabled}, + deleted: ${deleted} + ) { name } + } + ` +} + +export function relate (type, params) { + const { from, to } = params + return ` + mutation { + ${from}_${type}_${to}: AddOrganization${type}( + from: { id: "${from}" }, + to: { id: "${to}" } + ) { from { id } } + } + ` +} diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js new file mode 100644 index 000000000..80f5e289d --- /dev/null +++ b/src/seed/factories/posts.js @@ -0,0 +1,46 @@ +import faker from 'faker' +import uuid from 'uuid/v4' + +export default function (params) { + const { + id = uuid(), + title = faker.lorem.sentence(), + content = [ + faker.lorem.sentence(), + faker.lorem.sentence(), + faker.lorem.sentence(), + faker.lorem.sentence(), + faker.lorem.sentence() + ].join('. '), + image = faker.image.image(), + visibility = 'public', + disabled = false, + deleted = false + } = params + + return ` + mutation { + CreatePost( + id: "${id}", + title: "${title}", + content: "${content}", + image: "${image}", + visibility: ${visibility}, + disabled: ${disabled}, + deleted: ${deleted} + ) { title, content } + } + ` +} + +export function relate (type, params) { + const { from, to } = params + return ` + mutation { + ${from}_${type}_${to}: AddPost${type}( + from: { id: "${from}" }, + to: { id: "${to}" } + ) { from { id } } + } + ` +} diff --git a/src/seed/factories/reports.js b/src/seed/factories/reports.js new file mode 100644 index 000000000..4dcd479f1 --- /dev/null +++ b/src/seed/factories/reports.js @@ -0,0 +1,23 @@ +import faker from 'faker' + +export default function create (params) { + const { + description = faker.lorem.sentence(), + resource: { id: resourceId, type } + } = params + + return ` + mutation { + report( + description: "${description}", + resource: { + id: "${resourceId}", + type: ${type} + } + ) { + id, + createdAt + } + } + ` +} diff --git a/src/seed/factories/tags.js b/src/seed/factories/tags.js new file mode 100644 index 000000000..c603c5629 --- /dev/null +++ b/src/seed/factories/tags.js @@ -0,0 +1,17 @@ +import uuid from 'uuid/v4' + +export default function (params) { + const { + id = uuid(), + name + } = params + + return ` + mutation { + CreateTag( + id: "${id}", + name: "${name}", + ) { name } + } + ` +} diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index 452059a73..b3a6e83c1 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -1,25 +1,30 @@ import faker from 'faker' +import uuid from 'uuid/v4' -export default function (params) { +export default function create (params) { const { + id = uuid(), name = faker.name.findName(), email = faker.internet.email(), password = '1234', - avatar = faker.internet.avatar() + role = 'user', + avatar = faker.internet.avatar(), + disabled = false, + deleted = false } = params return ` mutation { - u1: CreateUser( - id: "u1", + CreateUser( + id: "${id}", name: "${name}", password: "${password}", email: "${email}", avatar: "${avatar}", - role: admin, - disabled: false, - deleted: false) { - id + role: ${role}, + disabled: ${disabled}, + deleted: ${deleted} + ) { name email avatar @@ -28,3 +33,15 @@ export default function (params) { } ` } + +export function relate (type, params) { + const { from, to } = params + return ` + mutation { + ${from}_${type}_${to}: AddUser${type}( + from: { id: "${from}" }, + to: { id: "${to}" } + ) { from { id } } + } + ` +} diff --git a/src/server.js b/src/server.js index 1d85cbd00..5867e6952 100644 --- a/src/server.js +++ b/src/server.js @@ -7,7 +7,7 @@ import mocks from './mocks' import middleware from './middleware' import applyDirectives from './bootstrap/directives' import applyScalars from './bootstrap/scalars' -import neo4j from './bootstrap/neo4j' +import { getDriver } from './bootstrap/neo4j' import passport from 'passport' import jwtStrategy from './jwt/strategy' @@ -22,7 +22,7 @@ requiredEnvVars.forEach(env => { } }) -const driver = neo4j().getDriver() +const driver = getDriver() const debug = process.env.NODE_ENV !== 'production' && process.env.DEBUG === 'true' let schema = makeAugmentedSchema({ From 55395a2ffc7986269989881badb162025f97aee4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 22 Feb 2019 04:17:49 +0000 Subject: [PATCH 397/554] Bump slug from 0.9.3 to 1.0.0 Bumps [slug](https://github.com/Trott/node-slug) from 0.9.3 to 1.0.0. - [Release notes](https://github.com/Trott/node-slug/releases) - [Commits](https://github.com/Trott/node-slug/compare/v0.9.3...v1.0.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 0cf71cddd..330b5dd74 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "passport": "~0.4.0", "passport-jwt": "~4.0.0", "sanitize-html": "~1.20.0", - "slug": "~0.9.3", + "slug": "~1.0.0", "trunc-html": "~1.1.2", "wait-on": "~3.2.0" }, diff --git a/yarn.lock b/yarn.lock index f77e60551..6a24f45f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6232,10 +6232,10 @@ slice-ansi@2.0.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -slug@~0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.3.tgz#8c9c773d79367c0188733316cf49fd2b8db40f6a" - integrity sha512-DddSQQnUdAofjFOKRT+zsMNrdzdte04G5DUA+NeaUJlPAqR1bWQ22qVfayRxHFiRGR3bUV0wt5VSj4849pGKSw== +slug@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slug/-/slug-1.0.0.tgz#503be07b150226a42abf7a9c52d345e6b163fea8" + integrity sha512-m3uDtlWbJmYiwxVU1+jIvYEgfYmvtjWE/KtM6IfNzuRyHv+9RMukxMVph1ra+/499fVOKgTcK/8s2gLrYoP+BA== dependencies: unicode ">= 0.3.1" From 5856e74b396b64ae0a4d3672b43dc44918e3e87b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 22 Feb 2019 14:13:03 +0100 Subject: [PATCH 398/554] Fix `yarn run db:reset` --- src/seed/reset-db.js | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/seed/reset-db.js b/src/seed/reset-db.js index 7d7c4f3f9..4075489f9 100644 --- a/src/seed/reset-db.js +++ b/src/seed/reset-db.js @@ -1,30 +1,19 @@ -import { query } from '../graphql-schema' +import { cleanDatabase } from './factories' import dotenv from 'dotenv' -import neo4j from '../bootstrap/neo4j' dotenv.config() if (process.env.NODE_ENV === 'production') { - throw new Error('YOU CAN`T UNSEED IN PRODUCTION MODE') + throw new Error(`YOU CAN'T CLEAN THE DATABASE WITH NODE_ENV=${process.env.NODE_ENV}`) } -const driver = neo4j().getDriver() -const session = driver.session() - -const deleteAll = ` -MATCH (n) -OPTIONAL MATCH (n)-[r]-() -DELETE n,r -` -query(deleteAll, session).then(() => { - /* eslint-disable-next-line no-console */ - console.log('Successfully deleted all nodes and relations!') -}).catch((err) => { - /* eslint-disable-next-line no-console */ - console.log(`Error occurred deleting the nodes and relations (reset the db)\n\n${err}`) -}).finally(() => { - if (session) { - session.close() +(async function () { + try { + await cleanDatabase() + console.log('Successfully deleted all nodes and relations!') + process.exit(0) + } catch (err) { + console.log(`Error occurred deleting the nodes and relations (reset the db)\n\n${err}`) + process.exit(1) } - process.exit(0) -}) +})() From 889818cd2de5ae5bca1bced8dcf4335045af4cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 22 Feb 2019 15:21:23 +0100 Subject: [PATCH 399/554] Expose bug in Query { isLoggedin } The idMiddleware was adding selection fields to the resolveInfo even if the selection fields were empty. This caused a bug for each resolve function including ``` { isLoggedin } ``` which does not have any additional curly braces after the query. --- src/graphql-schema.spec.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/graphql-schema.spec.js b/src/graphql-schema.spec.js index 463d91af2..2211a514a 100644 --- a/src/graphql-schema.spec.js +++ b/src/graphql-schema.spec.js @@ -16,6 +16,15 @@ afterEach(async () => { await factory.cleanDatabase() }) +describe('isLoggedIn', () => { + describe('unauthenticated', () => { + it('returns false', async () => { + const query = '{ isLoggedIn }' + await expect(request(host, query)).resolves.toEqual({ isLoggedIn: false }) + }) + }) +}) + describe('login', () => { const mutation = (params) => { const { email, password } = params From 2e7e0579e46b8bbded5827402d6c83e43bb68248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 22 Feb 2019 16:11:07 +0100 Subject: [PATCH 400/554] Fix bug with id middleware Ids are queried only for well known queries and mutations --- src/graphql-schema.js | 1 - src/middleware/idMiddleware.js | 12 ++++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 521ac97bd..ce84dde36 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -1,4 +1,3 @@ -// import { neo4jgraphql } from "neo4j-graphql-js" import fs from 'fs' import path from 'path' import bcrypt from 'bcryptjs' diff --git a/src/middleware/idMiddleware.js b/src/middleware/idMiddleware.js index d6dac0580..2f1854fa6 100644 --- a/src/middleware/idMiddleware.js +++ b/src/middleware/idMiddleware.js @@ -15,10 +15,14 @@ const includeId = async (resolve, root, args, context, resolveInfo) => { } export default { - Query: (resolve, root, args, context, info) => { - return includeId(resolve, root, args, context, info) + Query: { + User: (resolve, root, args, context, info) => { + return includeId(resolve, root, args, context, info) + } }, - Mutation: (resolve, root, args, context, info) => { - return includeId(resolve, root, args, context, info) + Mutation: { + CreatePost: (resolve, root, args, context, info) => { + return includeId(resolve, root, args, context, info) + } } } From 6b66b33d8b49d0124c88cec98042bbd8b8ace801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 22 Feb 2019 21:21:58 +0100 Subject: [PATCH 401/554] Revert "Bump neo4j-graphql-js from 2.3.1 to 2.4.0" This reverts commit d8af7cb2e57b4623baa719c181899f4d72f7b185. @appinteractive this broke the index page on the frontend side. If you log in, you don't see posts and instead you see this error on the developer console: ``` GraphQL error: Invalid input '}': expected whitespace, comment or a property key name (line 4, column 39 (offset: 464)) "RETURN COUNT(r)", {this: post_author, }, false),shoutedCount: apoc.cypher.runFirstColumn("MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)", {this: post_author, }, false),commentsCount: apoc.cypher.runFirstColumn("MATCH (this)-[:WROTE]->(r:Comment) WHERE NOT r.deleted = true RETURN COUNT(r)", {this: post_author, }, false),followedByCount: apoc.cypher.runFirstColumn("MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(r)", {this: post_author, }, false),location: head([ post_author_location IN apoc.cypher.runFirstColumn("MATCH (this)-[:IS_IN]->(l:Location) RETURN l", {this: post_author, }, true) | post_author_location { .nameEN }]) ,badges: [(`post_author`)<-[:`REWARDED`]-(`post_author_badges`:`Badge`) | post_author_badges { .id , .key , .icon }] }]) ,commentsCount: apoc.cypher.runFirstColumn("MATCH (this)<-[:COMMENTS]-(r:Comment) RETURN COUNT(r)", {this: post, }, false),categories: [(`post`)-[:`CATEGORIZED`]->(`post_categories`:`Category`) | post_categories { .id , .name , .icon }] ,shoutedCount: apoc.cypher.runFirstColumn("MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)", {this: post, }, false)} AS `post` SKIP $offset LIMIT $first" ``` --- package.json | 2 +- yarn.lock | 61 +++++++++++----------------------------------------- 2 files changed, 14 insertions(+), 49 deletions(-) diff --git a/package.json b/package.json index 330b5dd74..957d9fd45 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "lodash": "~4.17.11", "ms": "~2.1.1", "neo4j-driver": "~1.7.2", - "neo4j-graphql-js": "~2.4.0", + "neo4j-graphql-js": "~2.3.1", "node-fetch": "~2.3.0", "npm-run-all": "~4.1.5", "passport": "~0.4.0", diff --git a/yarn.lock b/yarn.lock index 6a24f45f3..2fe610fee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1010,14 +1010,6 @@ apollo-env@0.3.3: core-js "3.0.0-beta.13" node-fetch "^2.2.0" -apollo-errors@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/apollo-errors/-/apollo-errors-1.9.0.tgz#f1ed0ca0a6be5cd2f24e2eaa7b0860a10146ff51" - integrity sha512-XVukHd0KLvgY6tNjsPS3/Re3U6RQlTKrTbIpqqeTMo2N34uQMr+H1UheV21o8hOZBAFosvBORVricJiP5vfmrw== - dependencies: - assert "^1.4.1" - extendable-error "^0.1.5" - apollo-graphql@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.1.1.tgz#dc5eac3062abf9f063ac9869f0ef5c54fdc136e5" @@ -1303,13 +1295,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= -assert@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" - integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= - dependencies: - util "0.10.3" - assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -2741,11 +2726,6 @@ extend@^3.0.0, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -extendable-error@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/extendable-error/-/extendable-error-0.1.5.tgz#122308a7097bc89a263b2c4fbf089c78140e3b6d" - integrity sha1-EiMIpwl7yJomOyxPvwiceBQOO20= - external-editor@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" @@ -3098,15 +3078,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== -graphql-auth-directives@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/graphql-auth-directives/-/graphql-auth-directives-2.0.0.tgz#8e8c5118d362d19e99f9a2ae6d854c563d9da293" - integrity sha512-bqKXJjjf2pXnZRAJiqzemXAc3Wp5fUjnKb/w5bZvJLBxN4doSeVfnSQFMjnoSUKyd8eayyuPyjZj/+PXUO99Yg== - dependencies: - apollo-errors "^1.9.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" @@ -3259,7 +3230,14 @@ graphql-yoga@~1.17.4: graphql-tools "^4.0.0" subscriptions-transport-ws "^0.9.8" -"graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0", graphql@^14.0.2, graphql@~14.1.1: +"graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0", graphql@^14.0.2: + version "14.0.2" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.0.2.tgz#7dded337a4c3fd2d075692323384034b357f5650" + integrity sha512-gUC4YYsaiSJT1h40krG3J+USGlwhzNTXSb4IOZljn9ag5Tj+RkoXrWp+Kh7WyE3t1NCfab5kzCuxBIvOMERMXw== + dependencies: + iterall "^1.2.2" + +graphql@~14.1.1: version "14.1.1" resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.1.1.tgz#d5d77df4b19ef41538d7215d1e7a28834619fac0" integrity sha512-C5zDzLqvfPAgTtP8AUPIt9keDabrdRAqSWjj2OPRKrKxI9Fb65I36s1uCs1UUBFnSWTdO7hyHi7z1ZbwKMKF6Q== @@ -3526,11 +3504,6 @@ inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, i resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= - ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" @@ -4375,7 +4348,7 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= -jsonwebtoken@^8.2.0, jsonwebtoken@^8.3.0, jsonwebtoken@~8.5.0: +jsonwebtoken@^8.2.0, jsonwebtoken@~8.5.0: version "8.5.0" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#ebd0ca2a69797816e1c5af65b6c759787252947e" integrity sha512-IqEycp0znWHNA11TpYi77bVgyBO/pGESDh7Ajhas+u0ttkGkKYIIAjniL4Bw5+oVejVF+SYkaI7XKfwCCyeTuA== @@ -4884,13 +4857,12 @@ neo4j-driver@^1.7.2, neo4j-driver@~1.7.2: text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-graphql-js@~2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.4.0.tgz#6e87f57bd5f4892ada66c3c4b31aac9eba9c8c64" - integrity sha512-lFerSRsUXVwEr8AWUpQ7rWN7Cabn6RCAvymZPTltVaQR2gS/jZoKbJsVUmXurtNQCBJbDg9YWguNQy8uloLjZg== +neo4j-graphql-js@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.3.1.tgz#9a5de7e312594d63481e947a0cbe4e08b05ffed3" + integrity sha512-9DExWXD2vFdDJOmqorT1ygFOUEos7KF8KyF8Wt3jYxejWUuq+a5fAFBu7+YDH8QbvA23paKPEX0Pn1nS+Q5C1A== dependencies: graphql "^14.0.2" - graphql-auth-directives "^2.0.0" lodash "^4.17.11" neo4j-driver "^1.7.2" @@ -6916,13 +6888,6 @@ util.promisify@^1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= - dependencies: - inherits "2.0.1" - utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" From 0053f78f94d3bc34a9c76d0c1a1c560c026bb0b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 22 Feb 2019 20:27:35 +0000 Subject: [PATCH 402/554] Bump eslint from 5.13.0 to 5.14.1 Bumps [eslint](https://github.com/eslint/eslint) from 5.13.0 to 5.14.1. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v5.13.0...v5.14.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 183 +++++++++++++++++++++++++++------------------------ 2 files changed, 99 insertions(+), 86 deletions(-) diff --git a/package.json b/package.json index 957d9fd45..f80496878 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "babel-eslint": "~10.0.1", "babel-jest": "~24.1.0", "chai": "~4.2.0", - "eslint": "~5.13.0", + "eslint": "~5.14.1", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.16.0", "eslint-plugin-jest": "~22.3.0", diff --git a/yarn.lock b/yarn.lock index 2fe610fee..91e971746 100644 --- a/yarn.lock +++ b/yarn.lock @@ -871,15 +871,20 @@ acorn@^5.5.3: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== -acorn@^6.0.1, acorn@^6.0.2: +acorn@^6.0.1: version "6.0.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== -ajv@^6.5.3, ajv@^6.5.5, ajv@^6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.1.tgz#6360f5ed0d80f232cc2b294c362d5dc2e538dd61" - integrity sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww== +acorn@^6.0.7: + version "6.1.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.0.tgz#b0a3be31752c97a0f7013c5f4903b71a05db6818" + integrity sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw== + +ajv@^6.5.5, ajv@^6.9.1: + version "6.9.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.9.2.tgz#4927adb83e7f48e5a32b45729744c71ec39c9c7b" + integrity sha512-4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -898,6 +903,11 @@ ansi-escapes@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -1693,16 +1703,7 @@ chai@~4.2.0: pathval "^1.1.0" type-detect "^4.0.5" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1767,11 +1768,6 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -circular-json@^0.3.1: - version "0.3.3" - resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" - integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== - class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -2225,10 +2221,10 @@ doctrine@1.5.0: esutils "^2.0.2" isarray "^1.0.0" -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" @@ -2327,6 +2323,11 @@ electron-to-chromium@^1.3.86: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.88.tgz#f36ab32634f49ef2b0fdc1e82e2d1cc17feb29e7" integrity sha512-UPV4NuQMKeUh1S0OWRvwg0PI8ASHN9kBC8yDTk1ROXLC85W5GnhTRu/MZu3Teqx3JjlQYuckuHYXSUSgtb3J+A== +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -2508,35 +2509,35 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@~5.13.0: - version "5.13.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.13.0.tgz#ce71cc529c450eed9504530939aa97527861ede9" - integrity sha512-nqD5WQMisciZC5EHZowejLKQjWGuFS5c70fxqSKlnDME+oz9zmE8KTlX+lHSg+/5wsC/kf9Q9eMkC8qS3oM2fg== +eslint@~5.14.1: + version "5.14.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.14.1.tgz#490a28906be313685c55ccd43a39e8d22efc04ba" + integrity sha512-CyUMbmsjxedx8B0mr79mNOqetvkbij/zrXnFeK2zc3pGRn3/tibjiNAv/3UxFEyfMDjh+ZqTrJrEGBFiGfD5Og== dependencies: "@babel/code-frame" "^7.0.0" - ajv "^6.5.3" + ajv "^6.9.1" chalk "^2.1.0" cross-spawn "^6.0.5" debug "^4.0.1" - doctrine "^2.1.0" + doctrine "^3.0.0" eslint-scope "^4.0.0" eslint-utils "^1.3.1" eslint-visitor-keys "^1.0.0" - espree "^5.0.0" + espree "^5.0.1" esquery "^1.0.1" esutils "^2.0.2" - file-entry-cache "^2.0.0" + file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" glob "^7.1.2" globals "^11.7.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^6.1.0" + inquirer "^6.2.2" js-yaml "^3.12.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.17.5" + lodash "^4.17.11" minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" @@ -2547,15 +2548,15 @@ eslint@~5.13.0: semver "^5.5.1" strip-ansi "^4.0.0" strip-json-comments "^2.0.1" - table "^5.0.2" + table "^5.2.3" text-table "^0.2.0" -espree@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.0.tgz#fc7f984b62b36a0f543b13fb9cd7b9f4a7f5b65c" - integrity sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA== +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== dependencies: - acorn "^6.0.2" + acorn "^6.0.7" acorn-jsx "^5.0.0" eslint-visitor-keys "^1.0.0" @@ -2726,7 +2727,7 @@ extend@^3.0.0, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^3.0.0: +external-editor@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== @@ -2793,13 +2794,12 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== dependencies: - flat-cache "^1.2.1" - object-assign "^4.0.1" + flat-cache "^2.0.1" fileset@^2.0.3: version "2.0.3" @@ -2864,15 +2864,19 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -flat-cache@^1.2.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" - integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== dependencies: - circular-json "^0.3.1" - graceful-fs "^4.1.2" - rimraf "~2.6.2" - write "^0.2.1" + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" + integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== fn-name@~2.0.1: version "2.0.1" @@ -3509,21 +3513,21 @@ ini@^1.3.4, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== -inquirer@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52" - integrity sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg== +inquirer@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406" + integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA== dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" + ansi-escapes "^3.2.0" + chalk "^2.4.2" cli-cursor "^2.1.0" cli-width "^2.0.0" - external-editor "^3.0.0" + external-editor "^3.0.3" figures "^2.0.0" - lodash "^4.17.10" + lodash "^4.17.11" mute-stream "0.0.7" run-async "^2.2.0" - rxjs "^6.1.0" + rxjs "^6.4.0" string-width "^2.1.0" strip-ansi "^5.0.0" through "^2.3.6" @@ -5079,7 +5083,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -5970,7 +5974,7 @@ retry@0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@~2.6.2: +rimraf@2.6.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -5994,10 +5998,10 @@ rx@^4.1.0: resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= -rxjs@^6.1.0: - version "6.3.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" - integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== +rxjs@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.4.0.tgz#f3bb0fe7bda7fb69deac0c16f17b50b0b8790504" + integrity sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw== dependencies: tslib "^1.9.0" @@ -6195,10 +6199,10 @@ slash@^2.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== -slice-ansi@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.0.0.tgz#5373bdb8559b45676e8541c66916cdd6251612e7" - integrity sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ== +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== dependencies: ansi-styles "^3.2.0" astral-regex "^1.0.0" @@ -6406,6 +6410,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.0.0.tgz#5a1690a57cc78211fffd9bf24bbe24d090604eb1" + integrity sha512-rr8CUxBbvOZDUvc5lNIJ+OC1nPVpz+Siw9VBtUjB9b6jZehZLFt0JMCZzShFHIsI8cbhm0EsNIfWJMFV3cu3Ew== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.0.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" @@ -6534,15 +6547,15 @@ synchronous-promise@^2.0.5: resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.6.tgz#de76e0ea2b3558c1e673942e47e714a930fa64aa" integrity sha512-TyOuWLwkmtPL49LHCX1caIwHjRzcVd62+GF6h8W/jHOeZUFHpnd2XJDVuUlaTaLPH1nuu2M69mfHr5XbQJnf/g== -table@^5.0.2: - version "5.1.1" - resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837" - integrity sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw== +table@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/table/-/table-5.2.3.tgz#cde0cc6eb06751c009efab27e8c820ca5b67b7f2" + integrity sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ== dependencies: - ajv "^6.6.1" + ajv "^6.9.1" lodash "^4.17.11" - slice-ansi "2.0.0" - string-width "^2.1.1" + slice-ansi "^2.1.0" + string-width "^3.0.0" tar@^4: version "4.4.8" @@ -7081,10 +7094,10 @@ write-file-atomic@^2.3.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" -write@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== dependencies: mkdirp "^0.5.1" From 95dbba336906af3f1bc4fbd6000d49edb45f11ed Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 24 Feb 2019 15:02:05 +0100 Subject: [PATCH 403/554] Added more badges to readme --- README.md | 11 +++++++++-- humanconnection.png | Bin 0 -> 132723 bytes 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 humanconnection.png diff --git a/README.md b/README.md index 1b12562d2..29f2adee0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ -# Human-Connection - NITRO Backend -[![Build Status](https://travis-ci.com/Human-Connection/Nitro-Backend.svg?branch=master)](https://travis-ci.com/Human-Connection/Nitro-Backend) +

+ Human Connection +

+ +# NITRO Backend +[![Build Status](https://img.shields.io/travis/com/Human-Connection/Nitro-Backend/master.svg)](https://travis-ci.com/Human-Connection/Nitro-Backend) +[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Human-Connection/Nitor-Backend/blob/develop/LICENSE.md) +[![FOSSA Status](https://app.fossa.io/api/projects/git+github.com/Human-Connection/Nitro-Backend.svg?type=shield)](https://app.fossa.io/projects/git+github.com/Human-Connection/Nitro-Backend?ref=badge_shield) +[![Discord Channel](https://img.shields.io/discord/489522408076738561.svg)](https://discord.gg/6ub73U3) > This Prototype tries to resolve the biggest hurdle of connecting > our services together. This is not possible in a sane way using diff --git a/humanconnection.png b/humanconnection.png new file mode 100644 index 0000000000000000000000000000000000000000..f0576413ff0663ce0c79b6a0ef8ccd2ffbc77594 GIT binary patch literal 132723 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∈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�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 iz4^aRaB;J9wD Date: Sun, 24 Feb 2019 15:04:16 +0100 Subject: [PATCH 404/554] Fixed FOSSA status --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 29f2adee0..bc0f3ff39 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ # NITRO Backend [![Build Status](https://img.shields.io/travis/com/Human-Connection/Nitro-Backend/master.svg)](https://travis-ci.com/Human-Connection/Nitro-Backend) [![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Human-Connection/Nitor-Backend/blob/develop/LICENSE.md) -[![FOSSA Status](https://app.fossa.io/api/projects/git+github.com/Human-Connection/Nitro-Backend.svg?type=shield)](https://app.fossa.io/projects/git+github.com/Human-Connection/Nitro-Backend?ref=badge_shield) +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend?ref=badge_shield) [![Discord Channel](https://img.shields.io/discord/489522408076738561.svg)](https://discord.gg/6ub73U3) > This Prototype tries to resolve the biggest hurdle of connecting @@ -155,9 +155,13 @@ npm run test - [x] add jwt authentication - [ ] get directives working correctly (@toLower, @auth, @role, etc.) -- [ ] check if search is working +- [x] check if search is working - [x] check if sorting is working - [x] check if pagination is working - [ ] check if upload is working (using graphql-yoga?) - [x] evaluate middleware - [ ] ignore Posts and Comments by blacklisted Users + + +## License +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend?ref=badge_large) From 56610d0d3d449e3a037bc5a2c9baf8cee5b737dc Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 24 Feb 2019 15:07:41 +0100 Subject: [PATCH 405/554] Fixed FOSSA status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bc0f3ff39..5350f212f 100644 --- a/README.md +++ b/README.md @@ -164,4 +164,4 @@ npm run test ## License -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend?ref=badge_large) +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend.svg?type=small)](https://app.fossa.io/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend?ref=badge_small) From 5a255db0181b5f497bd488b7398391a29c0b0e5d Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 24 Feb 2019 15:08:00 +0100 Subject: [PATCH 406/554] Fixed FOSSA status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5350f212f..bc0f3ff39 100644 --- a/README.md +++ b/README.md @@ -164,4 +164,4 @@ npm run test ## License -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend.svg?type=small)](https://app.fossa.io/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend?ref=badge_small) +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend?ref=badge_large) From bc6089dbf5e1c8cb7a663969ee2597e7e003f1d1 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 24 Feb 2019 17:05:59 +0100 Subject: [PATCH 407/554] Fixed readme --- LICENSE.md | 21 +++++++++++++++++++++ README.md | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..9d4508b38 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Human-Connection gGmbH + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index bc0f3ff39..b3b4764b7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # NITRO Backend [![Build Status](https://img.shields.io/travis/com/Human-Connection/Nitro-Backend/master.svg)](https://travis-ci.com/Human-Connection/Nitro-Backend) -[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Human-Connection/Nitor-Backend/blob/develop/LICENSE.md) +[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Human-Connection/Nitro-Backend/blob/backend/LICENSE.md) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend?ref=badge_shield) [![Discord Channel](https://img.shields.io/discord/489522408076738561.svg)](https://discord.gg/6ub73U3) From aef367b210b6ed51cb3cdb3ba72f1c6c96c57bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 25 Feb 2019 19:33:51 +0100 Subject: [PATCH 408/554] Backend runs test- and seed-server on travis This is necessary for fullstack testing in the frontend repository --- docker-compose.travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml index e1998f6dd..3d577e638 100644 --- a/docker-compose.travis.yml +++ b/docker-compose.travis.yml @@ -8,7 +8,11 @@ services: - 7687:7687 - 7474:7474 backend: + ports: + - 4001:4001 + - 4123:4123 image: humanconnection/nitro-backend:builder build: context: . target: builder + command: yarn run test:cypress From ec2b1050bccc3bd1d1e821a624450e0ee4a85311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 25 Feb 2019 21:23:45 +0100 Subject: [PATCH 409/554] Less redundancy and more consistency in factories * use the same `relate` method for now * use a capital letter for the model `user` instead of `User` --- src/graphql-schema.spec.js | 6 +- src/middleware/permissionsMiddleware.spec.js | 4 +- src/middleware/slugifyMiddleware.spec.js | 6 +- src/seed/factories/comments.js | 12 - src/seed/factories/index.js | 58 ++-- src/seed/factories/organizations.js | 12 - src/seed/factories/posts.js | 12 - src/seed/factories/users.js | 12 - src/seed/seed-db.js | 277 ++++++++++--------- 9 files changed, 175 insertions(+), 224 deletions(-) diff --git a/src/graphql-schema.spec.js b/src/graphql-schema.spec.js index 3d259ab42..7aa47835f 100644 --- a/src/graphql-schema.spec.js +++ b/src/graphql-schema.spec.js @@ -6,7 +6,7 @@ import { host, login } from './jest/helpers' const factory = Factory() beforeEach(async () => { - await factory.create('user', { + await factory.create('User', { email: 'test@example.org', password: '1234' }) @@ -122,11 +122,11 @@ describe('CreatePost', () => { describe('report', () => { beforeEach(async () => { - await factory.create('user', { + await factory.create('User', { email: 'test@example.org', password: '1234' }) - await factory.create('user', { + await factory.create('User', { id: 'u2', name: 'abusive-user', role: 'user', diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index a22f2bb72..78766aad2 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -7,12 +7,12 @@ const factory = Factory() describe('authorization', () => { describe('given two existing users', () => { beforeEach(async () => { - await factory.create('user', { + await factory.create('User', { email: 'owner@example.org', name: 'Owner', password: 'iamtheowner' }) - await factory.create('user', { + await factory.create('User', { email: 'someone@example.org', name: 'Someone else', password: 'else' diff --git a/src/middleware/slugifyMiddleware.spec.js b/src/middleware/slugifyMiddleware.spec.js index aaa09d29a..c7cd9806f 100644 --- a/src/middleware/slugifyMiddleware.spec.js +++ b/src/middleware/slugifyMiddleware.spec.js @@ -7,8 +7,8 @@ let headers const factory = Factory() beforeEach(async () => { - await factory.create('user', { email: 'user@example.org', password: '1234' }) - await factory.create('user', { email: 'someone@example.org', password: '1234' }) + await factory.create('User', { email: 'user@example.org', password: '1234' }) + await factory.create('User', { email: 'someone@example.org', password: '1234' }) headers = await login({ email: 'user@example.org', password: '1234' }) authenticatedClient = new GraphQLClient(host, { headers }) }) @@ -35,7 +35,7 @@ describe('slugify', () => { email: 'someone@example.org', password: '1234' }) - await asSomeoneElse.create('post', { + await asSomeoneElse.create('Post', { title: 'Pre-existing post', slug: 'pre-existing-post' }) diff --git a/src/seed/factories/comments.js b/src/seed/factories/comments.js index acf493f6d..92dca5b14 100644 --- a/src/seed/factories/comments.js +++ b/src/seed/factories/comments.js @@ -23,15 +23,3 @@ export default function (params) { } ` } - -export function relate (type, params) { - const { from, to } = params - return ` - mutation { - ${from}_${type}_${to}: AddComment${type}( - from: { id: "${from}" }, - to: { id: "${to}" } - ) { from { id } } - } - ` -} diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index a107fc6b7..752ae3369 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -1,6 +1,15 @@ import { GraphQLClient, request } from 'graphql-request' import { getDriver } from '../../bootstrap/neo4j' +import createBadge from './badges.js' +import createUser from './users.js' +import createOrganization from './organizations.js' +import createPost from './posts.js' +import createComment from './comments.js' +import createCategory from './categories.js' +import createTag from './tags.js' +import createReport from './reports.js' + export const seedServerHost = 'http://127.0.0.1:4001' const authenticatedHeaders = async ({ email, password }, host) => { @@ -15,35 +24,15 @@ const authenticatedHeaders = async ({ email, password }, host) => { authorization: `Bearer ${response.login.token}` } } - const factories = { - 'badge': require('./badges.js').default, - 'user': require('./users.js').default, - 'organization': require('./organizations.js').default, - 'post': require('./posts.js').default, - 'comment': require('./comments.js').default, - 'category': require('./categories.js').default, - 'tag': require('./tags.js').default, - 'report': require('./reports.js').default -} - -const relationFactories = { - 'user': require('./users.js').relate, - 'organization': require('./organizations.js').relate, - 'post': require('./posts.js').relate, - 'comment': require('./comments.js').relate -} - -export const create = (model, parameters, options) => { - const graphQLClient = new GraphQLClient(seedServerHost, options) - const mutation = factories[model](parameters) - return graphQLClient.request(mutation) -} - -export const relate = (model, type, parameters, options) => { - const graphQLClient = new GraphQLClient(seedServerHost, options) - const mutation = relationFactories[model](type, parameters) - return graphQLClient.request(mutation) + 'Badge': createBadge, + 'User': createUser, + 'Organization': createOrganization, + 'Post': createPost, + 'Comment': createComment, + 'Category': createCategory, + 'Tag': createTag, + 'Report': createReport } export const cleanDatabase = async (options = {}) => { @@ -73,6 +62,7 @@ export default function Factory (options = {}) { neo4jDriver, seedServerHost, graphQLClient, + factories, lastResponse: null, async authenticateAs ({ email, password }) { const headers = await authenticatedHeaders({ email, password }, seedServerHost) @@ -81,12 +71,20 @@ export default function Factory (options = {}) { return this }, async create (node, properties) { - const mutation = factories[node](properties) + const mutation = this.factories[node](properties) this.lastResponse = await this.graphQLClient.request(mutation) return this }, async relate (node, relationship, properties) { - const mutation = relationFactories[node](relationship, properties) + const { from, to } = properties + const mutation = ` + mutation { + Add${node}${relationship}( + from: { id: "${from}" }, + to: { id: "${to}" } + ) { from { id } } + } + ` this.lastResponse = await this.graphQLClient.request(mutation) return this }, diff --git a/src/seed/factories/organizations.js b/src/seed/factories/organizations.js index 0ab73beb8..783edac26 100644 --- a/src/seed/factories/organizations.js +++ b/src/seed/factories/organizations.js @@ -22,15 +22,3 @@ export default function create (params) { } ` } - -export function relate (type, params) { - const { from, to } = params - return ` - mutation { - ${from}_${type}_${to}: AddOrganization${type}( - from: { id: "${from}" }, - to: { id: "${to}" } - ) { from { id } } - } - ` -} diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index 80f5e289d..d96cf4f73 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -32,15 +32,3 @@ export default function (params) { } ` } - -export function relate (type, params) { - const { from, to } = params - return ` - mutation { - ${from}_${type}_${to}: AddPost${type}( - from: { id: "${from}" }, - to: { id: "${to}" } - ) { from { id } } - } - ` -} diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index b3a6e83c1..8e0ee693c 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -33,15 +33,3 @@ export default function create (params) { } ` } - -export function relate (type, params) { - const { from, to } = params - return ` - mutation { - ${from}_${type}_${to}: AddUser${type}( - from: { id: "${from}" }, - to: { id: "${to}" } - ) { from { id } } - } - ` -} diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 58984b12a..b2ee8fbdb 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -1,72 +1,73 @@ -import Factory, { create, relate } from './factories' +import Factory from './factories' /* eslint-disable no-multi-spaces */ (async function () { try { + const f = Factory() await Promise.all([ - create('badge', { id: 'b1', key: 'indiegogo_en_racoon', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_racoon.svg' }), - create('badge', { id: 'b2', key: 'indiegogo_en_rabbit', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rabbit.svg' }), - create('badge', { id: 'b3', key: 'indiegogo_en_wolf', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_wolf.svg' }), - create('badge', { id: 'b4', key: 'indiegogo_en_bear', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_bear.svg' }), - create('badge', { id: 'b5', key: 'indiegogo_en_turtle', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_turtle.svg' }), - create('badge', { id: 'b6', key: 'indiegogo_en_rhino', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rhino.svg' }) + f.create('Badge', { id: 'b1', key: 'indiegogo_en_racoon', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_racoon.svg' }), + f.create('Badge', { id: 'b2', key: 'indiegogo_en_rabbit', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rabbit.svg' }), + f.create('Badge', { id: 'b3', key: 'indiegogo_en_wolf', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_wolf.svg' }), + f.create('Badge', { id: 'b4', key: 'indiegogo_en_bear', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_bear.svg' }), + f.create('Badge', { id: 'b5', key: 'indiegogo_en_turtle', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_turtle.svg' }), + f.create('Badge', { id: 'b6', key: 'indiegogo_en_rhino', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rhino.svg' }) ]) await Promise.all([ - create('user', { id: 'u1', name: 'Peter Lustig', role: 'admin', email: 'admin@example.org' }), - create('user', { id: 'u2', name: 'Bob der Baumeister', role: 'moderator', email: 'moderator@example.org' }), - create('user', { id: 'u3', name: 'Jenny Rostock', role: 'user', email: 'user@example.org' }), - create('user', { id: 'u4', name: 'Tick', role: 'user', email: 'tick@example.org' }), - create('user', { id: 'u5', name: 'Trick', role: 'user', email: 'trick@example.org' }), - create('user', { id: 'u6', name: 'Track', role: 'user', email: 'track@example.org' }), - create('user', { id: 'u7', name: 'Dagobert', role: 'user', email: 'dagobert@example.org' }) + f.create('User', { id: 'u1', name: 'Peter Lustig', role: 'admin', email: 'admin@example.org' }), + f.create('User', { id: 'u2', name: 'Bob der Baumeister', role: 'moderator', email: 'moderator@example.org' }), + f.create('User', { id: 'u3', name: 'Jenny Rostock', role: 'user', email: 'user@example.org' }), + f.create('User', { id: 'u4', name: 'Tick', role: 'user', email: 'tick@example.org' }), + f.create('User', { id: 'u5', name: 'Trick', role: 'user', email: 'trick@example.org' }), + f.create('User', { id: 'u6', name: 'Track', role: 'user', email: 'track@example.org' }), + f.create('User', { id: 'u7', name: 'Dagobert', role: 'user', email: 'dagobert@example.org' }) ]) await Promise.all([ - relate('user', 'Badges', { from: 'b6', to: 'u1' }), - relate('user', 'Badges', { from: 'b5', to: 'u2' }), - relate('user', 'Badges', { from: 'b4', to: 'u3' }), - relate('user', 'Badges', { from: 'b3', to: 'u4' }), - relate('user', 'Badges', { from: 'b2', to: 'u5' }), - relate('user', 'Badges', { from: 'b1', to: 'u6' }), - relate('user', 'Following', { from: 'u1', to: 'u2' }), - relate('user', 'Following', { from: 'u2', to: 'u3' }), - relate('user', 'Following', { from: 'u3', to: 'u4' }), - relate('user', 'Following', { from: 'u4', to: 'u5' }), - relate('user', 'Following', { from: 'u5', to: 'u6' }), - relate('user', 'Following', { from: 'u6', to: 'u7' }), - relate('user', 'Friends', { from: 'u1', to: 'u2' }), - relate('user', 'Friends', { from: 'u1', to: 'u3' }), - relate('user', 'Friends', { from: 'u2', to: 'u3' }), - relate('user', 'Blacklisted', { from: 'u7', to: 'u4' }), - relate('user', 'Blacklisted', { from: 'u7', to: 'u5' }), - relate('user', 'Blacklisted', { from: 'u7', to: 'u6' }) + f.relate('User', 'Badges', { from: 'b6', to: 'u1' }), + f.relate('User', 'Badges', { from: 'b5', to: 'u2' }), + f.relate('User', 'Badges', { from: 'b4', to: 'u3' }), + f.relate('User', 'Badges', { from: 'b3', to: 'u4' }), + f.relate('User', 'Badges', { from: 'b2', to: 'u5' }), + f.relate('User', 'Badges', { from: 'b1', to: 'u6' }), + f.relate('User', 'Following', { from: 'u1', to: 'u2' }), + f.relate('User', 'Following', { from: 'u2', to: 'u3' }), + f.relate('User', 'Following', { from: 'u3', to: 'u4' }), + f.relate('User', 'Following', { from: 'u4', to: 'u5' }), + f.relate('User', 'Following', { from: 'u5', to: 'u6' }), + f.relate('User', 'Following', { from: 'u6', to: 'u7' }), + f.relate('User', 'Friends', { from: 'u1', to: 'u2' }), + f.relate('User', 'Friends', { from: 'u1', to: 'u3' }), + f.relate('User', 'Friends', { from: 'u2', to: 'u3' }), + f.relate('User', 'Blacklisted', { from: 'u7', to: 'u4' }), + f.relate('User', 'Blacklisted', { from: 'u7', to: 'u5' }), + f.relate('User', 'Blacklisted', { from: 'u7', to: 'u6' }) ]) await Promise.all([ - create('category', { id: 'cat1', name: 'Just For Fun', slug: 'justforfun', icon: 'smile' }), - create('category', { id: 'cat2', name: 'Happyness & Values', slug: 'happyness-values', icon: 'heart-o' }), - create('category', { id: 'cat3', name: 'Health & Wellbeing', slug: 'health-wellbeing', icon: 'medkit' }), - create('category', { id: 'cat4', name: 'Environment & Nature', slug: 'environment-nature', icon: 'tree' }), - create('category', { id: 'cat5', name: 'Animal Protection', slug: 'animalprotection', icon: 'paw' }), - create('category', { id: 'cat6', name: 'Humanrights Justice', slug: 'humanrights-justice', icon: 'balance-scale' }), - create('category', { id: 'cat7', name: 'Education & Sciences', slug: 'education-sciences', icon: 'graduation-cap' }), - create('category', { id: 'cat8', name: 'Cooperation & Development', slug: 'cooperation-development', icon: 'users' }), - create('category', { id: 'cat9', name: 'Democracy & Politics', slug: 'democracy-politics', icon: 'university' }), - create('category', { id: 'cat10', name: 'Economy & Finances', slug: 'economy-finances', icon: 'money' }), - create('category', { id: 'cat11', name: 'Energy & Technology', slug: 'energy-technology', icon: 'flash' }), - create('category', { id: 'cat12', name: 'IT, Internet & Data Privacy', slug: 'it-internet-dataprivacy', icon: 'mouse-pointer' }), - create('category', { id: 'cat13', name: 'Art, Curlure & Sport', slug: 'art-culture-sport', icon: 'paint-brush' }), - create('category', { id: 'cat14', name: 'Freedom of Speech', slug: 'freedomofspeech', icon: 'bullhorn' }), - create('category', { id: 'cat15', name: 'Consumption & Sustainability', slug: 'consumption-sustainability', icon: 'shopping-cart' }), - create('category', { id: 'cat16', name: 'Global Peace & Nonviolence', slug: 'globalpeace-nonviolence', icon: 'angellist' }) + f.create('Category', { id: 'cat1', name: 'Just For Fun', slug: 'justforfun', icon: 'smile' }), + f.create('Category', { id: 'cat2', name: 'Happyness & Values', slug: 'happyness-values', icon: 'heart-o' }), + f.create('Category', { id: 'cat3', name: 'Health & Wellbeing', slug: 'health-wellbeing', icon: 'medkit' }), + f.create('Category', { id: 'cat4', name: 'Environment & Nature', slug: 'environment-nature', icon: 'tree' }), + f.create('Category', { id: 'cat5', name: 'Animal Protection', slug: 'animalprotection', icon: 'paw' }), + f.create('Category', { id: 'cat6', name: 'Humanrights Justice', slug: 'humanrights-justice', icon: 'balance-scale' }), + f.create('Category', { id: 'cat7', name: 'Education & Sciences', slug: 'education-sciences', icon: 'graduation-cap' }), + f.create('Category', { id: 'cat8', name: 'Cooperation & Development', slug: 'cooperation-development', icon: 'users' }), + f.create('Category', { id: 'cat9', name: 'Democracy & Politics', slug: 'democracy-politics', icon: 'university' }), + f.create('Category', { id: 'cat10', name: 'Economy & Finances', slug: 'economy-finances', icon: 'money' }), + f.create('Category', { id: 'cat11', name: 'Energy & Technology', slug: 'energy-technology', icon: 'flash' }), + f.create('Category', { id: 'cat12', name: 'IT, Internet & Data Privacy', slug: 'it-internet-dataprivacy', icon: 'mouse-pointer' }), + f.create('Category', { id: 'cat13', name: 'Art, Curlure & Sport', slug: 'art-culture-sport', icon: 'paint-brush' }), + f.create('Category', { id: 'cat14', name: 'Freedom of Speech', slug: 'freedomofspeech', icon: 'bullhorn' }), + f.create('Category', { id: 'cat15', name: 'Consumption & Sustainability', slug: 'consumption-sustainability', icon: 'shopping-cart' }), + f.create('Category', { id: 'cat16', name: 'Global Peace & Nonviolence', slug: 'globalpeace-nonviolence', icon: 'angellist' }) ]) await Promise.all([ - create('tag', { id: 't1', name: 'Umwelt' }), - create('tag', { id: 't2', name: 'Naturschutz' }), - create('tag', { id: 't3', name: 'Demokratie' }), - create('tag', { id: 't4', name: 'Freiheit' }) + f.create('Tag', { id: 't1', name: 'Umwelt' }), + f.create('Tag', { id: 't2', name: 'Naturschutz' }), + f.create('Tag', { id: 't3', name: 'Demokratie' }), + f.create('Tag', { id: 't4', name: 'Freiheit' }) ]) const [ asAdmin, asModerator, asUser, asTick, asTrick, asTrack ] = await Promise.all([ @@ -79,113 +80,113 @@ import Factory, { create, relate } from './factories' ]) await Promise.all([ - asAdmin.create('post', { id: 'p0' }), - asModerator.create('post', { id: 'p1' }), - asUser.create('post', { id: 'p2' }), - asTick.create('post', { id: 'p3' }), - asTrick.create('post', { id: 'p4' }), - asTrack.create('post', { id: 'p5' }), - asAdmin.create('post', { id: 'p6' }), - asModerator.create('post', { id: 'p7' }), - asUser.create('post', { id: 'p8' }), - asTick.create('post', { id: 'p9' }), - asTrick.create('post', { id: 'p10' }), - asTrack.create('post', { id: 'p11' }), - asAdmin.create('post', { id: 'p12' }), - asModerator.create('post', { id: 'p13' }), - asUser.create('post', { id: 'p14' }), - asTick.create('post', { id: 'p15' }) + asAdmin.create('Post', { id: 'p0' }), + asModerator.create('Post', { id: 'p1' }), + asUser.create('Post', { id: 'p2' }), + asTick.create('Post', { id: 'p3' }), + asTrick.create('Post', { id: 'p4' }), + asTrack.create('Post', { id: 'p5' }), + asAdmin.create('Post', { id: 'p6' }), + asModerator.create('Post', { id: 'p7' }), + asUser.create('Post', { id: 'p8' }), + asTick.create('Post', { id: 'p9' }), + asTrick.create('Post', { id: 'p10' }), + asTrack.create('Post', { id: 'p11' }), + asAdmin.create('Post', { id: 'p12' }), + asModerator.create('Post', { id: 'p13' }), + asUser.create('Post', { id: 'p14' }), + asTick.create('Post', { id: 'p15' }) ]) await Promise.all([ - relate('post', 'Categories', { from: 'p0', to: 'cat16' }), - relate('post', 'Categories', { from: 'p1', to: 'cat1' }), - relate('post', 'Categories', { from: 'p2', to: 'cat2' }), - relate('post', 'Categories', { from: 'p3', to: 'cat3' }), - relate('post', 'Categories', { from: 'p4', to: 'cat4' }), - relate('post', 'Categories', { from: 'p5', to: 'cat5' }), - relate('post', 'Categories', { from: 'p6', to: 'cat6' }), - relate('post', 'Categories', { from: 'p7', to: 'cat7' }), - relate('post', 'Categories', { from: 'p8', to: 'cat8' }), - relate('post', 'Categories', { from: 'p9', to: 'cat9' }), - relate('post', 'Categories', { from: 'p10', to: 'cat10' }), - relate('post', 'Categories', { from: 'p11', to: 'cat11' }), - relate('post', 'Categories', { from: 'p12', to: 'cat12' }), - relate('post', 'Categories', { from: 'p13', to: 'cat13' }), - relate('post', 'Categories', { from: 'p14', to: 'cat14' }), - relate('post', 'Categories', { from: 'p15', to: 'cat15' }), + f.relate('Post', 'Categories', { from: 'p0', to: 'cat16' }), + f.relate('Post', 'Categories', { from: 'p1', to: 'cat1' }), + f.relate('Post', 'Categories', { from: 'p2', to: 'cat2' }), + f.relate('Post', 'Categories', { from: 'p3', to: 'cat3' }), + f.relate('Post', 'Categories', { from: 'p4', to: 'cat4' }), + f.relate('Post', 'Categories', { from: 'p5', to: 'cat5' }), + f.relate('Post', 'Categories', { from: 'p6', to: 'cat6' }), + f.relate('Post', 'Categories', { from: 'p7', to: 'cat7' }), + f.relate('Post', 'Categories', { from: 'p8', to: 'cat8' }), + f.relate('Post', 'Categories', { from: 'p9', to: 'cat9' }), + f.relate('Post', 'Categories', { from: 'p10', to: 'cat10' }), + f.relate('Post', 'Categories', { from: 'p11', to: 'cat11' }), + f.relate('Post', 'Categories', { from: 'p12', to: 'cat12' }), + f.relate('Post', 'Categories', { from: 'p13', to: 'cat13' }), + f.relate('Post', 'Categories', { from: 'p14', to: 'cat14' }), + f.relate('Post', 'Categories', { from: 'p15', to: 'cat15' }), - relate('post', 'Tags', { from: 'p0', to: 't4' }), - relate('post', 'Tags', { from: 'p1', to: 't1' }), - relate('post', 'Tags', { from: 'p2', to: 't2' }), - relate('post', 'Tags', { from: 'p3', to: 't3' }), - relate('post', 'Tags', { from: 'p4', to: 't4' }), - relate('post', 'Tags', { from: 'p5', to: 't1' }), - relate('post', 'Tags', { from: 'p6', to: 't2' }), - relate('post', 'Tags', { from: 'p7', to: 't3' }), - relate('post', 'Tags', { from: 'p8', to: 't4' }), - relate('post', 'Tags', { from: 'p9', to: 't1' }), - relate('post', 'Tags', { from: 'p10', to: 't2' }), - relate('post', 'Tags', { from: 'p11', to: 't3' }), - relate('post', 'Tags', { from: 'p12', to: 't4' }), - relate('post', 'Tags', { from: 'p13', to: 't1' }), - relate('post', 'Tags', { from: 'p14', to: 't2' }), - relate('post', 'Tags', { from: 'p15', to: 't3' }) + f.relate('Post', 'Tags', { from: 'p0', to: 't4' }), + f.relate('Post', 'Tags', { from: 'p1', to: 't1' }), + f.relate('Post', 'Tags', { from: 'p2', to: 't2' }), + f.relate('Post', 'Tags', { from: 'p3', to: 't3' }), + f.relate('Post', 'Tags', { from: 'p4', to: 't4' }), + f.relate('Post', 'Tags', { from: 'p5', to: 't1' }), + f.relate('Post', 'Tags', { from: 'p6', to: 't2' }), + f.relate('Post', 'Tags', { from: 'p7', to: 't3' }), + f.relate('Post', 'Tags', { from: 'p8', to: 't4' }), + f.relate('Post', 'Tags', { from: 'p9', to: 't1' }), + f.relate('Post', 'Tags', { from: 'p10', to: 't2' }), + f.relate('Post', 'Tags', { from: 'p11', to: 't3' }), + f.relate('Post', 'Tags', { from: 'p12', to: 't4' }), + f.relate('Post', 'Tags', { from: 'p13', to: 't1' }), + f.relate('Post', 'Tags', { from: 'p14', to: 't2' }), + f.relate('Post', 'Tags', { from: 'p15', to: 't3' }) ]) await Promise.all([ - relate('user', 'Shouted', { from: 'u1', to: 'p2' }), - relate('user', 'Shouted', { from: 'u1', to: 'p3' }), - relate('user', 'Shouted', { from: 'u2', to: 'p1' }), - relate('user', 'Shouted', { from: 'u3', to: 'p1' }), - relate('user', 'Shouted', { from: 'u3', to: 'p4' }), - relate('user', 'Shouted', { from: 'u4', to: 'p1' }) + f.relate('User', 'Shouted', { from: 'u1', to: 'p2' }), + f.relate('User', 'Shouted', { from: 'u1', to: 'p3' }), + f.relate('User', 'Shouted', { from: 'u2', to: 'p1' }), + f.relate('User', 'Shouted', { from: 'u3', to: 'p1' }), + f.relate('User', 'Shouted', { from: 'u3', to: 'p4' }), + f.relate('User', 'Shouted', { from: 'u4', to: 'p1' }) ]) await Promise.all([ - create('comment', { id: 'c1' }), - create('comment', { id: 'c2' }), - create('comment', { id: 'c3' }), - create('comment', { id: 'c4' }), - create('comment', { id: 'c5' }), - create('comment', { id: 'c6' }), - create('comment', { id: 'c7' }) + f.create('Comment', { id: 'c1' }), + f.create('Comment', { id: 'c2' }), + f.create('Comment', { id: 'c3' }), + f.create('Comment', { id: 'c4' }), + f.create('Comment', { id: 'c5' }), + f.create('Comment', { id: 'c6' }), + f.create('Comment', { id: 'c7' }) ]) await Promise.all([ - relate('comment', 'Author', { from: 'u3', to: 'c1' }), - relate('comment', 'Post', { from: 'c1', to: 'p1' }), - relate('comment', 'Author', { from: 'u1', to: 'c2' }), - relate('comment', 'Post', { from: 'c2', to: 'p1' }), - relate('comment', 'Author', { from: 'u1', to: 'c3' }), - relate('comment', 'Post', { from: 'c3', to: 'p3' }), - relate('comment', 'Author', { from: 'u4', to: 'c4' }), - relate('comment', 'Post', { from: 'c4', to: 'p2' }), - relate('comment', 'Author', { from: 'u4', to: 'c5' }), - relate('comment', 'Post', { from: 'c5', to: 'p3' }), - relate('comment', 'Author', { from: 'u3', to: 'c6' }), - relate('comment', 'Post', { from: 'c6', to: 'p4' }), - relate('comment', 'Author', { from: 'u2', to: 'c7' }), - relate('comment', 'Post', { from: 'c7', to: 'p2' }) + f.relate('Comment', 'Author', { from: 'u3', to: 'c1' }), + f.relate('Comment', 'Post', { from: 'c1', to: 'p1' }), + f.relate('Comment', 'Author', { from: 'u1', to: 'c2' }), + f.relate('Comment', 'Post', { from: 'c2', to: 'p1' }), + f.relate('Comment', 'Author', { from: 'u1', to: 'c3' }), + f.relate('Comment', 'Post', { from: 'c3', to: 'p3' }), + f.relate('Comment', 'Author', { from: 'u4', to: 'c4' }), + f.relate('Comment', 'Post', { from: 'c4', to: 'p2' }), + f.relate('Comment', 'Author', { from: 'u4', to: 'c5' }), + f.relate('Comment', 'Post', { from: 'c5', to: 'p3' }), + f.relate('Comment', 'Author', { from: 'u3', to: 'c6' }), + f.relate('Comment', 'Post', { from: 'c6', to: 'p4' }), + f.relate('Comment', 'Author', { from: 'u2', to: 'c7' }), + f.relate('Comment', 'Post', { from: 'c7', to: 'p2' }) ]) await Promise.all([ - asTick.create('report', { description: 'I don\'t like this comment', resource: { id: 'c1', type: 'comment' } }), - asTrick.create('report', { description: 'I don\'t like this post', resource: { id: 'p1', type: 'contribution' } }), - asTrack.create('report', { description: 'I don\'t like this user', resource: { id: 'u1', type: 'user' } }) + asTick.create('Report', { description: 'I don\'t like this comment', resource: { id: 'c1', type: 'comment' } }), + asTrick.create('Report', { description: 'I don\'t like this post', resource: { id: 'p1', type: 'contribution' } }), + asTrack.create('Report', { description: 'I don\'t like this user', resource: { id: 'u1', type: 'user' } }) ]) await Promise.all([ - create('organization', { id: 'o1', name: 'Democracy Deutschland', description: 'Description for democracy-deutschland.' }), - create('organization', { id: 'o2', name: 'Human-Connection', description: 'Description for human-connection.' }), - create('organization', { id: 'o3', name: 'Pro Veg', description: 'Description for pro-veg.' }), - create('organization', { id: 'o4', name: 'Greenpeace', description: 'Description for greenpeace.' }) + f.create('Organization', { id: 'o1', name: 'Democracy Deutschland', description: 'Description for democracy-deutschland.' }), + f.create('Organization', { id: 'o2', name: 'Human-Connection', description: 'Description for human-connection.' }), + f.create('Organization', { id: 'o3', name: 'Pro Veg', description: 'Description for pro-veg.' }), + f.create('Organization', { id: 'o4', name: 'Greenpeace', description: 'Description for greenpeace.' }) ]) await Promise.all([ - relate('organization', 'CreatedBy', { from: 'u1', to: 'o1' }), - relate('organization', 'CreatedBy', { from: 'u1', to: 'o2' }), - relate('organization', 'OwnedBy', { from: 'u2', to: 'o2' }), - relate('organization', 'OwnedBy', { from: 'u2', to: 'o3' }) + f.relate('Organization', 'CreatedBy', { from: 'u1', to: 'o1' }), + f.relate('Organization', 'CreatedBy', { from: 'u1', to: 'o2' }), + f.relate('Organization', 'OwnedBy', { from: 'u2', to: 'o2' }), + f.relate('Organization', 'OwnedBy', { from: 'u2', to: 'o3' }) ]) /* eslint-disable-next-line no-console */ console.log('Seeded Data...') From f74a45379fb3dd7a100253565afd236f74ef200e Mon Sep 17 00:00:00 2001 From: Armin Date: Mon, 25 Feb 2019 23:57:44 +0100 Subject: [PATCH 410/554] Integrate ActivityPub into the Backend --- .babelrc | 3 + .travis.yml | 1 + package.json | 11 +- src/activitypub/ActivityPub.js | 137 ++++ src/activitypub/NitroDatasource.js | 377 +++++++++++ src/activitypub/routes/inbox.js | 50 ++ src/activitypub/routes/index.js | 27 + src/activitypub/routes/user.js | 88 +++ src/activitypub/routes/webfinger.js | 34 + src/activitypub/security/index.js | 227 +++++++ src/activitypub/utils/index.js | 215 +++++++ src/activitypub/utils/serveUser.js | 43 ++ src/index.js | 2 + src/middleware/userMiddleware.js | 8 + src/schema.graphql | 3 + .../features/activity-article.feature.disable | 30 + test/features/activity-delete.feature.disable | 28 + test/features/activity-follow.feature | 51 ++ test/features/collection.feature | 101 +++ test/features/support/steps.js | 125 ++++ test/features/webfinger.feature | 65 ++ test/features/world.js | 58 ++ yarn.lock | 600 +++++++++++++++++- 23 files changed, 2265 insertions(+), 19 deletions(-) create mode 100644 src/activitypub/ActivityPub.js create mode 100644 src/activitypub/NitroDatasource.js create mode 100644 src/activitypub/routes/inbox.js create mode 100644 src/activitypub/routes/index.js create mode 100644 src/activitypub/routes/user.js create mode 100644 src/activitypub/routes/webfinger.js create mode 100644 src/activitypub/security/index.js create mode 100644 src/activitypub/utils/index.js create mode 100644 src/activitypub/utils/serveUser.js create mode 100644 test/features/activity-article.feature.disable create mode 100644 test/features/activity-delete.feature.disable create mode 100644 test/features/activity-follow.feature create mode 100644 test/features/collection.feature create mode 100644 test/features/support/steps.js create mode 100644 test/features/webfinger.feature create mode 100644 test/features/world.js diff --git a/.babelrc b/.babelrc index 2d91b3635..f36dbeadb 100644 --- a/.babelrc +++ b/.babelrc @@ -8,5 +8,8 @@ } } ] + ], + "plugins": [ + "@babel/plugin-proposal-throw-expressions" ] } diff --git a/.travis.yml b/.travis.yml index e699197cf..47d252435 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,7 @@ install: script: - docker-compose exec backend yarn run lint - docker-compose exec backend yarn run test --ci + - docker-compose exec backend yarn run test:cucumber - docker-compose exec backend yarn run test:coverage - docker-compose exec backend yarn run db:reset - docker-compose exec backend yarn run db:seed diff --git a/package.json b/package.json index 39c9c14c6..799c45085 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,15 @@ "dev": "nodemon --exec babel-node src/", "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "lint": "eslint src --config .eslintrc.js", - "test": "nyc --reporter=text-lcov yarn run test:jest", + "test": "nyc --reporter=text-lcov yarn test:jest", "test:cypress": "run-p --race test:before:*", "test:before:server": "cross-env GRAPHQL_URI=http://localhost:4123 GRAPHQL_PORT=4123 babel-node src/ 2> /dev/null", "test:before:seeder": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 PERMISSIONS=disabled babel-node src/ 2> /dev/null", "test:jest:cmd": "wait-on tcp:4001 tcp:4123 && jest --forceExit --detectOpenHandles --runInBand", + "test:cucumber:cmd": "wait-on tcp:4001 tcp:4123 && cucumber-js --require-module @babel/register --exit test/", "test:jest:cmd:debug": "wait-on tcp:4001 tcp:4123 && node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand", "test:jest": "run-p --race test:before:* 'test:jest:cmd {@}' --", + "test:cucumber": "ACTIVITYPUB_PORT=4123 run-p --race test:before:* 'test:cucumber:cmd {@}' --", "test:jest:debug": "run-p --race test:before:* 'test:jest:cmd:debug {@}' --", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", @@ -34,15 +36,18 @@ ] }, "dependencies": { + "activitystrea.ms": "^2.1.3", "apollo-cache-inmemory": "~1.4.3", "apollo-client": "~2.4.13", "apollo-link-http": "~1.5.11", "apollo-server": "~2.4.2", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", + "cors": "^2.8.5", "cross-env": "~5.2.0", "date-fns": "2.0.0-alpha.26", "dotenv": "~6.2.0", + "express": "^4.16.4", "faker": "~4.1.0", "graphql": "~14.1.1", "graphql-custom-directives": "~0.2.14", @@ -61,6 +66,7 @@ "npm-run-all": "~4.1.5", "passport": "~0.4.0", "passport-jwt": "~4.0.0", + "request": "^2.88.0", "sanitize-html": "~1.20.0", "slug": "~1.0.0", "trunc-html": "~1.1.2", @@ -70,6 +76,7 @@ "@babel/cli": "~7.2.3", "@babel/core": "~7.3.3", "@babel/node": "~7.2.2", + "@babel/plugin-proposal-throw-expressions": "^7.2.0", "@babel/preset-env": "~7.3.1", "@babel/register": "~7.0.0", "apollo-server-testing": "~2.4.2", @@ -77,6 +84,8 @@ "babel-eslint": "~10.0.1", "babel-jest": "~24.1.0", "chai": "~4.2.0", + "cucumber": "^5.1.0", + "debug": "^4.1.1", "eslint": "~5.13.0", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.16.0", diff --git a/src/activitypub/ActivityPub.js b/src/activitypub/ActivityPub.js new file mode 100644 index 000000000..57b1a5353 --- /dev/null +++ b/src/activitypub/ActivityPub.js @@ -0,0 +1,137 @@ +import { sendAcceptActivity, sendRejectActivity, extractNameFromId, extractDomainFromUrl } from './utils' +import request from 'request' +import as from 'activitystrea.ms' +import NitroDatasource from './NitroDatasource' +import router from './routes' +import dotenv from 'dotenv' +import { resolve } from 'path' +const debug = require('debug')('ea') + +let activityPub = null + +export { activityPub } + +export default class ActivityPub { + constructor (domain, port) { + if (domain === 'localhost') { this.domain = `${domain}:${port}` } else { this.domain = domain } + this.port = port + this.dataSource = new NitroDatasource(this.domain) + } + static init (server) { + if (!activityPub) { + dotenv.config({ path: resolve('src', 'activitypub', '.env') }) + // const app = express() + activityPub = new ActivityPub(process.env.ACTIVITYPUB_DOMAIN || 'localhost', process.env.ACTIVITYPUB_PORT || 4100) + server.express.set('ap', activityPub) + server.express.use(router) + debug('ActivityPub service added to graphql endpoint') + } else { + debug('ActivityPub service already added to graphql endpoint') + } + } + + getFollowersCollection (actorId) { + return this.dataSource.getFollowersCollection(actorId) + } + + getFollowersCollectionPage (actorId) { + return this.dataSource.getFollowersCollectionPage(actorId) + } + + getFollowingCollection (actorId) { + return this.dataSource.getFollowingCollection(actorId) + } + + getFollowingCollectionPage (actorId) { + return this.dataSource.getFollowingCollectionPage(actorId) + } + + getOutboxCollection (actorId) { + return this.dataSource.getOutboxCollection(actorId) + } + + getOutboxCollectionPage (actorId) { + return this.dataSource.getOutboxCollectionPage(actorId) + } + + handleFollowActivity (activity) { + debug(`inside FOLLOW ${activity.actor}`) + let toActorName = extractNameFromId(activity.object) + let fromDomain = extractDomainFromUrl(activity.actor) + const dataSource = this.dataSource + + return new Promise((resolve, reject) => { + request({ + url: activity.actor, + headers: { + 'Accept': 'application/activity+json' + } + }, async (err, response, toActorObject) => { + if (err) return reject(err) + debug(`name = ${toActorName}@${this.domain}`) + + let followersCollectionPage = await this.dataSource.getFollowersCollectionPage(activity.object) + + const followActivity = as.follow() + .id(activity.id) + .actor(activity.actor) + .object(activity.object) + + // add follower if not already in collection + if (followersCollectionPage.orderedItems.includes(activity.actor)) { + debug('follower already in collection!') + debug(`inbox = ${toActorObject.inbox}`) + resolve(sendRejectActivity(followActivity, toActorName, fromDomain, toActorObject.inbox)) + } else { + followersCollectionPage.orderedItems.push(activity.actor) + } + debug(`toActorObject = ${toActorObject}`) + toActorObject = typeof toActorObject !== 'object' ? JSON.parse(toActorObject) : toActorObject + debug(`followers = ${JSON.stringify(followersCollectionPage.orderedItems, null, 2)}`) + debug(`inbox = ${toActorObject.inbox}`) + debug(`outbox = ${toActorObject.outbox}`) + debug(`followers = ${toActorObject.followers}`) + debug(`following = ${toActorObject.following}`) + + // TODO save after accept activity for the corresponding follow is received + try { + await dataSource.saveFollowersCollectionPage(followersCollectionPage) + debug('follow activity saved') + resolve(sendAcceptActivity(followActivity, toActorName, fromDomain, toActorObject.inbox)) + } catch (e) { + debug('followers update error!', e) + resolve(sendRejectActivity(followActivity, toActorName, fromDomain, toActorObject.inbox)) + } + }) + }) + } + + handleUndoActivity (activity) { + debug('inside UNDO') + switch (activity.object.type) { + case 'Follow': + const followActivity = activity.object + return this.dataSource.undoFollowActivity(followActivity.actor, followActivity.object) + default: + } + } + + handleCreateActivity (activity) { + debug('inside create') + switch (activity.object.type) { + case 'Article': + case 'Note': + const articleObject = activity.object + if (articleObject.inReplyTo) { + return this.dataSource.createComment(articleObject) + } else { + return this.dataSource.createPost(articleObject) + } + default: + } + } + + handleDeleteActivity (activity) { + debug('inside delete') + } +} diff --git a/src/activitypub/NitroDatasource.js b/src/activitypub/NitroDatasource.js new file mode 100644 index 000000000..957026a2c --- /dev/null +++ b/src/activitypub/NitroDatasource.js @@ -0,0 +1,377 @@ +import { + throwErrorIfGraphQLErrorOccurred, + extractIdFromActivityId, + createOrderedCollection, + createOrderedCollectionPage, + extractNameFromId, + createArticleActivity, + constructIdFromName +} from './utils' +import crypto from 'crypto' +import gql from 'graphql-tag' +import { createHttpLink } from 'apollo-link-http' +import { InMemoryCache } from 'apollo-cache-inmemory' +import fetch from 'node-fetch' +import { ApolloClient } from 'apollo-client' +import dotenv from 'dotenv' +const debug = require('debug')('ea:nitro-datasource') + +dotenv.config() + +export default class NitroDatasource { + constructor (domain) { + this.domain = domain + const defaultOptions = { + query: { + fetchPolicy: 'network-only', + errorPolicy: 'all' + } + } + const link = createHttpLink({ uri: process.env.GRAPHQL_URI, fetch: fetch }) // eslint-disable-line + const cache = new InMemoryCache() + this.client = new ApolloClient({ + link: link, + cache: cache, + defaultOptions + }) + } + + async getFollowersCollection (actorId) { + const slug = extractNameFromId(actorId) + debug(`slug= ${slug}`) + const result = await this.client.query({ + query: gql` + query { + User(slug: "${slug}") { + followedByCount + } + } + ` + }) + debug('successfully fetched followers') + debug(result.data) + if (result.data) { + const actor = result.data.User[0] + const followersCount = actor.followedByCount + + const followersCollection = createOrderedCollection(slug, 'followers') + followersCollection.totalItems = followersCount + + return followersCollection + } else { + throwErrorIfGraphQLErrorOccurred(result) + } + } + + async getFollowersCollectionPage (actorId) { + const slug = extractNameFromId(actorId) + debug(`getFollowersPage slug = ${slug}`) + const result = await this.client.query({ + query: gql` + query { + User(slug:"${slug}") { + followedBy { + slug + } + followedByCount + } + } + ` + }) + + debug(result.data) + if (result.data) { + const actor = result.data.User[0] + const followers = actor.followedBy + const followersCount = actor.followedByCount + + const followersCollection = createOrderedCollectionPage(slug, 'followers') + followersCollection.totalItems = followersCount + debug(`followers = ${JSON.stringify(followers, null, 2)}`) + await Promise.all( + followers.map(async (follower) => { + followersCollection.orderedItems.push(constructIdFromName(follower.slug)) + }) + ) + + return followersCollection + } else { + throwErrorIfGraphQLErrorOccurred(result) + } + } + + async getFollowingCollection (actorId) { + const slug = extractNameFromId(actorId) + const result = await this.client.query({ + query: gql` + query { + User(slug:"${slug}") { + followingCount + } + } + ` + }) + + debug(result.data) + if (result.data) { + const actor = result.data.User[0] + const followingCount = actor.followingCount + + const followingCollection = createOrderedCollection(slug, 'following') + followingCollection.totalItems = followingCount + + return followingCollection + } else { + throwErrorIfGraphQLErrorOccurred(result) + } + } + + async getFollowingCollectionPage (actorId) { + const slug = extractNameFromId(actorId) + const result = await this.client.query({ + query: gql` + query { + User(slug:"${slug}") { + following { + slug + } + followingCount + } + } + ` + }) + + debug(result.data) + if (result.data) { + const actor = result.data.User[0] + const following = actor.following + const followingCount = actor.followingCount + + const followingCollection = createOrderedCollectionPage(slug, 'following') + followingCollection.totalItems = followingCount + + await Promise.all( + following.map(async (user) => { + followingCollection.orderedItems.push(await constructIdFromName(user.slug)) + }) + ) + + return followingCollection + } else { + throwErrorIfGraphQLErrorOccurred(result) + } + } + + async getOutboxCollection (actorId) { + const slug = extractNameFromId(actorId) + const result = await this.client.query({ + query: gql` + query { + User(slug:"${slug}") { + contributions { + title + slug + content + contentExcerpt + createdAt + } + } + } + ` + }) + + debug(result.data) + if (result.data) { + const actor = result.data.User[0] + const posts = actor.contributions + + const outboxCollection = createOrderedCollection(slug, 'outbox') + outboxCollection.totalItems = posts.length + + return outboxCollection + } else { + throwErrorIfGraphQLErrorOccurred(result) + } + } + + async getOutboxCollectionPage (actorId) { + const slug = extractNameFromId(actorId) + const result = await this.client.query({ + query: gql` + query { + User(slug:"${slug}") { + contributions { + id + title + slug + content + contentExcerpt + createdAt + } + } + } + ` + }) + + debug(result.data) + if (result.data) { + const actor = result.data.User[0] + const posts = actor.contributions + + const outboxCollection = createOrderedCollectionPage(slug, 'outbox') + outboxCollection.totalItems = posts.length + await Promise.all( + posts.map((post) => { + outboxCollection.orderedItems.push(createArticleActivity(post.content, slug, post.id, post.createdAt)) + }) + ) + + debug('after createNote') + return outboxCollection + } else { + throwErrorIfGraphQLErrorOccurred(result) + } + } + + async undoFollowActivity (fromActorId, toActorId) { + const fromUserId = await this.ensureUser(fromActorId) + const toUserId = await this.ensureUser(toActorId) + const result = await this.client.mutate({ + mutation: gql` + mutation { + RemoveUserFollowedBy(from: {id: "${fromUserId}"}, to: {id: "${toUserId}"}) { + from { name } + } + } + ` + }) + debug(`undoFollowActivity result = ${JSON.stringify(result, null, 2)}`) + throwErrorIfGraphQLErrorOccurred(result) + } + + async saveFollowersCollectionPage (followersCollection, onlyNewestItem = true) { + debug('inside saveFollowers') + let orderedItems = followersCollection.orderedItems + const toUserName = extractNameFromId(followersCollection.id) + const toUserId = await this.ensureUser(constructIdFromName(toUserName)) + orderedItems = onlyNewestItem ? [orderedItems.pop()] : orderedItems + + return Promise.all( + await Promise.all(orderedItems.map(async (follower) => { + debug(`follower = ${follower}`) + const fromUserId = await this.ensureUser(follower) + debug(`fromUserId = ${fromUserId}`) + debug(`toUserId = ${toUserId}`) + const result = await this.client.mutate({ + mutation: gql` + mutation { + AddUserFollowedBy(from: {id: "${fromUserId}"}, to: {id: "${toUserId}"}) { + from { name } + } + } + ` + }) + debug(`addUserFollowedBy edge = ${JSON.stringify(result, null, 2)}`) + throwErrorIfGraphQLErrorOccurred(result) + debug('saveFollowers: added follow edge successfully') + })) + ) + } + + async createPost (postObject) { + // TODO how to handle the to field? Now the post is just created, doesn't matter who is the recipient + // createPost + const title = postObject.summary ? postObject.summary : postObject.content.split(' ').slice(0, 5).join(' ') + const id = extractIdFromActivityId(postObject.id) + let result = await this.client.mutate({ + mutation: gql` + mutation { + CreatePost(content: "${postObject.content}", title: "${title}", id: "${id}") { + id + } + } + ` + }) + + throwErrorIfGraphQLErrorOccurred(result) + + // ensure user and add author to post + const userId = await this.ensureUser(postObject.attributedTo) + result = await this.client.mutate({ + mutation: gql` + mutation { + AddPostAuthor(from: {id: "${userId}"}, to: {id: "${id}"}) + } + ` + }) + + throwErrorIfGraphQLErrorOccurred(result) + } + + async createComment (postObject) { + let result = await this.client.mutate({ + mutation: gql` + mutation { + CreateComment(content: "${postObject.content}") { + id + } + } + ` + }) + + throwErrorIfGraphQLErrorOccurred(result) + const postId = extractIdFromActivityId(postObject.inReplyTo) + + result = await this.client.mutate({ + mutation: gql` + mutation { + AddCommentPost(from: { id: "${result.data.CreateComment.id}", to: { id: "${postId}" }}) { + id + } + } + ` + }) + + throwErrorIfGraphQLErrorOccurred(result) + } + + /** + * This function will search for user existence and will create a disabled user with a random 16 bytes password when no user is found. + * + * @param actorId + * @returns {Promise<*>} + */ + async ensureUser (actorId) { + debug(`inside ensureUser = ${actorId}`) + const queryResult = await this.client.query({ + query: gql` + query { + User(slug: "${extractNameFromId(actorId)}") { + id + } + } + ` + }) + + if (queryResult.data && Array.isArray(queryResult.data.User) && queryResult.data.User.length > 0) { + debug('ensureUser: user exists.. return id') + // user already exists.. return the id + return queryResult.data.User[0].id + } else { + debug('ensureUser: user not exists.. createUser') + // user does not exist.. create it + const result = await this.client.mutate({ + mutation: gql` + mutation { + CreateUser(password: "${crypto.randomBytes(16).toString('hex')}", slug:"${extractNameFromId(actorId)}", actorId: "${actorId}", name: "${extractNameFromId(actorId)}") { + id + } + } + ` + }) + throwErrorIfGraphQLErrorOccurred(result) + + return result.data.CreateUser.id + } + } +} diff --git a/src/activitypub/routes/inbox.js b/src/activitypub/routes/inbox.js new file mode 100644 index 000000000..0f33ebaec --- /dev/null +++ b/src/activitypub/routes/inbox.js @@ -0,0 +1,50 @@ +import express from 'express' +import { verify } from '../security' +const debug = require('debug')('ea:inbox') + +const router = express.Router() + +// Shared Inbox endpoint (federated Server) +// For now its only able to handle Note Activities!! +router.post('/', async function (req, res, next) { + debug(`Content-Type = ${req.get('Content-Type')}`) + debug(`body = ${JSON.stringify(req.body, null, 2)}`) + debug(`Request headers = ${JSON.stringify(req.headers, null, 2)}`) + debug(`verify = ${await verify(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)}`) + switch (req.body.type) { + case 'Create': + await await req.app.get('activityPub').handleCreateActivity(req.body).catch(next) + break + case 'Undo': + await await req.app.get('activityPub').handleUndoActivity(req.body).catch(next) + break + case 'Follow': + debug('handleFollow') + await req.app.get('activityPub').handleFollowActivity(req.body) + debug('handledFollow') + break + case 'Delete': + await await req.app.get('activityPub').handleDeleteActivity(req.body).catch(next) + break + /* eslint-disable */ + case 'Update': + + case 'Accept': + + case 'Reject': + + case 'Add': + + case 'Remove': + + case 'Like': + + case 'Announce': + debug('else!!') + debug(JSON.stringify(req.body, null, 2)) + } + /* eslint-enable */ + res.status(200).end() +}) + +export default router diff --git a/src/activitypub/routes/index.js b/src/activitypub/routes/index.js new file mode 100644 index 000000000..7a8524a9e --- /dev/null +++ b/src/activitypub/routes/index.js @@ -0,0 +1,27 @@ +import user from './user' +import inbox from './inbox' +import webfinger from './webfinger' +import express from 'express' +import cors from 'cors' + +const router = express.Router() + +router.use('/.well-known/webfinger', + cors(), + express.urlencoded({ extended: true }), + webfinger +) +router.use('/activitypub/users', + cors(), + express.json({ type: ['application/activity+json', 'application/ld+json', 'application/json'] }), + express.urlencoded({ extended: true }), + user +) +router.use('/activitypub/inbox', + cors(), + express.json({ type: ['application/activity+json', 'application/ld+json', 'application/json'] }), + express.urlencoded({ extended: true }), + inbox +) + +export default router diff --git a/src/activitypub/routes/user.js b/src/activitypub/routes/user.js new file mode 100644 index 000000000..8240ba393 --- /dev/null +++ b/src/activitypub/routes/user.js @@ -0,0 +1,88 @@ +import { sendCollection } from '../utils' +import express from 'express' +import { serveUser } from '../utils/serveUser' +import { verify } from '../security' + +const router = express.Router() +const debug = require('debug')('ea:user') + +router.get('/:name', async function (req, res, next) { + debug('inside user.js -> serveUser') + await serveUser(req, res, next) +}) + +router.get('/:name/following', (req, res) => { + debug('inside user.js -> serveFollowingCollection') + const name = req.params.name + if (!name) { + res.status(400).send('Bad request! Please specify a name.') + } else { + const collectionName = req.query.page ? 'followingPage' : 'following' + sendCollection(collectionName, req, res) + } +}) + +router.get('/:name/followers', (req, res) => { + debug('inside user.js -> serveFollowersCollection') + const name = req.params.name + if (!name) { + return res.status(400).send('Bad request! Please specify a name.') + } else { + const collectionName = req.query.page ? 'followersPage' : 'followers' + sendCollection(collectionName, req, res) + } +}) + +router.get('/:name/outbox', (req, res) => { + debug('inside user.js -> serveOutboxCollection') + const name = req.params.name + if (!name) { + return res.status(400).send('Bad request! Please specify a name.') + } else { + const collectionName = req.query.page ? 'outboxPage' : 'outbox' + sendCollection(collectionName, req, res) + } +}) + +router.post('/:name/inbox', async function (req, res, next) { + debug(`body = ${JSON.stringify(req.body, null, 2)}`) + debug(`actorId = ${req.body.actor}`) + debug(`verify = ${await verify(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)}`) + // const result = await saveActorId(req.body.actor) + switch (req.body.type) { + case 'Create': + await req.app.get('ap').handleCreateActivity(req.body).catch(next) + break + case 'Undo': + await req.app.get('ap').handleUndoActivity(req.body).catch(next) + break + case 'Follow': + debug('handleFollow') + await req.app.get('ap').handleFollowActivity(req.body).catch(next) + debug('handledFollow') + break + case 'Delete': + req.app.get('ap').handleDeleteActivity(req.body).catch(next) + break + /* eslint-disable */ + case 'Update': + + case 'Accept': + + case 'Reject': + + case 'Add': + + case 'Remove': + + case 'Like': + + case 'Announce': + debug('else!!') + debug(JSON.stringify(req.body, null, 2)) + } + /* eslint-enable */ + res.status(200).end() +}) + +export default router diff --git a/src/activitypub/routes/webfinger.js b/src/activitypub/routes/webfinger.js new file mode 100644 index 000000000..9e51dcdfd --- /dev/null +++ b/src/activitypub/routes/webfinger.js @@ -0,0 +1,34 @@ +import express from 'express' +import { createWebFinger } from '../utils' +import gql from 'graphql-tag' + +const router = express.Router() + +router.get('/', async function (req, res) { + const resource = req.query.resource + if (!resource || !resource.includes('acct:')) { + return res.status(400).send('Bad request. Please make sure "acct:USER@DOMAIN" is what you are sending as the "resource" query parameter.') + } else { + const nameAndDomain = resource.replace('acct:', '') + const name = nameAndDomain.split('@')[0] + + const result = await req.app.get('ap').dataSource.client.query({ + query: gql` + query { + User(slug: "${name}") { + slug + } + } + ` + }) + + if (result.data && result.data.User.length > 0) { + const webFinger = createWebFinger(name) + return res.contentType('application/jrd+json').json(webFinger) + } else { + return res.status(404).json({ error: `No record found for ${nameAndDomain}.` }) + } + } +}) + +export default router diff --git a/src/activitypub/security/index.js b/src/activitypub/security/index.js new file mode 100644 index 000000000..93b6cc08a --- /dev/null +++ b/src/activitypub/security/index.js @@ -0,0 +1,227 @@ +import dotenv from 'dotenv' +import { resolve } from 'path' +import crypto from 'crypto' +import { activityPub } from '../ActivityPub' +import gql from 'graphql-tag' +import request from 'request' +const debug = require('debug')('ea:security') + +dotenv.config({ path: resolve('src', 'activitypub', '.env') }) + +export function generateRsaKeyPair () { + return crypto.generateKeyPairSync('rsa', { + modulusLength: 4096, + publicKeyEncoding: { + type: 'spki', + format: 'pem' + }, + privateKeyEncoding: { + type: 'pkcs8', + format: 'pem', + cipher: 'aes-256-cbc', + passphrase: process.env.PRIVATE_KEY_PASSPHRASE + } + }) +} + +export function signAndSend (activity, fromName, targetDomain, url) { + // fix for development: replace with http + url = url.indexOf('localhost') > -1 ? url.replace('https', 'http') : url + debug(`passhprase = ${process.env.PRIVATE_KEY_PASSPHRASE}`) + return new Promise(async (resolve, reject) => { + debug('inside signAndSend') + // get the private key + const result = await activityPub.dataSource.client.query({ + query: gql` + query { + User(slug: "${fromName}") { + privateKey + } + } + ` + }) + + if (result.error) { + reject(result.error) + } else { + const parsedActivity = JSON.parse(activity) + if (Array.isArray(parsedActivity['@context'])) { + parsedActivity['@context'].push('https://w3id.org/security/v1') + } else { + const context = [parsedActivity['@context']] + context.push('https://w3id.org/security/v1') + parsedActivity['@context'] = context + } + + // deduplicate context strings + parsedActivity['@context'] = [...new Set(parsedActivity['@context'])] + const privateKey = result.data.User[0].privateKey + const date = new Date().toUTCString() + + debug(`url = ${url}`) + request({ + url: url, + headers: { + 'Host': targetDomain, + 'Date': date, + 'Signature': createSignature(privateKey, `http://${activityPub.domain}/activitypub/users/${fromName}#main-key`, url, + { + 'Host': targetDomain, + 'Date': date, + 'Content-Type': 'application/activity+json' + }), + 'Content-Type': 'application/activity+json' + }, + method: 'POST', + body: JSON.stringify(parsedActivity) + }, (error, response) => { + if (error) { + debug(`Error = ${JSON.stringify(error, null, 2)}`) + reject(error) + } else { + debug('Response Headers:', JSON.stringify(response.headers, null, 2)) + debug('Response Body:', JSON.stringify(response.body, null, 2)) + resolve() + } + }) + } + }) +} + +export function verify (url, headers) { + return new Promise((resolve, reject) => { + const signatureHeader = headers['signature'] ? headers['signature'] : headers['Signature'] + if (!signatureHeader) { + debug('No Signature header present!') + resolve(false) + } + debug(`Signature Header = ${signatureHeader}`) + const signature = extractKeyValueFromSignatureHeader(signatureHeader, 'signature') + const algorithm = extractKeyValueFromSignatureHeader(signatureHeader, 'algorithm') + const headersString = extractKeyValueFromSignatureHeader(signatureHeader, 'headers') + const keyId = extractKeyValueFromSignatureHeader(signatureHeader, 'keyId') + + if (!SUPPORTED_HASH_ALGORITHMS.includes(algorithm)) { + debug('Unsupported hash algorithm specified!') + resolve(false) + } + + const usedHeaders = headersString.split(' ') + const verifyHeaders = {} + Object.keys(headers).forEach((key) => { + if (usedHeaders.includes(key.toLowerCase())) { + verifyHeaders[key.toLowerCase()] = headers[key] + } + }) + const signingString = constructSigningString(url, verifyHeaders) + debug(`keyId= ${keyId}`) + request({ + url: keyId, + headers: { + 'Accept': 'application/json' + } + }, (err, response, body) => { + if (err) reject(err) + debug(`body = ${body}`) + const actor = JSON.parse(body) + const publicKeyPem = actor.publicKey.publicKeyPem + resolve(httpVerify(publicKeyPem, signature, signingString, algorithm)) + }) + }) +} + +// specify the public key owner object +/* const testPublicKeyOwner = { + "@context": jsig.SECURITY_CONTEXT_URL, + '@id': 'https://example.com/i/alice', + publicKey: [testPublicKey] +} */ + +/* const publicKey = { + '@context': jsig.SECURITY_CONTEXT_URL, + type: 'RsaVerificationKey2018', + id: `https://${ActivityPub.domain}/users/${fromName}#main-key`, + controller: `https://${ActivityPub.domain}/users/${fromName}`, + publicKeyPem +} */ + +// Obtained from invoking crypto.getHashes() +export const SUPPORTED_HASH_ALGORITHMS = [ + 'rsa-md4', + 'rsa-md5', + 'rsa-mdC2', + 'rsa-ripemd160', + 'rsa-sha1', + 'rsa-sha1-2', + 'rsa-sha224', + 'rsa-sha256', + 'rsa-sha384', + 'rsa-sha512', + 'blake2b512', + 'blake2s256', + 'md4', + 'md4WithRSAEncryption', + 'md5', + 'md5-sha1', + 'md5WithRSAEncryption', + 'mdc2', + 'mdc2WithRSA', + 'ripemd', + 'ripemd160', + 'ripemd160WithRSA', + 'rmd160', + 'sha1', + 'sha1WithRSAEncryption', + 'sha224', + 'sha224WithRSAEncryption', + 'sha256', + 'sha256WithRSAEncryption', + 'sha384', + 'sha384WithRSAEncryption', + 'sha512', + 'sha512WithRSAEncryption', + 'ssl3-md5', + 'ssl3-sha1', + 'whirlpool'] + +// signing +function createSignature (privKey, keyId, url, headers = {}, algorithm = 'rsa-sha256') { + if (!SUPPORTED_HASH_ALGORITHMS.includes(algorithm)) { return throw Error(`SIGNING: Unsupported hashing algorithm = ${algorithm}`) } + const signer = crypto.createSign(algorithm) + const signingString = constructSigningString(url, headers) + signer.update(signingString) + const signatureB64 = signer.sign({ key: privKey, passphrase: process.env.PRIVATE_KEY_PASSPHRASE }, 'base64') + const headersString = Object.keys(headers).reduce((result, key) => { return result + ' ' + key.toLowerCase() }, '') + return `keyId="${keyId}",algorithm="${algorithm}",headers="(request-target)${headersString}",signature="${signatureB64}"` +} + +// signing +function constructSigningString (url, headers) { + const urlObj = new URL(url) + let signingString = `(request-target): post ${urlObj.pathname}${urlObj.search !== '' ? urlObj.search : ''}` + return Object.keys(headers).reduce((result, key) => { + return result + `\n${key.toLowerCase()}: ${headers[key]}` + }, signingString) +} + +// verifying +function httpVerify (pubKey, signature, signingString, algorithm) { + if (!SUPPORTED_HASH_ALGORITHMS.includes(algorithm)) { throw Error(`SIGNING: Unsupported hashing algorithm = ${algorithm}`) } + const verifier = crypto.createVerify(algorithm) + verifier.update(signingString) + return verifier.verify(pubKey, signature, 'base64') +} + +// verifying +// This function can be used to extract the signature,headers,algorithm etc. out of the Signature Header. +// Just pass what you want as key +function extractKeyValueFromSignatureHeader (signatureHeader, key) { + const keyString = signatureHeader.split(',').filter((el) => { + return !!el.startsWith(key) + })[0] + + let firstEqualIndex = keyString.search('=') + // When headers are requested add 17 to the index to remove "(request-target) " from the string + if (key === 'headers') { firstEqualIndex += 17 } + return keyString.substring(firstEqualIndex + 2, keyString.length - 1) +} diff --git a/src/activitypub/utils/index.js b/src/activitypub/utils/index.js new file mode 100644 index 000000000..d1d4be845 --- /dev/null +++ b/src/activitypub/utils/index.js @@ -0,0 +1,215 @@ +import crypto from 'crypto' +import { signAndSend } from '../security' +import as from 'activitystrea.ms' +import { activityPub } from '../ActivityPub' +const debug = require('debug')('ea:utils') + +export function extractNameFromId (uri) { + const urlObject = new URL(uri) + const pathname = urlObject.pathname + const splitted = pathname.split('/') + + return splitted[splitted.indexOf('users') + 1] +} + +export function extractIdFromActivityId (uri) { + const urlObject = new URL(uri) + const pathname = urlObject.pathname + const splitted = pathname.split('/') + + return splitted[splitted.indexOf('status') + 1] +} + +export function constructIdFromName (name, fromDomain = activityPub.domain) { + return `https://${fromDomain}/activitypub/users/${name}` +} + +export function extractDomainFromUrl (url) { + return new URL(url).hostname +} + +export async function getActorIdByName (name) { + debug(`name = ${name}`) + return Promise.resolve() +} + +export function sendCollection (collectionName, req, res) { + const name = req.params.name + const id = constructIdFromName(name) + + switch (collectionName) { + case 'followers': + attachThenCatch(activityPub.getFollowersCollection(id), res) + break + + case 'followersPage': + attachThenCatch(activityPub.getFollowersCollectionPage(id), res) + break + + case 'following': + attachThenCatch(activityPub.getFollowingCollection(id), res) + break + + case 'followingPage': + attachThenCatch(activityPub.getFollowingCollectionPage(id), res) + break + + case 'outbox': + attachThenCatch(activityPub.getOutboxCollection(id), res) + break + + case 'outboxPage': + attachThenCatch(activityPub.getOutboxCollectionPage(id), res) + break + + default: + res.status(500).end() + } +} + +function attachThenCatch (promise, res) { + return promise + .then((collection) => { + res.status(200).contentType('application/activity+json').send(collection) + }) + .catch((err) => { + debug(`error getting a Collection: = ${err}`) + res.status(500).end() + }) +} + +export function createActor (name, pubkey) { + return { + '@context': [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1' + ], + 'id': `https://${activityPub.domain}/activitypub/users/${name}`, + 'type': 'Person', + 'preferredUsername': `${name}`, + 'name': `${name}`, + 'following': `https://${activityPub.domain}/activitypub/users/${name}/following`, + 'followers': `https://${activityPub.domain}/activitypub/users/${name}/followers`, + 'inbox': `https://${activityPub.domain}/activitypub/users/${name}/inbox`, + 'outbox': `https://${activityPub.domain}/activitypub/users/${name}/outbox`, + 'url': `https://${activityPub.domain}/activitypub/@${name}`, + 'endpoints': { + 'sharedInbox': `https://${activityPub.domain}/activitypub/inbox` + }, + 'publicKey': { + 'id': `https://${activityPub.domain}/activitypub/users/${name}#main-key`, + 'owner': `https://${activityPub.domain}/activitypub/users/${name}`, + 'publicKeyPem': pubkey + } + } +} + +export function createWebFinger (name) { + return { + 'subject': `acct:${name}@${activityPub.domain}`, + 'links': [ + { + 'rel': 'self', + 'type': 'application/activity+json', + 'href': `https://${activityPub.domain}/users/${name}` + } + ] + } +} + +export function createOrderedCollection (name, collectionName) { + return { + '@context': 'https://www.w3.org/ns/activitystreams', + 'id': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}`, + 'summary': `${name}s ${collectionName} collection`, + 'type': 'OrderedCollection', + 'first': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}?page=true`, + 'totalItems': 0 + } +} + +export function createOrderedCollectionPage (name, collectionName) { + return { + '@context': 'https://www.w3.org/ns/activitystreams', + 'id': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}?page=true`, + 'summary': `${name}s ${collectionName} collection`, + 'type': 'OrderedCollectionPage', + 'totalItems': 0, + 'partOf': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}`, + 'orderedItems': [] + } +} + +export function createNoteActivity (text, name, id, published) { + const createUuid = crypto.randomBytes(16).toString('hex') + + return { + '@context': 'https://www.w3.org/ns/activitystreams', + 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${createUuid}`, + 'type': 'Create', + 'actor': `https://${activityPub.domain}/activitypub/users/${name}`, + 'object': { + 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${id}`, + 'type': 'Note', + 'published': published, + 'attributedTo': `https://${activityPub.domain}/activitypub/users/${name}`, + 'content': text, + 'to': 'https://www.w3.org/ns/activitystreams#Public' + } + } +} + +export function createArticleActivity (text, name, id, published) { + const createUuid = crypto.randomBytes(16).toString('hex') + + return { + '@context': 'https://www.w3.org/ns/activitystreams', + 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${createUuid}`, + 'type': 'Create', + 'actor': `https://${activityPub.domain}/activitypub/users/${name}`, + 'object': { + 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${id}`, + 'type': 'Article', + 'published': published, + 'attributedTo': `https://${activityPub.domain}/activitypub/users/${name}`, + 'content': text, + 'to': 'https://www.w3.org/ns/activitystreams#Public' + } + } +} + +export function sendAcceptActivity (theBody, name, targetDomain, url) { + as.accept() + .id(`https://${activityPub.domain}/activitypub/users/${name}/status/` + crypto.randomBytes(16).toString('hex')) + .actor(`https://${activityPub.domain}/activitypub/users/${name}`) + .object(theBody) + .prettyWrite((err, doc) => { + if (!err) { + return signAndSend(doc, name, targetDomain, url) + } else { + debug(`error serializing Accept object: ${err}`) + throw new Error('error serializing Accept object') + } + }) +} + +export function sendRejectActivity (theBody, name, targetDomain, url) { + as.reject() + .id(`https://${activityPub.domain}/activitypub/users/${name}/status/` + crypto.randomBytes(16).toString('hex')) + .actor(`https://${activityPub.domain}/activitypub/users/${name}`) + .object(theBody) + .prettyWrite((err, doc) => { + if (!err) { + return signAndSend(doc, name, targetDomain, url) + } else { + debug(`error serializing Accept object: ${err}`) + throw new Error('error serializing Accept object') + } + }) +} + +export function throwErrorIfGraphQLErrorOccurred (result) { + if (result.error && (result.error.message || result.error.errors)) { + throw new Error(`${result.error.message ? result.error.message : result.error.errors[0].message}`) + } +} diff --git a/src/activitypub/utils/serveUser.js b/src/activitypub/utils/serveUser.js new file mode 100644 index 000000000..9a13275eb --- /dev/null +++ b/src/activitypub/utils/serveUser.js @@ -0,0 +1,43 @@ +import { createActor } from '../utils' +const gql = require('graphql-tag') +const debug = require('debug')('ea:serveUser') + +export async function serveUser (req, res, next) { + let name = req.params.name + + if (name.startsWith('@')) { + name = name.slice(1) + } + + debug(`name = ${name}`) + const result = await req.app.get('ap').dataSource.client.query({ + query: gql` + query { + User(slug: "${name}") { + publicKey + } + } + ` + }).catch(reason => { debug(`serveUser User fetch error: ${reason}`) }) + + if (result.data && Array.isArray(result.data.User) && result.data.User.length > 0) { + const publicKey = result.data.User[0].publicKey + const actor = createActor(name, publicKey) + debug(`actor = ${JSON.stringify(actor, null, 2)}`) + debug(`accepts json = ${req.accepts(['application/activity+json', 'application/ld+json', 'application/json'])}`) + if (req.accepts(['application/activity+json', 'application/ld+json', 'application/json'])) { + return res.json(actor) + } else if (req.accepts('text/html')) { + // TODO show user's profile page instead of the actor object + /* const outbox = JSON.parse(result.outbox) + const posts = outbox.orderedItems.filter((el) => { return el.object.type === 'Note'}) + const actor = result.actor + debug(posts) */ + // res.render('user', { user: actor, posts: JSON.stringify(posts)}) + return res.json(actor) + } + } else { + debug(`error getting publicKey for actor ${name}`) + next() + } +} diff --git a/src/index.js b/src/index.js index f594cb7f7..01063f573 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,5 @@ import createServer from './server' +import ActiviyPub from './activitypub/ActivityPub' const serverConfig = { port: process.env.GRAPHQL_PORT || 4000 @@ -12,4 +13,5 @@ const server = createServer() server.start(serverConfig, options => { /* eslint-disable-next-line no-console */ console.log(`Server ready at ${process.env.GRAPHQL_URI} 🚀`) + ActiviyPub.init(server) }) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 55b181bc9..9f3864dfe 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -1,8 +1,16 @@ import createOrUpdateLocations from './nodes/locations' +import { generateRsaKeyPair } from '../activitypub/security' +import dotenv from 'dotenv' +import { resolve } from 'path' + +dotenv.config({ path: resolve('src', 'activitypub', '.env') }) export default { Mutation: { CreateUser: async (resolve, root, args, context, info) => { + const keys = generateRsaKeyPair() + Object.assign(args, keys) + args.actorId = `${process.env.ACTIVITYPUB_URI}/activitypub/users/${args.slug}` const result = await resolve(root, args, context, info) await createOrUpdateLocations(args.id, args.locationName, context.driver) return result diff --git a/src/schema.graphql b/src/schema.graphql index 55f23d5ca..3626dd3c2 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -77,6 +77,7 @@ type Location { type User { id: ID! + actorId: String name: String email: String slug: String @@ -85,6 +86,8 @@ type User { deleted: Boolean disabled: Boolean role: UserGroupEnum + publicKey: String + privateKey: String location: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l") locationName: String diff --git a/test/features/activity-article.feature.disable b/test/features/activity-article.feature.disable new file mode 100644 index 000000000..858f85473 --- /dev/null +++ b/test/features/activity-article.feature.disable @@ -0,0 +1,30 @@ +Feature: Send and receive Articles + I want to send and receive article's via ActivityPub + + Background: + Given our own server runs at "http://localhost:4100" + And we have the following users in our database: + | Slug | + | marvin | + | max | + + Scenario: Send an article to a user inbox and make sure it's added to the inbox + When I send a POST request with the following activity to "/activitypub/users/max/inbox": + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://aronda.org/users/marvin/status/lka7dfzkjn2398hsfd", + "type": "Create", + "actor": "https://aronda.org/users/marvin", + "object": { + "id": "https://aronda.org/users/marvin/status/kljsdfg9843jknsdf", + "type": "Article", + "published": "2019-02-07T19:37:55.002Z", + "attributedTo": "https://aronda.org/users/marvin", + "content": "Hi John, how are you?", + "to": "https://localhost:4100/activitypub/users/max" + } + } + """ + Then I expect the status code to be 200 + And the post with id "kljsdfg9843jknsdf" to be created diff --git a/test/features/activity-delete.feature.disable b/test/features/activity-delete.feature.disable new file mode 100644 index 000000000..9d671500f --- /dev/null +++ b/test/features/activity-delete.feature.disable @@ -0,0 +1,28 @@ +Feature: Delete an object + I want to delete objects + + Background: + Given our own server runs at "http://localhost:4100" + And we have the following users in our database: + | Slug | + | bernd-das-brot| + + Scenario: Deleting a post (Article Object) + When I send a POST request with the following activity to "/activitypub/users/bernd-das-brot/inbox": + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4100/users/karl-heinz/status/a4DJ2afdg323v32641vna42lkj685kasd2", + "type": "Delete", + "object": { + "id": "https://aronda.org/users/marvin/status/kljsdfg9843jknsdf", + "type": "Article", + "published": "2019-02-07T19:37:55.002Z", + "attributedTo": "https://aronda.org/users/marvin", + "content": "Hi John, how are you?", + "to": "https://localhost:4100/activitypub/users/max" + } + } + """ + Then I expect the status code to be 200 + And the object is removed from the outbox collection of "karl-heinz" diff --git a/test/features/activity-follow.feature b/test/features/activity-follow.feature new file mode 100644 index 000000000..0797279d8 --- /dev/null +++ b/test/features/activity-follow.feature @@ -0,0 +1,51 @@ +Feature: Follow a user + I want to be able to follow a user on another instance. + Also if I do not want to follow a previous followed user anymore, + I want to undo the follow. + + Background: + Given our own server runs at "http://localhost:4123" + And we have the following users in our database: + | Slug | + | karl-heinz | + | peter-lustiger | + + Scenario: Send a follow to a user inbox and make sure it's added to the right followers collection + When I send a POST request with the following activity to "/activitypub/users/peter-lustiger/inbox": + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4123/activitypub/users/bob-der-baumeister/status/83J23549sda1k72fsa4567na42312455kad83", + "type": "Follow", + "actor": "http://localhost:4123/activitypub/users/bob-der-baumeister", + "object": "http://localhost:4123/activitypub/users/peter-lustiger" + } + """ + Then I expect the status code to be 200 + And the follower is added to the followers collection of "peter-lustiger" + """ + https://localhost:4123/activitypub/users/bob-der-baumeister + """ + + Scenario: Send an undo activity to revert the previous follow activity + When I send a POST request with the following activity to "/activitypub/users/bob-der-baumeister/inbox": + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4123/activitypub/users/peter-lustiger/status/a4DJ2afdg323v32641vna42lkj685kasd2", + "type": "Undo", + "actor": "http://localhost:4123/activitypub/users/peter-lustiger", + "object": { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4123/activitypub/users/bob-der-baumeister/status/83J23549sda1k72fsa4567na42312455kad83", + "type": "Follow", + "actor": "http://localhost:4123/activitypub/users/bob-der-baumeister", + "object": "http://localhost:4123/activitypub/users/peter-lustiger" + } + } + """ + Then I expect the status code to be 200 + And the follower is removed from the followers collection of "peter-lustiger" + """ + https://localhost:4123/activitypub/users/bob-der-baumeister + """ diff --git a/test/features/collection.feature b/test/features/collection.feature new file mode 100644 index 000000000..536d3aa2d --- /dev/null +++ b/test/features/collection.feature @@ -0,0 +1,101 @@ +Feature: Receiving collections + As a member of the Fediverse I want to be able of fetching collections + + Background: + Given our own server runs at "http://localhost:4123" + And we have the following users in our database: + | Slug | + | renate-oberdorfer | + + Scenario: Send a request to the outbox URI of peter-lustig and expect a ordered collection + When I send a GET request to "/activitypub/users/renate-oberdorfer/outbox" + Then I expect the status code to be 200 + And I receive the following json: + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4123/activitypub/users/renate-oberdorfer/outbox", + "summary": "renate-oberdorfers outbox collection", + "type": "OrderedCollection", + "first": "https://localhost:4123/activitypub/users/renate-oberdorfer/outbox?page=true", + "totalItems": 0 + } + """ + + Scenario: Send a request to the following URI of peter-lustig and expect a ordered collection + When I send a GET request to "/activitypub/users/renate-oberdorfer/following" + Then I expect the status code to be 200 + And I receive the following json: + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4123/activitypub/users/renate-oberdorfer/following", + "summary": "renate-oberdorfers following collection", + "type": "OrderedCollection", + "first": "https://localhost:4123/activitypub/users/renate-oberdorfer/following?page=true", + "totalItems": 0 + } + """ + + Scenario: Send a request to the followers URI of peter-lustig and expect a ordered collection + When I send a GET request to "/activitypub/users/renate-oberdorfer/followers" + Then I expect the status code to be 200 + And I receive the following json: + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4123/activitypub/users/renate-oberdorfer/followers", + "summary": "renate-oberdorfers followers collection", + "type": "OrderedCollection", + "first": "https://localhost:4123/activitypub/users/renate-oberdorfer/followers?page=true", + "totalItems": 0 + } + """ + + Scenario: Send a request to the outbox URI of peter-lustig and expect a paginated outbox collection + When I send a GET request to "/activitypub/users/renate-oberdorfer/outbox?page=true" + Then I expect the status code to be 200 + And I receive the following json: + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4123/activitypub/users/renate-oberdorfer/outbox?page=true", + "summary": "renate-oberdorfers outbox collection", + "type": "OrderedCollectionPage", + "totalItems": 0, + "partOf": "https://localhost:4123/activitypub/users/renate-oberdorfer/outbox", + "orderedItems": [] + } + """ + + Scenario: Send a request to the following URI of peter-lustig and expect a paginated following collection + When I send a GET request to "/activitypub/users/renate-oberdorfer/following?page=true" + Then I expect the status code to be 200 + And I receive the following json: + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4123/activitypub/users/renate-oberdorfer/following?page=true", + "summary": "renate-oberdorfers following collection", + "type": "OrderedCollectionPage", + "totalItems": 0, + "partOf": "https://localhost:4123/activitypub/users/renate-oberdorfer/following", + "orderedItems": [] + } + """ + + Scenario: Send a request to the followers URI of peter-lustig and expect a paginated followers collection + When I send a GET request to "/activitypub/users/renate-oberdorfer/followers?page=true" + Then I expect the status code to be 200 + And I receive the following json: + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4123/activitypub/users/renate-oberdorfer/followers?page=true", + "summary": "renate-oberdorfers followers collection", + "type": "OrderedCollectionPage", + "totalItems": 0, + "partOf": "https://localhost:4123/activitypub/users/renate-oberdorfer/followers", + "orderedItems": [] + } + """ diff --git a/test/features/support/steps.js b/test/features/support/steps.js new file mode 100644 index 000000000..454db0e31 --- /dev/null +++ b/test/features/support/steps.js @@ -0,0 +1,125 @@ +// features/support/steps.js +import { Given, When, Then, AfterAll } from 'cucumber' +import { expect } from 'chai' +// import { client } from '../../../src/activitypub/apollo-client' +import { GraphQLClient } from 'graphql-request' +import Factory from '../../../src/seed/factories' +import { host } from '../../../src/jest/helpers' +const debug = require('debug')('ea:test:steps') + +const factory = Factory() +const client = new GraphQLClient(host) + +function createUser (slug) { + debug(`creating user ${slug}`) + return factory.create('User', { + name: slug, + email: 'example@test.org', + password: '1234' + }) + // await login({ email: 'example@test.org', password: '1234' }) +} + +AfterAll('Clean up the test data', function () { + debug('All the tests are done! Deleting test data') +}) + +Given('our own server runs at {string}', function (string) { + // just documenation +}) + +Given('we have the following users in our database:', async function (dataTable) { + await Promise.all(dataTable.hashes().map((user) => { + return createUser(user.Slug) + })) +}) + +When('I send a GET request to {string}', async function (pathname) { + const response = await this.get(pathname) + this.lastContentType = response.lastContentType + + this.lastResponses.push(response.lastResponse) + this.statusCode = response.statusCode +}) + +When('I send a POST request with the following activity to {string}:', async function (inboxUrl, activity) { + debug(`inboxUrl = ${inboxUrl}`) + debug(`activity = ${activity}`) + this.lastInboxUrl = inboxUrl + this.lastActivity = activity + const response = await this.post(inboxUrl, activity) + + this.lastResponses.push(response.lastResponse) + this.lastResponse = response.lastResponse + this.statusCode = response.statusCode +}) + +Then('I receive the following json:', function (docString) { + const parsedDocString = JSON.parse(docString) + const parsedLastResponse = JSON.parse(this.lastResponses.shift()) + if (Array.isArray(parsedDocString.orderedItems)) { + parsedDocString.orderedItems.forEach((el) => { + delete el.id + if (el.object) delete el.object.published + }) + parsedLastResponse.orderedItems.forEach((el) => { + delete el.id + if (el.object) delete el.object.published + }) + } + if (parsedDocString.publicKey && parsedDocString.publicKey.publicKeyPem) { + delete parsedDocString.publicKey.publicKeyPem + delete parsedLastResponse.publicKey.publicKeyPem + } + expect(parsedDocString).to.eql(parsedLastResponse) +}) + +Then('I expect the Content-Type to be {string}', function (contentType) { + expect(this.lastContentType).to.equal(contentType) +}) + +Then('I expect the status code to be {int}', function (statusCode) { + expect(this.statusCode).to.equal(statusCode) +}) + +Then('the activity is added to the {string} collection', async function (collectionName) { + const response = await this.get(this.lastInboxUrl.replace('inbox', collectionName) + '?page=true') + debug(`orderedItems = ${JSON.parse(response.lastResponse).orderedItems}`) + expect(JSON.parse(response.lastResponse).orderedItems).to.include(JSON.parse(this.lastActivity).object) +}) + +Then('the follower is added to the followers collection of {string}', async function (userName, follower) { + const response = await this.get(`/activitypub/users/${userName}/followers?page=true`) + const responseObject = JSON.parse(response.lastResponse) + expect(responseObject.orderedItems).to.include(follower) +}) + +Then('the follower is removed from the followers collection of {string}', async function (userName, follower) { + const response = await this.get(`/activitypub/users/${userName}/followers?page=true`) + const responseObject = JSON.parse(response.lastResponse) + expect(responseObject.orderedItems).to.not.include(follower) +}) + +Then('the activity is added to the users inbox collection', async function () { + +}) + +Then('the post with id {string} to be created', async function (id) { + const result = await client.request(` + query { + Post(id: "${id}") { + name + } + } + `) + + expect(result.data.Post).to.be.an('array').that.is.not.empty // eslint-disable-line +}) + +Then('the object is removed from the outbox collection of {string}', (name) => { + +}) + +Then('I send a GET request to {string} and expect a ordered collection', () => { + +}) diff --git a/test/features/webfinger.feature b/test/features/webfinger.feature new file mode 100644 index 000000000..e7d1ace04 --- /dev/null +++ b/test/features/webfinger.feature @@ -0,0 +1,65 @@ +Feature: Webfinger discovery + From an external server, e.g. Mastodon + I want to search for an actor alias + In order to follow the actor + + Background: + Given our own server runs at "http://localhost:4100" + And we have the following users in our database: + | Slug | + | peter-lustiger | + + Scenario: Search + When I send a GET request to "/.well-known/webfinger?resource=acct:peter-lustiger@localhost" + Then I receive the following json: + """ + { + "subject": "acct:peter-lustiger@localhost:4123", + "links": [ + { + "rel": "self", + "type": "application/activity+json", + "href": "https://localhost:4123/users/peter-lustiger" + } + ] + } + """ + And I expect the Content-Type to be "application/jrd+json; charset=utf-8" + + Scenario: User does not exist + When I send a GET request to "/.well-known/webfinger?resource=acct:nonexisting@localhost" + Then I receive the following json: + """ + { + "error": "No record found for nonexisting@localhost." + } + """ + + Scenario: Receiving an actor object + When I send a GET request to "/activitypub/users/peter-lustiger" + Then I receive the following json: + """ + { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1" + ], + "id": "https://localhost:4123/activitypub/users/peter-lustiger", + "type": "Person", + "preferredUsername": "peter-lustiger", + "name": "peter-lustiger", + "following": "https://localhost:4123/activitypub/users/peter-lustiger/following", + "followers": "https://localhost:4123/activitypub/users/peter-lustiger/followers", + "inbox": "https://localhost:4123/activitypub/users/peter-lustiger/inbox", + "outbox": "https://localhost:4123/activitypub/users/peter-lustiger/outbox", + "url": "https://localhost:4123/activitypub/@peter-lustiger", + "endpoints": { + "sharedInbox": "https://localhost:4123/activitypub/inbox" + }, + "publicKey": { + "id": "https://localhost:4123/activitypub/users/peter-lustiger#main-key", + "owner": "https://localhost:4123/activitypub/users/peter-lustiger", + "publicKeyPem": "adglkjlk89235kjn8obn2384f89z5bv9..." + } + } + """ diff --git a/test/features/world.js b/test/features/world.js new file mode 100644 index 000000000..26282f45a --- /dev/null +++ b/test/features/world.js @@ -0,0 +1,58 @@ +// features/support/world.js +import { setWorldConstructor } from 'cucumber' +import request from 'request' +const debug = require('debug')('ea:test:world') + +class CustomWorld { + constructor () { + // webfinger.feature + this.lastResponses = [] + this.lastContentType = null + this.lastInboxUrl = null + this.lastActivity = null + // activity-article.feature.disable + this.statusCode = null + } + get (pathname) { + return new Promise((resolve, reject) => { + request(`http://localhost:4123/${this.replaceSlashes(pathname)}`, { + headers: { + 'Accept': 'application/activity+json' + }}, function (error, response, body) { + if (!error) { + debug(`get response = ${response.headers['content-type']}`) + debug(`body = ${body}`) + resolve({ lastResponse: body, lastContentType: response.headers['content-type'], statusCode: response.statusCode }) + } else { + reject(error) + } + }) + }) + } + + replaceSlashes (pathname) { + return pathname.replace(/^\/+/, '') + } + + post (pathname, activity) { + return new Promise((resolve, reject) => { + request({ + url: `http://localhost:4123/${this.replaceSlashes(pathname)}`, + method: 'POST', + headers: { + 'Content-Type': 'application/activity+json' + }, + body: activity + }, function (error, response, body) { + if (!error) { + debug(`post response = ${response.headers['content-type']}`) + resolve({ lastResponse: body, lastContentType: response.headers['content-type'], statusCode: response.statusCode }) + } else { + reject(error) + } + }) + }) + } +} + +setWorldConstructor(CustomWorld) diff --git a/yarn.lock b/yarn.lock index 2fe610fee..fc6697b2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -291,6 +291,14 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" +"@babel/plugin-proposal-throw-expressions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-throw-expressions/-/plugin-proposal-throw-expressions-7.2.0.tgz#2d9e452d370f139000e51db65d0a85dc60c64739" + integrity sha512-adsydM8DQF4i5DLNO4ySAU5VtHTPewOtNBV3u7F4lNMPADFF9bWQ+iDtUUe8+033cYCUz+bFlQdXQJmJOwoLpw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-throw-expressions" "^7.2.0" + "@babel/plugin-proposal-unicode-property-regex@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz#abe7281fe46c95ddc143a65e5358647792039520" @@ -328,6 +336,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-throw-expressions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-throw-expressions/-/plugin-syntax-throw-expressions-7.2.0.tgz#79001ee2afe1b174b1733cdc2fc69c9a46a0f1f8" + integrity sha512-ngwynuqu1Rx0JUS9zxSDuPgW1K8TyVZCi2hHehrL4vyjqE7RGoNHWlZsS7KQT2vw9Yjk4YLa0+KldBXTRdPLRg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-arrow-functions@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" @@ -558,6 +573,14 @@ core-js "^2.5.7" regenerator-runtime "^0.11.1" +"@babel/polyfill@^7.2.3": + version "7.2.5" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.2.5.tgz#6c54b964f71ad27edddc567d065e57e87ed7fa7d" + integrity sha512-8Y/t3MWThtMLYr0YNC/Q76tqN1w30+b0uQMeFUYauG2UGTR19zyUtFrAzT23zNtBxPp+LbE5E/nwV/q/r3y6ug== + dependencies: + core-js "^2.5.7" + regenerator-runtime "^0.12.0" + "@babel/preset-env@~7.3.1": version "7.3.1" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.1.tgz#389e8ca6b17ae67aaf9a2111665030be923515db" @@ -876,6 +899,33 @@ acorn@^6.0.1, acorn@^6.0.2: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== +activitystrea.ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/activitystrea.ms/-/activitystrea.ms-2.1.3.tgz#553548733e367dc0b6a7badc25fa6f8996cd80c3" + integrity sha512-iiG5g5fYgfdaaqqFPaFIZC/KX8/4mOWkvniK+BNwJY6XDDKdIu56wmc9r0x1INHVnbFOTGuM8mZEntaM3I+YXw== + dependencies: + activitystreams-context "^3.0.0" + jsonld "^0.4.11" + jsonld-signatures "^1.1.5" + moment "^2.17.1" + readable-stream "^2.2.3" + reasoner "2.0.0" + rfc5646 "^2.0.0" + vocabs-as "^3.0.0" + vocabs-asx "^0.11.1" + vocabs-interval "^0.11.1" + vocabs-ldp "^0.1.0" + vocabs-owl "^0.11.1" + vocabs-rdf "^0.11.1" + vocabs-rdfs "^0.11.1" + vocabs-social "^0.11.1" + vocabs-xsd "^0.11.1" + +activitystreams-context@>=3.0.0, activitystreams-context@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/activitystreams-context/-/activitystreams-context-3.1.0.tgz#28334e129f17cfb937e8c702c52c1bcb1d2830c7" + integrity sha512-KBQ+igwf1tezMXGVw5MvRSEm0gp97JI1hTZ45I6MEkWv25lEgNoA9L6wqfaOiCX8wnMRWw9pwRsPZKypdtxAtg== + ajv@^6.5.3, ajv@^6.5.5, ajv@^6.6.1: version "6.6.1" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.1.tgz#6360f5ed0d80f232cc2b294c362d5dc2e538dd61" @@ -920,6 +970,11 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1295,6 +1350,15 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +assertion-error-formatter@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/assertion-error-formatter/-/assertion-error-formatter-2.0.1.tgz#6bbdffaec8e2fa9e2b0eb158bfe353132d7c0a9b" + integrity sha512-cjC3jUCh9spkroKue5PDSKH5RFQ/KNuZJhk3GwHYmB/8qqETxLOmMdLH+ohi/VukNzxDlMvIe7zScvLoOdhb6Q== + dependencies: + diff "^3.0.0" + pad-right "^0.2.2" + repeat-string "^1.6.1" + assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -1337,6 +1401,11 @@ async-retry@^1.2.1: dependencies: retry "0.12.0" +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + async@^2.5.0, async@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" @@ -1485,11 +1554,49 @@ bcryptjs@~2.4.3: resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= +becke-ch--regex--s0-0-v1--base--pl--lib@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/becke-ch--regex--s0-0-v1--base--pl--lib/-/becke-ch--regex--s0-0-v1--base--pl--lib-1.4.0.tgz#429ceebbfa5f7e936e78d73fbdc7da7162b20e20" + integrity sha1-Qpzuu/pffpNueNc/vcfacWKyDiA= + binary-extensions@^1.0.0: version "1.12.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== +bitcore-lib@^0.13.7: + version "0.13.19" + resolved "https://registry.yarnpkg.com/bitcore-lib/-/bitcore-lib-0.13.19.tgz#48af1e9bda10067c1ab16263472b5add2000f3dc" + integrity sha1-SK8em9oQBnwasWJjRyta3SAA89w= + dependencies: + bn.js "=2.0.4" + bs58 "=2.0.0" + buffer-compare "=1.0.0" + elliptic "=3.0.3" + inherits "=2.0.1" + lodash "=3.10.1" + +"bitcore-message@github:comakery/bitcore-message#dist": + version "1.0.2" + resolved "https://codeload.github.com/comakery/bitcore-message/tar.gz/8799cc327029c3d34fc725f05b2cf981363f6ebf" + dependencies: + bitcore-lib "^0.13.7" + +bluebird@^3.4.1: + version "3.5.3" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" + integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== + +bn.js@=2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-2.0.4.tgz#220a7cd677f7f1bfa93627ff4193776fe7819480" + integrity sha1-Igp81nf38b+pNif/QZN3b+eBlIA= + +bn.js@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-2.2.0.tgz#12162bc2ae71fc40a5626c33438f3a875cd37625" + integrity sha1-EhYrwq5x/EClYmwzQ486h1zTdiU= + body-parser-graphql@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/body-parser-graphql/-/body-parser-graphql-1.1.0.tgz#80a80353c7cb623562fd375750dfe018d75f0f7c" @@ -1555,6 +1662,11 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + browser-process-hrtime@^0.1.2: version "0.1.3" resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" @@ -1576,6 +1688,11 @@ browserslist@^4.3.4: electron-to-chromium "^1.3.86" node-releases "^1.0.5" +bs58@=2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.0.tgz#72b713bed223a0ac518bbda0e3ce3f4817f39eb5" + integrity sha1-crcTvtIjoKxRi72g484/SBfznrU= + bser@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" @@ -1583,6 +1700,11 @@ bser@^2.0.0: dependencies: node-int64 "^0.4.0" +buffer-compare@=1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-compare/-/buffer-compare-1.0.0.tgz#acaa7a966e98eee9fae14b31c39a5f158fb3c4a2" + integrity sha1-rKp6lm6Y7un64Usxw5pfFY+zxKI= + buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" @@ -1794,7 +1916,7 @@ cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" -cli-table3@^0.5.0: +cli-table3@^0.5.0, cli-table3@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== @@ -1860,7 +1982,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.5.0, commander@^2.8.1: +commander@^2.5.0, commander@^2.8.1, commander@^2.9.0: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== @@ -1870,6 +1992,13 @@ commander@~2.17.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== +commander@~2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= + dependencies: + graceful-readlink ">= 1.0.0" + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1973,7 +2102,7 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cors@^2.8.4: +cors@^2.8.4, cors@^2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== @@ -2064,6 +2193,60 @@ cssstyle@^1.0.0: dependencies: cssom "0.3.x" +cucumber-expressions@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/cucumber-expressions/-/cucumber-expressions-6.0.1.tgz#47c9c573781c2ff721d7ad5b2cd1c97f4399ab8e" + integrity sha1-R8nFc3gcL/ch161bLNHJf0OZq44= + dependencies: + becke-ch--regex--s0-0-v1--base--pl--lib "^1.2.0" + +cucumber-tag-expressions@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cucumber-tag-expressions/-/cucumber-tag-expressions-1.1.1.tgz#7f5c7b70009bc2b666591bfe64854578bedee85a" + integrity sha1-f1x7cACbwrZmWRv+ZIVFeL7e6Fo= + +cucumber@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cucumber/-/cucumber-5.1.0.tgz#7b166812c255bec7eac4b0df7007a40d089c895d" + integrity sha512-zrl2VYTBRgvxucwV2GKAvLqcfA1Naeax8plPvWgPEzl3SCJiuPPv3WxBHIRHtPYcEdbHDR6oqLpZP4bJ8UIdmA== + dependencies: + "@babel/polyfill" "^7.2.3" + assertion-error-formatter "^2.0.1" + bluebird "^3.4.1" + cli-table3 "^0.5.1" + colors "^1.1.2" + commander "^2.9.0" + cross-spawn "^6.0.5" + cucumber-expressions "^6.0.0" + cucumber-tag-expressions "^1.1.1" + duration "^0.2.1" + escape-string-regexp "^1.0.5" + figures "2.0.0" + gherkin "^5.0.0" + glob "^7.1.3" + indent-string "^3.1.0" + is-generator "^1.0.2" + is-stream "^1.1.0" + knuth-shuffle-seeded "^1.0.6" + lodash "^4.17.10" + mz "^2.4.0" + progress "^2.0.0" + resolve "^1.3.3" + serialize-error "^3.0.0" + stack-chain "^2.0.0" + stacktrace-js "^2.0.0" + string-argv "0.1.1" + title-case "^2.1.1" + util-arity "^1.0.2" + verror "^1.9.0" + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= + dependencies: + es5-ext "^0.10.9" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -2217,6 +2400,11 @@ diff-sequences@^24.0.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.0.0.tgz#cdf8e27ed20d8b8d3caccb4e0c0d8fe31a173013" integrity sha512-46OkIuVGBBnrC0soO/4LHu5LHGHx0uhP65OVz8XOrAJpqiCB2aVIuESvjI1F9oqebuvY8lekS1pt6TN7vt7qsw== +diff@^3.0.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -2302,6 +2490,14 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= +duration@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/duration/-/duration-0.2.2.tgz#ddf149bc3bc6901150fe9017111d016b3357f529" + integrity sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg== + dependencies: + d "1" + es5-ext "~0.10.46" + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -2327,6 +2523,16 @@ electron-to-chromium@^1.3.86: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.88.tgz#f36ab32634f49ef2b0fdc1e82e2d1cc17feb29e7" integrity sha512-UPV4NuQMKeUh1S0OWRvwg0PI8ASHN9kBC8yDTk1ROXLC85W5GnhTRu/MZu3Teqx3JjlQYuckuHYXSUSgtb3J+A== +elliptic@=3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-3.0.3.tgz#865c9b420bfbe55006b9f969f97a0d2c44966595" + integrity sha1-hlybQgv75VAGuflp+XoNLESWZZU= + dependencies: + bn.js "^2.0.0" + brorand "^1.0.1" + hash.js "^1.0.0" + inherits "^2.0.1" + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -2351,6 +2557,13 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +error-stack-parser@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.2.tgz#4ae8dbaa2bf90a8b450707b9149dcabca135520d" + integrity sha512-E1fPutRDdIj/hohG0UpT5mayXNCxXP9d+snxFsPU9X0XgccOumKraa3juDMwTUyi7+Bu5+mCGagjg4IYeNbOdw== + dependencies: + stackframe "^1.0.4" + es-abstract@^1.4.3: version "1.12.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" @@ -2383,11 +2596,52 @@ es-to-primitive@^1.1.1, es-to-primitive@^1.2.0: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.46: + version "0.10.48" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.48.tgz#9a0b31eeded39e64453bcedf6f9d50bbbfb43850" + integrity sha512-CdRvPlX/24Mj5L4NVxTs4804sxiS2CjVprgCmrgoDkdmjdY4D+ySHa7K3jJf8R40dFg0tIm3z/dk326LrnuSGw== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + next-tick "1" + es6-error@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== +es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-promise@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-2.3.0.tgz#96edb9f2fdb01995822b263dd8aadab6748181bc" + integrity sha1-lu258v2wGZWCKyY92KratnSBgbw= + +es6-promise@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-2.0.1.tgz#ccc4963e679f0ca9fb187c777b9e583d3c7573c2" + integrity sha1-zMSWPmefDKn7GHx3e55YPTx1c8I= + +es6-promise@~4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.0.5.tgz#7882f30adde5b240ccfa7f7d78c548330951ae42" + integrity sha1-eILzCt3lskDM+n99eMVIMwlRrkI= + +es6-symbol@^3.1.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2670,7 +2924,7 @@ expect@^24.1.0: jest-message-util "^24.0.0" jest-regex-util "^24.0.0" -express@^4.0.0, express@^4.16.3: +express@^4.0.0, express@^4.16.3, express@^4.16.4: version "4.16.4" resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== @@ -2786,7 +3040,7 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" -figures@^2.0.0: +figures@2.0.0, figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= @@ -3024,6 +3278,11 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +gherkin@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/gherkin/-/gherkin-5.1.0.tgz#684bbb03add24eaf7bdf544f58033eb28fb3c6d5" + integrity sha1-aEu7A63STq9731RPWAM+so+zxtU= + glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -3078,6 +3337,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + 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" @@ -3230,14 +3494,7 @@ graphql-yoga@~1.17.4: graphql-tools "^4.0.0" subscriptions-transport-ws "^0.9.8" -"graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0", graphql@^14.0.2: - version "14.0.2" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.0.2.tgz#7dded337a4c3fd2d075692323384034b357f5650" - integrity sha512-gUC4YYsaiSJT1h40krG3J+USGlwhzNTXSb4IOZljn9ag5Tj+RkoXrWp+Kh7WyE3t1NCfab5kzCuxBIvOMERMXw== - dependencies: - iterall "^1.2.2" - -graphql@~14.1.1: +"graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0", graphql@^14.0.2, graphql@~14.1.1: version "14.1.1" resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.1.1.tgz#d5d77df4b19ef41538d7215d1e7a28834619fac0" integrity sha512-C5zDzLqvfPAgTtP8AUPIt9keDabrdRAqSWjj2OPRKrKxI9Fb65I36s1uCs1UUBFnSWTdO7hyHi7z1ZbwKMKF6Q== @@ -3326,6 +3583,14 @@ has@^1.0.1, has@^1.0.3: dependencies: function-bind "^1.1.1" +hash.js@^1.0.0: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + hasha@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/hasha/-/hasha-3.0.0.tgz#52a32fab8569d41ca69a61ff1a214f8eb7c8bd39" @@ -3491,6 +3756,11 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +indent-string@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -3504,6 +3774,11 @@ inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, i resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +inherits@=2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" @@ -3681,6 +3956,11 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.0.0.tgz#038c31b774709641bda678b1f06a4e3227c10b3e" integrity sha512-elzyIdM7iKoFHzcrndIqjYomImhxrFRnGP3galODoII4TB9gI7mZ+FnlLQmmjf27SxHS2gKEeyhX5/+YRS6H9g== +is-generator@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-generator/-/is-generator-1.0.3.tgz#c14c21057ed36e328db80347966c693f886389f3" + integrity sha1-wUwhBX7TbjKNuANHlmxpP4hjifM= + is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -4348,6 +4628,38 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= +jsonld-signatures@^1.1.5: + version "1.2.1" + resolved "https://registry.yarnpkg.com/jsonld-signatures/-/jsonld-signatures-1.2.1.tgz#493df5df9cd3a9f1b1cb296bbd3d081679f20ca8" + integrity sha1-ST3135zTqfGxyylrvT0IFnnyDKg= + dependencies: + async "^1.5.2" + bitcore-message "github:CoMakery/bitcore-message#dist" + commander "~2.9.0" + es6-promise "~4.0.5" + jsonld "0.4.3" + node-forge "~0.6.45" + +jsonld@0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/jsonld/-/jsonld-0.4.3.tgz#0bbc929190064d6650a5af5876e1bfdf0ed288f3" + integrity sha1-C7ySkZAGTWZQpa9YduG/3w7SiPM= + dependencies: + es6-promise "~2.0.1" + pkginfo "~0.3.0" + request "^2.61.0" + xmldom "0.1.19" + +jsonld@^0.4.11: + version "0.4.12" + resolved "https://registry.yarnpkg.com/jsonld/-/jsonld-0.4.12.tgz#a02f205d5341414df1b6d8414f1b967a712073e8" + integrity sha1-oC8gXVNBQU3xtthBTxuWenEgc+g= + dependencies: + es6-promise "^2.0.0" + pkginfo "~0.4.0" + request "^2.61.0" + xmldom "0.1.19" + jsonwebtoken@^8.2.0, jsonwebtoken@~8.5.0: version "8.5.0" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#ebd0ca2a69797816e1c5af65b6c759787252947e" @@ -4420,6 +4732,13 @@ kleur@^3.0.0: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.1.tgz#4f5b313f5fa315432a400f19a24db78d451ede62" integrity sha512-P3kRv+B+Ra070ng2VKQqW4qW7gd/v3iD8sy/zOdcYRsfiD+QBokQNOps/AfP6Hr48cBhIIBFWckB9aO+IZhrWg== +knuth-shuffle-seeded@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/knuth-shuffle-seeded/-/knuth-shuffle-seeded-1.0.6.tgz#01f1b65733aa7540ee08d8b0174164d22081e4e1" + integrity sha1-AfG2VzOqdUDuCNiwF0Fk0iCB5OE= + dependencies: + seed-random "~2.2.0" + latest-version@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" @@ -4571,6 +4890,11 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= +lodash@=3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y= + lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.11: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -4588,6 +4912,11 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + lowercase-keys@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -4735,6 +5064,11 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== +minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -4787,6 +5121,11 @@ mkdirp@^0.5.0, mkdirp@^0.5.1: dependencies: minimist "0.0.8" +moment@^2.17.1: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + moment@^2.22.2: version "2.22.2" resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" @@ -4807,6 +5146,20 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= +mz@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +n3@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/n3/-/n3-0.9.1.tgz#430b547d58dc7381408c45784dd8058171903932" + integrity sha1-QwtUfVjcc4FAjEV4TdgFgXGQOTI= + nan@^2.9.2: version "2.11.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" @@ -4866,11 +5219,23 @@ neo4j-graphql-js@~2.3.1: lodash "^4.17.11" neo4j-driver "^1.7.2" +next-tick@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + node-fetch@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" @@ -4881,6 +5246,11 @@ node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@~2.3.0: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== +node-forge@~0.6.45: + version "0.6.49" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.6.49.tgz#f1ee95d5d74623938fe19d698aa5a26d54d2f60f" + integrity sha1-8e6V1ddGI5OP4Z1piqWibVTS9g8= + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -5299,6 +5669,13 @@ package-json@^4.0.0: registry-url "^3.0.3" semver "^5.1.0" +pad-right@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/pad-right/-/pad-right-0.2.2.tgz#6fbc924045d244f2a2a244503060d3bfc6009774" + integrity sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q= + dependencies: + repeat-string "^1.5.2" + parent-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.0.tgz#df250bdc5391f4a085fb589dad761f5ad6b865b5" @@ -5469,6 +5846,16 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +pkginfo@~0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" + integrity sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE= + +pkginfo@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff" + integrity sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8= + pn@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" @@ -5716,7 +6103,7 @@ readable-stream@1.1.x: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.3.5: +readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.3, readable-stream@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -5754,6 +6141,18 @@ realpath-native@^1.0.0, realpath-native@^1.0.2: dependencies: util.promisify "^1.0.0" +reasoner@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/reasoner/-/reasoner-2.0.0.tgz#6ccf76cb9baf96b82c45ab0bd60211c2aa1b701b" + integrity sha1-bM92y5uvlrgsRasL1gIRwqobcBs= + dependencies: + n3 "^0.9.1" + rfc5646 "^2.0.0" + vocabs-asx "^0.11.1" + vocabs-rdf "^0.11.1" + vocabs-rdfs "^0.11.1" + vocabs-xsd "^0.11.1" + regenerate-unicode-properties@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" @@ -5861,7 +6260,7 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.6.1: +repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -5882,7 +6281,7 @@ request-promise-native@^1.0.5: stealthy-require "^1.1.0" tough-cookie ">=2.3.3" -request@^2.87.0, request@^2.88.0: +request@^2.61.0, request@^2.87.0, request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -5945,7 +6344,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0: +resolve@^1.3.2, resolve@^1.3.3, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== @@ -5970,6 +6369,11 @@ retry@0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= +rfc5646@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/rfc5646/-/rfc5646-2.0.0.tgz#ac0c67b6cd04411ef7c80751ba159d9371ce116c" + integrity sha1-rAxnts0EQR73yAdRuhWdk3HOEWw= + rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -6069,6 +6473,11 @@ scheduler@^0.11.2: loose-envify "^1.1.0" object-assign "^4.1.1" +seed-random@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/seed-random/-/seed-random-2.2.0.tgz#2a9b19e250a817099231a5b99a4daf80b7fbed54" + integrity sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ= + semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" @@ -6105,6 +6514,11 @@ send@0.16.2: range-parser "~1.2.0" statuses "~1.4.0" +serialize-error@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-3.0.0.tgz#80100282b09be33c611536f50033481cb9cc87cf" + integrity sha512-+y3nkkG/go1Vdw+2f/+XUXM1DXX1XcxTl99FfiD/OEPUNw4uo0i6FKABfTAN5ZcgGtjTRZcEbxcE/jtXbEY19A== + serve-static@1.13.2: version "1.13.2" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" @@ -6265,6 +6679,11 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -6348,11 +6767,45 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +stack-chain@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-2.0.0.tgz#d73d1172af89565f07438b5bcc086831b6689b2d" + integrity sha512-GGrHXePi305aW7XQweYZZwiRwR7Js3MWoK/EHzzB9ROdc75nCnjSJVi21rdAGxFl+yCx2L2qdfl5y7NO4lTyqg== + +stack-generator@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.3.tgz#bb74385c67ffc4ccf3c4dee5831832d4e509c8a0" + integrity sha512-kdzGoqrnqsMxOEuXsXyQTmvWXZmG0f3Ql2GDx5NtmZs59sT2Bt9Vdyq0XdtxUi58q/+nxtbF9KOQ9HkV1QznGg== + dependencies: + stackframe "^1.0.4" + stack-utils@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== +stackframe@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.0.4.tgz#357b24a992f9427cba6b545d96a14ed2cbca187b" + integrity sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw== + +stacktrace-gps@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.2.tgz#33f8baa4467323ab2bd1816efa279942ba431ccc" + integrity sha512-9o+nWhiz5wFnrB3hBHs2PTyYrS60M1vvpSzHxwxnIbtY2q9Nt51hZvhrG1+2AxD374ecwyS+IUwfkHRE/2zuGg== + dependencies: + source-map "0.5.6" + stackframe "^1.0.4" + +stacktrace-js@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.0.tgz#776ca646a95bc6c6b2b90776536a7fc72c6ddb58" + integrity sha1-d2ymRqlbxsayuQd2U2p/xyxt21g= + dependencies: + error-stack-parser "^2.0.1" + stack-generator "^2.0.1" + stacktrace-gps "^3.0.1" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -6381,6 +6834,11 @@ streamsearch@0.1.2: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= +string-argv@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.1.1.tgz#66bd5ae3823708eaa1916fa5412703150d4ddfaf" + integrity sha512-El1Va5ehZ0XTj3Ekw4WFidXvTmt9SrC0+eigdojgtJMVtPkF0qbBe9fyNSl9eQf+kUHnTSQxdQYzuHfZy8V+DQ== + string-length@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" @@ -6584,6 +7042,20 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.0" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" + integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= + dependencies: + any-promise "^1.0.0" + throat@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" @@ -6599,6 +7071,14 @@ timed-out@^4.0.0: resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= +title-case@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa" + integrity sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o= + dependencies: + no-case "^2.2.0" + upper-case "^1.0.3" + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -6843,6 +7323,11 @@ update-notifier@^2.5.0: semver-diff "^2.0.0" xdg-basedir "^3.0.0" +upper-case@^1.0.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + uri-js@^4.2.1, uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -6875,6 +7360,11 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +util-arity@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/util-arity/-/util-arity-1.1.0.tgz#59d01af1fdb3fede0ac4e632b0ab5f6ce97c9330" + integrity sha1-WdAa8f2z/t4KxOYysKtfbOl8kzA= + util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -6923,7 +7413,7 @@ vary@^1, vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -verror@1.10.0: +verror@1.10.0, verror@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= @@ -6932,6 +7422,75 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +vocabs-as@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/vocabs-as/-/vocabs-as-3.0.0.tgz#0dd0549cecb331ba4e917d2c5a4e83b146865c23" + integrity sha512-Dfze+B0CYZzhSK12jWvbxaL8/vXPnlzhhqhQTrEVxkGht+qzU4MmSLXSomQrdiSNKokVVtt16tyKoJWBW9TdNQ== + dependencies: + activitystreams-context ">=3.0.0" + vocabs ">=0.11.2" + +vocabs-asx@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/vocabs-asx/-/vocabs-asx-0.11.1.tgz#6667e4e174dc4556722b6cb1b9619fb16491519a" + integrity sha1-Zmfk4XTcRVZyK2yxuWGfsWSRUZo= + dependencies: + vocabs ">=0.11.1" + +vocabs-interval@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/vocabs-interval/-/vocabs-interval-0.11.1.tgz#1c009421f3e88a307aafbb75bfa670ff0f4f6d3c" + integrity sha1-HACUIfPoijB6r7t1v6Zw/w9PbTw= + dependencies: + vocabs ">=0.11.1" + +vocabs-ldp@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/vocabs-ldp/-/vocabs-ldp-0.1.0.tgz#da1728df560471750dfc7050e7e2df1bab901ce6" + integrity sha1-2hco31YEcXUN/HBQ5+LfG6uQHOY= + dependencies: + vocabs ">=0.11.1" + +vocabs-owl@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/vocabs-owl/-/vocabs-owl-0.11.1.tgz#2355bbd27bfc19c5992d98079bbab3d7d65459e9" + integrity sha1-I1W70nv8GcWZLZgHm7qz19ZUWek= + dependencies: + vocabs ">=0.11.1" + +vocabs-rdf@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/vocabs-rdf/-/vocabs-rdf-0.11.1.tgz#c7fa91d83b050ffb7b98ce2c72ab25c6fbcd1194" + integrity sha1-x/qR2DsFD/t7mM4scqslxvvNEZQ= + dependencies: + vocabs ">=0.11.1" + +vocabs-rdfs@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/vocabs-rdfs/-/vocabs-rdfs-0.11.1.tgz#2e2df56ae0de008585b21057570386018da455bf" + integrity sha1-Li31auDeAIWFshBXVwOGAY2kVb8= + dependencies: + vocabs ">=0.11.1" + +vocabs-social@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/vocabs-social/-/vocabs-social-0.11.1.tgz#d28545868cce325ba0c88e394f3de6e03fad85b1" + integrity sha1-0oVFhozOMlugyI45Tz3m4D+thbE= + dependencies: + vocabs ">=0.11.1" + +vocabs-xsd@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/vocabs-xsd/-/vocabs-xsd-0.11.1.tgz#20e201d8fd0fd330d6650d9061fda60baae6cd6c" + integrity sha1-IOIB2P0P0zDWZQ2QYf2mC6rmzWw= + dependencies: + vocabs ">=0.11.1" + +vocabs@>=0.11.1, vocabs@>=0.11.2: + version "0.11.2" + resolved "https://registry.yarnpkg.com/vocabs/-/vocabs-0.11.2.tgz#8944b40f11d415f07db6e259804024a1dbfaa4d4" + integrity sha512-OIon2MWA21ZO42UBsTa5DuMsk5zv72DxMdQNvLsPN1M9GrjVTovn3LgWUZdPVnKBpdWhqWV7Mfbq/Sh0vkHIBw== + w3c-hr-time@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" @@ -7125,6 +7684,11 @@ xmlbuilder@~9.0.1: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= +xmldom@0.1.19: + version "0.1.19" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.19.tgz#631fc07776efd84118bf25171b37ed4d075a0abc" + integrity sha1-Yx/Ad3bv2EEYvyUXGzftTQdaCrw= + xtend@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" From c4f15e626d433ca2f740d2bf5497909407b604a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 26 Feb 2019 00:46:14 +0100 Subject: [PATCH 411/554] Fix lint and unblock port 4001 We have to specify the `yarn run test:cypress` in `.travis.yml` in the Nitro-Web repo. --- docker-compose.travis.yml | 1 - src/seed/factories/index.js | 28 ++++++++++++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml index 3d577e638..27f53dfef 100644 --- a/docker-compose.travis.yml +++ b/docker-compose.travis.yml @@ -15,4 +15,3 @@ services: build: context: . target: builder - command: yarn run test:cypress diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 752ae3369..d9bbd700c 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -1,14 +1,14 @@ import { GraphQLClient, request } from 'graphql-request' import { getDriver } from '../../bootstrap/neo4j' -import createBadge from './badges.js' -import createUser from './users.js' +import createBadge from './badges.js' +import createUser from './users.js' import createOrganization from './organizations.js' -import createPost from './posts.js' -import createComment from './comments.js' -import createCategory from './categories.js' -import createTag from './tags.js' -import createReport from './reports.js' +import createPost from './posts.js' +import createComment from './comments.js' +import createCategory from './categories.js' +import createTag from './tags.js' +import createReport from './reports.js' export const seedServerHost = 'http://127.0.0.1:4001' @@ -25,14 +25,14 @@ const authenticatedHeaders = async ({ email, password }, host) => { } } const factories = { - 'Badge': createBadge, - 'User': createUser, + 'Badge': createBadge, + 'User': createUser, 'Organization': createOrganization, - 'Post': createPost, - 'Comment': createComment, - 'Category': createCategory, - 'Tag': createTag, - 'Report': createReport + 'Post': createPost, + 'Comment': createComment, + 'Category': createCategory, + 'Tag': createTag, + 'Report': createReport } export const cleanDatabase = async (options = {}) => { From 706fccc7332e07babac0a077dc25d28eb107306f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 26 Feb 2019 12:16:27 +0100 Subject: [PATCH 412/554] Fix Cypress with a dedicated docker-compose.yml --- docker-compose.cypress.yml | 18 ++++++++++++++++++ docker-compose.travis.yml | 3 --- 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 docker-compose.cypress.yml diff --git a/docker-compose.cypress.yml b/docker-compose.cypress.yml new file mode 100644 index 000000000..3d577e638 --- /dev/null +++ b/docker-compose.cypress.yml @@ -0,0 +1,18 @@ +version: "3.7" + +services: + neo4j: + environment: + - NEO4J_AUTH=none + ports: + - 7687:7687 + - 7474:7474 + backend: + ports: + - 4001:4001 + - 4123:4123 + image: humanconnection/nitro-backend:builder + build: + context: . + target: builder + command: yarn run test:cypress diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml index 27f53dfef..e1998f6dd 100644 --- a/docker-compose.travis.yml +++ b/docker-compose.travis.yml @@ -8,9 +8,6 @@ services: - 7687:7687 - 7474:7474 backend: - ports: - - 4001:4001 - - 4123:4123 image: humanconnection/nitro-backend:builder build: context: . From d0df4e8df0d2620b9b375c9a77340c45c59ec184 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 26 Feb 2019 15:16:38 +0000 Subject: [PATCH 413/554] Bump @babel/core from 7.3.3 to 7.3.4 Bumps [@babel/core](https://github.com/babel/babel) from 7.3.3 to 7.3.4. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.3.3...v7.3.4) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 58 ++++++++++++++++++++++++++-------------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 39c9c14c6..65db47e1f 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ }, "devDependencies": { "@babel/cli": "~7.2.3", - "@babel/core": "~7.3.3", + "@babel/core": "~7.3.4", "@babel/node": "~7.2.2", "@babel/preset-env": "~7.3.1", "@babel/register": "~7.0.0", diff --git a/yarn.lock b/yarn.lock index 2fe610fee..34884e22b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38,18 +38,18 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.1.0", "@babel/core@~7.3.3": - version "7.3.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.3.tgz#d090d157b7c5060d05a05acaebc048bd2b037947" - integrity sha512-w445QGI2qd0E0GlSnq6huRZWPMmQGCp5gd5ZWS4hagn0EiwzxD5QMFkpchyusAyVC1n27OKXzQ0/88aVU9n4xQ== +"@babel/core@^7.1.0", "@babel/core@~7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.4.tgz#921a5a13746c21e32445bf0798680e9d11a6530b" + integrity sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.3.3" + "@babel/generator" "^7.3.4" "@babel/helpers" "^7.2.0" - "@babel/parser" "^7.3.3" + "@babel/parser" "^7.3.4" "@babel/template" "^7.2.2" - "@babel/traverse" "^7.2.2" - "@babel/types" "^7.3.3" + "@babel/traverse" "^7.3.4" + "@babel/types" "^7.3.4" convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -58,12 +58,12 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.2.2", "@babel/generator@^7.3.3": - version "7.3.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.3.tgz#185962ade59a52e00ca2bdfcfd1d58e528d4e39e" - integrity sha512-aEADYwRRZjJyMnKN7llGIlircxTCofm3dtV5pmY6ob18MSIuipHpA2yZWkPlycwu5HJcx/pADS3zssd8eY7/6A== +"@babel/generator@^7.0.0", "@babel/generator@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.4.tgz#9aa48c1989257877a9d971296e5b73bfe72e446e" + integrity sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg== dependencies: - "@babel/types" "^7.3.3" + "@babel/types" "^7.3.4" jsesc "^2.5.1" lodash "^4.17.11" source-map "^0.5.0" @@ -253,10 +253,10 @@ lodash "^4.17.10" v8flags "^3.1.1" -"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.2.3", "@babel/parser@^7.3.3": - version "7.3.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.3.tgz#092d450db02bdb6ccb1ca8ffd47d8774a91aef87" - integrity sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg== +"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.4.tgz#a43357e4bbf4b92a437fb9e465c192848287f27c" + integrity sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ== "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.2.0" @@ -636,25 +636,25 @@ "@babel/parser" "^7.2.2" "@babel/types" "^7.2.2" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.2.2": - version "7.2.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8" - integrity sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.3.4.tgz#1330aab72234f8dea091b08c4f8b9d05c7119e06" + integrity sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.2.2" + "@babel/generator" "^7.3.4" "@babel/helper-function-name" "^7.1.0" "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/parser" "^7.2.3" - "@babel/types" "^7.2.2" + "@babel/parser" "^7.3.4" + "@babel/types" "^7.3.4" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.10" + lodash "^4.17.11" -"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.3": - version "7.3.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.3.tgz#6c44d1cdac2a7625b624216657d5bc6c107ab436" - integrity sha512-2tACZ80Wg09UnPg5uGAOUvvInaqLk3l/IAhQzlxLQOIXacr6bMsra5SH6AWw/hIDRCSbCdHP2KzSOD+cT7TzMQ== +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.4.tgz#bf482eaeaffb367a28abbf9357a94963235d90ed" + integrity sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ== dependencies: esutils "^2.0.2" lodash "^4.17.11" From 69bf53e05e2529d7cef21bd816da1c39fc73ce59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 26 Feb 2019 16:28:22 +0100 Subject: [PATCH 414/554] Impplement currentUser query * remove dead code (passport-jwt) * refactor resolves to have a separate folder * currentUser and login have the same response --- package.json | 2 - src/graphql-schema.js | 178 ++--------------------- src/graphql-schema.spec.js | 184 ------------------------ src/jwt/decode.js | 29 ++++ src/jwt/{generateToken.js => encode.js} | 2 +- src/jwt/strategy.js | 42 ------ src/middleware/permissionsMiddleware.js | 3 +- src/resolvers/posts.js | 22 +++ src/resolvers/posts.spec.js | 61 ++++++++ src/resolvers/reports.js | 51 +++++++ src/resolvers/reports.spec.js | 68 +++++++++ src/resolvers/statistics.js | 67 +++++++++ src/resolvers/user_management.js | 52 +++++++ src/resolvers/user_management.spec.js | 183 +++++++++++++++++++++++ src/schema.graphql | 4 +- src/server.js | 27 +--- yarn.lock | 28 +--- 17 files changed, 555 insertions(+), 448 deletions(-) delete mode 100644 src/graphql-schema.spec.js create mode 100644 src/jwt/decode.js rename src/jwt/{generateToken.js => encode.js} (90%) delete mode 100644 src/jwt/strategy.js create mode 100644 src/resolvers/posts.js create mode 100644 src/resolvers/posts.spec.js create mode 100644 src/resolvers/reports.js create mode 100644 src/resolvers/reports.spec.js create mode 100644 src/resolvers/statistics.js create mode 100644 src/resolvers/user_management.js create mode 100644 src/resolvers/user_management.spec.js diff --git a/package.json b/package.json index 39c9c14c6..e313b45d5 100644 --- a/package.json +++ b/package.json @@ -59,8 +59,6 @@ "neo4j-graphql-js": "~2.3.1", "node-fetch": "~2.3.0", "npm-run-all": "~4.1.5", - "passport": "~0.4.0", - "passport-jwt": "~4.0.0", "sanitize-html": "~1.20.0", "slug": "~1.0.0", "trunc-html": "~1.1.2", diff --git a/src/graphql-schema.js b/src/graphql-schema.js index ce84dde36..6d10183c9 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -1,182 +1,22 @@ import fs from 'fs' import path from 'path' -import bcrypt from 'bcryptjs' -import generateJwt from './jwt/generateToken' -import uuid from 'uuid/v4' -import { fixUrl } from './middleware/fixImageUrlsMiddleware' -import { AuthenticationError } from 'apollo-server' -import { neo4jgraphql } from 'neo4j-graphql-js' +import userManagement from './resolvers/user_management.js' +import statistics from './resolvers/statistics.js' +import reports from './resolvers/reports.js' +import posts from './resolvers/posts.js' export const typeDefs = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, 'schema.graphql')) .toString('utf-8') -export const query = (cypher, session) => { - return new Promise((resolve, reject) => { - let data = [] - session - .run(cypher) - .subscribe({ - onNext: function (record) { - let item = {} - record.keys.forEach(key => { - item[key] = record.get(key) - }) - data.push(item) - }, - onCompleted: function () { - session.close() - resolve(data) - }, - onError: function (error) { - reject(error) - } - }) - }) -} -const queryOne = (cypher, session) => { - return new Promise((resolve, reject) => { - query(cypher, session) - .then(res => { - resolve(res.length ? res.pop() : {}) - }) - .catch(err => { - reject(err) - }) - }) -} - export const resolvers = { Query: { - isLoggedIn: (parent, args, { driver, user }) => { - return Boolean(user && user.id) - }, - statistics: async (parent, args, { driver, user }) => { - return new Promise(async (resolve) => { - const session = driver.session() - const queries = { - countUsers: 'MATCH (r:User) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countUsers', - countPosts: 'MATCH (r:Post) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countPosts', - countComments: 'MATCH (r:Comment) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countComments', - countNotifications: 'MATCH (r:Notification) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countNotifications', - countOrganizations: 'MATCH (r:Organization) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countOrganizations', - countProjects: 'MATCH (r:Project) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countProjects', - countInvites: 'MATCH (r:Invite) WHERE r.wasUsed <> true OR NOT exists(r.wasUsed) RETURN COUNT(r) AS countInvites', - countFollows: 'MATCH (:User)-[r:FOLLOWS]->(:User) RETURN COUNT(r) AS countFollows', - countShouts: 'MATCH (:User)-[r:SHOUTED]->(:Post) RETURN COUNT(r) AS countShouts' - } - let data = { - countUsers: (await queryOne(queries.countUsers, session)).countUsers.low, - countPosts: (await queryOne(queries.countPosts, session)).countPosts.low, - countComments: (await queryOne(queries.countComments, session)).countComments.low, - countNotifications: (await queryOne(queries.countNotifications, session)).countNotifications.low, - countOrganizations: (await queryOne(queries.countOrganizations, session)).countOrganizations.low, - countProjects: (await queryOne(queries.countProjects, session)).countProjects.low, - countInvites: (await queryOne(queries.countInvites, session)).countInvites.low, - countFollows: (await queryOne(queries.countFollows, session)).countFollows.low, - countShouts: (await queryOne(queries.countShouts, session)).countShouts.low - } - resolve(data) - }) - } - // usersBySubstring: neo4jgraphql + ...statistics.Query, + ...userManagement.Query }, Mutation: { - signup: async (parent, { email, password }, { req }) => { - // if (data[email]) { - // throw new Error('Another User with same email exists.') - // } - // data[email] = { - // password: await bcrypt.hashSync(password, 10), - // } - - return true - }, - login: async (parent, { email, password }, { driver, req, user }) => { - // if (user && user.id) { - // throw new Error('Already logged in.') - // } - const session = driver.session() - return session.run( - 'MATCH (user:User {email: $userEmail}) ' + - 'RETURN user {.id, .slug, .name, .avatar, .locationName, .about, .email, .password, .role} as user LIMIT 1', { - userEmail: email - }) - .then(async (result) => { - session.close() - const [currentUser] = await result.records.map(function (record) { - return record.get('user') - }) - - if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { - delete currentUser.password - currentUser.avatar = fixUrl(currentUser.avatar) - return Object.assign(currentUser, { - token: generateJwt(currentUser) - }) - } else throw new AuthenticationError('Incorrect email address or password.') - }) - }, - report: async (parent, { resource, description }, { driver, req, user }, resolveInfo) => { - const contextId = uuid() - const session = driver.session() - const data = { - id: contextId, - type: resource.type, - createdAt: (new Date()).toISOString(), - description: resource.description - } - await session.run( - 'CREATE (r:Report $report) ' + - 'RETURN r.id, r.type, r.description', { - report: data - } - ) - let contentType - - switch (resource.type) { - case 'post': - case 'contribution': - contentType = 'Post' - break - case 'comment': - contentType = 'Comment' - break - case 'user': - contentType = 'User' - break - } - - await session.run( - `MATCH (author:User {id: $userId}), (context:${contentType} {id: $resourceId}), (report:Report {id: $contextId}) ` + - 'MERGE (report)<-[:REPORTED]-(author) ' + - 'MERGE (context)<-[:REPORTED]-(report) ' + - 'RETURN context', { - resourceId: resource.id, - userId: user.id, - contextId: contextId - } - ) - session.close() - - // TODO: output Report compatible object - return data - }, - CreatePost: async (object, params, ctx, resolveInfo) => { - const result = await neo4jgraphql(object, params, ctx, resolveInfo, false) - - const session = ctx.driver.session() - await session.run( - 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + - 'MERGE (post)<-[:WROTE]-(author) ' + - 'RETURN author', { - userId: ctx.user.id, - postId: result.id - }) - session.close() - - return result - } - + ...userManagement.Mutation, + ...reports.Mutation, + ...posts.Mutation } } diff --git a/src/graphql-schema.spec.js b/src/graphql-schema.spec.js deleted file mode 100644 index 7aa47835f..000000000 --- a/src/graphql-schema.spec.js +++ /dev/null @@ -1,184 +0,0 @@ -import Factory from './seed/factories' -import { GraphQLClient, request } from 'graphql-request' -import jwt from 'jsonwebtoken' -import { host, login } from './jest/helpers' - -const factory = Factory() - -beforeEach(async () => { - await factory.create('User', { - email: 'test@example.org', - password: '1234' - }) -}) - -afterEach(async () => { - await factory.cleanDatabase() -}) - -describe('isLoggedIn', () => { - describe('unauthenticated', () => { - it('returns false', async () => { - const query = '{ isLoggedIn }' - await expect(request(host, query)).resolves.toEqual({ isLoggedIn: false }) - }) - }) -}) - -describe('login', () => { - const mutation = (params) => { - const { email, password } = params - return ` - mutation { - login(email:"${email}", password:"${password}"){ - token - } - }` - } - - describe('ask for a `token`', () => { - describe('with valid email/password combination', () => { - it('responds with a JWT token', async () => { - const data = await request(host, mutation({ - email: 'test@example.org', - password: '1234' - })) - const { token } = data.login - jwt.verify(token, process.env.JWT_SECRET, (err, data) => { - expect(data.email).toEqual('test@example.org') - expect(err).toBeNull() - }) - }) - }) - - describe('with a valid email but incorrect password', () => { - it('responds with "Incorrect email address or password."', async () => { - await expect( - request(host, mutation({ - email: 'test@example.org', - password: 'wrong' - })) - ).rejects.toThrow('Incorrect email address or password.') - }) - }) - - describe('with a non-existing email', () => { - it('responds with "Incorrect email address or password."', async () => { - await expect( - request(host, mutation({ - email: 'non-existent@example.org', - password: 'wrong' - })) - ).rejects.toThrow('Incorrect email address or password.') - }) - }) - }) -}) - -describe('CreatePost', () => { - describe('unauthenticated', () => { - let client - it('throws authorization error', async () => { - client = new GraphQLClient(host) - await expect(client.request(`mutation { - CreatePost( - title: "I am a post", - content: "Some content" - ) { slug } - }`)).rejects.toThrow('Not Authorised') - }) - - describe('authenticated', () => { - let headers - let response - beforeEach(async () => { - headers = await login({ email: 'test@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - response = await client.request(`mutation { - CreatePost( - title: "A title", - content: "Some content" - ) { title, content } - }`, { headers }) - }) - - it('creates a post', () => { - expect(response).toEqual({ CreatePost: { title: 'A title', content: 'Some content' } }) - }) - - it('assigns the authenticated user as author', async () => { - const { User } = await client.request(`{ - User(email:"test@example.org") { - contributions { - title - } - } - }`, { headers }) - expect(User).toEqual([ { contributions: [ { title: 'A title' } ] } ]) - }) - }) - }) -}) - -describe('report', () => { - beforeEach(async () => { - await factory.create('User', { - email: 'test@example.org', - password: '1234' - }) - await factory.create('User', { - id: 'u2', - name: 'abusive-user', - role: 'user', - email: 'abusive-user@example.org' - }) - }) - - afterEach(async () => { - await factory.cleanDatabase() - }) - - describe('unauthenticated', () => { - let client - it('throws authorization error', async () => { - client = new GraphQLClient(host) - await expect( - client.request(`mutation { - report( - description: "I don't like this user", - resource: { - id: "u2", - type: user - } - ) { id, createdAt } - }`) - ).rejects.toThrow('Not Authorised') - }) - - describe('authenticated', () => { - let headers - let response - beforeEach(async () => { - headers = await login({ email: 'test@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - response = await client.request(`mutation { - report( - description: "I don't like this user", - resource: { - id: "u2", - type: user - } - ) { id, createdAt } - }`, - { headers } - ) - }) - it('creates a report', () => { - let { id, createdAt } = response.report - expect(response).toEqual({ - report: { id, createdAt } - }) - }) - }) - }) -}) diff --git a/src/jwt/decode.js b/src/jwt/decode.js new file mode 100644 index 000000000..0ab1e4529 --- /dev/null +++ b/src/jwt/decode.js @@ -0,0 +1,29 @@ +import jwt from 'jsonwebtoken' + +export default async (driver, authorizationHeader) => { + if (!authorizationHeader) return null + const token = authorizationHeader.replace('Bearer ', '') + let id = null + try { + const decoded = await jwt.verify(token, process.env.JWT_SECRET) + id = decoded.sub + } catch { + return null + } + const session = driver.session() + const query = ` + MATCH (user:User {id: {id} }) + RETURN user {.id, .slug, .name, .avatar, .email, .role} as user + LIMIT 1 + ` + const result = await session.run(query, { id }) + session.close() + const [currentUser] = await result.records.map((record) => { + return record.get('user') + }) + if (!currentUser) return null + return { + token, + ...currentUser + } +} diff --git a/src/jwt/generateToken.js b/src/jwt/encode.js similarity index 90% rename from src/jwt/generateToken.js rename to src/jwt/encode.js index 7cbc70330..62e85616b 100644 --- a/src/jwt/generateToken.js +++ b/src/jwt/encode.js @@ -3,7 +3,7 @@ import jwt from 'jsonwebtoken' import ms from 'ms' // Generate an Access Token for the given User ID -export default function generateJwt (user) { +export default function encode (user) { const token = jwt.sign(user, process.env.JWT_SECRET, { expiresIn: ms('1d'), issuer: process.env.GRAPHQL_URI, diff --git a/src/jwt/strategy.js b/src/jwt/strategy.js deleted file mode 100644 index 5b1ea1231..000000000 --- a/src/jwt/strategy.js +++ /dev/null @@ -1,42 +0,0 @@ -import { Strategy } from 'passport-jwt' -import { fixUrl } from '../middleware/fixImageUrlsMiddleware' - -const cookieExtractor = (req) => { - var token = null - if (req && req.cookies) { - token = req.cookies['jwt'] - } - return token -} - -export default (driver) => { - const options = { - jwtFromRequest: cookieExtractor, - secretOrKey: process.env.JWT_SECRET, - issuer: process.env.GRAPHQL_URI, - audience: process.env.CLIENT_URI - } - - return new Strategy(options, - async (JWTPayload, next) => { - const session = driver.session() - const result = await session.run( - 'MATCH (user:User {id: $userId}) ' + - 'RETURN user {.id, .slug, .name, .avatar, .email, .role} as user LIMIT 1', - { - userId: JWTPayload.id - } - ) - session.close() - const [currentUser] = await result.records.map((record) => { - return record.get('user') - }) - - if (currentUser) { - currentUser.avatar = fixUrl(currentUser.avatar) - return next(null, currentUser) - } else { - return next(null, false) - } - }) -} diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 1a3f04ceb..0c6723b4b 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -23,7 +23,8 @@ const isMyOwn = rule({ cache: 'no_cache' })(async (parent, args, ctx, info) => { // Permissions const permissions = shield({ Query: { - statistics: allow + statistics: allow, + currentUser: allow // fruits: and(isAuthenticated, or(isAdmin, isModerator)), // customers: and(isAuthenticated, isAdmin) }, diff --git a/src/resolvers/posts.js b/src/resolvers/posts.js new file mode 100644 index 000000000..6a8a0c25f --- /dev/null +++ b/src/resolvers/posts.js @@ -0,0 +1,22 @@ +import { neo4jgraphql } from 'neo4j-graphql-js' + +export default { + Mutation: { + CreatePost: async (object, params, ctx, resolveInfo) => { + const result = await neo4jgraphql(object, params, ctx, resolveInfo, false) + + const session = ctx.driver.session() + await session.run( + 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + + 'MERGE (post)<-[:WROTE]-(author) ' + + 'RETURN author', { + userId: ctx.user.id, + postId: result.id + }) + session.close() + + return result + } + + } +} diff --git a/src/resolvers/posts.spec.js b/src/resolvers/posts.spec.js new file mode 100644 index 000000000..a6c1d7e3e --- /dev/null +++ b/src/resolvers/posts.spec.js @@ -0,0 +1,61 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() + +beforeEach(async () => { + await factory.create('User', { + email: 'test@example.org', + password: '1234' + }) +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + +describe('CreatePost', () => { + describe('unauthenticated', () => { + let client + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect(client.request(`mutation { + CreatePost( + title: "I am a post", + content: "Some content" + ) { slug } + }`)).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { + let headers + let response + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + response = await client.request(`mutation { + CreatePost( + title: "A title", + content: "Some content" + ) { title, content } + }`, { headers }) + }) + + it('creates a post', () => { + expect(response).toEqual({ CreatePost: { title: 'A title', content: 'Some content' } }) + }) + + it('assigns the authenticated user as author', async () => { + const { User } = await client.request(`{ + User(email:"test@example.org") { + contributions { + title + } + } + }`, { headers }) + expect(User).toEqual([ { contributions: [ { title: 'A title' } ] } ]) + }) + }) + }) +}) diff --git a/src/resolvers/reports.js b/src/resolvers/reports.js new file mode 100644 index 000000000..c471d7b7a --- /dev/null +++ b/src/resolvers/reports.js @@ -0,0 +1,51 @@ +import uuid from 'uuid/v4' + +export default { + Mutation: { + report: async (parent, { resource, description }, { driver, req, user }, resolveInfo) => { + const contextId = uuid() + const session = driver.session() + const data = { + id: contextId, + type: resource.type, + createdAt: (new Date()).toISOString(), + description: resource.description + } + await session.run( + 'CREATE (r:Report $report) ' + + 'RETURN r.id, r.type, r.description', { + report: data + } + ) + let contentType + + switch (resource.type) { + case 'post': + case 'contribution': + contentType = 'Post' + break + case 'comment': + contentType = 'Comment' + break + case 'user': + contentType = 'User' + break + } + + await session.run( + `MATCH (author:User {id: $userId}), (context:${contentType} {id: $resourceId}), (report:Report {id: $contextId}) ` + + 'MERGE (report)<-[:REPORTED]-(author) ' + + 'MERGE (context)<-[:REPORTED]-(report) ' + + 'RETURN context', { + resourceId: resource.id, + userId: user.id, + contextId: contextId + } + ) + session.close() + + // TODO: output Report compatible object + return data + } + } +} diff --git a/src/resolvers/reports.spec.js b/src/resolvers/reports.spec.js new file mode 100644 index 000000000..253cdadcc --- /dev/null +++ b/src/resolvers/reports.spec.js @@ -0,0 +1,68 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() + +describe('report', () => { + beforeEach(async () => { + await factory.create('User', { + email: 'test@example.org', + password: '1234' + }) + await factory.create('User', { + id: 'u2', + name: 'abusive-user', + role: 'user', + email: 'abusive-user@example.org' + }) + }) + + afterEach(async () => { + await factory.cleanDatabase() + }) + + describe('unauthenticated', () => { + let client + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect( + client.request(`mutation { + report( + description: "I don't like this user", + resource: { + id: "u2", + type: user + } + ) { id, createdAt } + }`) + ).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { + let headers + let response + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + response = await client.request(`mutation { + report( + description: "I don't like this user", + resource: { + id: "u2", + type: user + } + ) { id, createdAt } + }`, + { headers } + ) + }) + it('creates a report', () => { + let { id, createdAt } = response.report + expect(response).toEqual({ + report: { id, createdAt } + }) + }) + }) + }) +}) diff --git a/src/resolvers/statistics.js b/src/resolvers/statistics.js new file mode 100644 index 000000000..17c4be956 --- /dev/null +++ b/src/resolvers/statistics.js @@ -0,0 +1,67 @@ +export const query = (cypher, session) => { + return new Promise((resolve, reject) => { + let data = [] + session + .run(cypher) + .subscribe({ + onNext: function (record) { + let item = {} + record.keys.forEach(key => { + item[key] = record.get(key) + }) + data.push(item) + }, + onCompleted: function () { + session.close() + resolve(data) + }, + onError: function (error) { + reject(error) + } + }) + }) +} +const queryOne = (cypher, session) => { + return new Promise((resolve, reject) => { + query(cypher, session) + .then(res => { + resolve(res.length ? res.pop() : {}) + }) + .catch(err => { + reject(err) + }) + }) +} + +export default { + Query: { + statistics: async (parent, args, { driver, user }) => { + return new Promise(async (resolve) => { + const session = driver.session() + const queries = { + countUsers: 'MATCH (r:User) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countUsers', + countPosts: 'MATCH (r:Post) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countPosts', + countComments: 'MATCH (r:Comment) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countComments', + countNotifications: 'MATCH (r:Notification) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countNotifications', + countOrganizations: 'MATCH (r:Organization) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countOrganizations', + countProjects: 'MATCH (r:Project) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countProjects', + countInvites: 'MATCH (r:Invite) WHERE r.wasUsed <> true OR NOT exists(r.wasUsed) RETURN COUNT(r) AS countInvites', + countFollows: 'MATCH (:User)-[r:FOLLOWS]->(:User) RETURN COUNT(r) AS countFollows', + countShouts: 'MATCH (:User)-[r:SHOUTED]->(:Post) RETURN COUNT(r) AS countShouts' + } + let data = { + countUsers: (await queryOne(queries.countUsers, session)).countUsers.low, + countPosts: (await queryOne(queries.countPosts, session)).countPosts.low, + countComments: (await queryOne(queries.countComments, session)).countComments.low, + countNotifications: (await queryOne(queries.countNotifications, session)).countNotifications.low, + countOrganizations: (await queryOne(queries.countOrganizations, session)).countOrganizations.low, + countProjects: (await queryOne(queries.countProjects, session)).countProjects.low, + countInvites: (await queryOne(queries.countInvites, session)).countInvites.low, + countFollows: (await queryOne(queries.countFollows, session)).countFollows.low, + countShouts: (await queryOne(queries.countShouts, session)).countShouts.low + } + resolve(data) + }) + } + } +} diff --git a/src/resolvers/user_management.js b/src/resolvers/user_management.js new file mode 100644 index 000000000..b0c9d3df5 --- /dev/null +++ b/src/resolvers/user_management.js @@ -0,0 +1,52 @@ +import encode from '../jwt/encode' +import { fixUrl } from '../middleware/fixImageUrlsMiddleware' +import bcrypt from 'bcryptjs' +import { AuthenticationError } from 'apollo-server' + +export default { + Query: { + isLoggedIn: (parent, args, { driver, user }) => { + return Boolean(user && user.id) + }, + currentUser: (parent, args, { user }) => { + return user + } + }, + Mutation: { + signup: async (parent, { email, password }, { req }) => { + // if (data[email]) { + // throw new Error('Another User with same email exists.') + // } + // data[email] = { + // password: await bcrypt.hashSync(password, 10), + // } + + return true + }, + login: async (parent, { email, password }, { driver, req, user }) => { + // if (user && user.id) { + // throw new Error('Already logged in.') + // } + const session = driver.session() + return session.run( + 'MATCH (user:User {email: $userEmail}) ' + + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', { + userEmail: email + }) + .then(async (result) => { + session.close() + const [currentUser] = await result.records.map(function (record) { + return record.get('user') + }) + + if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { + delete currentUser.password + currentUser.avatar = fixUrl(currentUser.avatar) + return Object.assign(currentUser, { + token: encode(currentUser) + }) + } else throw new AuthenticationError('Incorrect email address or password.') + }) + } + } +} diff --git a/src/resolvers/user_management.spec.js b/src/resolvers/user_management.spec.js new file mode 100644 index 000000000..cb12efb2d --- /dev/null +++ b/src/resolvers/user_management.spec.js @@ -0,0 +1,183 @@ +import Factory from '../seed/factories' +import { GraphQLClient, request } from 'graphql-request' +import jwt from 'jsonwebtoken' +import { host, login } from '../jest/helpers' + +const factory = Factory() + +// here is the decoded JWT token: +// { +// role: 'user', +// locationName: null, +// name: 'Jenny Rostock', +// about: null, +// avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/sasha_shestakov/128.jpg', +// id: 'u3', +// email: 'user@example.org', +// slug: 'jenny-rostock', +// iat: 1550846680, +// exp: 1637246680, +// aud: 'http://localhost:3000', +// iss: 'http://localhost:4000', +// sub: 'u3' +// } +const jennyRostocksHeaders = { authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoidXNlciIsImxvY2F0aW9uTmFtZSI6bnVsbCwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJhYm91dCI6bnVsbCwiYXZhdGFyIjoiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3VpZmFjZXMvZmFjZXMvdHdpdHRlci9zYXNoYV9zaGVzdGFrb3YvMTI4LmpwZyIsImlkIjoidTMiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5vcmciLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTU1MDg0NjY4MCwiZXhwIjoxNjM3MjQ2NjgwLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.eZ_mVKas4Wzoc_JrQTEWXyRn7eY64cdIg4vqQ-F_7Jc' } + +beforeEach(async () => { + await factory.create('User', { + avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', + id: 'acb2d923-f3af-479e-9f00-61b12e864666', + name: 'Matilde Hermiston', + slug: 'matilde-hermiston', + role: 'user', + email: 'test@example.org', + password: '1234' + }) +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + +describe('isLoggedIn', () => { + const query = '{ isLoggedIn }' + describe('unauthenticated', () => { + it('returns false', async () => { + await expect(request(host, query)).resolves.toEqual({ isLoggedIn: false }) + }) + }) + + describe('with malformed JWT Bearer token', () => { + const headers = { authorization: 'blah' } + const client = new GraphQLClient(host, { headers }) + + it('returns false', async () => { + await expect(client.request(query)).resolves.toEqual({ isLoggedIn: false }) + }) + }) + + describe('with valid JWT Bearer token', () => { + const client = new GraphQLClient(host, { headers: jennyRostocksHeaders }) + + it('returns false', async () => { + await expect(client.request(query)).resolves.toEqual({ isLoggedIn: false }) + }) + + describe('and a corresponding user in the database', () => { + it('returns true', async () => { + // see the decoded token above + await factory.create('User', { id: 'u3' }) + await expect(client.request(query)).resolves.toEqual({ isLoggedIn: true }) + }) + }) + }) +}) + +describe('currentUser', () => { + const query = `{ + currentUser { + id + slug + name + avatar + email + role + token + } + }` + + describe('unauthenticated', () => { + it('returns null', async () => { + const expected = { currentUser: null } + await expect(request(host, query)).resolves.toEqual(expected) + }) + }) + + describe('with valid JWT Bearer Token', () => { + let client + let headers + + describe('but no corresponding user in the database', () => { + beforeEach(async () => { + client = new GraphQLClient(host, { headers: jennyRostocksHeaders }) + }) + + it('returns null', async () => { + const expected = { currentUser: null } + await expect(client.request(query)).resolves.toEqual(expected) + }) + }) + + describe('and corresponding user in the database', () => { + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('returns the whole user object', async () => { + const expected = { + currentUser: { + avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', + email: 'test@example.org', + id: 'acb2d923-f3af-479e-9f00-61b12e864666', + name: 'Matilde Hermiston', + slug: 'matilde-hermiston', + role: 'user', + token: headers.authorization.replace('Bearer ', '') + } + } + await expect(client.request(query)).resolves.toEqual(expected) + }) + }) + }) +}) + +describe('login', () => { + const mutation = (params) => { + const { email, password } = params + return ` + mutation { + login(email:"${email}", password:"${password}"){ + token + } + }` + } + + describe('ask for a `token`', () => { + describe('with valid email/password combination', () => { + it('responds with a JWT token', async () => { + const data = await request(host, mutation({ + email: 'test@example.org', + password: '1234' + })) + const { token } = data.login + jwt.verify(token, process.env.JWT_SECRET, (err, data) => { + expect(data.email).toEqual('test@example.org') + expect(err).toBeNull() + }) + }) + }) + + describe('with a valid email but incorrect password', () => { + it('responds with "Incorrect email address or password."', async () => { + await expect( + request(host, mutation({ + email: 'test@example.org', + password: 'wrong' + })) + ).rejects.toThrow('Incorrect email address or password.') + }) + }) + + describe('with a non-existing email', () => { + it('responds with "Incorrect email address or password."', async () => { + await expect( + request(host, mutation({ + email: 'non-existent@example.org', + password: 'wrong' + })) + ).rejects.toThrow('Incorrect email address or password.') + }) + }) + }) +}) diff --git a/src/schema.graphql b/src/schema.graphql index 55f23d5ca..4413e1deb 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -1,5 +1,6 @@ type Query { isLoggedIn: Boolean! + currentUser: LoggedInUser statistics: Statistics! } type Mutation { @@ -7,6 +8,7 @@ type Mutation { signup(email: String!, password: String!): Boolean! report(resource: Resource!, description: String): Report } + type LoggedInUser { id: ID! slug: String! @@ -14,8 +16,6 @@ type LoggedInUser { avatar:String! email: String! role: String! - locationName: String - about: String token: String! } diff --git a/src/server.js b/src/server.js index 5867e6952..2fc3af871 100644 --- a/src/server.js +++ b/src/server.js @@ -8,10 +8,7 @@ import middleware from './middleware' import applyDirectives from './bootstrap/directives' import applyScalars from './bootstrap/scalars' import { getDriver } from './bootstrap/neo4j' - -import passport from 'passport' -import jwtStrategy from './jwt/strategy' -import jwt from 'jsonwebtoken' +import decode from './jwt/decode' dotenv.config() // check env and warn @@ -42,20 +39,14 @@ schema = applyScalars(applyDirectives(schema)) const createServer = (options) => { const defaults = { - context: async (req) => { - const payload = { + context: async ({ request }) => { + const authorizationHeader = request.headers.authorization || '' + const user = await decode(driver, authorizationHeader) + return { driver, - user: null, - req: req.request + user, + req: request } - try { - const token = payload.req.headers.authorization.replace('Bearer ', '') - payload.user = await jwt.verify(token, process.env.JWT_SECRET) - } catch (err) { - // nothing - } - - return payload }, schema: schema, debug: debug, @@ -65,11 +56,7 @@ const createServer = (options) => { } const server = new GraphQLServer(Object.assign({}, defaults, options)) - passport.use('jwt', jwtStrategy(driver)) - server.express.use(passport.initialize()) server.express.use(express.static('public')) - - server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) return server } diff --git a/yarn.lock b/yarn.lock index 2fe610fee..5ec9c94a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4348,7 +4348,7 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= -jsonwebtoken@^8.2.0, jsonwebtoken@~8.5.0: +jsonwebtoken@~8.5.0: version "8.5.0" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#ebd0ca2a69797816e1c5af65b6c759787252947e" integrity sha512-IqEycp0znWHNA11TpYi77bVgyBO/pGESDh7Ajhas+u0ttkGkKYIIAjniL4Bw5+oVejVF+SYkaI7XKfwCCyeTuA== @@ -5348,27 +5348,6 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -passport-jwt@~4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" - integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg== - dependencies: - jsonwebtoken "^8.2.0" - passport-strategy "^1.0.0" - -passport-strategy@1.x.x, passport-strategy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" - integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= - -passport@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" - integrity sha1-xQlWkTR71a07XhgCOMORTRbwWBE= - dependencies: - passport-strategy "1.x.x" - pause "0.0.1" - path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" @@ -5423,11 +5402,6 @@ pathval@^1.1.0: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= -pause@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" - integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= - performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" From 577157c5057f3f15fa41bbf4be052e1c0f44f809 Mon Sep 17 00:00:00 2001 From: Armin Date: Tue, 26 Feb 2019 17:11:41 +0100 Subject: [PATCH 415/554] Some fixes + refactoring + logic to receive sharedInboxEndpoints and to add new one --- package.json | 1 + src/activitypub/ActivityPub.js | 27 ++++- src/activitypub/NitroDatasource.js | 44 ++++++-- src/activitypub/routes/inbox.js | 16 +-- src/activitypub/routes/user.js | 4 +- src/activitypub/security/index.js | 160 ++++++++--------------------- src/activitypub/utils/index.js | 69 ++++++++++++- src/jwt/generateToken.js | 2 +- src/schema.graphql | 6 ++ yarn.lock | 4 +- 10 files changed, 192 insertions(+), 141 deletions(-) diff --git a/package.json b/package.json index 799c45085..1aa02fc96 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "sanitize-html": "~1.20.0", "slug": "~1.0.0", "trunc-html": "~1.1.2", + "uuid": "^3.3.2", "wait-on": "~3.2.0" }, "devDependencies": { diff --git a/src/activitypub/ActivityPub.js b/src/activitypub/ActivityPub.js index 57b1a5353..b4d9677c2 100644 --- a/src/activitypub/ActivityPub.js +++ b/src/activitypub/ActivityPub.js @@ -1,4 +1,10 @@ -import { sendAcceptActivity, sendRejectActivity, extractNameFromId, extractDomainFromUrl } from './utils' +import { + sendAcceptActivity, + sendRejectActivity, + extractNameFromId, + extractDomainFromUrl, + signAndSend +} from './utils' import request from 'request' import as from 'activitystrea.ms' import NitroDatasource from './NitroDatasource' @@ -69,6 +75,8 @@ export default class ActivityPub { }, async (err, response, toActorObject) => { if (err) return reject(err) debug(`name = ${toActorName}@${this.domain}`) + // save shared inbox + await this.dataSource.addSharedInboxEndpoint(toActorObject.endpoints.sharedInbox) let followersCollectionPage = await this.dataSource.getFollowersCollectionPage(activity.object) @@ -123,9 +131,9 @@ export default class ActivityPub { case 'Note': const articleObject = activity.object if (articleObject.inReplyTo) { - return this.dataSource.createComment(articleObject) + return this.dataSource.createComment(activity) } else { - return this.dataSource.createPost(articleObject) + return this.dataSource.createPost(activity) } default: } @@ -134,4 +142,17 @@ export default class ActivityPub { handleDeleteActivity (activity) { debug('inside delete') } + + async sendActivity (activity) { + if (Array.isArray(activity.to) && activity.to.includes('https://www.w3.org/ns/activitystreams#Public')) { + delete activity.send + const fromName = extractNameFromId(activity.actor) + const sharedInboxEndpoints = await this.dataSource.getSharedInboxEndpoints() + await Promise.all( + sharedInboxEndpoints.map((el) => { + return signAndSend(activity, fromName, new URL(el).host, el) + }) + ) + } + } } diff --git a/src/activitypub/NitroDatasource.js b/src/activitypub/NitroDatasource.js index 957026a2c..b723fa72c 100644 --- a/src/activitypub/NitroDatasource.js +++ b/src/activitypub/NitroDatasource.js @@ -278,15 +278,17 @@ export default class NitroDatasource { ) } - async createPost (postObject) { + async createPost (activity) { // TODO how to handle the to field? Now the post is just created, doesn't matter who is the recipient // createPost + const postObject = activity.object const title = postObject.summary ? postObject.summary : postObject.content.split(' ').slice(0, 5).join(' ') - const id = extractIdFromActivityId(postObject.id) + const postId = extractIdFromActivityId(postObject.id) + const activityId = extractIdFromActivityId(activity.id) let result = await this.client.mutate({ mutation: gql` mutation { - CreatePost(content: "${postObject.content}", title: "${title}", id: "${id}") { + CreatePost(content: "${postObject.content}", title: "${title}", id: "${postId}", activityId: "${activityId}") { id } } @@ -300,7 +302,7 @@ export default class NitroDatasource { result = await this.client.mutate({ mutation: gql` mutation { - AddPostAuthor(from: {id: "${userId}"}, to: {id: "${id}"}) + AddPostAuthor(from: {id: "${userId}"}, to: {id: "${postId}"}) } ` }) @@ -308,11 +310,41 @@ export default class NitroDatasource { throwErrorIfGraphQLErrorOccurred(result) } - async createComment (postObject) { + async getSharedInboxEndpoints () { + const result = await this.client.query({ + query: gql` + query { + SharedInboxEndpoint { + uri + } + } + ` + }) + throwErrorIfGraphQLErrorOccurred(result) + return result.data.SharedInboxEnpoint + } + async addSharedInboxEndpoint (uri) { + try { + const result = await this.client.mutate({ + mutation: gql` + mutation { + CreateSharedInboxEndpoint(uri: "${uri}") + } + ` + }) + throwErrorIfGraphQLErrorOccurred(result) + return true + } catch (e) { + return false + } + } + + async createComment (activity) { + const postObject = activity.object let result = await this.client.mutate({ mutation: gql` mutation { - CreateComment(content: "${postObject.content}") { + CreateComment(content: "${postObject.content}", activityId: "${extractIdFromActivityId(activity.id)}") { id } } diff --git a/src/activitypub/routes/inbox.js b/src/activitypub/routes/inbox.js index 0f33ebaec..e8af10c2c 100644 --- a/src/activitypub/routes/inbox.js +++ b/src/activitypub/routes/inbox.js @@ -1,5 +1,5 @@ import express from 'express' -import { verify } from '../security' +import { verifySignature } from '../security' const debug = require('debug')('ea:inbox') const router = express.Router() @@ -10,21 +10,25 @@ router.post('/', async function (req, res, next) { debug(`Content-Type = ${req.get('Content-Type')}`) debug(`body = ${JSON.stringify(req.body, null, 2)}`) debug(`Request headers = ${JSON.stringify(req.headers, null, 2)}`) - debug(`verify = ${await verify(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)}`) + debug(`verify = ${await verifySignature(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)}`) switch (req.body.type) { case 'Create': - await await req.app.get('activityPub').handleCreateActivity(req.body).catch(next) + if (req.body.send) { + await req.app.get('ap').sendActivity(req.body).catch(next) + break + } + await req.app.get('ap').handleCreateActivity(req.body).catch(next) break case 'Undo': - await await req.app.get('activityPub').handleUndoActivity(req.body).catch(next) + await req.app.get('ap').handleUndoActivity(req.body).catch(next) break case 'Follow': debug('handleFollow') - await req.app.get('activityPub').handleFollowActivity(req.body) + await req.app.get('ap').handleFollowActivity(req.body) debug('handledFollow') break case 'Delete': - await await req.app.get('activityPub').handleDeleteActivity(req.body).catch(next) + await req.app.get('ap').handleDeleteActivity(req.body).catch(next) break /* eslint-disable */ case 'Update': diff --git a/src/activitypub/routes/user.js b/src/activitypub/routes/user.js index 8240ba393..36bb7c2db 100644 --- a/src/activitypub/routes/user.js +++ b/src/activitypub/routes/user.js @@ -1,7 +1,7 @@ import { sendCollection } from '../utils' import express from 'express' import { serveUser } from '../utils/serveUser' -import { verify } from '../security' +import { verifySignature } from '../security' const router = express.Router() const debug = require('debug')('ea:user') @@ -47,7 +47,7 @@ router.get('/:name/outbox', (req, res) => { router.post('/:name/inbox', async function (req, res, next) { debug(`body = ${JSON.stringify(req.body, null, 2)}`) debug(`actorId = ${req.body.actor}`) - debug(`verify = ${await verify(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)}`) + debug(`verify = ${await verifySignature(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)}`) // const result = await saveActorId(req.body.actor) switch (req.body.type) { case 'Create': diff --git a/src/activitypub/security/index.js b/src/activitypub/security/index.js index 93b6cc08a..583535bcc 100644 --- a/src/activitypub/security/index.js +++ b/src/activitypub/security/index.js @@ -1,8 +1,6 @@ import dotenv from 'dotenv' import { resolve } from 'path' import crypto from 'crypto' -import { activityPub } from '../ActivityPub' -import gql from 'graphql-tag' import request from 'request' const debug = require('debug')('ea:security') @@ -24,71 +22,19 @@ export function generateRsaKeyPair () { }) } -export function signAndSend (activity, fromName, targetDomain, url) { - // fix for development: replace with http - url = url.indexOf('localhost') > -1 ? url.replace('https', 'http') : url - debug(`passhprase = ${process.env.PRIVATE_KEY_PASSPHRASE}`) - return new Promise(async (resolve, reject) => { - debug('inside signAndSend') - // get the private key - const result = await activityPub.dataSource.client.query({ - query: gql` - query { - User(slug: "${fromName}") { - privateKey - } - } - ` - }) - - if (result.error) { - reject(result.error) - } else { - const parsedActivity = JSON.parse(activity) - if (Array.isArray(parsedActivity['@context'])) { - parsedActivity['@context'].push('https://w3id.org/security/v1') - } else { - const context = [parsedActivity['@context']] - context.push('https://w3id.org/security/v1') - parsedActivity['@context'] = context - } - - // deduplicate context strings - parsedActivity['@context'] = [...new Set(parsedActivity['@context'])] - const privateKey = result.data.User[0].privateKey - const date = new Date().toUTCString() - - debug(`url = ${url}`) - request({ - url: url, - headers: { - 'Host': targetDomain, - 'Date': date, - 'Signature': createSignature(privateKey, `http://${activityPub.domain}/activitypub/users/${fromName}#main-key`, url, - { - 'Host': targetDomain, - 'Date': date, - 'Content-Type': 'application/activity+json' - }), - 'Content-Type': 'application/activity+json' - }, - method: 'POST', - body: JSON.stringify(parsedActivity) - }, (error, response) => { - if (error) { - debug(`Error = ${JSON.stringify(error, null, 2)}`) - reject(error) - } else { - debug('Response Headers:', JSON.stringify(response.headers, null, 2)) - debug('Response Body:', JSON.stringify(response.body, null, 2)) - resolve() - } - }) - } - }) +// signing +export function createSignature (privKey, keyId, url, headers = {}, algorithm = 'rsa-sha256') { + if (!SUPPORTED_HASH_ALGORITHMS.includes(algorithm)) { return throw Error(`SIGNING: Unsupported hashing algorithm = ${algorithm}`) } + const signer = crypto.createSign(algorithm) + const signingString = constructSigningString(url, headers) + signer.update(signingString) + const signatureB64 = signer.sign({ key: privKey, passphrase: process.env.PRIVATE_KEY_PASSPHRASE }, 'base64') + const headersString = Object.keys(headers).reduce((result, key) => { return result + ' ' + key.toLowerCase() }, '') + return `keyId="${keyId}",algorithm="${algorithm}",headers="(request-target)${headersString}",signature="${signatureB64}"` } -export function verify (url, headers) { +// verifying +export function verifySignature (url, headers) { return new Promise((resolve, reject) => { const signatureHeader = headers['signature'] ? headers['signature'] : headers['Signature'] if (!signatureHeader) { @@ -130,20 +76,36 @@ export function verify (url, headers) { }) } -// specify the public key owner object -/* const testPublicKeyOwner = { - "@context": jsig.SECURITY_CONTEXT_URL, - '@id': 'https://example.com/i/alice', - publicKey: [testPublicKey] -} */ +// private: signing +function constructSigningString (url, headers) { + const urlObj = new URL(url) + let signingString = `(request-target): post ${urlObj.pathname}${urlObj.search !== '' ? urlObj.search : ''}` + return Object.keys(headers).reduce((result, key) => { + return result + `\n${key.toLowerCase()}: ${headers[key]}` + }, signingString) +} -/* const publicKey = { - '@context': jsig.SECURITY_CONTEXT_URL, - type: 'RsaVerificationKey2018', - id: `https://${ActivityPub.domain}/users/${fromName}#main-key`, - controller: `https://${ActivityPub.domain}/users/${fromName}`, - publicKeyPem -} */ +// private: verifying +function httpVerify (pubKey, signature, signingString, algorithm) { + if (!SUPPORTED_HASH_ALGORITHMS.includes(algorithm)) { throw Error(`SIGNING: Unsupported hashing algorithm = ${algorithm}`) } + const verifier = crypto.createVerify(algorithm) + verifier.update(signingString) + return verifier.verify(pubKey, signature, 'base64') +} + +// private: verifying +// This function can be used to extract the signature,headers,algorithm etc. out of the Signature Header. +// Just pass what you want as key +function extractKeyValueFromSignatureHeader (signatureHeader, key) { + const keyString = signatureHeader.split(',').filter((el) => { + return !!el.startsWith(key) + })[0] + + let firstEqualIndex = keyString.search('=') + // When headers are requested add 17 to the index to remove "(request-target) " from the string + if (key === 'headers') { firstEqualIndex += 17 } + return keyString.substring(firstEqualIndex + 2, keyString.length - 1) +} // Obtained from invoking crypto.getHashes() export const SUPPORTED_HASH_ALGORITHMS = [ @@ -183,45 +145,3 @@ export const SUPPORTED_HASH_ALGORITHMS = [ 'ssl3-md5', 'ssl3-sha1', 'whirlpool'] - -// signing -function createSignature (privKey, keyId, url, headers = {}, algorithm = 'rsa-sha256') { - if (!SUPPORTED_HASH_ALGORITHMS.includes(algorithm)) { return throw Error(`SIGNING: Unsupported hashing algorithm = ${algorithm}`) } - const signer = crypto.createSign(algorithm) - const signingString = constructSigningString(url, headers) - signer.update(signingString) - const signatureB64 = signer.sign({ key: privKey, passphrase: process.env.PRIVATE_KEY_PASSPHRASE }, 'base64') - const headersString = Object.keys(headers).reduce((result, key) => { return result + ' ' + key.toLowerCase() }, '') - return `keyId="${keyId}",algorithm="${algorithm}",headers="(request-target)${headersString}",signature="${signatureB64}"` -} - -// signing -function constructSigningString (url, headers) { - const urlObj = new URL(url) - let signingString = `(request-target): post ${urlObj.pathname}${urlObj.search !== '' ? urlObj.search : ''}` - return Object.keys(headers).reduce((result, key) => { - return result + `\n${key.toLowerCase()}: ${headers[key]}` - }, signingString) -} - -// verifying -function httpVerify (pubKey, signature, signingString, algorithm) { - if (!SUPPORTED_HASH_ALGORITHMS.includes(algorithm)) { throw Error(`SIGNING: Unsupported hashing algorithm = ${algorithm}`) } - const verifier = crypto.createVerify(algorithm) - verifier.update(signingString) - return verifier.verify(pubKey, signature, 'base64') -} - -// verifying -// This function can be used to extract the signature,headers,algorithm etc. out of the Signature Header. -// Just pass what you want as key -function extractKeyValueFromSignatureHeader (signatureHeader, key) { - const keyString = signatureHeader.split(',').filter((el) => { - return !!el.startsWith(key) - })[0] - - let firstEqualIndex = keyString.search('=') - // When headers are requested add 17 to the index to remove "(request-target) " from the string - if (key === 'headers') { firstEqualIndex += 17 } - return keyString.substring(firstEqualIndex + 2, keyString.length - 1) -} diff --git a/src/activitypub/utils/index.js b/src/activitypub/utils/index.js index d1d4be845..9df537e79 100644 --- a/src/activitypub/utils/index.js +++ b/src/activitypub/utils/index.js @@ -1,7 +1,9 @@ import crypto from 'crypto' -import { signAndSend } from '../security' import as from 'activitystrea.ms' import { activityPub } from '../ActivityPub' +import gql from 'graphql-tag' +import { createSignature } from '../security' +import request from 'request' const debug = require('debug')('ea:utils') export function extractNameFromId (uri) { @@ -213,3 +215,68 @@ export function throwErrorIfGraphQLErrorOccurred (result) { throw new Error(`${result.error.message ? result.error.message : result.error.errors[0].message}`) } } + +export function signAndSend (activity, fromName, targetDomain, url) { + // fix for development: replace with http + url = url.indexOf('localhost') > -1 ? url.replace('https', 'http') : url + debug(`passhprase = ${process.env.PRIVATE_KEY_PASSPHRASE}`) + return new Promise(async (resolve, reject) => { + debug('inside signAndSend') + // get the private key + const result = await activityPub.dataSource.client.query({ + query: gql` + query { + User(slug: "${fromName}") { + privateKey + } + } + ` + }) + + if (result.error) { + reject(result.error) + } else { + // add security context + const parsedActivity = JSON.parse(activity) + if (Array.isArray(parsedActivity['@context'])) { + parsedActivity['@context'].push('https://w3id.org/security/v1') + } else { + const context = [parsedActivity['@context']] + context.push('https://w3id.org/security/v1') + parsedActivity['@context'] = context + } + + // deduplicate context strings + parsedActivity['@context'] = [...new Set(parsedActivity['@context'])] + const privateKey = result.data.User[0].privateKey + const date = new Date().toUTCString() + + debug(`url = ${url}`) + request({ + url: url, + headers: { + 'Host': targetDomain, + 'Date': date, + 'Signature': createSignature(privateKey, `http://${activityPub.domain}/activitypub/users/${fromName}#main-key`, url, + { + 'Host': targetDomain, + 'Date': date, + 'Content-Type': 'application/activity+json' + }), + 'Content-Type': 'application/activity+json' + }, + method: 'POST', + body: JSON.stringify(parsedActivity) + }, (error, response) => { + if (error) { + debug(`Error = ${JSON.stringify(error, null, 2)}`) + reject(error) + } else { + debug('Response Headers:', JSON.stringify(response.headers, null, 2)) + debug('Response Body:', JSON.stringify(response.body, null, 2)) + resolve() + } + }) + } + }) +} diff --git a/src/jwt/generateToken.js b/src/jwt/generateToken.js index 7cbc70330..fb61bb4ac 100644 --- a/src/jwt/generateToken.js +++ b/src/jwt/generateToken.js @@ -10,7 +10,7 @@ export default function generateJwt (user) { audience: process.env.CLIENT_URI, subject: user.id.toString() }) - // jwt.verify(token, process.env.JWT_SECRET, (err, data) => { + // jwt.verifySignature(token, process.env.JWT_SECRET, (err, data) => { // console.log('token verification:', err, data) // }) return token diff --git a/src/schema.graphql b/src/schema.graphql index 3626dd3c2..eacbab55f 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -137,6 +137,7 @@ type User { type Post { id: ID! + activityId: String author: User @relation(name: "WROTE", direction: "IN") title: String! slug: String @@ -167,6 +168,7 @@ type Post { type Comment { id: ID! + activityId: String author: User @relation(name: "WROTE", direction: "IN") content: String! contentExcerpt: String @@ -241,3 +243,7 @@ type Tag { deleted: Boolean disabled: Boolean } +type SharedInboxEndpoint { + id: ID! + uri: String +} diff --git a/yarn.lock b/yarn.lock index fc6697b2a..78cabe011 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1576,9 +1576,9 @@ bitcore-lib@^0.13.7: inherits "=2.0.1" lodash "=3.10.1" -"bitcore-message@github:comakery/bitcore-message#dist": +"bitcore-message@github:CoMakery/bitcore-message#dist": version "1.0.2" - resolved "https://codeload.github.com/comakery/bitcore-message/tar.gz/8799cc327029c3d34fc725f05b2cf981363f6ebf" + resolved "https://codeload.github.com/CoMakery/bitcore-message/tar.gz/8799cc327029c3d34fc725f05b2cf981363f6ebf" dependencies: bitcore-lib "^0.13.7" From 9e5b6865b8fd4d860648aac9c198604e7e7fce85 Mon Sep 17 00:00:00 2001 From: Armin Date: Tue, 26 Feb 2019 17:17:42 +0100 Subject: [PATCH 416/554] Create and send Post via ActivityPub inbox of the server --- src/graphql-schema.js | 48 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index ce84dde36..e5da2ce54 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -6,6 +6,10 @@ import uuid from 'uuid/v4' import { fixUrl } from './middleware/fixImageUrlsMiddleware' import { AuthenticationError } from 'apollo-server' import { neo4jgraphql } from 'neo4j-graphql-js' +import as from 'activitystrea.ms' +import request from 'request' + +const debug = require('debug')('backend:schema') export const typeDefs = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, 'schema.graphql')) @@ -163,10 +167,10 @@ export const resolvers = { return data }, CreatePost: async (object, params, ctx, resolveInfo) => { + params.activityId = uuid() const result = await neo4jgraphql(object, params, ctx, resolveInfo, false) - const session = ctx.driver.session() - await session.run( + const author = await session.run( 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + 'MERGE (post)<-[:WROTE]-(author) ' + 'RETURN author', { @@ -174,7 +178,45 @@ export const resolvers = { postId: result.id }) session.close() - + const actorId = author.records[0]._fields[0].properties.actorId + const createActivity = await new Promise((resolve, reject) => { + as.create() + .id(`${actorId}/status/${params.activityId}`) + .actor(`${actorId}`) + .object( + as.article() + .id(`${actorId}/status/${result.id}`) + .content(result.content) + .to('https://www.w3.org/ns/activitystreams#Public') + .attributedTo(`${actorId}`) + ).prettyWrite((err, doc) => { + if (err) { + reject(err) + } else { + debug(doc) + const parsedDoc = JSON.parse(doc) + parsedDoc.send = true + resolve(JSON.stringify(parsedDoc)) + } + }) + }) + // try sending post via ActivityPub + await new Promise((resolve) => { + const url = new URL(actorId) + request(`${url.origin}/activitypub/inbox`, { + method: 'POST', + headers: { + 'Content-Type': 'application/activity+json' + }, + body: createActivity + }, (err) => { + if (err) { + debug(`error = ${JSON.stringify(err, null, 2)}`) + resolve(err) + } + resolve(null) + }) + }) return result } From e48ce8a94eaaea2c2c2c4f63c400f681ce1a4999 Mon Sep 17 00:00:00 2001 From: Armin Date: Wed, 27 Feb 2019 02:34:44 +0100 Subject: [PATCH 417/554] Test fixes + add remove from outbox collection step --- test/features/activity-delete.feature | 55 +++++++++++++++++++ test/features/activity-delete.feature.disable | 28 ---------- test/features/activity-follow.feature | 1 - ...feature.disable => object-article.feature} | 2 +- test/features/support/steps.js | 9 +-- test/features/world.js | 2 +- 6 files changed, 62 insertions(+), 35 deletions(-) create mode 100644 test/features/activity-delete.feature delete mode 100644 test/features/activity-delete.feature.disable rename test/features/{activity-article.feature.disable => object-article.feature} (96%) diff --git a/test/features/activity-delete.feature b/test/features/activity-delete.feature new file mode 100644 index 000000000..0e0d13253 --- /dev/null +++ b/test/features/activity-delete.feature @@ -0,0 +1,55 @@ +Feature: Delete an object + I want to delete objects + + Background: + Given our own server runs at "http://localhost:4100" + And we have the following users in our database: + | Slug | + | bernd-das-brot| + And I send a POST request with the following activity to "/activitypub/users/bernd-das-brot/inbox": + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://aronda.org/users/bernd-das-brot/status/lka7dfzkjn2398hsfd", + "type": "Create", + "actor": "https://aronda.org/users/bernd-das-brot", + "object": { + "id": "https://aronda.org/users/bernd-das-brot/status/kljsdfg9843jknsdf", + "type": "Article", + "published": "2019-02-07T19:37:55.002Z", + "attributedTo": "https://aronda.org/users/bernd-das-brot", + "content": "Hi Max, how are you?", + "to": "https://localhost:4100/activitypub/users/moritz" + } + } + """ + + Scenario: Deleting a post (Article Object) + When I send a POST request with the following activity to "/activitypub/users/bernd-das-brot/inbox": + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4100/users/karl-heinz/status/a4DJ2afdg323v32641vna42lkj685kasd2", + "type": "Delete", + "object": { + "id": "https://aronda.org/users/bernd-das-brot/status/kljsdfg9843jknsdf", + "type": "Article", + "published": "2019-02-07T19:37:55.002Z", + "attributedTo": "https://aronda.org/users/bernd-das-brot", + "content": "Hi Max, how are you?", + "to": "https://localhost:4100/activitypub/users/moritz" + } + } + """ + Then I expect the status code to be 200 + And the object is removed from the outbox collection of "bernd-das-brot" + """ + { + "id": "https://aronda.org/users/bernd-das-brot/status/kljsdfg9843jknsdf", + "type": "Article", + "published": "2019-02-07T19:37:55.002Z", + "attributedTo": "https://aronda.org/users/bernd-das-brot", + "content": "Hi Max, how are you?", + "to": "https://localhost:4100/activitypub/users/moritz" + } + """ diff --git a/test/features/activity-delete.feature.disable b/test/features/activity-delete.feature.disable deleted file mode 100644 index 9d671500f..000000000 --- a/test/features/activity-delete.feature.disable +++ /dev/null @@ -1,28 +0,0 @@ -Feature: Delete an object - I want to delete objects - - Background: - Given our own server runs at "http://localhost:4100" - And we have the following users in our database: - | Slug | - | bernd-das-brot| - - Scenario: Deleting a post (Article Object) - When I send a POST request with the following activity to "/activitypub/users/bernd-das-brot/inbox": - """ - { - "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://localhost:4100/users/karl-heinz/status/a4DJ2afdg323v32641vna42lkj685kasd2", - "type": "Delete", - "object": { - "id": "https://aronda.org/users/marvin/status/kljsdfg9843jknsdf", - "type": "Article", - "published": "2019-02-07T19:37:55.002Z", - "attributedTo": "https://aronda.org/users/marvin", - "content": "Hi John, how are you?", - "to": "https://localhost:4100/activitypub/users/max" - } - } - """ - Then I expect the status code to be 200 - And the object is removed from the outbox collection of "karl-heinz" diff --git a/test/features/activity-follow.feature b/test/features/activity-follow.feature index 0797279d8..578e57cb1 100644 --- a/test/features/activity-follow.feature +++ b/test/features/activity-follow.feature @@ -36,7 +36,6 @@ Feature: Follow a user "type": "Undo", "actor": "http://localhost:4123/activitypub/users/peter-lustiger", "object": { - "@context": "https://www.w3.org/ns/activitystreams", "id": "https://localhost:4123/activitypub/users/bob-der-baumeister/status/83J23549sda1k72fsa4567na42312455kad83", "type": "Follow", "actor": "http://localhost:4123/activitypub/users/bob-der-baumeister", diff --git a/test/features/activity-article.feature.disable b/test/features/object-article.feature similarity index 96% rename from test/features/activity-article.feature.disable rename to test/features/object-article.feature index 858f85473..0a8af2606 100644 --- a/test/features/activity-article.feature.disable +++ b/test/features/object-article.feature @@ -21,7 +21,7 @@ Feature: Send and receive Articles "type": "Article", "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/users/marvin", - "content": "Hi John, how are you?", + "content": "Hi Max, how are you?", "to": "https://localhost:4100/activitypub/users/max" } } diff --git a/test/features/support/steps.js b/test/features/support/steps.js index 454db0e31..7f7bde455 100644 --- a/test/features/support/steps.js +++ b/test/features/support/steps.js @@ -108,16 +108,17 @@ Then('the post with id {string} to be created', async function (id) { const result = await client.request(` query { Post(id: "${id}") { - name + title } } `) - expect(result.data.Post).to.be.an('array').that.is.not.empty // eslint-disable-line }) -Then('the object is removed from the outbox collection of {string}', (name) => { - +Then('the object is removed from the outbox collection of {string}', async function (name, object) { + const response = await this.get(`/activitypub/users/${name}/outbox?page=true`) + const parsedResponse = JSON.parse(response.lastResponse) + expect(parsedResponse.orderedItems).to.not.include(object) }) Then('I send a GET request to {string} and expect a ordered collection', () => { diff --git a/test/features/world.js b/test/features/world.js index 26282f45a..9a27bd154 100644 --- a/test/features/world.js +++ b/test/features/world.js @@ -10,7 +10,7 @@ class CustomWorld { this.lastContentType = null this.lastInboxUrl = null this.lastActivity = null - // activity-article.feature.disable + // object-article.feature this.statusCode = null } get (pathname) { From adb674b98da4db8bda389773e00f1b31a34476bf Mon Sep 17 00:00:00 2001 From: Armin Date: Wed, 27 Feb 2019 02:42:34 +0100 Subject: [PATCH 418/554] Handle update, like, dislike and accept activities and also sending activities through the ActivityPub protocol + refactoring --- package.json | 1 + src/activitypub/ActivityPub.js | 87 ++++++-- src/activitypub/NitroDatasource.js | 174 +++++++++++++--- src/activitypub/routes/inbox.js | 15 +- .../{utils => routes}/serveUser.js | 2 +- src/activitypub/routes/user.js | 34 ++-- src/activitypub/routes/webfinger.js | 2 +- src/activitypub/utils/activity.js | 82 ++++++++ src/activitypub/utils/actor.js | 40 ++++ src/activitypub/utils/collection.js | 70 +++++++ src/activitypub/utils/index.js | 186 +----------------- src/graphql-schema.js | 5 +- yarn.lock | 7 + 13 files changed, 460 insertions(+), 245 deletions(-) rename src/activitypub/{utils => routes}/serveUser.js (97%) create mode 100644 src/activitypub/utils/activity.js create mode 100644 src/activitypub/utils/actor.js create mode 100644 src/activitypub/utils/collection.js diff --git a/package.json b/package.json index 1aa02fc96..85dfac6a2 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "activitystrea.ms": "^2.1.3", "apollo-cache-inmemory": "~1.4.3", "apollo-client": "~2.4.13", + "apollo-link-context": "^1.0.14", "apollo-link-http": "~1.5.11", "apollo-server": "~2.4.2", "bcryptjs": "~2.4.3", diff --git a/src/activitypub/ActivityPub.js b/src/activitypub/ActivityPub.js index b4d9677c2..74e047e12 100644 --- a/src/activitypub/ActivityPub.js +++ b/src/activitypub/ActivityPub.js @@ -1,10 +1,13 @@ import { - sendAcceptActivity, - sendRejectActivity, extractNameFromId, extractDomainFromUrl, signAndSend } from './utils' +import { + isPublicAddressed, + sendAcceptActivity, + sendRejectActivity +} from './utils/activity' import request from 'request' import as from 'activitystrea.ms' import NitroDatasource from './NitroDatasource' @@ -30,9 +33,9 @@ export default class ActivityPub { activityPub = new ActivityPub(process.env.ACTIVITYPUB_DOMAIN || 'localhost', process.env.ACTIVITYPUB_PORT || 4100) server.express.set('ap', activityPub) server.express.use(router) - debug('ActivityPub service added to graphql endpoint') + debug('ActivityPub middleware added to the express service') } else { - debug('ActivityPub service already added to graphql endpoint') + debug('ActivityPub middleware already added to the express service') } } @@ -101,7 +104,6 @@ export default class ActivityPub { debug(`followers = ${toActorObject.followers}`) debug(`following = ${toActorObject.following}`) - // TODO save after accept activity for the corresponding follow is received try { await dataSource.saveFollowersCollectionPage(followersCollectionPage) debug('follow activity saved') @@ -141,18 +143,77 @@ export default class ActivityPub { handleDeleteActivity (activity) { debug('inside delete') + switch (activity.object.type) { + case 'Article': + case 'Note': + return this.dataSource.deletePost(activity) + default: + } + } + + handleUpdateActivity (activity) { + debug('inside update') + switch (activity.object.type) { + case 'Note': + case 'Article': + return this.dataSource.updatePost(activity) + default: + } + } + + handleLikeActivity (activity) { + return this.dataSource.createShouted(activity) + } + + handleDislikeActivity (activity) { + return this.dataSource.deleteShouted(activity) + } + + async handleAcceptActivity (activity) { + debug('inside accept') + switch (activity.object.type) { + case 'Follow': + const followObject = activity.object + const followingCollectionPage = await this.getFollowingCollectionPage(followObject.actor) + followingCollectionPage.orderedItems.push(followObject.object) + await this.dataSource.saveFollowingCollectionPage(followingCollectionPage) + } } async sendActivity (activity) { - if (Array.isArray(activity.to) && activity.to.includes('https://www.w3.org/ns/activitystreams#Public')) { - delete activity.send - const fromName = extractNameFromId(activity.actor) + delete activity.send + const fromName = extractNameFromId(activity.actor) + + if (Array.isArray(activity.to) && isPublicAddressed(activity)) { const sharedInboxEndpoints = await this.dataSource.getSharedInboxEndpoints() - await Promise.all( - sharedInboxEndpoints.map((el) => { - return signAndSend(activity, fromName, new URL(el).host, el) - }) - ) + // serve shared inbox endpoints + sharedInboxEndpoints.map((el) => { + return this.trySend(activity, fromName, new URL(el).host, el) + }) + activity.to = activity.to.filter((el) => { + return !(isPublicAddressed({ to: el })) + }) + // serve the rest + activity.to.map((el) => { + return this.trySend(activity, fromName, new URL(el).host, el) + }) + } else if (typeof activity.to === 'string') { + return this.trySend(activity, fromName, new URL(activity.to).host, activity.to) + } else if (Array.isArray(activity.to)) { + activity.to.map((el) => { + return this.trySend(activity, fromName, new URL(el).host, el) + }) + } + } + async trySend (activity, fromName, host, url, tries = 5) { + try { + return await signAndSend(activity, fromName, host, url) + } catch (e) { + if (tries > 0) { + setTimeout(function () { + return this.trySend(activity, fromName, host, url, --tries) + }, 20000) + } } } } diff --git a/src/activitypub/NitroDatasource.js b/src/activitypub/NitroDatasource.js index b723fa72c..19e931eef 100644 --- a/src/activitypub/NitroDatasource.js +++ b/src/activitypub/NitroDatasource.js @@ -1,22 +1,32 @@ import { - throwErrorIfGraphQLErrorOccurred, + throwErrorIfApolloErrorOccurred, extractIdFromActivityId, - createOrderedCollection, - createOrderedCollectionPage, extractNameFromId, - createArticleActivity, constructIdFromName } from './utils' +import { + createOrderedCollection, + createOrderedCollectionPage +} from './utils/collection' +import { + createArticleActivity, + isPublicAddressed +} from './utils/activity' import crypto from 'crypto' import gql from 'graphql-tag' import { createHttpLink } from 'apollo-link-http' +import { setContext } from 'apollo-link-context' import { InMemoryCache } from 'apollo-cache-inmemory' import fetch from 'node-fetch' import { ApolloClient } from 'apollo-client' import dotenv from 'dotenv' +import uuid from 'uuid' +import generateJwtToken from '../jwt/generateToken' +import { resolve } from 'path' +import trunc from 'trunc-html' const debug = require('debug')('ea:nitro-datasource') -dotenv.config() +dotenv.config({ path: resolve('src', 'activitypub', '.env') }) export default class NitroDatasource { constructor (domain) { @@ -29,8 +39,19 @@ export default class NitroDatasource { } const link = createHttpLink({ uri: process.env.GRAPHQL_URI, fetch: fetch }) // eslint-disable-line const cache = new InMemoryCache() + const authLink = setContext((_, { headers }) => { + // generate the authentication token (maybe from env? Which user?) + const token = generateJwtToken({ name: 'ActivityPub', id: uuid() }) + // return the headers to the context so httpLink can read them + return { + headers: { + ...headers, + authorization: token ? `Bearer ${token}` : '' + } + } + }) this.client = new ApolloClient({ - link: link, + link: authLink.concat(link), cache: cache, defaultOptions }) @@ -59,7 +80,7 @@ export default class NitroDatasource { return followersCollection } else { - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) } } @@ -96,7 +117,7 @@ export default class NitroDatasource { return followersCollection } else { - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) } } @@ -122,7 +143,7 @@ export default class NitroDatasource { return followingCollection } else { - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) } } @@ -158,7 +179,7 @@ export default class NitroDatasource { return followingCollection } else { - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) } } @@ -190,7 +211,7 @@ export default class NitroDatasource { return outboxCollection } else { - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) } } @@ -229,7 +250,7 @@ export default class NitroDatasource { debug('after createNote') return outboxCollection } else { - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) } } @@ -246,7 +267,7 @@ export default class NitroDatasource { ` }) debug(`undoFollowActivity result = ${JSON.stringify(result, null, 2)}`) - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) } async saveFollowersCollectionPage (followersCollection, onlyNewestItem = true) { @@ -257,7 +278,7 @@ export default class NitroDatasource { orderedItems = onlyNewestItem ? [orderedItems.pop()] : orderedItems return Promise.all( - await Promise.all(orderedItems.map(async (follower) => { + orderedItems.map(async (follower) => { debug(`follower = ${follower}`) const fromUserId = await this.ensureUser(follower) debug(`fromUserId = ${fromUserId}`) @@ -272,9 +293,36 @@ export default class NitroDatasource { ` }) debug(`addUserFollowedBy edge = ${JSON.stringify(result, null, 2)}`) - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) debug('saveFollowers: added follow edge successfully') - })) + }) + ) + } + async saveFollowingCollectionPage (followingCollection, onlyNewestItem = true) { + debug('inside saveFollowers') + let orderedItems = followingCollection.orderedItems + const fromUserName = extractNameFromId(followingCollection.id) + const fromUserId = await this.ensureUser(constructIdFromName(fromUserName)) + orderedItems = onlyNewestItem ? [orderedItems.pop()] : orderedItems + return Promise.all( + orderedItems.map(async (following) => { + debug(`follower = ${following}`) + const toUserId = await this.ensureUser(following) + debug(`fromUserId = ${fromUserId}`) + debug(`toUserId = ${toUserId}`) + const result = await this.client.mutate({ + mutation: gql` + mutation { + AddUserFollowing(from: {id: "${fromUserId}"}, to: {id: "${toUserId}"}) { + from { name } + } + } + ` + }) + debug(`addUserFollowing edge = ${JSON.stringify(result, null, 2)}`) + throwErrorIfApolloErrorOccurred(result) + debug('saveFollowing: added follow edge successfully') + }) ) } @@ -282,6 +330,9 @@ export default class NitroDatasource { // TODO how to handle the to field? Now the post is just created, doesn't matter who is the recipient // createPost const postObject = activity.object + if (!isPublicAddressed(postObject)) { + return debug('createPost: not send to public (sending to specific persons is not implemented yet)') + } const title = postObject.summary ? postObject.summary : postObject.content.split(' ').slice(0, 5).join(' ') const postId = extractIdFromActivityId(postObject.id) const activityId = extractIdFromActivityId(activity.id) @@ -295,7 +346,7 @@ export default class NitroDatasource { ` }) - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) // ensure user and add author to post const userId = await this.ensureUser(postObject.attributedTo) @@ -307,7 +358,78 @@ export default class NitroDatasource { ` }) - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) + } + + async deletePost (activity) { + const result = await this.client.mutate({ + mutation: gql` + mutation { + DeletePost(id: "${extractIdFromActivityId(activity.object.id)}") { + title + } + } + ` + }) + throwErrorIfApolloErrorOccurred(result) + } + + async updatePost (activity) { + const postObject = activity.object + const postId = extractIdFromActivityId(postObject.id) + const date = postObject.updated ? postObject.updated : new Date().toISOString() + const result = await this.client.mutate({ + mutation: gql` + mutation { + UpdatePost(content: "${postObject.content}", contentExcerpt: "${trunc(postObject.content, 120).html}", id: "${postId}", updatedAt: "${date}") { + title + } + } + ` + }) + throwErrorIfApolloErrorOccurred(result) + } + + async createShouted (activity) { + const userId = await this.ensureUser(activity.actor) + const postId = extractIdFromActivityId(activity.object) + const result = await this.client.mutate({ + mutation: gql` + mutation { + AddUserShouted(from: {id: "${userId}"}, to: {id: "${postId}"}) { + from { + name + } + } + } + ` + }) + throwErrorIfApolloErrorOccurred(result) + if (!result.data.AddUserShouted) { + debug('something went wrong shouting post') + throw Error('User or Post not exists') + } + } + + async deleteShouted (activity) { + const userId = await this.ensureUser(activity.actor) + const postId = extractIdFromActivityId(activity.object) + const result = await this.client.mutate({ + mutation: gql` + mutation { + RemoveUserShouted(from: {id: "${userId}"}, to: {id: "${postId}"}) { + from { + name + } + } + } + ` + }) + throwErrorIfApolloErrorOccurred(result) + if (!result.data.AddUserShouted) { + debug('something went wrong disliking a post') + throw Error('User or Post not exists') + } } async getSharedInboxEndpoints () { @@ -320,7 +442,7 @@ export default class NitroDatasource { } ` }) - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) return result.data.SharedInboxEnpoint } async addSharedInboxEndpoint (uri) { @@ -332,7 +454,7 @@ export default class NitroDatasource { } ` }) - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) return true } catch (e) { return false @@ -351,7 +473,7 @@ export default class NitroDatasource { ` }) - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) const postId = extractIdFromActivityId(postObject.inReplyTo) result = await this.client.mutate({ @@ -364,7 +486,7 @@ export default class NitroDatasource { ` }) - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) } /** @@ -375,10 +497,11 @@ export default class NitroDatasource { */ async ensureUser (actorId) { debug(`inside ensureUser = ${actorId}`) + const name = extractNameFromId(actorId) const queryResult = await this.client.query({ query: gql` query { - User(slug: "${extractNameFromId(actorId)}") { + User(slug: "${name}") { id } } @@ -392,16 +515,17 @@ export default class NitroDatasource { } else { debug('ensureUser: user not exists.. createUser') // user does not exist.. create it + const pw = crypto.randomBytes(16).toString('hex') const result = await this.client.mutate({ mutation: gql` mutation { - CreateUser(password: "${crypto.randomBytes(16).toString('hex')}", slug:"${extractNameFromId(actorId)}", actorId: "${actorId}", name: "${extractNameFromId(actorId)}") { + CreateUser(password: "${pw}", slug:"${name}", actorId: "${actorId}", name: "${name}") { id } } ` }) - throwErrorIfGraphQLErrorOccurred(result) + throwErrorIfApolloErrorOccurred(result) return result.data.CreateUser.id } diff --git a/src/activitypub/routes/inbox.js b/src/activitypub/routes/inbox.js index e8af10c2c..eb720e042 100644 --- a/src/activitypub/routes/inbox.js +++ b/src/activitypub/routes/inbox.js @@ -1,5 +1,7 @@ import express from 'express' import { verifySignature } from '../security' +import { activityPub } from '../ActivityPub' + const debug = require('debug')('ea:inbox') const router = express.Router() @@ -10,31 +12,32 @@ router.post('/', async function (req, res, next) { debug(`Content-Type = ${req.get('Content-Type')}`) debug(`body = ${JSON.stringify(req.body, null, 2)}`) debug(`Request headers = ${JSON.stringify(req.headers, null, 2)}`) + // TODO stop if signature validation fails debug(`verify = ${await verifySignature(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)}`) switch (req.body.type) { case 'Create': if (req.body.send) { - await req.app.get('ap').sendActivity(req.body).catch(next) + await activityPub.sendActivity(req.body).catch(next) break } - await req.app.get('ap').handleCreateActivity(req.body).catch(next) + await activityPub.handleCreateActivity(req.body).catch(next) break case 'Undo': - await req.app.get('ap').handleUndoActivity(req.body).catch(next) + await activityPub.handleUndoActivity(req.body).catch(next) break case 'Follow': debug('handleFollow') - await req.app.get('ap').handleFollowActivity(req.body) + await activityPub.handleFollowActivity(req.body) debug('handledFollow') break case 'Delete': - await req.app.get('ap').handleDeleteActivity(req.body).catch(next) + await activityPub.handleDeleteActivity(req.body).catch(next) break /* eslint-disable */ case 'Update': case 'Accept': - + await activityPub.handleAcceptActivity(req.body).catch(next) case 'Reject': case 'Add': diff --git a/src/activitypub/utils/serveUser.js b/src/activitypub/routes/serveUser.js similarity index 97% rename from src/activitypub/utils/serveUser.js rename to src/activitypub/routes/serveUser.js index 9a13275eb..f65876741 100644 --- a/src/activitypub/utils/serveUser.js +++ b/src/activitypub/routes/serveUser.js @@ -1,4 +1,4 @@ -import { createActor } from '../utils' +import { createActor } from '../utils/actor' const gql = require('graphql-tag') const debug = require('debug')('ea:serveUser') diff --git a/src/activitypub/routes/user.js b/src/activitypub/routes/user.js index 36bb7c2db..2316d319c 100644 --- a/src/activitypub/routes/user.js +++ b/src/activitypub/routes/user.js @@ -1,7 +1,8 @@ -import { sendCollection } from '../utils' +import { sendCollection } from '../utils/collection' import express from 'express' -import { serveUser } from '../utils/serveUser' +import { serveUser } from './serveUser' import { verifySignature } from '../security' +import { activityPub } from '../ActivityPub' const router = express.Router() const debug = require('debug')('ea:user') @@ -47,36 +48,41 @@ router.get('/:name/outbox', (req, res) => { router.post('/:name/inbox', async function (req, res, next) { debug(`body = ${JSON.stringify(req.body, null, 2)}`) debug(`actorId = ${req.body.actor}`) + // TODO stop if signature validation fails debug(`verify = ${await verifySignature(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)}`) // const result = await saveActorId(req.body.actor) switch (req.body.type) { case 'Create': - await req.app.get('ap').handleCreateActivity(req.body).catch(next) + await activityPub.handleCreateActivity(req.body).catch(next) break case 'Undo': - await req.app.get('ap').handleUndoActivity(req.body).catch(next) + await activityPub.handleUndoActivity(req.body).catch(next) break case 'Follow': - debug('handleFollow') - await req.app.get('ap').handleFollowActivity(req.body).catch(next) - debug('handledFollow') + await activityPub.handleFollowActivity(req.body).catch(next) break case 'Delete': - req.app.get('ap').handleDeleteActivity(req.body).catch(next) + await activityPub.handleDeleteActivity(req.body).catch(next) break /* eslint-disable */ case 'Update': - + await activityPub.handleUpdateActivity(req.body).catch(next) + break case 'Accept': - + await activityPub.handleAcceptActivity(req.body).catch(next) case 'Reject': - + // Do nothing + break case 'Add': - + break case 'Remove': - + break case 'Like': - + await activityPub.handleLikeActivity(req.body).catch(next) + break + case 'Dislike': + await activityPub.handleDislikeActivity(req.body).catch(next) + break case 'Announce': debug('else!!') debug(JSON.stringify(req.body, null, 2)) diff --git a/src/activitypub/routes/webfinger.js b/src/activitypub/routes/webfinger.js index 9e51dcdfd..ad1c806ad 100644 --- a/src/activitypub/routes/webfinger.js +++ b/src/activitypub/routes/webfinger.js @@ -1,5 +1,5 @@ import express from 'express' -import { createWebFinger } from '../utils' +import { createWebFinger } from '../utils/actor' import gql from 'graphql-tag' const router = express.Router() diff --git a/src/activitypub/utils/activity.js b/src/activitypub/utils/activity.js new file mode 100644 index 000000000..afe13dfca --- /dev/null +++ b/src/activitypub/utils/activity.js @@ -0,0 +1,82 @@ +import crypto from 'crypto' +import { activityPub } from '../ActivityPub' +import as from 'activitystrea.ms' +import { signAndSend } from './index' +const debug = require('debug')('ea:utils:activity') + +export function createNoteActivity (text, name, id, published) { + const createUuid = crypto.randomBytes(16).toString('hex') + + return { + '@context': 'https://www.w3.org/ns/activitystreams', + 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${createUuid}`, + 'type': 'Create', + 'actor': `https://${activityPub.domain}/activitypub/users/${name}`, + 'object': { + 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${id}`, + 'type': 'Note', + 'published': published, + 'attributedTo': `https://${activityPub.domain}/activitypub/users/${name}`, + 'content': text, + 'to': 'https://www.w3.org/ns/activitystreams#Public' + } + } +} + +export function createArticleActivity (text, name, id, published) { + const createUuid = crypto.randomBytes(16).toString('hex') + + return { + '@context': 'https://www.w3.org/ns/activitystreams', + 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${createUuid}`, + 'type': 'Create', + 'actor': `https://${activityPub.domain}/activitypub/users/${name}`, + 'object': { + 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${id}`, + 'type': 'Article', + 'published': published, + 'attributedTo': `https://${activityPub.domain}/activitypub/users/${name}`, + 'content': text, + 'to': 'https://www.w3.org/ns/activitystreams#Public' + } + } +} + +export function sendAcceptActivity (theBody, name, targetDomain, url) { + as.accept() + .id(`https://${activityPub.domain}/activitypub/users/${name}/status/` + crypto.randomBytes(16).toString('hex')) + .actor(`https://${activityPub.domain}/activitypub/users/${name}`) + .object(theBody) + .prettyWrite((err, doc) => { + if (!err) { + return signAndSend(doc, name, targetDomain, url) + } else { + debug(`error serializing Accept object: ${err}`) + throw new Error('error serializing Accept object') + } + }) +} + +export function sendRejectActivity (theBody, name, targetDomain, url) { + as.reject() + .id(`https://${activityPub.domain}/activitypub/users/${name}/status/` + crypto.randomBytes(16).toString('hex')) + .actor(`https://${activityPub.domain}/activitypub/users/${name}`) + .object(theBody) + .prettyWrite((err, doc) => { + if (!err) { + return signAndSend(doc, name, targetDomain, url) + } else { + debug(`error serializing Accept object: ${err}`) + throw new Error('error serializing Accept object') + } + }) +} + +export function isPublicAddressed (postObject) { + if (typeof postObject.to === 'string') { + postObject.to = [postObject.to] + } + return postObject.to.includes('Public') || + postObject.to.includes('as:Public') || + postObject.to.includes('https://www.w3.org/ns/activitystreams#Public') +} diff --git a/src/activitypub/utils/actor.js b/src/activitypub/utils/actor.js new file mode 100644 index 000000000..0b8cc7454 --- /dev/null +++ b/src/activitypub/utils/actor.js @@ -0,0 +1,40 @@ +import { activityPub } from '../ActivityPub' + +export function createActor (name, pubkey) { + return { + '@context': [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1' + ], + 'id': `https://${activityPub.domain}/activitypub/users/${name}`, + 'type': 'Person', + 'preferredUsername': `${name}`, + 'name': `${name}`, + 'following': `https://${activityPub.domain}/activitypub/users/${name}/following`, + 'followers': `https://${activityPub.domain}/activitypub/users/${name}/followers`, + 'inbox': `https://${activityPub.domain}/activitypub/users/${name}/inbox`, + 'outbox': `https://${activityPub.domain}/activitypub/users/${name}/outbox`, + 'url': `https://${activityPub.domain}/activitypub/@${name}`, + 'endpoints': { + 'sharedInbox': `https://${activityPub.domain}/activitypub/inbox` + }, + 'publicKey': { + 'id': `https://${activityPub.domain}/activitypub/users/${name}#main-key`, + 'owner': `https://${activityPub.domain}/activitypub/users/${name}`, + 'publicKeyPem': pubkey + } + } +} + +export function createWebFinger (name) { + return { + 'subject': `acct:${name}@${activityPub.domain}`, + 'links': [ + { + 'rel': 'self', + 'type': 'application/activity+json', + 'href': `https://${activityPub.domain}/users/${name}` + } + ] + } +} diff --git a/src/activitypub/utils/collection.js b/src/activitypub/utils/collection.js new file mode 100644 index 000000000..379febe43 --- /dev/null +++ b/src/activitypub/utils/collection.js @@ -0,0 +1,70 @@ +import { activityPub } from '../ActivityPub' +import { constructIdFromName } from './index' +const debug = require('debug')('ea:utils:collections') + +export function createOrderedCollection (name, collectionName) { + return { + '@context': 'https://www.w3.org/ns/activitystreams', + 'id': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}`, + 'summary': `${name}s ${collectionName} collection`, + 'type': 'OrderedCollection', + 'first': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}?page=true`, + 'totalItems': 0 + } +} + +export function createOrderedCollectionPage (name, collectionName) { + return { + '@context': 'https://www.w3.org/ns/activitystreams', + 'id': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}?page=true`, + 'summary': `${name}s ${collectionName} collection`, + 'type': 'OrderedCollectionPage', + 'totalItems': 0, + 'partOf': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}`, + 'orderedItems': [] + } +} +export function sendCollection (collectionName, req, res) { + const name = req.params.name + const id = constructIdFromName(name) + + switch (collectionName) { + case 'followers': + attachThenCatch(activityPub.getFollowersCollection(id), res) + break + + case 'followersPage': + attachThenCatch(activityPub.getFollowersCollectionPage(id), res) + break + + case 'following': + attachThenCatch(activityPub.getFollowingCollection(id), res) + break + + case 'followingPage': + attachThenCatch(activityPub.getFollowingCollectionPage(id), res) + break + + case 'outbox': + attachThenCatch(activityPub.getOutboxCollection(id), res) + break + + case 'outboxPage': + attachThenCatch(activityPub.getOutboxCollectionPage(id), res) + break + + default: + res.status(500).end() + } +} + +function attachThenCatch (promise, res) { + return promise + .then((collection) => { + res.status(200).contentType('application/activity+json').send(collection) + }) + .catch((err) => { + debug(`error getting a Collection: = ${err}`) + res.status(500).end() + }) +} diff --git a/src/activitypub/utils/index.js b/src/activitypub/utils/index.js index 9df537e79..0cb4b7d0d 100644 --- a/src/activitypub/utils/index.js +++ b/src/activitypub/utils/index.js @@ -1,5 +1,3 @@ -import crypto from 'crypto' -import as from 'activitystrea.ms' import { activityPub } from '../ActivityPub' import gql from 'graphql-tag' import { createSignature } from '../security' @@ -23,194 +21,14 @@ export function extractIdFromActivityId (uri) { } export function constructIdFromName (name, fromDomain = activityPub.domain) { - return `https://${fromDomain}/activitypub/users/${name}` + return `http://${fromDomain}/activitypub/users/${name}` } export function extractDomainFromUrl (url) { return new URL(url).hostname } -export async function getActorIdByName (name) { - debug(`name = ${name}`) - return Promise.resolve() -} - -export function sendCollection (collectionName, req, res) { - const name = req.params.name - const id = constructIdFromName(name) - - switch (collectionName) { - case 'followers': - attachThenCatch(activityPub.getFollowersCollection(id), res) - break - - case 'followersPage': - attachThenCatch(activityPub.getFollowersCollectionPage(id), res) - break - - case 'following': - attachThenCatch(activityPub.getFollowingCollection(id), res) - break - - case 'followingPage': - attachThenCatch(activityPub.getFollowingCollectionPage(id), res) - break - - case 'outbox': - attachThenCatch(activityPub.getOutboxCollection(id), res) - break - - case 'outboxPage': - attachThenCatch(activityPub.getOutboxCollectionPage(id), res) - break - - default: - res.status(500).end() - } -} - -function attachThenCatch (promise, res) { - return promise - .then((collection) => { - res.status(200).contentType('application/activity+json').send(collection) - }) - .catch((err) => { - debug(`error getting a Collection: = ${err}`) - res.status(500).end() - }) -} - -export function createActor (name, pubkey) { - return { - '@context': [ - 'https://www.w3.org/ns/activitystreams', - 'https://w3id.org/security/v1' - ], - 'id': `https://${activityPub.domain}/activitypub/users/${name}`, - 'type': 'Person', - 'preferredUsername': `${name}`, - 'name': `${name}`, - 'following': `https://${activityPub.domain}/activitypub/users/${name}/following`, - 'followers': `https://${activityPub.domain}/activitypub/users/${name}/followers`, - 'inbox': `https://${activityPub.domain}/activitypub/users/${name}/inbox`, - 'outbox': `https://${activityPub.domain}/activitypub/users/${name}/outbox`, - 'url': `https://${activityPub.domain}/activitypub/@${name}`, - 'endpoints': { - 'sharedInbox': `https://${activityPub.domain}/activitypub/inbox` - }, - 'publicKey': { - 'id': `https://${activityPub.domain}/activitypub/users/${name}#main-key`, - 'owner': `https://${activityPub.domain}/activitypub/users/${name}`, - 'publicKeyPem': pubkey - } - } -} - -export function createWebFinger (name) { - return { - 'subject': `acct:${name}@${activityPub.domain}`, - 'links': [ - { - 'rel': 'self', - 'type': 'application/activity+json', - 'href': `https://${activityPub.domain}/users/${name}` - } - ] - } -} - -export function createOrderedCollection (name, collectionName) { - return { - '@context': 'https://www.w3.org/ns/activitystreams', - 'id': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}`, - 'summary': `${name}s ${collectionName} collection`, - 'type': 'OrderedCollection', - 'first': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}?page=true`, - 'totalItems': 0 - } -} - -export function createOrderedCollectionPage (name, collectionName) { - return { - '@context': 'https://www.w3.org/ns/activitystreams', - 'id': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}?page=true`, - 'summary': `${name}s ${collectionName} collection`, - 'type': 'OrderedCollectionPage', - 'totalItems': 0, - 'partOf': `https://${activityPub.domain}/activitypub/users/${name}/${collectionName}`, - 'orderedItems': [] - } -} - -export function createNoteActivity (text, name, id, published) { - const createUuid = crypto.randomBytes(16).toString('hex') - - return { - '@context': 'https://www.w3.org/ns/activitystreams', - 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${createUuid}`, - 'type': 'Create', - 'actor': `https://${activityPub.domain}/activitypub/users/${name}`, - 'object': { - 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${id}`, - 'type': 'Note', - 'published': published, - 'attributedTo': `https://${activityPub.domain}/activitypub/users/${name}`, - 'content': text, - 'to': 'https://www.w3.org/ns/activitystreams#Public' - } - } -} - -export function createArticleActivity (text, name, id, published) { - const createUuid = crypto.randomBytes(16).toString('hex') - - return { - '@context': 'https://www.w3.org/ns/activitystreams', - 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${createUuid}`, - 'type': 'Create', - 'actor': `https://${activityPub.domain}/activitypub/users/${name}`, - 'object': { - 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${id}`, - 'type': 'Article', - 'published': published, - 'attributedTo': `https://${activityPub.domain}/activitypub/users/${name}`, - 'content': text, - 'to': 'https://www.w3.org/ns/activitystreams#Public' - } - } -} - -export function sendAcceptActivity (theBody, name, targetDomain, url) { - as.accept() - .id(`https://${activityPub.domain}/activitypub/users/${name}/status/` + crypto.randomBytes(16).toString('hex')) - .actor(`https://${activityPub.domain}/activitypub/users/${name}`) - .object(theBody) - .prettyWrite((err, doc) => { - if (!err) { - return signAndSend(doc, name, targetDomain, url) - } else { - debug(`error serializing Accept object: ${err}`) - throw new Error('error serializing Accept object') - } - }) -} - -export function sendRejectActivity (theBody, name, targetDomain, url) { - as.reject() - .id(`https://${activityPub.domain}/activitypub/users/${name}/status/` + crypto.randomBytes(16).toString('hex')) - .actor(`https://${activityPub.domain}/activitypub/users/${name}`) - .object(theBody) - .prettyWrite((err, doc) => { - if (!err) { - return signAndSend(doc, name, targetDomain, url) - } else { - debug(`error serializing Accept object: ${err}`) - throw new Error('error serializing Accept object') - } - }) -} - -export function throwErrorIfGraphQLErrorOccurred (result) { +export function throwErrorIfApolloErrorOccurred (result) { if (result.error && (result.error.message || result.error.errors)) { throw new Error(`${result.error.message ? result.error.message : result.error.errors[0].message}`) } diff --git a/src/graphql-schema.js b/src/graphql-schema.js index e5da2ce54..65dfc8cda 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -169,6 +169,7 @@ export const resolvers = { CreatePost: async (object, params, ctx, resolveInfo) => { params.activityId = uuid() const result = await neo4jgraphql(object, params, ctx, resolveInfo, false) + debug(`user = ${JSON.stringify(ctx.user, null, 2)}`) const session = ctx.driver.session() const author = await session.run( 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + @@ -177,7 +178,7 @@ export const resolvers = { userId: ctx.user.id, postId: result.id }) - session.close() + debug(`author = ${JSON.stringify(author, null, 2)}`) const actorId = author.records[0]._fields[0].properties.actorId const createActivity = await new Promise((resolve, reject) => { as.create() @@ -188,6 +189,7 @@ export const resolvers = { .id(`${actorId}/status/${result.id}`) .content(result.content) .to('https://www.w3.org/ns/activitystreams#Public') + .publishedNow() .attributedTo(`${actorId}`) ).prettyWrite((err, doc) => { if (err) { @@ -200,6 +202,7 @@ export const resolvers = { } }) }) + session.close() // try sending post via ActivityPub await new Promise((resolve) => { const url = new URL(actorId) diff --git a/yarn.lock b/yarn.lock index 78cabe011..05299ad6e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1072,6 +1072,13 @@ apollo-graphql@^0.1.0: dependencies: lodash.sortby "^4.7.0" +apollo-link-context@^1.0.14: + version "1.0.14" + resolved "https://registry.yarnpkg.com/apollo-link-context/-/apollo-link-context-1.0.14.tgz#6265eef49bedadddbbcff4026d04cd351094cd6c" + integrity sha512-l6SIN7Fwqhgg5C5eA8xSrt8gulHBmYTE3J4z5/Q2hP/8Kok0rQ/z5q3uy42/hkdYlnaktOvpz+ZIwEFzcXwujQ== + dependencies: + apollo-link "^1.2.8" + apollo-link-dedup@^1.0.0: version "1.0.11" resolved "https://registry.yarnpkg.com/apollo-link-dedup/-/apollo-link-dedup-1.0.11.tgz#6f34ea748d2834850329ad03111ef18445232b05" From 7a063d1707bdff3b680e1be8fe2a5866519964c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 27 Feb 2019 04:34:03 +0000 Subject: [PATCH 419/554] Bump apollo-cache-inmemory from 1.4.3 to 1.5.0 Bumps [apollo-cache-inmemory](https://github.com/apollographql/apollo-client) from 1.4.3 to 1.5.0. - [Release notes](https://github.com/apollographql/apollo-client/releases) - [Changelog](https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-client/compare/apollo-cache-inmemory@1.4.3...apollo-cache-inmemory@1.5.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 41 +++++++++++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 173f1ced7..989925a2c 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ ] }, "dependencies": { - "apollo-cache-inmemory": "~1.4.3", + "apollo-cache-inmemory": "~1.5.0", "apollo-client": "~2.4.13", "apollo-link-http": "~1.5.11", "apollo-server": "~2.4.2", diff --git a/yarn.lock b/yarn.lock index 91e971746..473cf22ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -953,17 +953,18 @@ apollo-cache-control@^0.1.0: dependencies: graphql-extensions "^0.0.x" -apollo-cache-inmemory@~1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.4.3.tgz#aded4fb8b3de9e2fb2573a6c03591b07ef98ed36" - integrity sha512-p9KGtEZ9Mlb+FS0UEaxR8WvKOijYV0c+TXlhC/XZ3/ltYvP1zL3b1ozSOLGR9SawN2895Fc7QDV5nzPpihV0rA== +apollo-cache-inmemory@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.5.0.tgz#90b1a38f744762ab47c415b9d7b2d32fbd803088" + integrity sha512-hyg8R7G3XOfZhl8fQLs0vGEwi2rr8PuEIiumCY4qmwviaGsmwjs/Dm63cyeMm3Sfu05vzFQkwMdBf5u7xBg3cQ== dependencies: - apollo-cache "^1.1.26" - apollo-utilities "^1.1.3" + apollo-cache "^1.2.0" + apollo-utilities "^1.2.0" optimism "^0.6.9" + ts-invariant "^0.2.1" tslib "^1.9.3" -apollo-cache@1.1.26, apollo-cache@^1.1.26: +apollo-cache@1.1.26: version "1.1.26" resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.26.tgz#5afe023270effbc2063d90f51d8e56bce274ab37" integrity sha512-JKFHijwkhXpcQ3jOat+ctwiXyjDhQgy0p6GSaj7zG+or+ZSalPqUnPzFRgRwFLVbYxBKJgHCkWX+2VkxWTZzQQ== @@ -971,6 +972,14 @@ apollo-cache@1.1.26, apollo-cache@^1.1.26: apollo-utilities "^1.1.3" tslib "^1.9.3" +apollo-cache@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.2.0.tgz#7ebfc9a53027264e4a5bce9b886471cc77c50784" + integrity sha512-aZduG7o75crjWeONq9kVzkqO9hAcEklo3oN6Rd+ANpB+ImRklCFkz88XdXQ2/GHV26jh8VtQJIhiNIow10QzIg== + dependencies: + apollo-utilities "^1.2.0" + tslib "^1.9.3" + apollo-client@~2.4.13: version "2.4.13" resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.13.tgz#09829fcbd68e069de9840d0a10764d7c6a3d0787" @@ -1198,7 +1207,7 @@ apollo-upload-server@^7.0.0: http-errors "^1.7.0" object-path "^0.11.4" -apollo-utilities@1.1.3, apollo-utilities@^1.0.1, apollo-utilities@^1.1.3: +apollo-utilities@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.3.tgz#a8883c0392f6b46eac0d366204ebf34be9307c87" integrity sha512-pF9abhiClX5gfj/WFWZh8DiI33nOLGxRhXH9ZMquaM1V8bhq1WLFPt2QjShWH3kGQVeIGUK+FQefnhe+ZaaAYg== @@ -1206,6 +1215,15 @@ apollo-utilities@1.1.3, apollo-utilities@^1.0.1, apollo-utilities@^1.1.3: fast-json-stable-stringify "^2.0.0" tslib "^1.9.3" +apollo-utilities@^1.0.1, apollo-utilities@^1.1.3, apollo-utilities@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.2.0.tgz#ba5a1271c55e0d79069b1919c9d533164a70f9c3" + integrity sha512-4+vxCpEuirQjPqLCckBnOMGZxK/c+2eJtYEbh3xhccNM1pYB5Gx/lrfCdZS5MKDykuWZYY08EvidDy21nr049w== + dependencies: + fast-json-stable-stringify "^2.0.0" + ts-invariant "^0.2.1" + tslib "^1.9.3" + append-transform@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" @@ -6720,6 +6738,13 @@ trunc-text@1.0.1: resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" integrity sha1-WPh22KxZsiS3mDS7R4uGVuaWIrU= +ts-invariant@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.2.1.tgz#3d587f9d6e3bded97bf9ec17951dd9814d5a9d3f" + integrity sha512-Z/JSxzVmhTo50I+LKagEISFJW3pvPCqsMWLamCTX8Kr3N5aMrnGOqcflbe5hLUzwjvgPfnLzQtHZv0yWQ+FIHg== + dependencies: + tslib "^1.9.3" + tslib@^1.9.0, tslib@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" From 5fd44230ddc5660757185a78b572979da0d5e6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 27 Feb 2019 10:42:55 +0100 Subject: [PATCH 420/554] Get rid of LoggedInUser graphql type This was causing a lot of headache on the frontend. Now, there a single source of truth. If you query `currentUser` you can overwrite your local copy of the user and update the UI. --- src/jest/helpers.js | 6 ++---- src/resolvers/user_management.js | 15 +++++++-------- src/resolvers/user_management.spec.js | 10 +++------- src/schema.graphql | 14 ++------------ src/seed/factories/index.js | 6 ++---- 5 files changed, 16 insertions(+), 35 deletions(-) diff --git a/src/jest/helpers.js b/src/jest/helpers.js index ff6a535e2..0d358ed40 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -7,12 +7,10 @@ export const host = 'http://127.0.0.1:4123' export async function login ({ email, password }) { const mutation = ` mutation { - login(email:"${email}", password:"${password}"){ - token - } + login(email:"${email}", password:"${password}") }` const response = await request(host, mutation) return { - authorization: `Bearer ${response.login.token}` + authorization: `Bearer ${response.login}` } } diff --git a/src/resolvers/user_management.js b/src/resolvers/user_management.js index b0c9d3df5..552f6201a 100644 --- a/src/resolvers/user_management.js +++ b/src/resolvers/user_management.js @@ -1,16 +1,18 @@ import encode from '../jwt/encode' -import { fixUrl } from '../middleware/fixImageUrlsMiddleware' import bcrypt from 'bcryptjs' import { AuthenticationError } from 'apollo-server' +import { neo4jgraphql } from 'neo4j-graphql-js' export default { Query: { isLoggedIn: (parent, args, { driver, user }) => { return Boolean(user && user.id) }, - currentUser: (parent, args, { user }) => { - return user - } + currentUser: async (object, params, ctx, resolveInfo) => { + const { user} = ctx + if(!user) return null + return neo4jgraphql(object, {id: user.id}, ctx, resolveInfo, false) + }, }, Mutation: { signup: async (parent, { email, password }, { req }) => { @@ -41,10 +43,7 @@ export default { if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { delete currentUser.password - currentUser.avatar = fixUrl(currentUser.avatar) - return Object.assign(currentUser, { - token: encode(currentUser) - }) + return encode(currentUser) } else throw new AuthenticationError('Incorrect email address or password.') }) } diff --git a/src/resolvers/user_management.spec.js b/src/resolvers/user_management.spec.js index cb12efb2d..a3bf6fdd0 100644 --- a/src/resolvers/user_management.spec.js +++ b/src/resolvers/user_management.spec.js @@ -82,7 +82,6 @@ describe('currentUser', () => { avatar email role - token } }` @@ -122,8 +121,7 @@ describe('currentUser', () => { id: 'acb2d923-f3af-479e-9f00-61b12e864666', name: 'Matilde Hermiston', slug: 'matilde-hermiston', - role: 'user', - token: headers.authorization.replace('Bearer ', '') + role: 'user' } } await expect(client.request(query)).resolves.toEqual(expected) @@ -137,9 +135,7 @@ describe('login', () => { const { email, password } = params return ` mutation { - login(email:"${email}", password:"${password}"){ - token - } + login(email:"${email}", password:"${password}") }` } @@ -150,7 +146,7 @@ describe('login', () => { email: 'test@example.org', password: '1234' })) - const { token } = data.login + const token = data.login jwt.verify(token, process.env.JWT_SECRET, (err, data) => { expect(data.email).toEqual('test@example.org') expect(err).toBeNull() diff --git a/src/schema.graphql b/src/schema.graphql index 4413e1deb..1f9bcb477 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -1,24 +1,14 @@ type Query { isLoggedIn: Boolean! - currentUser: LoggedInUser + currentUser: User statistics: Statistics! } type Mutation { - login(email: String!, password: String!): LoggedInUser + login(email: String!, password: String!): String! signup(email: String!, password: String!): Boolean! report(resource: Resource!, description: String): Report } -type LoggedInUser { - id: ID! - slug: String! - name: String! - avatar:String! - email: String! - role: String! - token: String! -} - type Statistics { countUsers: Int! countPosts: Int! diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index d9bbd700c..ed35d2c3b 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -15,13 +15,11 @@ export const seedServerHost = 'http://127.0.0.1:4001' const authenticatedHeaders = async ({ email, password }, host) => { const mutation = ` mutation { - login(email:"${email}", password:"${password}"){ - token - } + login(email:"${email}", password:"${password}") }` const response = await request(host, mutation) return { - authorization: `Bearer ${response.login.token}` + authorization: `Bearer ${response.login}` } } const factories = { From f9b60fa0b0b7bbec42eab38c22e39d58695c066d Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Wed, 27 Feb 2019 08:10:20 -0300 Subject: [PATCH 421/554] Fix lint --- src/resolvers/user_management.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/resolvers/user_management.js b/src/resolvers/user_management.js index 552f6201a..ec4ae7ce2 100644 --- a/src/resolvers/user_management.js +++ b/src/resolvers/user_management.js @@ -9,10 +9,10 @@ export default { return Boolean(user && user.id) }, currentUser: async (object, params, ctx, resolveInfo) => { - const { user} = ctx - if(!user) return null - return neo4jgraphql(object, {id: user.id}, ctx, resolveInfo, false) - }, + const { user } = ctx + if (!user) return null + return neo4jgraphql(object, { id: user.id }, ctx, resolveInfo, false) + } }, Mutation: { signup: async (parent, { email, password }, { req }) => { From 25eef848f6ae55af9b3e3faf354eb6b5fbb8bf98 Mon Sep 17 00:00:00 2001 From: Armin Date: Wed, 27 Feb 2019 15:04:54 +0100 Subject: [PATCH 422/554] Fetch actorObject and lookup inbox before sending object + addCommentAuthor --- src/activitypub/ActivityPub.js | 32 ++++++++++++++++++++++----- src/activitypub/NitroDatasource.js | 15 +++++++++++-- test/features/activity-follow.feature | 7 +++--- test/features/activity-like.feature | 24 ++++++++++++++++++++ 4 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 test/features/activity-like.feature diff --git a/src/activitypub/ActivityPub.js b/src/activitypub/ActivityPub.js index 74e047e12..c2ea1b2c1 100644 --- a/src/activitypub/ActivityPub.js +++ b/src/activitypub/ActivityPub.js @@ -122,6 +122,8 @@ export default class ActivityPub { case 'Follow': const followActivity = activity.object return this.dataSource.undoFollowActivity(followActivity.actor, followActivity.object) + case 'Like': + return this.dataSource.deleteShouted(activity) default: } } @@ -180,10 +182,25 @@ export default class ActivityPub { } } + getActorObject (url) { + return new Promise((resolve, reject) => { + request({ + url: url, + headers: { + 'Accept': 'application/json' + } + }, (err, response, body) => { + if (err) { + reject(err) + } + resolve(JSON.parse(body)) + }) + }) + } + async sendActivity (activity) { delete activity.send const fromName = extractNameFromId(activity.actor) - if (Array.isArray(activity.to) && isPublicAddressed(activity)) { const sharedInboxEndpoints = await this.dataSource.getSharedInboxEndpoints() // serve shared inbox endpoints @@ -194,14 +211,17 @@ export default class ActivityPub { return !(isPublicAddressed({ to: el })) }) // serve the rest - activity.to.map((el) => { - return this.trySend(activity, fromName, new URL(el).host, el) + activity.to.map(async (el) => { + const actorObject = await this.getActorObject(el) + return this.trySend(activity, fromName, new URL(el).host, actorObject.inbox) }) } else if (typeof activity.to === 'string') { - return this.trySend(activity, fromName, new URL(activity.to).host, activity.to) + const actorObject = await this.getActorObject(activity.to) + return this.trySend(activity, fromName, new URL(activity.to).host, actorObject.inbox) } else if (Array.isArray(activity.to)) { - activity.to.map((el) => { - return this.trySend(activity, fromName, new URL(el).host, el) + activity.to.map(async (el) => { + const actorObject = await this.getActorObject(el) + return this.trySend(activity, fromName, new URL(el).host, actorObject.inbox) }) } } diff --git a/src/activitypub/NitroDatasource.js b/src/activitypub/NitroDatasource.js index 19e931eef..054b77854 100644 --- a/src/activitypub/NitroDatasource.js +++ b/src/activitypub/NitroDatasource.js @@ -472,10 +472,21 @@ export default class NitroDatasource { } ` }) - throwErrorIfApolloErrorOccurred(result) - const postId = extractIdFromActivityId(postObject.inReplyTo) + const toUserId = await this.ensureUser(activity.actor) + const result2 = await this.client.mutate({ + mutation: gql` + mutation { + AddCommentAuthor(from: {id: "${result.data.CreateComment.id}"}, to: {id: "${toUserId}"}) { + id + } + } + ` + }) + throwErrorIfApolloErrorOccurred(result2) + + const postId = extractIdFromActivityId(postObject.inReplyTo) result = await this.client.mutate({ mutation: gql` mutation { diff --git a/test/features/activity-follow.feature b/test/features/activity-follow.feature index 578e57cb1..a6974309c 100644 --- a/test/features/activity-follow.feature +++ b/test/features/activity-follow.feature @@ -6,9 +6,10 @@ Feature: Follow a user Background: Given our own server runs at "http://localhost:4123" And we have the following users in our database: - | Slug | - | karl-heinz | - | peter-lustiger | + | Slug | + | peter-lustiger | + | bob-der-baumeister | + | karl-heinz | Scenario: Send a follow to a user inbox and make sure it's added to the right followers collection When I send a POST request with the following activity to "/activitypub/users/peter-lustiger/inbox": diff --git a/test/features/activity-like.feature b/test/features/activity-like.feature new file mode 100644 index 000000000..c605bdb76 --- /dev/null +++ b/test/features/activity-like.feature @@ -0,0 +1,24 @@ +Feature: Like an object like an article or note + As a user I want to like others posts + Also if I do not want to follow a previous followed user anymore, + I want to undo the follow. + + Background: + Given our own server runs at "http://localhost:4123" + And we have the following users in our database: + | Slug | + | karl-heinz | + | peter-lustiger | + + Scenario: Send a like of a person to an users inbox and make sure it's added to the likes collection + When I send a POST request with the following activity to "/activitypub/users/karl-heinz/inbox": + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4123/activitypub/users/peter-lustiger/status/83J23549sda1k72fsa4567na42312455kad83", + "type": "Like", + "actor": "http://localhost:4123/activitypub/users/peter-lustiger + "object": "http://localhost:4123/activitypub/users/karl-heinz" + } + """ + Then I expect the status code to be 200 From b76de03e2804afcb0b4da16b7e6d923adc639a9e Mon Sep 17 00:00:00 2001 From: Armin Date: Wed, 27 Feb 2019 15:17:12 +0100 Subject: [PATCH 423/554] ActivityPub now also usable standalone --- src/activitypub/ActivityPub.js | 37 +++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/activitypub/ActivityPub.js b/src/activitypub/ActivityPub.js index c2ea1b2c1..4f5774d9d 100644 --- a/src/activitypub/ActivityPub.js +++ b/src/activitypub/ActivityPub.js @@ -8,13 +8,18 @@ import { sendAcceptActivity, sendRejectActivity } from './utils/activity' +import cluster from 'cluster' +import os from 'os' import request from 'request' import as from 'activitystrea.ms' import NitroDatasource from './NitroDatasource' import router from './routes' import dotenv from 'dotenv' +import express from 'express' +import http from 'http' import { resolve } from 'path' const debug = require('debug')('ea') +const numCPUs = os.cpus().length let activityPub = null @@ -29,11 +34,33 @@ export default class ActivityPub { static init (server) { if (!activityPub) { dotenv.config({ path: resolve('src', 'activitypub', '.env') }) - // const app = express() - activityPub = new ActivityPub(process.env.ACTIVITYPUB_DOMAIN || 'localhost', process.env.ACTIVITYPUB_PORT || 4100) - server.express.set('ap', activityPub) - server.express.use(router) - debug('ActivityPub middleware added to the express service') + const port = process.env.ACTIVITYPUB_PORT + activityPub = new ActivityPub(process.env.ACTIVITYPUB_DOMAIN || 'localhost', port || 4100) + + if (server) { + // integrated into "server" express framework + server.express.set('ap', activityPub) + server.express.use(router) + debug('ActivityPub middleware added to the express service') + } else { + if (cluster.isMaster) { + debug(`master with pid = ${process.pid} is running`) + for (let i = 0; i < numCPUs; i++) { + cluster.fork() + } + cluster.on('exit', (worker, code, signal) => { + debug(`worker ${worker.process.pid} died with code ${code} and signal ${signal}`) + }) + } else { + // Standalone + const app = express() + app.set('ap', activityPub) + app.use(router) + http.createServer(app).listen(port, () => { + debug(`ActivityPub express service listening on port ${port}`) + }) + } + } } else { debug('ActivityPub middleware already added to the express service') } From 14a57d1ebfbb4348943891ce80761b89f498e442 Mon Sep 17 00:00:00 2001 From: Armin Date: Wed, 27 Feb 2019 15:44:01 +0100 Subject: [PATCH 424/554] Refactoring + fixes --- src/activitypub/ActivityPub.js | 34 ++++--------------- src/activitypub/Collections.js | 28 +++++++++++++++ ...{NitroDatasource.js => NitroDataSource.js} | 2 +- src/activitypub/utils/collection.js | 12 +++---- 4 files changed, 42 insertions(+), 34 deletions(-) create mode 100644 src/activitypub/Collections.js rename src/activitypub/{NitroDatasource.js => NitroDataSource.js} (99%) diff --git a/src/activitypub/ActivityPub.js b/src/activitypub/ActivityPub.js index 4f5774d9d..4bdbc9563 100644 --- a/src/activitypub/ActivityPub.js +++ b/src/activitypub/ActivityPub.js @@ -12,12 +12,13 @@ import cluster from 'cluster' import os from 'os' import request from 'request' import as from 'activitystrea.ms' -import NitroDatasource from './NitroDatasource' +import NitroDataSource from './NitroDataSource' import router from './routes' import dotenv from 'dotenv' import express from 'express' import http from 'http' import { resolve } from 'path' +import Collections from './Collections' const debug = require('debug')('ea') const numCPUs = os.cpus().length @@ -29,7 +30,8 @@ export default class ActivityPub { constructor (domain, port) { if (domain === 'localhost') { this.domain = `${domain}:${port}` } else { this.domain = domain } this.port = port - this.dataSource = new NitroDatasource(this.domain) + this.dataSource = new NitroDataSource(this.domain) + this.collections = new Collections(this.dataSource) } static init (server) { if (!activityPub) { @@ -43,6 +45,7 @@ export default class ActivityPub { server.express.use(router) debug('ActivityPub middleware added to the express service') } else { + // standalone clustered ActivityPub service if (cluster.isMaster) { debug(`master with pid = ${process.pid} is running`) for (let i = 0; i < numCPUs; i++) { @@ -52,7 +55,6 @@ export default class ActivityPub { debug(`worker ${worker.process.pid} died with code ${code} and signal ${signal}`) }) } else { - // Standalone const app = express() app.set('ap', activityPub) app.use(router) @@ -66,30 +68,6 @@ export default class ActivityPub { } } - getFollowersCollection (actorId) { - return this.dataSource.getFollowersCollection(actorId) - } - - getFollowersCollectionPage (actorId) { - return this.dataSource.getFollowersCollectionPage(actorId) - } - - getFollowingCollection (actorId) { - return this.dataSource.getFollowingCollection(actorId) - } - - getFollowingCollectionPage (actorId) { - return this.dataSource.getFollowingCollectionPage(actorId) - } - - getOutboxCollection (actorId) { - return this.dataSource.getOutboxCollection(actorId) - } - - getOutboxCollectionPage (actorId) { - return this.dataSource.getOutboxCollectionPage(actorId) - } - handleFollowActivity (activity) { debug(`inside FOLLOW ${activity.actor}`) let toActorName = extractNameFromId(activity.object) @@ -191,10 +169,12 @@ export default class ActivityPub { } handleLikeActivity (activity) { + // TODO differ if activity is an Article/Note/etc. return this.dataSource.createShouted(activity) } handleDislikeActivity (activity) { + // TODO differ if activity is an Article/Note/etc. return this.dataSource.deleteShouted(activity) } diff --git a/src/activitypub/Collections.js b/src/activitypub/Collections.js new file mode 100644 index 000000000..227e1717b --- /dev/null +++ b/src/activitypub/Collections.js @@ -0,0 +1,28 @@ +export default class Collections { + constructor (dataSource) { + this.dataSource = dataSource + } + getFollowersCollection (actorId) { + return this.dataSource.getFollowersCollection(actorId) + } + + getFollowersCollectionPage (actorId) { + return this.dataSource.getFollowersCollectionPage(actorId) + } + + getFollowingCollection (actorId) { + return this.dataSource.getFollowingCollection(actorId) + } + + getFollowingCollectionPage (actorId) { + return this.dataSource.getFollowingCollectionPage(actorId) + } + + getOutboxCollection (actorId) { + return this.dataSource.getOutboxCollection(actorId) + } + + getOutboxCollectionPage (actorId) { + return this.dataSource.getOutboxCollectionPage(actorId) + } +} diff --git a/src/activitypub/NitroDatasource.js b/src/activitypub/NitroDataSource.js similarity index 99% rename from src/activitypub/NitroDatasource.js rename to src/activitypub/NitroDataSource.js index 054b77854..11be287d7 100644 --- a/src/activitypub/NitroDatasource.js +++ b/src/activitypub/NitroDataSource.js @@ -28,7 +28,7 @@ const debug = require('debug')('ea:nitro-datasource') dotenv.config({ path: resolve('src', 'activitypub', '.env') }) -export default class NitroDatasource { +export default class NitroDataSource { constructor (domain) { this.domain = domain const defaultOptions = { diff --git a/src/activitypub/utils/collection.js b/src/activitypub/utils/collection.js index 379febe43..4c46adbde 100644 --- a/src/activitypub/utils/collection.js +++ b/src/activitypub/utils/collection.js @@ -30,27 +30,27 @@ export function sendCollection (collectionName, req, res) { switch (collectionName) { case 'followers': - attachThenCatch(activityPub.getFollowersCollection(id), res) + attachThenCatch(activityPub.collections.getFollowersCollection(id), res) break case 'followersPage': - attachThenCatch(activityPub.getFollowersCollectionPage(id), res) + attachThenCatch(activityPub.collections.getFollowersCollectionPage(id), res) break case 'following': - attachThenCatch(activityPub.getFollowingCollection(id), res) + attachThenCatch(activityPub.collections.getFollowingCollection(id), res) break case 'followingPage': - attachThenCatch(activityPub.getFollowingCollectionPage(id), res) + attachThenCatch(activityPub.collections.getFollowingCollectionPage(id), res) break case 'outbox': - attachThenCatch(activityPub.getOutboxCollection(id), res) + attachThenCatch(activityPub.collections.getOutboxCollection(id), res) break case 'outboxPage': - attachThenCatch(activityPub.getOutboxCollectionPage(id), res) + attachThenCatch(activityPub.collections.getOutboxCollectionPage(id), res) break default: From 100aad61e12424e868453005366754a6de1aafa5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 27 Feb 2019 19:33:45 +0000 Subject: [PATCH 425/554] Bump apollo-client from 2.4.13 to 2.5.1 Bumps [apollo-client](https://github.com/apollographql/apollo-client) from 2.4.13 to 2.5.1. - [Release notes](https://github.com/apollographql/apollo-client/releases) - [Changelog](https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-client/compare/apollo-client@2.4.13...apollo-client@2.5.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 47 ++++++++++++++++------------------------------- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 989925a2c..a50bf4bfb 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "dependencies": { "apollo-cache-inmemory": "~1.5.0", - "apollo-client": "~2.4.13", + "apollo-client": "~2.5.1", "apollo-link-http": "~1.5.11", "apollo-server": "~2.4.2", "bcryptjs": "~2.4.3", diff --git a/yarn.lock b/yarn.lock index 473cf22ce..ab877303f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -964,33 +964,26 @@ apollo-cache-inmemory@~1.5.0: ts-invariant "^0.2.1" tslib "^1.9.3" -apollo-cache@1.1.26: - version "1.1.26" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.26.tgz#5afe023270effbc2063d90f51d8e56bce274ab37" - integrity sha512-JKFHijwkhXpcQ3jOat+ctwiXyjDhQgy0p6GSaj7zG+or+ZSalPqUnPzFRgRwFLVbYxBKJgHCkWX+2VkxWTZzQQ== +apollo-cache@1.2.1, apollo-cache@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.2.1.tgz#aae71eb4a11f1f7322adc343f84b1a39b0693644" + integrity sha512-nzFmep/oKlbzUuDyz6fS6aYhRmfpcHWqNkkA9Bbxwk18RD6LXC4eZkuE0gXRX0IibVBHNjYVK+Szi0Yied4SpQ== dependencies: - apollo-utilities "^1.1.3" + apollo-utilities "^1.2.1" tslib "^1.9.3" -apollo-cache@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.2.0.tgz#7ebfc9a53027264e4a5bce9b886471cc77c50784" - integrity sha512-aZduG7o75crjWeONq9kVzkqO9hAcEklo3oN6Rd+ANpB+ImRklCFkz88XdXQ2/GHV26jh8VtQJIhiNIow10QzIg== - dependencies: - apollo-utilities "^1.2.0" - tslib "^1.9.3" - -apollo-client@~2.4.13: - version "2.4.13" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.13.tgz#09829fcbd68e069de9840d0a10764d7c6a3d0787" - integrity sha512-7mBdW/CW1qHB8Mj4EFAG3MTtbRc6S8aUUntUdrKfRWV1rZdWa0NovxsgVD/R4HZWZjRQ2UOM4ENsHdM5g1uXOQ== +apollo-client@~2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.5.1.tgz#36126ed1d32edd79c3713c6684546a3bea80e6d1" + integrity sha512-MNcQKiqLHdGmNJ0rZ0NXaHrToXapJgS/5kPk0FygXt+/FmDCdzqcujI7OPxEC6e9Yw5S/8dIvOXcRNuOMElHkA== dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.26" + apollo-cache "1.2.1" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "1.1.3" + apollo-utilities "1.2.1" symbol-observable "^1.0.2" + ts-invariant "^0.2.1" tslib "^1.9.3" zen-observable "^0.8.0" @@ -1207,18 +1200,10 @@ apollo-upload-server@^7.0.0: http-errors "^1.7.0" object-path "^0.11.4" -apollo-utilities@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.3.tgz#a8883c0392f6b46eac0d366204ebf34be9307c87" - integrity sha512-pF9abhiClX5gfj/WFWZh8DiI33nOLGxRhXH9ZMquaM1V8bhq1WLFPt2QjShWH3kGQVeIGUK+FQefnhe+ZaaAYg== - dependencies: - fast-json-stable-stringify "^2.0.0" - tslib "^1.9.3" - -apollo-utilities@^1.0.1, apollo-utilities@^1.1.3, apollo-utilities@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.2.0.tgz#ba5a1271c55e0d79069b1919c9d533164a70f9c3" - integrity sha512-4+vxCpEuirQjPqLCckBnOMGZxK/c+2eJtYEbh3xhccNM1pYB5Gx/lrfCdZS5MKDykuWZYY08EvidDy21nr049w== +apollo-utilities@1.2.1, apollo-utilities@^1.0.1, apollo-utilities@^1.2.0, apollo-utilities@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.2.1.tgz#1c3a1ebf5607d7c8efe7636daaf58e7463b41b3c" + integrity sha512-Zv8Udp9XTSFiN8oyXOjf6PMHepD4yxxReLsl6dPUy5Ths7jti3nmlBzZUOxuTWRwZn0MoclqL7RQ5UEJN8MAxg== dependencies: fast-json-stable-stringify "^2.0.0" ts-invariant "^0.2.1" From 85a702c8de32f6b1a5e799b253e3808a553085aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 27 Feb 2019 20:54:07 +0000 Subject: [PATCH 426/554] Bump apollo-server from 2.4.2 to 2.4.8 Bumps [apollo-server](https://github.com/apollographql/apollo-server) from 2.4.2 to 2.4.8. - [Release notes](https://github.com/apollographql/apollo-server/releases) - [Changelog](https://github.com/apollographql/apollo-server/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-server/compare/apollo-server@2.4.2...apollo-server@2.4.8) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 100 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 90 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index a50bf4bfb..1ff3ce9ab 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "apollo-cache-inmemory": "~1.5.0", "apollo-client": "~2.5.1", "apollo-link-http": "~1.5.11", - "apollo-server": "~2.4.2", + "apollo-server": "~2.4.8", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", "cross-env": "~5.2.0", diff --git a/yarn.lock b/yarn.lock index ab877303f..ab8c1d402 100644 --- a/yarn.lock +++ b/yarn.lock @@ -946,6 +946,14 @@ apollo-cache-control@0.5.1: apollo-server-env "2.2.0" graphql-extensions "0.5.2" +apollo-cache-control@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.5.2.tgz#47931ede0b11c64d45429850c274b30d19322362" + integrity sha512-uehXDUrd3Qim+nzxqqN7XT1YTbNSyumW3/FY5BxbKZTI8d4oPG4eyVQKqaggooSjswKQnOoIQVes3+qg9tGAkw== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.5.4" + apollo-cache-control@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz#173d14ceb3eb9e7cb53de7eb8b61bee6159d4171" @@ -1014,6 +1022,18 @@ apollo-engine-reporting@1.0.2: async-retry "^1.2.1" graphql-extensions "0.5.2" +apollo-engine-reporting@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.0.7.tgz#d326b51b12b1f71a40885b8189dbcd162171c953" + integrity sha512-mFsXvd+1/o5jSa9tI2RoXYGcvCLcwwcfLwchjSTxqUd4ViB8RbqYKynzEZ+Omji7PBRM0azioBm43f7PSsQPqA== + dependencies: + apollo-engine-reporting-protobuf "0.2.1" + apollo-graphql "^0.1.0" + apollo-server-core "2.4.8" + apollo-server-env "2.2.0" + async-retry "^1.2.1" + graphql-extensions "0.5.7" + apollo-env@0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.3.3.tgz#e758ece2fbc4f81abc6f07442680ed9e314ecf6c" @@ -1091,6 +1111,32 @@ apollo-server-core@2.4.2: subscriptions-transport-ws "^0.9.11" ws "^6.0.0" +apollo-server-core@2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.4.8.tgz#47e503a345e314222725597c889773e018d8c67a" + integrity sha512-N+5UOzHhMOnHizEiArJtNvEe/cGhSHQyTn5tlU4RJ36FDBJ/WlYZfPbGDMLISSUCJ6t+aP8GLL4Mnudt9d2PDQ== + dependencies: + "@apollographql/apollo-tools" "^0.3.3" + "@apollographql/graphql-playground-html" "^1.6.6" + "@types/ws" "^6.0.0" + apollo-cache-control "0.5.2" + apollo-datasource "0.3.1" + apollo-engine-reporting "1.0.7" + apollo-server-caching "0.3.1" + apollo-server-env "2.2.0" + apollo-server-errors "2.2.1" + apollo-server-plugin-base "0.3.7" + apollo-tracing "0.5.2" + fast-json-stable-stringify "^2.0.0" + graphql-extensions "0.5.7" + graphql-subscriptions "^1.0.0" + graphql-tag "^2.9.2" + graphql-tools "^4.0.0" + graphql-upload "^8.0.2" + sha.js "^2.4.11" + subscriptions-transport-ws "^0.9.11" + ws "^6.0.0" + apollo-server-core@^1.3.6, apollo-server-core@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592" @@ -1113,10 +1159,15 @@ apollo-server-errors@2.2.0: resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== -apollo-server-express@2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.4.2.tgz#870daf04fd9b727a54b1339cdb55066450b3e05a" - integrity sha512-Q5/unCAi6a2dT39LQaIiLC1d8O4fmBDU2CrRhVhPWP8I344xPgNOcrs7MsNN7Ecb56UGbgDKxBoWowFG65ulKw== +apollo-server-errors@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.1.tgz#f68a3f845929768057da7e1c6d30517db5872205" + integrity sha512-wY/YE3iJVMYC+WYIf8QODBjIP4jhI+oc7kiYo9mrz7LdYPKAgxr/he+NteGcqn/0Ea9K5/ZFTGJDbEstSMeP8g== + +apollo-server-express@2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.4.8.tgz#ec9eb61a87324555d49097e9fade3c7d142eb6cb" + integrity sha512-i60l32mfVe33jnKDPNYgUKUKu4Al0xEm2HLOSMgtJ9Wbpe/MbOx5X8M5F27fnHYdM+G5XfAErsakAyRGnQJ48Q== dependencies: "@apollographql/graphql-playground-html" "^1.6.6" "@types/accepts" "^1.3.5" @@ -1124,7 +1175,7 @@ apollo-server-express@2.4.2: "@types/cors" "^2.8.4" "@types/express" "4.16.1" accepts "^1.3.5" - apollo-server-core "2.4.2" + apollo-server-core "2.4.8" body-parser "^1.18.3" cors "^2.8.4" graphql-subscriptions "^1.0.0" @@ -1157,6 +1208,11 @@ apollo-server-plugin-base@0.3.2: resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.2.tgz#4609c9a9d154568401d84b7ac17d1e30e3529104" integrity sha512-yzXrkVSPBoux2uPgbTGROGh7W0axRWopMZM+KT9aF9H/+yMCwtt0EhGOGyNUDMOFA4rT3z+cLVvYuZr1rSQWcg== +apollo-server-plugin-base@0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.7.tgz#bfa4932fc9481bb36221545578d311db464af5a6" + integrity sha512-hW1jaLKf9qNOxMTwRq2CSqz3eqXsZuEiCc8/mmEtOciiVBq1GMtxFf19oIYM9HQuPvQU2RWpns1VrYN59L3vbg== + apollo-server-testing@~2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.4.2.tgz#5c87b34b0b6a1a3e5a1784cadc16bc495dded2e1" @@ -1164,13 +1220,13 @@ apollo-server-testing@~2.4.2: dependencies: apollo-server-core "2.4.2" -apollo-server@~2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.4.2.tgz#6ca42906664918c32d8be391db1178c6eaa8dc54" - integrity sha512-oFwHUhJtJedIPCtZ2ftvRWrVA3KpmeWsgDBs4e5jW/7f5ozkUF22h7L3iy8rEljppiEa2X/GgSi11SVxIOL8gw== +apollo-server@~2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.4.8.tgz#b18ec24e6356dd2a191a6fa0f1429b07ef7c89e3" + integrity sha512-IU6RekO2dqrDdC+5hU6aeVvGg/2t/f01inBMjDhAn1a7hoITUXEh8Sa57TgmYEZ5uAtDuWW7cdiZN2j0cMI3/w== dependencies: - apollo-server-core "2.4.2" - apollo-server-express "2.4.2" + apollo-server-core "2.4.8" + apollo-server-express "2.4.8" express "^4.0.0" graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" @@ -1183,6 +1239,14 @@ apollo-tracing@0.5.1: apollo-server-env "2.2.0" graphql-extensions "0.5.2" +apollo-tracing@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.5.2.tgz#cc49936fb435fa98d19c841514cfe05237c85b33" + integrity sha512-2FdwRvPIq9uuF6OzONroXep6VBGqzHOkP6LlcFQe7SdwxfRP+SD/ycHNSC1acVg2b8d+am9Kzqg2vV54UpOIKA== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.5.4" + apollo-tracing@^0.1.0: version "0.1.4" resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.1.4.tgz#5b8ae1b01526b160ee6e552a7f131923a9aedcc7" @@ -3107,6 +3171,20 @@ graphql-extensions@0.5.2: dependencies: "@apollographql/apollo-tools" "^0.3.3" +graphql-extensions@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.4.tgz#18a9674f9adb11aa6c0737485887ea8877914cff" + integrity sha512-qLThJGVMqcItE7GDf/xX/E40m/aeqFheEKiR5bfra4q5eHxQKGjnIc20P9CVqjOn9I0FkEiU9ypOobfmIf7t6g== + dependencies: + "@apollographql/apollo-tools" "^0.3.3" + +graphql-extensions@0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.7.tgz#2b647e4e36997dc85b7f58ebd64324a5250fb2cf" + integrity sha512-HrU6APE1PiehZ46scMB3S5DezSeCATd8v+e4mmg2bqszMyCFkmAnmK6hR1b5VjHxhzt5/FX21x1WsXfqF4FwdQ== + dependencies: + "@apollographql/apollo-tools" "^0.3.3" + graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: version "0.0.10" resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.0.10.tgz#34bdb2546d43f6a5bc89ab23c295ec0466c6843d" From 832a778ca1294c532cf6a3d67cd54efe84e39578 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 13 Feb 2019 16:02:25 +0100 Subject: [PATCH 427/554] Added findPost query --- src/schema.graphql | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/schema.graphql b/src/schema.graphql index 55f23d5ca..95e7b3d48 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -1,6 +1,16 @@ type Query { isLoggedIn: Boolean! statistics: Statistics! + findPosts(filter: String!, limit: Int = 10): [Post]! @cypher( + statement: """ + CALL db.index.fulltext.queryNodes( + 'postTitleAndContent', $filter+'~') + YIELD node AS node + RETURN node + ORDER BY node.createdAt DESC + LIMIT $limit + """ + ) } type Mutation { login(email: String!, password: String!): LoggedInUser From 46436ca9b10a20cc80b9de2f5ff0304375ac6b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 14 Feb 2019 16:05:30 +0100 Subject: [PATCH 428/554] Setup a routine how to create indices initially In order to create the indices programmatically we need to change the default password for security concerns. To create the user we need to start the neo4j database. So I decided to provide a bash script that let us do it once the container are started. In production we must change the NEO4J_PASSWORD. --- README.md | 2 +- docker-compose.override.yml | 7 +++++++ docker-compose.prod.yml | 9 +++++++++ docker-compose.yml | 7 ------- neo4j/Dockerfile | 1 + neo4j/migrate.sh | 4 ++++ src/bootstrap/neo4j.js | 22 +++++++++++----------- src/graphql-schema.js | 2 +- src/schema.graphql | 2 +- 9 files changed, 35 insertions(+), 21 deletions(-) create mode 100644 docker-compose.prod.yml create mode 100755 neo4j/migrate.sh diff --git a/README.md b/README.md index b3b4764b7..b9b90b0a8 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ _.env_ ```yaml NEO4J_URI=bolt://localhost:7687 -NEO4J_USER=neo4j +NEO4J_USERNAME=neo4j NEO4J_PASSWORD=letmein ``` diff --git a/docker-compose.override.yml b/docker-compose.override.yml index ef7d52c7e..b972c31f6 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -11,6 +11,13 @@ services: - /nitro-backend/node_modules command: yarn run dev neo4j: + environment: + - NEO4J_AUTH=none ports: - 7687:7687 - 7474:7474 + volumes: + - neo4j-data:/data + +volumes: + neo4j-data: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 000000000..c4f5dc4f5 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,9 @@ +version: "3.7" + +services: + neo4j: + environment: + - NEO4J_PASSWORD=letmein + backend: + environment: + - NEO4J_PASSWORD=letmein diff --git a/docker-compose.yml b/docker-compose.yml index 6905bb893..1e8c9158c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,14 +27,7 @@ services: context: neo4j networks: - hc-network - volumes: - - neo4j-data:/data - environment: - - NEO4J_AUTH=none networks: hc-network: name: hc-network - -volumes: - neo4j-data: diff --git a/neo4j/Dockerfile b/neo4j/Dockerfile index cb7fd228f..f6e71811b 100644 --- a/neo4j/Dockerfile +++ b/neo4j/Dockerfile @@ -1,2 +1,3 @@ FROM neo4j:3.5.0 RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.1/apoc-3.5.0.1-all.jar -P plugins/ +COPY migrate.sh /usr/local/bin/migrate diff --git a/neo4j/migrate.sh b/neo4j/migrate.sh new file mode 100755 index 000000000..30a58c306 --- /dev/null +++ b/neo4j/migrate.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +echo "CALL dbms.security.changePassword('${NEO4J_PASSWORD}');" | cypher-shell --username neo4j --password neo4j +echo 'CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);' | cypher-shell --username neo4j --password $NEO4J_PASSWORD diff --git a/src/bootstrap/neo4j.js b/src/bootstrap/neo4j.js index 935449a0a..62f5f326d 100644 --- a/src/bootstrap/neo4j.js +++ b/src/bootstrap/neo4j.js @@ -1,18 +1,18 @@ -import { v1 as neo4j } from 'neo4j-driver' -import dotenv from 'dotenv' +import { v1 as neo4j } from "neo4j-driver"; +import dotenv from "dotenv"; -dotenv.config() +dotenv.config(); -let driver +let driver; -export function getDriver (options = {}) { +export function getDriver(options = {}) { const { - uri = process.env.NEO4J_URI || 'bolt://localhost:7687', - username = process.env.NEO4J_USERNAME || 'neo4j', - password = process.env.NEO4J_PASSWORD || 'neo4j' - } = options + uri = process.env.NEO4J_URI || "bolt://localhost:7687", + username = process.env.NEO4J_USERNAME || "neo4j", + password = process.env.NEO4J_PASSWORD || "neo4j" + } = options; if (!driver) { - driver = neo4j.driver(uri, neo4j.auth.basic(username, password)) + driver = neo4j.driver(uri, neo4j.auth.basic(username, password)); } - return driver + return driver; } diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 8b5f369e0..c525d67d7 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -34,7 +34,7 @@ export const query = (cypher, session) => { }) }) } -const queryOne = (cypher, session) => { +export const queryOne = (cypher, session) => { return new Promise((resolve, reject) => { query(cypher, session) .then(res => { diff --git a/src/schema.graphql b/src/schema.graphql index 95e7b3d48..472b345d7 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -4,7 +4,7 @@ type Query { findPosts(filter: String!, limit: Int = 10): [Post]! @cypher( statement: """ CALL db.index.fulltext.queryNodes( - 'postTitleAndContent', $filter+'~') + 'full_text_search', $filter+'~') YIELD node AS node RETURN node ORDER BY node.createdAt DESC From 34ecd07b1bf746211fbe34b777f5ca810fa690e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 14 Feb 2019 17:30:17 +0100 Subject: [PATCH 429/554] Modify migrate for development environment --- neo4j/migrate.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/neo4j/migrate.sh b/neo4j/migrate.sh index 30a58c306..cdb9ec46c 100755 --- a/neo4j/migrate.sh +++ b/neo4j/migrate.sh @@ -1,4 +1,8 @@ #!/usr/bin/env bash set -e -echo "CALL dbms.security.changePassword('${NEO4J_PASSWORD}');" | cypher-shell --username neo4j --password neo4j -echo 'CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);' | cypher-shell --username neo4j --password $NEO4J_PASSWORD +if [[ -z "${NEO4J_PASSWORD}" ]]; then + echo 'CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);' | cypher-shell +else + echo "CALL dbms.security.changePassword('${NEO4J_PASSWORD}');" | cypher-shell --username neo4j --password neo4j + echo 'CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);' | cypher-shell --username neo4j --password $NEO4J_PASSWORD +fi From 151bb2842985c7d1475ef7bd070ce4b1547e77bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 00:16:43 +0100 Subject: [PATCH 430/554] Provide README --- README.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b9b90b0a8..2717e7ed5 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,15 @@ > This Prototype tries to resolve the biggest hurdle of connecting > our services together. This is not possible in a sane way using -> our current approach. -> -> With this Prototype we can explore using the combination of +> our current approach. +> +> With this Prototype we can explore using the combination of > GraphQL and the Neo4j Graph Database for achieving the connected > nature of a social graph with better development experience as we > do not need to connect data by our own any more through weird table > structures etc. -> +> > #### Advantages: > - easer data structure > - better connected data @@ -26,10 +26,10 @@ > - more performant and better to understand API > - better API client that uses caching > -> We still need to evaluate the drawbacks and estimate the development +> We still need to evaluate the drawbacks and estimate the development > cost of such an approach -## How to get in touch +## How to get in touch Connect with other developers over [Discord](https://discord.gg/6ub73U3) ## Quick Start @@ -42,6 +42,10 @@ Before you start, fork the repository using the fork button above, then clone it Run: ```sh docker-compose up + +# create indices etc. +docker-compose exec neo4j migrate + # if you want seed data # open another terminal and run docker-compose exec backend yarn run db:seed @@ -123,7 +127,7 @@ Just set `MOCK=true` inside `.env` or pass it on application start. ## Seed and Reset the Database -Optionally you can seed the GraphQL service by executing mutations that +Optionally you can seed the GraphQL service by executing mutations that will write sample data to the database: ```bash @@ -159,7 +163,7 @@ npm run test - [x] check if sorting is working - [x] check if pagination is working - [ ] check if upload is working (using graphql-yoga?) -- [x] evaluate middleware +- [x] evaluate middleware - [ ] ignore Posts and Comments by blacklisted Users From 5230099e6b3d76542acc48d3054d596c1f70c4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 00:50:37 +0100 Subject: [PATCH 431/554] Sketch a test --- src/schema.graphql.spec.js | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/schema.graphql.spec.js diff --git a/src/schema.graphql.spec.js b/src/schema.graphql.spec.js new file mode 100644 index 000000000..304fdf557 --- /dev/null +++ b/src/schema.graphql.spec.js @@ -0,0 +1,51 @@ +import { request } from 'graphql-request' +import { create, cleanDatabase } from './seed/factories' +import { host } from './jest/helpers' + +describe('filter for searchQuery', () => { + const query = (searchQuery) => { + return ` + { + findPosts(filter: "${searchQuery}", limit: 10) { + title + } + } + ` + } + + describe('given some posts', () => { + beforeEach(async () => { + await create('post', { + title: 'Hamlet', + content: 'To be, or not to be: that is the question' + }) + await create('post', { + title: 'Threepenny Opera', + content: 'And the shark, it has teeth, And it wears them in the face.' + }) + }) + + afterEach(async () => { + await cleanDatabase() + }) + + describe('result set', () => { + describe('includes posts if search term', () => { + it('matches title', async () => { + const data = await request(host, query('Hamlet')) + expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) + }) + + it('matches a part of the title', async () => { + const data = await request(host, query('let')) + expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) + }) + + it('matches a part of the content', async () => { + const data = await request(host, query('shark')) + expect(data).toEqual({findPosts: [{title: 'Threepenny Opera'}]}) + }) + }) + }) + }) +}) From 5a995f9f86f2d484794faa883de23461d85b8014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 01:46:33 +0100 Subject: [PATCH 432/554] Implement test for search @appinteractive could you have a look if sanitization of search queries work? I created a test and I see "unterminated string" exceptions. This is not what we want! All user input should be escaped. --- src/schema.graphql | 3 +- src/schema.graphql.spec.js | 18 ++++- src/seed/factories/index.js | 141 ++++++++++++++++++------------------ src/seed/factories/posts.js | 20 ++--- 4 files changed, 96 insertions(+), 86 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index 472b345d7..ee519fff3 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -3,8 +3,7 @@ type Query { statistics: Statistics! findPosts(filter: String!, limit: Int = 10): [Post]! @cypher( statement: """ - CALL db.index.fulltext.queryNodes( - 'full_text_search', $filter+'~') + CALL db.index.fulltext.queryNodes('full_text_search', $filter+'~') YIELD node AS node RETURN node ORDER BY node.createdAt DESC diff --git a/src/schema.graphql.spec.js b/src/schema.graphql.spec.js index 304fdf557..5fdc67d0c 100644 --- a/src/schema.graphql.spec.js +++ b/src/schema.graphql.spec.js @@ -21,7 +21,7 @@ describe('filter for searchQuery', () => { }) await create('post', { title: 'Threepenny Opera', - content: 'And the shark, it has teeth, And it wears them in the face.' + content: 'And the shark, it has teeth, And it wears them in the face.' }) }) @@ -29,6 +29,18 @@ describe('filter for searchQuery', () => { await cleanDatabase() }) + describe('sanitization', () => { + it('escapes cypher statement', async () => { + await request(host, query(`''); + MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r; + CALL db.index.fulltext.queryNodes('full_text_search', '' + `)) + console.log(data) + const data = await request(host, query('the')) + expect(data).toEqual({findPosts: [{title: 'Hamlet'}, {title: 'Threepenny Opera'}]}) + }) + }) + describe('result set', () => { describe('includes posts if search term', () => { it('matches title', async () => { @@ -36,8 +48,8 @@ describe('filter for searchQuery', () => { expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) }) - it('matches a part of the title', async () => { - const data = await request(host, query('let')) + it('matches mistyped title', async () => { + const data = await request(host, query('amlet')) expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) }) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index a107fc6b7..fb59281fc 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -1,7 +1,16 @@ -import { GraphQLClient, request } from 'graphql-request' -import { getDriver } from '../../bootstrap/neo4j' +import { GraphQLClient, request } from "graphql-request"; +import { getDriver } from "../../bootstrap/neo4j"; -export const seedServerHost = 'http://127.0.0.1:4001' +import createBadge from "./badges.js"; +import createUser from "./users.js"; +import createOrganization from "./organizations.js"; +import createPost from "./posts.js"; +import createComment from "./comments.js"; +import createCategory from "./categories.js"; +import createTag from "./tags.js"; +import createReport from "./reports.js"; + +export const seedServerHost = "http://127.0.0.1:4001"; const authenticatedHeaders = async ({ email, password }, host) => { const mutation = ` @@ -9,95 +18,85 @@ const authenticatedHeaders = async ({ email, password }, host) => { login(email:"${email}", password:"${password}"){ token } - }` - const response = await request(host, mutation) + }`; + const response = await request(host, mutation); return { authorization: `Bearer ${response.login.token}` - } -} - + }; +}; const factories = { - 'badge': require('./badges.js').default, - 'user': require('./users.js').default, - 'organization': require('./organizations.js').default, - 'post': require('./posts.js').default, - 'comment': require('./comments.js').default, - 'category': require('./categories.js').default, - 'tag': require('./tags.js').default, - 'report': require('./reports.js').default -} - -const relationFactories = { - 'user': require('./users.js').relate, - 'organization': require('./organizations.js').relate, - 'post': require('./posts.js').relate, - 'comment': require('./comments.js').relate -} - -export const create = (model, parameters, options) => { - const graphQLClient = new GraphQLClient(seedServerHost, options) - const mutation = factories[model](parameters) - return graphQLClient.request(mutation) -} - -export const relate = (model, type, parameters, options) => { - const graphQLClient = new GraphQLClient(seedServerHost, options) - const mutation = relationFactories[model](type, parameters) - return graphQLClient.request(mutation) -} + Badge: createBadge, + User: createUser, + Organization: createOrganization, + Post: createPost, + Comment: createComment, + Category: createCategory, + Tag: createTag, + Report: createReport +}; export const cleanDatabase = async (options = {}) => { - const { - driver = getDriver() - } = options - const session = driver.session() - const cypher = 'MATCH (n) DETACH DELETE n' + const { driver = getDriver() } = options; + const session = driver.session(); + const cypher = "MATCH (n) DETACH DELETE n"; try { - return await session.run(cypher) + return await session.run(cypher); } catch (error) { - throw (error) + throw error; } finally { - session.close() + session.close(); } -} +}; -export default function Factory (options = {}) { +export default function Factory(options = {}) { const { neo4jDriver = getDriver(), - seedServerHost = 'http://127.0.0.1:4001' - } = options + seedServerHost = "http://127.0.0.1:4001" + } = options; - const graphQLClient = new GraphQLClient(seedServerHost) + const graphQLClient = new GraphQLClient(seedServerHost); const result = { neo4jDriver, seedServerHost, graphQLClient, + factories, lastResponse: null, - async authenticateAs ({ email, password }) { - const headers = await authenticatedHeaders({ email, password }, seedServerHost) - this.lastResponse = headers - this.graphQLClient = new GraphQLClient(seedServerHost, { headers }) - return this + async authenticateAs({ email, password }) { + const headers = await authenticatedHeaders( + { email, password }, + seedServerHost + ); + this.lastResponse = headers; + this.graphQLClient = new GraphQLClient(seedServerHost, { headers }); + return this; }, - async create (node, properties) { - const mutation = factories[node](properties) - this.lastResponse = await this.graphQLClient.request(mutation) - return this + async create(node, properties) { + const mutation = this.factories[node](properties); + this.lastResponse = await this.graphQLClient.request(mutation); + return this; }, - async relate (node, relationship, properties) { - const mutation = relationFactories[node](relationship, properties) - this.lastResponse = await this.graphQLClient.request(mutation) - return this + async relate(node, relationship, properties) { + const { from, to } = properties; + const mutation = ` + mutation { + Add${node}${relationship}( + from: { id: "${from}" }, + to: { id: "${to}" } + ) { from { id } } + } + `; + this.lastResponse = await this.graphQLClient.request(mutation); + return this; }, - async cleanDatabase () { - this.lastResponse = await cleanDatabase({ driver: this.neo4jDriver }) - return this + async cleanDatabase() { + this.lastResponse = await cleanDatabase({ driver: this.neo4jDriver }); + return this; } - } - result.authenticateAs.bind(result) - result.create.bind(result) - result.relate.bind(result) - result.cleanDatabase.bind(result) - return result + }; + result.authenticateAs.bind(result); + result.create.bind(result); + result.relate.bind(result); + result.cleanDatabase.bind(result); + return result; } diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index 80f5e289d..179f17a9e 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -1,7 +1,7 @@ -import faker from 'faker' -import uuid from 'uuid/v4' +import faker from "faker"; +import uuid from "uuid/v4"; -export default function (params) { +export default function(params) { const { id = uuid(), title = faker.lorem.sentence(), @@ -11,12 +11,12 @@ export default function (params) { faker.lorem.sentence(), faker.lorem.sentence(), faker.lorem.sentence() - ].join('. '), + ].join(". "), image = faker.image.image(), - visibility = 'public', + visibility = "public", disabled = false, deleted = false - } = params + } = params; return ` mutation { @@ -30,11 +30,11 @@ export default function (params) { deleted: ${deleted} ) { title, content } } - ` + `; } -export function relate (type, params) { - const { from, to } = params +export function relate(type, params) { + const { from, to } = params; return ` mutation { ${from}_${type}_${to}: AddPost${type}( @@ -42,5 +42,5 @@ export function relate (type, params) { to: { id: "${to}" } ) { from { id } } } - ` + `; } From 63845681b744d5fef94f50a9dd56979c8be0df3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 02:05:08 +0100 Subject: [PATCH 433/554] Fix lint --- src/schema.graphql.spec.js | 13 ++++++------- src/seed/factories/posts.js | 12 ------------ 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/schema.graphql.spec.js b/src/schema.graphql.spec.js index 5fdc67d0c..12abdd3c2 100644 --- a/src/schema.graphql.spec.js +++ b/src/schema.graphql.spec.js @@ -16,11 +16,11 @@ describe('filter for searchQuery', () => { describe('given some posts', () => { beforeEach(async () => { await create('post', { - title: 'Hamlet', + title: 'Hamlet', content: 'To be, or not to be: that is the question' }) await create('post', { - title: 'Threepenny Opera', + title: 'Threepenny Opera', content: 'And the shark, it has teeth, And it wears them in the face.' }) }) @@ -35,9 +35,8 @@ describe('filter for searchQuery', () => { MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r; CALL db.index.fulltext.queryNodes('full_text_search', '' `)) - console.log(data) const data = await request(host, query('the')) - expect(data).toEqual({findPosts: [{title: 'Hamlet'}, {title: 'Threepenny Opera'}]}) + expect(data).toEqual({ findPosts: [{ title: 'Hamlet' }, { title: 'Threepenny Opera' }] }) }) }) @@ -45,17 +44,17 @@ describe('filter for searchQuery', () => { describe('includes posts if search term', () => { it('matches title', async () => { const data = await request(host, query('Hamlet')) - expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) + expect(data).toEqual({ findPosts: [{ title: 'Hamlet' }] }) }) it('matches mistyped title', async () => { const data = await request(host, query('amlet')) - expect(data).toEqual({findPosts: [{title: 'Hamlet'}]}) + expect(data).toEqual({ findPosts: [{ title: 'Hamlet' }] }) }) it('matches a part of the content', async () => { const data = await request(host, query('shark')) - expect(data).toEqual({findPosts: [{title: 'Threepenny Opera'}]}) + expect(data).toEqual({ findPosts: [{ title: 'Threepenny Opera' }] }) }) }) }) diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index 179f17a9e..d77a7cad0 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -32,15 +32,3 @@ export default function(params) { } `; } - -export function relate(type, params) { - const { from, to } = params; - return ` - mutation { - ${from}_${type}_${to}: AddPost${type}( - from: { id: "${from}" }, - to: { id: "${to}" } - ) { from { id } } - } - `; -} From 14c61b3bf820db42363b4573396faee86067112c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 02:10:30 +0100 Subject: [PATCH 434/554] Create indices before testing --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index f4a01b147..f106ed5e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,10 +16,12 @@ before_install: - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose - chmod +x docker-compose - sudo mv docker-compose /usr/local/bin + - yarn global add wait-on install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-backend:latest . - docker-compose -f docker-compose.yml -f docker-compose.travis.yml up -d + - wait-on tcp:7687 && docker-compose exec neo4j migrate script: - docker-compose exec backend yarn run lint From a41063a60aeaa3b099d53f4230a7ff69ed701696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 02:20:28 +0100 Subject: [PATCH 435/554] On Travis we have to expose the port ...to be able to wait for it. --- docker-compose.travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml index 761a2aa64..bc26a2a34 100644 --- a/docker-compose.travis.yml +++ b/docker-compose.travis.yml @@ -1,6 +1,9 @@ version: "3.7" services: + neo4j: + ports: + - 7687:7687 backend: image: humanconnection/nitro-backend:builder build: From 8453d95f68d3107e321072b68b26db331456c2e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 02:29:09 +0100 Subject: [PATCH 436/554] Do we need to wait until the web client is up? --- .travis.yml | 2 +- docker-compose.travis.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f106ed5e8..e699197cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ before_install: install: - docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-backend:latest . - docker-compose -f docker-compose.yml -f docker-compose.travis.yml up -d - - wait-on tcp:7687 && docker-compose exec neo4j migrate + - wait-on http://localhost:7474 && docker-compose exec neo4j migrate script: - docker-compose exec backend yarn run lint diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml index bc26a2a34..1553347fa 100644 --- a/docker-compose.travis.yml +++ b/docker-compose.travis.yml @@ -4,6 +4,7 @@ services: neo4j: ports: - 7687:7687 + - 7474:7474 backend: image: humanconnection/nitro-backend:builder build: From e7c01d8877644b8920690de5bc045a6e68b5d406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Feb 2019 02:36:07 +0100 Subject: [PATCH 437/554] Disable authentication on Travis --- docker-compose.travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml index 1553347fa..e1998f6dd 100644 --- a/docker-compose.travis.yml +++ b/docker-compose.travis.yml @@ -2,6 +2,8 @@ version: "3.7" services: neo4j: + environment: + - NEO4J_AUTH=none ports: - 7687:7687 - 7474:7474 From 360acdb141ece84fa5cda7f9341848d20bebd04d Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 17 Feb 2019 17:32:14 +0100 Subject: [PATCH 438/554] Fix search --- src/schema.graphql | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index ee519fff3..e9b5d5106 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -3,10 +3,9 @@ type Query { statistics: Statistics! findPosts(filter: String!, limit: Int = 10): [Post]! @cypher( statement: """ - CALL db.index.fulltext.queryNodes('full_text_search', $filter+'~') - YIELD node AS node + CALL db.index.fulltext.queryNodes('full_text_search', $filter) + YIELD node RETURN node - ORDER BY node.createdAt DESC LIMIT $limit """ ) From 6a146aa699da7752a280a34d0372c8712caa6d38 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Mon, 18 Feb 2019 16:57:17 +0100 Subject: [PATCH 439/554] Improved search query --- src/schema.graphql | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index e9b5d5106..1e09768cb 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -4,8 +4,12 @@ type Query { findPosts(filter: String!, limit: Int = 10): [Post]! @cypher( statement: """ CALL db.index.fulltext.queryNodes('full_text_search', $filter) - YIELD node - RETURN node + YIELD node as post, score + MATCH (post)<-[:WROTE]-(user:User) + WHERE score >= 0.2 + AND NOT user.deleted = true AND NOT user.disabled = true + AND NOT post.deleted = true AND NOT post.disabled = true + RETURN post LIMIT $limit """ ) From 7ea408777501b25f6159548f570f209fe138c74d Mon Sep 17 00:00:00 2001 From: Armin Date: Thu, 28 Feb 2019 01:20:27 +0100 Subject: [PATCH 440/554] Run cucumber tests README entry --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f4676a6c..fc175dfb2 100644 --- a/README.md +++ b/README.md @@ -141,12 +141,18 @@ npm run db:reset **Beware**: We have no multiple database setup at the moment. We clean the database after each test, running the tests will wipe out all your data! -Run the tests: +Run the **_jest_** tests: ```bash yarn run test # -or- npm run test ``` +Run the **_cucumber_** features: +```bash +yarn run test:cucumber +# -or- +npm run test:cucumber +``` ## Todo`s From 067371581d7d95c0be30b16b99ad65015580d70c Mon Sep 17 00:00:00 2001 From: Armin Date: Thu, 28 Feb 2019 03:40:00 +0100 Subject: [PATCH 441/554] Create article before shouting in test and add "shouted" step + disable send Create Activity when creating a post --- src/graphql-schema.js | 69 ++++++++++++++------------- test/features/activity-delete.feature | 2 +- test/features/activity-like.feature | 26 ++++++++-- test/features/support/steps.js | 14 ++++++ 4 files changed, 73 insertions(+), 38 deletions(-) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 65dfc8cda..bdf72c0a0 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -6,8 +6,10 @@ import uuid from 'uuid/v4' import { fixUrl } from './middleware/fixImageUrlsMiddleware' import { AuthenticationError } from 'apollo-server' import { neo4jgraphql } from 'neo4j-graphql-js' +/* import as from 'activitystrea.ms' import request from 'request' +*/ const debug = require('debug')('backend:schema') @@ -179,19 +181,20 @@ export const resolvers = { postId: result.id }) debug(`author = ${JSON.stringify(author, null, 2)}`) - const actorId = author.records[0]._fields[0].properties.actorId - const createActivity = await new Promise((resolve, reject) => { - as.create() - .id(`${actorId}/status/${params.activityId}`) - .actor(`${actorId}`) - .object( - as.article() - .id(`${actorId}/status/${result.id}`) - .content(result.content) - .to('https://www.w3.org/ns/activitystreams#Public') - .publishedNow() - .attributedTo(`${actorId}`) - ).prettyWrite((err, doc) => { + /* if (Array.isArray(author.records) && author.records.length > 0) { + const actorId = author.records[0]._fields[0].properties.actorId + const createActivity = await new Promise((resolve, reject) => { + as.create() + .id(`${actorId}/status/${params.activityId}`) + .actor(`${actorId}`) + .object( + as.article() + .id(`${actorId}/status/${result.id}`) + .content(result.content) + .to('https://www.w3.org/ns/activitystreams#Public') + .publishedNow() + .attributedTo(`${actorId}`) + ).prettyWrite((err, doc) => { if (err) { reject(err) } else { @@ -201,27 +204,27 @@ export const resolvers = { resolve(JSON.stringify(parsedDoc)) } }) - }) - session.close() - // try sending post via ActivityPub - await new Promise((resolve) => { - const url = new URL(actorId) - request(`${url.origin}/activitypub/inbox`, { - method: 'POST', - headers: { - 'Content-Type': 'application/activity+json' - }, - body: createActivity - }, (err) => { - if (err) { - debug(`error = ${JSON.stringify(err, null, 2)}`) - resolve(err) - } - resolve(null) }) - }) - return result + session.close() + // try sending post via ActivityPub + await new Promise((resolve) => { + const url = new URL(actorId) + request(`${url.origin}/activitypub/inbox`, { + method: 'POST', + headers: { + 'Content-Type': 'application/activity+json' + }, + body: createActivity + }, (err) => { + if (err) { + debug(`error = ${JSON.stringify(err, null, 2)}`) + resolve(err) + } + resolve(null) + }) + }) + return result + } */ } - } } diff --git a/test/features/activity-delete.feature b/test/features/activity-delete.feature index 0e0d13253..ad33f1e4c 100644 --- a/test/features/activity-delete.feature +++ b/test/features/activity-delete.feature @@ -19,7 +19,7 @@ Feature: Delete an object "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/users/bernd-das-brot", "content": "Hi Max, how are you?", - "to": "https://localhost:4100/activitypub/users/moritz" + "to": "https://www.w3.org/ns/activitystreams#Public" } } """ diff --git a/test/features/activity-like.feature b/test/features/activity-like.feature index c605bdb76..d71a0396f 100644 --- a/test/features/activity-like.feature +++ b/test/features/activity-like.feature @@ -4,21 +4,39 @@ Feature: Like an object like an article or note I want to undo the follow. Background: - Given our own server runs at "http://localhost:4123" + Given our own server runs at "http://localhost:4100" And we have the following users in our database: | Slug | | karl-heinz | | peter-lustiger | + And I send a POST request with the following activity to "/activitypub/users/bernd-das-brot/inbox": + """ + { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://localhost:4100/activitypub/users/karl-heinz/status/faslkasa7dasfzkjn2398hsfd", + "type": "Create", + "actor": "https://localhost:4100/activitypub/users/karl-heinz", + "object": { + "id": "https://localhost:4100/activitypub/users/karl-heinz/status/dkasfljsdfaafg9843jknsdf", + "type": "Article", + "published": "2019-02-07T19:37:55.002Z", + "attributedTo": "https://localhost:4100/activitypub/users/karl-heinz", + "content": "Hi Max, how are you?", + "to": "https://www.w3.org/ns/activitystreams#Public" + } + } + """ Scenario: Send a like of a person to an users inbox and make sure it's added to the likes collection When I send a POST request with the following activity to "/activitypub/users/karl-heinz/inbox": """ { "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://localhost:4123/activitypub/users/peter-lustiger/status/83J23549sda1k72fsa4567na42312455kad83", + "id": "https://localhost:4100/activitypub/users/peter-lustiger/status/83J23549sda1k72fsa4567na42312455kad83", "type": "Like", - "actor": "http://localhost:4123/activitypub/users/peter-lustiger - "object": "http://localhost:4123/activitypub/users/karl-heinz" + "actor": "http://localhost:4100/activitypub/users/peter-lustiger", + "object": "http://localhost:4100/activitypub/users/karl-heinz/status/dkasfljsdfaafg9843jknsdf" } """ Then I expect the status code to be 200 + And the post with id "dkasfljsdfaafg9843jknsdf" has been liked by "peter-lustiger" diff --git a/test/features/support/steps.js b/test/features/support/steps.js index 7f7bde455..f2aaf6ffd 100644 --- a/test/features/support/steps.js +++ b/test/features/support/steps.js @@ -124,3 +124,17 @@ Then('the object is removed from the outbox collection of {string}', async funct Then('I send a GET request to {string} and expect a ordered collection', () => { }) + +Then('the post with id {string} has been liked by {string}', async function (id, slug) { + const result = await client.request(` + query { + Post(id: "${id}") { + shoutedBy { + slug + } + } + } + `) + expect(result.data.Post[0].shoutedBy).to.be.an('array').that.is.not.empty // eslint-disable-line + expect(result.data.Post[0].shoutedBy[0].slug).to.equal(slug) +}) From bb04ef0664d39edd481cbb55feb9a7a5ba5b0767 Mon Sep 17 00:00:00 2001 From: Armin Date: Thu, 28 Feb 2019 03:43:44 +0100 Subject: [PATCH 442/554] Refactoring --- src/activitypub/NitroDataSource.js | 2 +- src/activitypub/routes/inbox.js | 3 --- src/activitypub/routes/index.js | 8 +++++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/activitypub/NitroDataSource.js b/src/activitypub/NitroDataSource.js index 11be287d7..20339ec62 100644 --- a/src/activitypub/NitroDataSource.js +++ b/src/activitypub/NitroDataSource.js @@ -339,7 +339,7 @@ export default class NitroDataSource { let result = await this.client.mutate({ mutation: gql` mutation { - CreatePost(content: "${postObject.content}", title: "${title}", id: "${postId}", activityId: "${activityId}") { + CreatePost(content: "${postObject.content}", contentExcerpt: "${trunc(postObject.content, 120)}", title: "${title}", id: "${postId}", activityId: "${activityId}") { id } } diff --git a/src/activitypub/routes/inbox.js b/src/activitypub/routes/inbox.js index eb720e042..062f4b916 100644 --- a/src/activitypub/routes/inbox.js +++ b/src/activitypub/routes/inbox.js @@ -1,5 +1,4 @@ import express from 'express' -import { verifySignature } from '../security' import { activityPub } from '../ActivityPub' const debug = require('debug')('ea:inbox') @@ -12,8 +11,6 @@ router.post('/', async function (req, res, next) { debug(`Content-Type = ${req.get('Content-Type')}`) debug(`body = ${JSON.stringify(req.body, null, 2)}`) debug(`Request headers = ${JSON.stringify(req.headers, null, 2)}`) - // TODO stop if signature validation fails - debug(`verify = ${await verifySignature(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)}`) switch (req.body.type) { case 'Create': if (req.body.send) { diff --git a/src/activitypub/routes/index.js b/src/activitypub/routes/index.js index 7a8524a9e..24898e766 100644 --- a/src/activitypub/routes/index.js +++ b/src/activitypub/routes/index.js @@ -1,15 +1,16 @@ import user from './user' import inbox from './inbox' -import webfinger from './webfinger' +import webFinger from './webFinger' import express from 'express' import cors from 'cors' +import verify from './verify' const router = express.Router() -router.use('/.well-known/webfinger', +router.use('/.well-known/webFinger', cors(), express.urlencoded({ extended: true }), - webfinger + webFinger ) router.use('/activitypub/users', cors(), @@ -21,6 +22,7 @@ router.use('/activitypub/inbox', cors(), express.json({ type: ['application/activity+json', 'application/ld+json', 'application/json'] }), express.urlencoded({ extended: true }), + verify, inbox ) From ea2f6b7811d1b39c31f24c9d4674a99740cd36f8 Mon Sep 17 00:00:00 2001 From: Armin Date: Thu, 28 Feb 2019 03:44:57 +0100 Subject: [PATCH 443/554] Extract HTTP Signature verify middleware --- src/activitypub/routes/user.js | 6 ++---- src/activitypub/routes/verify.js | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 src/activitypub/routes/verify.js diff --git a/src/activitypub/routes/user.js b/src/activitypub/routes/user.js index 2316d319c..017891e61 100644 --- a/src/activitypub/routes/user.js +++ b/src/activitypub/routes/user.js @@ -1,8 +1,8 @@ import { sendCollection } from '../utils/collection' import express from 'express' import { serveUser } from './serveUser' -import { verifySignature } from '../security' import { activityPub } from '../ActivityPub' +import verify from './verify' const router = express.Router() const debug = require('debug')('ea:user') @@ -45,11 +45,9 @@ router.get('/:name/outbox', (req, res) => { } }) -router.post('/:name/inbox', async function (req, res, next) { +router.post('/:name/inbox', verify, async function (req, res, next) { debug(`body = ${JSON.stringify(req.body, null, 2)}`) debug(`actorId = ${req.body.actor}`) - // TODO stop if signature validation fails - debug(`verify = ${await verifySignature(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)}`) // const result = await saveActorId(req.body.actor) switch (req.body.type) { case 'Create': diff --git a/src/activitypub/routes/verify.js b/src/activitypub/routes/verify.js new file mode 100644 index 000000000..34676b44f --- /dev/null +++ b/src/activitypub/routes/verify.js @@ -0,0 +1,15 @@ +import { verifySignature } from '../security' +const debug = require('debug')('ea:verify') + +export default async (req, res, next) => { + debug(`actorId = ${req.body.actor}`) + // TODO stop if signature validation fails + if (await verifySignature(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)) { + debug('verify = true') + next() + } else { + // throw Error('Signature validation failed!') + debug('verify = false') + next() + } +} From e74962a2beb2b8ea351a3df92e06afa58a200890 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 28 Feb 2019 04:29:33 +0000 Subject: [PATCH 444/554] Bump apollo-cache-inmemory from 1.5.0 to 1.5.1 Bumps [apollo-cache-inmemory](https://github.com/apollographql/apollo-client) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/apollographql/apollo-client/releases) - [Changelog](https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-client/compare/apollo-cache-inmemory@1.5.0...apollo-cache-inmemory@1.5.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 1ff3ce9ab..f39b28a22 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ ] }, "dependencies": { - "apollo-cache-inmemory": "~1.5.0", + "apollo-cache-inmemory": "~1.5.1", "apollo-client": "~2.5.1", "apollo-link-http": "~1.5.11", "apollo-server": "~2.4.8", diff --git a/yarn.lock b/yarn.lock index ab8c1d402..15f107045 100644 --- a/yarn.lock +++ b/yarn.lock @@ -961,18 +961,18 @@ apollo-cache-control@^0.1.0: dependencies: graphql-extensions "^0.0.x" -apollo-cache-inmemory@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.5.0.tgz#90b1a38f744762ab47c415b9d7b2d32fbd803088" - integrity sha512-hyg8R7G3XOfZhl8fQLs0vGEwi2rr8PuEIiumCY4qmwviaGsmwjs/Dm63cyeMm3Sfu05vzFQkwMdBf5u7xBg3cQ== +apollo-cache-inmemory@~1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.5.1.tgz#265d1ee67b0bf0aca9c37629d410bfae44e62953" + integrity sha512-D3bdpPmWfaKQkWy8lfwUg+K8OBITo3sx0BHLs1B/9vIdOIZ7JNCKq3EUcAgAfInomJUdN0QG1yOfi8M8hxkN1g== dependencies: - apollo-cache "^1.2.0" - apollo-utilities "^1.2.0" + apollo-cache "^1.2.1" + apollo-utilities "^1.2.1" optimism "^0.6.9" ts-invariant "^0.2.1" tslib "^1.9.3" -apollo-cache@1.2.1, apollo-cache@^1.2.0: +apollo-cache@1.2.1, apollo-cache@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.2.1.tgz#aae71eb4a11f1f7322adc343f84b1a39b0693644" integrity sha512-nzFmep/oKlbzUuDyz6fS6aYhRmfpcHWqNkkA9Bbxwk18RD6LXC4eZkuE0gXRX0IibVBHNjYVK+Szi0Yied4SpQ== @@ -1264,7 +1264,7 @@ apollo-upload-server@^7.0.0: http-errors "^1.7.0" object-path "^0.11.4" -apollo-utilities@1.2.1, apollo-utilities@^1.0.1, apollo-utilities@^1.2.0, apollo-utilities@^1.2.1: +apollo-utilities@1.2.1, apollo-utilities@^1.0.1, apollo-utilities@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.2.1.tgz#1c3a1ebf5607d7c8efe7636daaf58e7463b41b3c" integrity sha512-Zv8Udp9XTSFiN8oyXOjf6PMHepD4yxxReLsl6dPUy5Ths7jti3nmlBzZUOxuTWRwZn0MoclqL7RQ5UEJN8MAxg== From 4b2ca9368b6eb155175426b7d9f21cecd4194699 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 28 Feb 2019 08:58:00 +0000 Subject: [PATCH 445/554] Bump apollo-server-testing from 2.4.2 to 2.4.8 Bumps [apollo-server-testing](https://github.com/apollographql/apollo-server) from 2.4.2 to 2.4.8. - [Release notes](https://github.com/apollographql/apollo-server/releases) - [Changelog](https://github.com/apollographql/apollo-server/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-server/compare/apollo-server-testing@2.4.2...apollo-server-testing@2.4.8) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 81 ++++------------------------------------------------ 2 files changed, 6 insertions(+), 77 deletions(-) diff --git a/package.json b/package.json index f39b28a22..50b2eddf3 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "@babel/node": "~7.2.2", "@babel/preset-env": "~7.3.1", "@babel/register": "~7.0.0", - "apollo-server-testing": "~2.4.2", + "apollo-server-testing": "~2.4.8", "babel-core": "~7.0.0-0", "babel-eslint": "~10.0.1", "babel-jest": "~24.1.0", diff --git a/yarn.lock b/yarn.lock index 15f107045..70a337743 100644 --- a/yarn.lock +++ b/yarn.lock @@ -938,14 +938,6 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -apollo-cache-control@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.5.1.tgz#db7e86cd7ede6cad0a2e0ea97488d9fb5c33d913" - integrity sha512-82hzX7/fFiu5dODLS8oGieEE4jLjMIhIkQ4JTsWj9drv8PZJltl0xqORtU2jA/FottjxfYab8+ebi3BgGPOaqw== - dependencies: - apollo-server-env "2.2.0" - graphql-extensions "0.5.2" - apollo-cache-control@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.5.2.tgz#47931ede0b11c64d45429850c274b30d19322362" @@ -1010,18 +1002,6 @@ apollo-engine-reporting-protobuf@0.2.1: dependencies: protobufjs "^6.8.6" -apollo-engine-reporting@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.0.2.tgz#5dd5411f17d76e6788a1166367a2ab7b52794224" - integrity sha512-g6JkO5WaMuqXfn3WoZMQyyFzpxfHsw/f7P7XTHSEqTSd/M4uk7/uih/xcqmgBGt4ET30KbaGFz2l4FJzO06A5w== - dependencies: - apollo-engine-reporting-protobuf "0.2.1" - apollo-graphql "^0.1.0" - apollo-server-core "2.4.2" - apollo-server-env "2.2.0" - async-retry "^1.2.1" - graphql-extensions "0.5.2" - apollo-engine-reporting@1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.0.7.tgz#d326b51b12b1f71a40885b8189dbcd162171c953" @@ -1085,32 +1065,6 @@ apollo-server-caching@0.3.1: dependencies: lru-cache "^5.0.0" -apollo-server-core@2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.4.2.tgz#916d98636b1bf576a84b4a469006c1c73741e03a" - integrity sha512-IOWhqjjI1sH38sj7ycjke0dXXEgaqOkb2hDpLBTSiVWKBIqFfo4gchWK5wcWW9jReDpf/+G2wogH+UvONs2ejg== - dependencies: - "@apollographql/apollo-tools" "^0.3.3" - "@apollographql/graphql-playground-html" "^1.6.6" - "@types/ws" "^6.0.0" - apollo-cache-control "0.5.1" - apollo-datasource "0.3.1" - apollo-engine-reporting "1.0.2" - apollo-server-caching "0.3.1" - apollo-server-env "2.2.0" - apollo-server-errors "2.2.0" - apollo-server-plugin-base "0.3.2" - apollo-tracing "0.5.1" - fast-json-stable-stringify "^2.0.0" - graphql-extensions "0.5.2" - graphql-subscriptions "^1.0.0" - graphql-tag "^2.9.2" - graphql-tools "^4.0.0" - graphql-upload "^8.0.2" - sha.js "^2.4.11" - subscriptions-transport-ws "^0.9.11" - ws "^6.0.0" - apollo-server-core@2.4.8: version "2.4.8" resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.4.8.tgz#47e503a345e314222725597c889773e018d8c67a" @@ -1154,11 +1108,6 @@ apollo-server-env@2.2.0: node-fetch "^2.1.2" util.promisify "^1.0.0" -apollo-server-errors@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" - integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== - apollo-server-errors@2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.1.tgz#f68a3f845929768057da7e1c6d30517db5872205" @@ -1203,22 +1152,17 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== -apollo-server-plugin-base@0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.2.tgz#4609c9a9d154568401d84b7ac17d1e30e3529104" - integrity sha512-yzXrkVSPBoux2uPgbTGROGh7W0axRWopMZM+KT9aF9H/+yMCwtt0EhGOGyNUDMOFA4rT3z+cLVvYuZr1rSQWcg== - apollo-server-plugin-base@0.3.7: version "0.3.7" resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.7.tgz#bfa4932fc9481bb36221545578d311db464af5a6" integrity sha512-hW1jaLKf9qNOxMTwRq2CSqz3eqXsZuEiCc8/mmEtOciiVBq1GMtxFf19oIYM9HQuPvQU2RWpns1VrYN59L3vbg== -apollo-server-testing@~2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.4.2.tgz#5c87b34b0b6a1a3e5a1784cadc16bc495dded2e1" - integrity sha512-WZ901nh7uG75342lMukJvuxFF/w3W5JDyWElY8KDhXfaDLbMKqhRqaWRIiEEX4YvciO5ACSzqKt+957/y1yUUQ== +apollo-server-testing@~2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.4.8.tgz#eb929a431e059723c298919688355434d53e3ea8" + integrity sha512-AmNn5pDn9FJ9AJbmc7gwsUFaUt4uf44IFHaCfZow/jkAeY2JZnIozt8LYC8Koidy+Lfb+i/HsjkgbBodElbGMQ== dependencies: - apollo-server-core "2.4.2" + apollo-server-core "2.4.8" apollo-server@~2.4.8: version "2.4.8" @@ -1231,14 +1175,6 @@ apollo-server@~2.4.8: graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" -apollo-tracing@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.5.1.tgz#16be201bc276120f0f8b7aa180201ee89d57e3bd" - integrity sha512-5gb8OWzkGaJFsmQdyMyZnOjcq6weMTkqJSGj0hfR7uX99X4SBFAzZV4nTeK4z0XkXO2I12xSTJoS4gxbFjgeaA== - dependencies: - apollo-server-env "2.2.0" - graphql-extensions "0.5.2" - apollo-tracing@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.5.2.tgz#cc49936fb435fa98d19c841514cfe05237c85b33" @@ -3164,13 +3100,6 @@ graphql-deduplicator@^2.0.1: resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3" integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA== -graphql-extensions@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.2.tgz#cdced94c1931c9983fffcc144e336d6cd4d8b02b" - integrity sha512-D/FAvjYEZ8GM3vfALxRvItozy5iLUfzyoauE2lli+0OuUBCAZDLP0fgqeTFK93NnQX/XSjBVGhcuDWBB7JesEw== - dependencies: - "@apollographql/apollo-tools" "^0.3.3" - graphql-extensions@0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.4.tgz#18a9674f9adb11aa6c0737485887ea8877914cff" From 57c24f62d19b99174026ec6158817186a390579c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 28 Feb 2019 09:25:48 +0000 Subject: [PATCH 446/554] Bump @babel/preset-env from 7.3.1 to 7.3.4 Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.3.1 to 7.3.4. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.3.1...v7.3.4) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 132 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 92 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index 50b2eddf3..c276a09d7 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@babel/cli": "~7.2.3", "@babel/core": "~7.3.3", "@babel/node": "~7.2.2", - "@babel/preset-env": "~7.3.1", + "@babel/preset-env": "~7.3.4", "@babel/register": "~7.0.0", "apollo-server-testing": "~2.4.8", "babel-core": "~7.0.0-0", diff --git a/yarn.lock b/yarn.lock index 70a337743..c36e11172 100644 --- a/yarn.lock +++ b/yarn.lock @@ -69,6 +69,17 @@ source-map "^0.5.0" trim-right "^1.0.1" +"@babel/generator@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.4.tgz#9aa48c1989257877a9d971296e5b73bfe72e446e" + integrity sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg== + dependencies: + "@babel/types" "^7.3.4" + jsesc "^2.5.1" + lodash "^4.17.11" + source-map "^0.5.0" + trim-right "^1.0.1" + "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" @@ -199,6 +210,16 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-replace-supers@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.3.4.tgz#a795208e9b911a6eeb08e5891faacf06e7013e13" + integrity sha512-pvObL9WVf2ADs+ePg0jrqlhHoxRXlOa+SHRHzAXIz2xkYuOHfGl+fKxPMaS4Fq+uje8JQPobnertBBvyrWnQ1A== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.3.4" + "@babel/types" "^7.3.4" + "@babel/helper-simple-access@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" @@ -258,6 +279,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.3.tgz#092d450db02bdb6ccb1ca8ffd47d8774a91aef87" integrity sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg== +"@babel/parser@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.4.tgz#a43357e4bbf4b92a437fb9e465c192848287f27c" + integrity sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ== + "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" @@ -275,10 +301,10 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-json-strings" "^7.2.0" -"@babel/plugin-proposal-object-rest-spread@^7.3.1": - version "7.3.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.2.tgz#6d1859882d4d778578e41f82cc5d7bf3d5daf6c1" - integrity sha512-DjeMS+J2+lpANkYLLO+m6GjoTMygYglKmRe6cDTbFv3L9i6mmiE8fe6B8MtCSLZpVXscD5kn7s6SgtHrDoBWoA== +"@babel/plugin-proposal-object-rest-spread@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.4.tgz#47f73cf7f2a721aad5c0261205405c642e424654" + integrity sha512-j7VQmbbkA+qrzNqbKHrBsW3ddFnOeva6wzSe/zB7T+xaxGc+RCpwo44wCmRixAIGRoIpmVgvzFzNJqQcO3/9RA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -335,10 +361,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-async-to-generator@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz#68b8a438663e88519e65b776f8938f3445b1a2ff" - integrity sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ== +"@babel/plugin-transform-async-to-generator@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.3.4.tgz#4e45408d3c3da231c0e7b823f407a53a7eb3048c" + integrity sha512-Y7nCzv2fw/jEZ9f678MuKdMo99MFDJMT/PvD9LisrR5JDFcJH6vYeH6RnjVt3p5tceyGRvTtEN0VOlU+rgHZjA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -351,25 +377,25 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-block-scoping@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz#f17c49d91eedbcdf5dd50597d16f5f2f770132d4" - integrity sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q== +"@babel/plugin-transform-block-scoping@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.3.4.tgz#5c22c339de234076eee96c8783b2fed61202c5c4" + integrity sha512-blRr2O8IOZLAOJklXLV4WhcEzpYafYQKSGT3+R26lWG41u/FODJuBggehtOwilVAcFu393v3OFj+HmaE6tVjhA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.10" + lodash "^4.17.11" -"@babel/plugin-transform-classes@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.0.tgz#374f8876075d7d21fea55aeb5c53561259163f96" - integrity sha512-aPCEkrhJYebDXcGTAP+cdUENkH7zqOlgbKwLbghjjHpJRJBWM/FSlCjMoPGA8oUdiMfOrk3+8EFPLLb5r7zj2w== +"@babel/plugin-transform-classes@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.3.4.tgz#dc173cb999c6c5297e0b5f2277fdaaec3739d0cc" + integrity sha512-J9fAvCFBkXEvBimgYxCjvaVDzL6thk0j0dBvCeZmIUDBwyt+nv6HfbImsSrWsYXfDNDivyANgJlFXDUWRTZBuA== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-define-map" "^7.1.0" "@babel/helper-function-name" "^7.1.0" "@babel/helper-optimise-call-expression" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" + "@babel/helper-replace-supers" "^7.3.4" "@babel/helper-split-export-declaration" "^7.0.0" globals "^11.1.0" @@ -450,10 +476,10 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" -"@babel/plugin-transform-modules-systemjs@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.2.0.tgz#912bfe9e5ff982924c81d0937c92d24994bb9068" - integrity sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ== +"@babel/plugin-transform-modules-systemjs@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.3.4.tgz#813b34cd9acb6ba70a84939f3680be0eb2e58861" + integrity sha512-VZ4+jlGOF36S7TjKs8g4ojp4MEI+ebCQZdswWb/T9I4X84j8OtFAyjXjt/M16iIm5RIZn0UMQgg/VgIwo/87vw== dependencies: "@babel/helper-hoist-variables" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -497,12 +523,12 @@ "@babel/helper-get-function-arity" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-regenerator@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz#5b41686b4ed40bef874d7ed6a84bdd849c13e0c1" - integrity sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw== +"@babel/plugin-transform-regenerator@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.3.4.tgz#1601655c362f5b38eead6a52631f5106b29fa46a" + integrity sha512-hvJg8EReQvXT6G9H2MvNPXkv9zK36Vxa1+csAVTpE1J3j0zlHplw76uudEbJxgvqZzAq9Yh45FLD4pk5mKRFQA== dependencies: - regenerator-transform "^0.13.3" + regenerator-transform "^0.13.4" "@babel/plugin-transform-shorthand-properties@^7.2.0": version "7.2.0" @@ -558,16 +584,16 @@ core-js "^2.5.7" regenerator-runtime "^0.11.1" -"@babel/preset-env@~7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.1.tgz#389e8ca6b17ae67aaf9a2111665030be923515db" - integrity sha512-FHKrD6Dxf30e8xgHQO0zJZpUPfVZg+Xwgz5/RdSWCbza9QLNk4Qbp40ctRoqDxml3O8RMzB1DU55SXeDG6PqHQ== +"@babel/preset-env@~7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.4.tgz#887cf38b6d23c82f19b5135298bdb160062e33e1" + integrity sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-async-generator-functions" "^7.2.0" "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.3.1" + "@babel/plugin-proposal-object-rest-spread" "^7.3.4" "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" "@babel/plugin-proposal-unicode-property-regex" "^7.2.0" "@babel/plugin-syntax-async-generators" "^7.2.0" @@ -575,10 +601,10 @@ "@babel/plugin-syntax-object-rest-spread" "^7.2.0" "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" "@babel/plugin-transform-arrow-functions" "^7.2.0" - "@babel/plugin-transform-async-to-generator" "^7.2.0" + "@babel/plugin-transform-async-to-generator" "^7.3.4" "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.2.0" - "@babel/plugin-transform-classes" "^7.2.0" + "@babel/plugin-transform-block-scoping" "^7.3.4" + "@babel/plugin-transform-classes" "^7.3.4" "@babel/plugin-transform-computed-properties" "^7.2.0" "@babel/plugin-transform-destructuring" "^7.2.0" "@babel/plugin-transform-dotall-regex" "^7.2.0" @@ -589,13 +615,13 @@ "@babel/plugin-transform-literals" "^7.2.0" "@babel/plugin-transform-modules-amd" "^7.2.0" "@babel/plugin-transform-modules-commonjs" "^7.2.0" - "@babel/plugin-transform-modules-systemjs" "^7.2.0" + "@babel/plugin-transform-modules-systemjs" "^7.3.4" "@babel/plugin-transform-modules-umd" "^7.2.0" "@babel/plugin-transform-named-capturing-groups-regex" "^7.3.0" "@babel/plugin-transform-new-target" "^7.0.0" "@babel/plugin-transform-object-super" "^7.2.0" "@babel/plugin-transform-parameters" "^7.2.0" - "@babel/plugin-transform-regenerator" "^7.0.0" + "@babel/plugin-transform-regenerator" "^7.3.4" "@babel/plugin-transform-shorthand-properties" "^7.2.0" "@babel/plugin-transform-spread" "^7.2.0" "@babel/plugin-transform-sticky-regex" "^7.2.0" @@ -651,6 +677,21 @@ globals "^11.1.0" lodash "^4.17.10" +"@babel/traverse@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.3.4.tgz#1330aab72234f8dea091b08c4f8b9d05c7119e06" + integrity sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.3.4" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/parser" "^7.3.4" + "@babel/types" "^7.3.4" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.11" + "@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.3": version "7.3.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.3.tgz#6c44d1cdac2a7625b624216657d5bc6c107ab436" @@ -660,6 +701,15 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" +"@babel/types@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.4.tgz#bf482eaeaffb367a28abbf9357a94963235d90ed" + integrity sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ== + dependencies: + esutils "^2.0.2" + lodash "^4.17.11" + to-fast-properties "^2.0.0" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -5790,10 +5840,10 @@ regenerator-runtime@^0.12.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== -regenerator-transform@^0.13.3: - version "0.13.3" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb" - integrity sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA== +regenerator-transform@^0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.4.tgz#18f6763cf1382c69c36df76c6ce122cc694284fb" + integrity sha512-T0QMBjK3J0MtxjPmdIMXm72Wvj2Abb0Bd4HADdfijwMdoIsyQZ6fWC7kDFhk2YinBBEMZDL7Y7wh0J1sGx3S4A== dependencies: private "^0.1.6" From ce28de893bd6fe3faaae3ac4701437b0a03f8e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 27 Feb 2019 16:41:18 +0100 Subject: [PATCH 447/554] Write a test for #27 Moderators are allowed to see disabled or deleted posts if they ask for it. --- src/middleware/softDeleteMiddleware.spec.js | 119 ++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/middleware/softDeleteMiddleware.spec.js diff --git a/src/middleware/softDeleteMiddleware.spec.js b/src/middleware/softDeleteMiddleware.spec.js new file mode 100644 index 000000000..2e5dbe054 --- /dev/null +++ b/src/middleware/softDeleteMiddleware.spec.js @@ -0,0 +1,119 @@ +import Factory from '../seed/factories' +import { host, login } from '../jest/helpers' +import { GraphQLClient } from 'graphql-request' + +const factory = Factory() +let client +let query +let action + +beforeEach(async () => { + await Promise.all([ + factory.create('User', { role: 'user', email: 'user@example.org', password: '1234' }), + factory.create('User', { role: 'moderator', email: 'moderator@example.org', password: '1234' }) + ]) + await factory.authenticateAs({email: 'user@example.org', password: '1234'}) + await Promise.all([ + factory.create('Post', { title: 'Deleted post', deleted: true, disabled: false }), + factory.create('Post', { title: 'Disabled post', deleted: false, disabled: true}), + factory.create('Post', { title: 'Publicly visible post', deleted: false, disabled: false }) + ]) +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + +describe('softDeleteMiddleware', () => { + describe('Post', () => { + action = () => { + return client.request(query) + } + + beforeEach(() => { + query = '{ Post { title } }' + }) + + describe('as user', () => { + beforeEach(async () => { + const headers = await login({ email: 'user@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('hides deleted or disabled posts', async () => { + const expected = {Post: [{title: 'Publicly visible post'}]} + await expect(action()).resolves.toEqual(expected) + }) + }) + + describe('as moderator', () => { + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('hides deleted or disabled posts', async () => { + const expected = {Post: [{title: 'Publicly visible post'}]} + await expect(action()).resolves.toEqual(expected) + }) + }) + + describe('filter (deleted: true)', () => { + beforeEach(() => { + query = '{ Post(deleted: true) { title } }' + }) + + describe('as user', () => { + beforeEach(async () => { + const headers = await login({ email: 'user@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorisation error', async () => { + await expect(action()).rejects.toThrow('Not Authorised!') + }) + }) + + describe('as moderator', () => { + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('shows deleted posts', async () => { + const expected = {Post: [{title: 'Deleted post'}]} + await expect(action()).resolves.toEqual(expected) + }) + }) + }) + + describe('filter (disabled: true)', () => { + beforeEach(() => { + query = '{ Post(disabled: true) { title } }' + }) + + describe('as user', () => { + beforeEach(async () => { + const headers = await login({ email: 'user@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorisation error', async () => { + await expect(action()).rejects.toThrow('Not Authorised!') + }) + }) + + describe('as moderator', () => { + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('shows disabled posts', async () => { + const expected = {Post: [{title: 'Disabled post'}]} + await expect(action()).resolves.toEqual(expected) + }) + }) + }) + }) +}) From 738ba4f51ca4dec9e61cb2372be64d767f4f3d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 27 Feb 2019 16:48:43 +0100 Subject: [PATCH 448/554] DRY softDeleteMiddleware --- src/middleware/softDeleteMiddleware.js | 43 +++++++++----------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/src/middleware/softDeleteMiddleware.js b/src/middleware/softDeleteMiddleware.js index 79e4a7d08..abc742bb3 100644 --- a/src/middleware/softDeleteMiddleware.js +++ b/src/middleware/softDeleteMiddleware.js @@ -1,38 +1,23 @@ +const normalize = (args) => { + if (typeof args.deleted !== 'boolean') { + args.deleted = false + } + if (typeof args.disabled !== 'boolean') { + args.disabled = false + } + return args +} + export default { Query: { - Post: async (resolve, root, args, context, info) => { - if (typeof args.deleted !== 'boolean') { - args.deleted = false - } - if (typeof args.disabled !== 'boolean') { - args.disabled = false - } - const result = await resolve(root, args, context, info) - return result + Post: (resolve, root, args, context, info) => { + return resolve(root, normalize(args), context, info) }, Comment: async (resolve, root, args, context, info) => { - if (typeof args.deleted !== 'boolean') { - args.deleted = false - } - if (typeof args.disabled !== 'boolean') { - args.disabled = false - } - const result = await resolve(root, args, context, info) - return result + return resolve(root, normalize(args), context, info) }, User: async (resolve, root, args, context, info) => { - if (typeof args.deleted !== 'boolean') { - args.deleted = false - } - if (typeof args.disabled !== 'boolean') { - args.disabled = false - } - // console.log('ROOT', root) - // console.log('ARGS', args) - // console.log('CONTEXT', context) - // console.log('info', info.fieldNodes[0].arguments) - const result = await resolve(root, args, context, info) - return result + return resolve(root, normalize(args), context, info) } } } From 911500a3bd3df99e9ca2cda3cddc2cd2743ad02c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 27 Feb 2019 16:49:03 +0100 Subject: [PATCH 449/554] Don't override given { deleted, disabled } = args @appinteractive I guess this was done unintentionally? --- src/middleware/dateTimeMiddleware.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/middleware/dateTimeMiddleware.js b/src/middleware/dateTimeMiddleware.js index 97e6e2767..473dbf444 100644 --- a/src/middleware/dateTimeMiddleware.js +++ b/src/middleware/dateTimeMiddleware.js @@ -2,29 +2,21 @@ export default { Mutation: { CreateUser: async (resolve, root, args, context, info) => { args.createdAt = (new Date()).toISOString() - args.disabled = false - args.deleted = false const result = await resolve(root, args, context, info) return result }, CreatePost: async (resolve, root, args, context, info) => { args.createdAt = (new Date()).toISOString() - args.disabled = false - args.deleted = false const result = await resolve(root, args, context, info) return result }, CreateComment: async (resolve, root, args, context, info) => { args.createdAt = (new Date()).toISOString() - args.disabled = false - args.deleted = false const result = await resolve(root, args, context, info) return result }, CreateOrganization: async (resolve, root, args, context, info) => { args.createdAt = (new Date()).toISOString() - args.disabled = false - args.deleted = false const result = await resolve(root, args, context, info) return result }, From f3ab671f2146b4bf597a6f4f6dda523f07048592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 28 Feb 2019 01:19:39 +0100 Subject: [PATCH 450/554] Soft delete middleware test passes --- src/middleware/permissionsMiddleware.js | 22 ++++++++++++---------- src/middleware/softDeleteMiddleware.js | 8 ++++---- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 0c6723b4b..c070e536d 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -1,4 +1,4 @@ -import { rule, shield, allow } from 'graphql-shield' +import { rule, shield, allow, or } from 'graphql-shield' /* * TODO: implement @@ -11,36 +11,38 @@ const isAuthenticated = rule()(async (parent, args, ctx, info) => { const isAdmin = rule()(async (parent, args, ctx, info) => { return ctx.user.role === 'ADMIN' }) -const isModerator = rule()(async (parent, args, ctx, info) => { - return ctx.user.role === 'MODERATOR' -}) */ +const isModerator = rule()(async (parent, args, { user }, info) => { + return user && (user.role === 'moderator' || user.role === 'admin') +}) + const isMyOwn = rule({ cache: 'no_cache' })(async (parent, args, ctx, info) => { return ctx.user.id === parent.id }) +const onlyEnabledContent = rule({ cache: 'strict' })(async (parent, args, ctx, info) => { + const { disabled, deleted } = args + return !(disabled || deleted) +}) + // Permissions const permissions = shield({ Query: { statistics: allow, - currentUser: allow - // fruits: and(isAuthenticated, or(isAdmin, isModerator)), - // customers: and(isAuthenticated, isAdmin) + currentUser: allow, + Post: or(onlyEnabledContent, isModerator) }, Mutation: { CreatePost: isAuthenticated, // TODO UpdatePost: isOwner, // TODO DeletePost: isOwner, report: isAuthenticated - // addFruitToBasket: isAuthenticated - // CreateUser: allow, }, User: { email: isMyOwn, password: isMyOwn } - // Post: isAuthenticated }) export default permissions diff --git a/src/middleware/softDeleteMiddleware.js b/src/middleware/softDeleteMiddleware.js index abc742bb3..bed7b6ca0 100644 --- a/src/middleware/softDeleteMiddleware.js +++ b/src/middleware/softDeleteMiddleware.js @@ -1,4 +1,4 @@ -const normalize = (args) => { +const setDefaults = (args) => { if (typeof args.deleted !== 'boolean') { args.deleted = false } @@ -11,13 +11,13 @@ const normalize = (args) => { export default { Query: { Post: (resolve, root, args, context, info) => { - return resolve(root, normalize(args), context, info) + return resolve(root, setDefaults(args), context, info) }, Comment: async (resolve, root, args, context, info) => { - return resolve(root, normalize(args), context, info) + return resolve(root, setDefaults(args), context, info) }, User: async (resolve, root, args, context, info) => { - return resolve(root, normalize(args), context, info) + return resolve(root, setDefaults(args), context, info) } } } From 8febf147cef2dd3eccb3b3331f47add0c02d6988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 28 Feb 2019 02:53:11 +0100 Subject: [PATCH 451/554] Fix lint --- src/middleware/softDeleteMiddleware.spec.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/middleware/softDeleteMiddleware.spec.js b/src/middleware/softDeleteMiddleware.spec.js index 2e5dbe054..925a03ccc 100644 --- a/src/middleware/softDeleteMiddleware.spec.js +++ b/src/middleware/softDeleteMiddleware.spec.js @@ -9,13 +9,13 @@ let action beforeEach(async () => { await Promise.all([ - factory.create('User', { role: 'user', email: 'user@example.org', password: '1234' }), + factory.create('User', { role: 'user', email: 'user@example.org', password: '1234' }), factory.create('User', { role: 'moderator', email: 'moderator@example.org', password: '1234' }) ]) - await factory.authenticateAs({email: 'user@example.org', password: '1234'}) + await factory.authenticateAs({ email: 'user@example.org', password: '1234' }) await Promise.all([ - factory.create('Post', { title: 'Deleted post', deleted: true, disabled: false }), - factory.create('Post', { title: 'Disabled post', deleted: false, disabled: true}), + factory.create('Post', { title: 'Deleted post', deleted: true, disabled: false }), + factory.create('Post', { title: 'Disabled post', deleted: false, disabled: true }), factory.create('Post', { title: 'Publicly visible post', deleted: false, disabled: false }) ]) }) @@ -41,7 +41,7 @@ describe('softDeleteMiddleware', () => { }) it('hides deleted or disabled posts', async () => { - const expected = {Post: [{title: 'Publicly visible post'}]} + const expected = { Post: [{ title: 'Publicly visible post' }] } await expect(action()).resolves.toEqual(expected) }) }) @@ -53,7 +53,7 @@ describe('softDeleteMiddleware', () => { }) it('hides deleted or disabled posts', async () => { - const expected = {Post: [{title: 'Publicly visible post'}]} + const expected = { Post: [{ title: 'Publicly visible post' }] } await expect(action()).resolves.toEqual(expected) }) }) @@ -81,7 +81,7 @@ describe('softDeleteMiddleware', () => { }) it('shows deleted posts', async () => { - const expected = {Post: [{title: 'Deleted post'}]} + const expected = { Post: [{ title: 'Deleted post' }] } await expect(action()).resolves.toEqual(expected) }) }) @@ -110,7 +110,7 @@ describe('softDeleteMiddleware', () => { }) it('shows disabled posts', async () => { - const expected = {Post: [{title: 'Disabled post'}]} + const expected = { Post: [{ title: 'Disabled post' }] } await expect(action()).resolves.toEqual(expected) }) }) From 5e592f666b78ffe12581639c55635426a6d4bb85 Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Thu, 28 Feb 2019 15:00:45 -0300 Subject: [PATCH 452/554] Write unit test badge creation - for unauthenticated - for authenticated admin Co-authored-by: Wolfgang Huss --- src/middleware/permissionsMiddleware.js | 3 +- src/resolvers/badges.spec.js | 85 +++++++++++++++++++++++++ src/seed/factories/badges.js | 18 +++--- 3 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 src/resolvers/badges.spec.js diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 0c6723b4b..928137847 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -32,7 +32,8 @@ const permissions = shield({ CreatePost: isAuthenticated, // TODO UpdatePost: isOwner, // TODO DeletePost: isOwner, - report: isAuthenticated + report: isAuthenticated, + CreateBadge: isAuthenticated // addFruitToBasket: isAuthenticated // CreateUser: allow, }, diff --git a/src/resolvers/badges.spec.js b/src/resolvers/badges.spec.js new file mode 100644 index 000000000..abaa85995 --- /dev/null +++ b/src/resolvers/badges.spec.js @@ -0,0 +1,85 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() + +describe('report', () => { + beforeEach(async () => { + await factory.create('User', { + email: 'user@example.org', + password: '1234' + }) + await factory.create('User', { + id: 'u2', + name: 'moderator', + role: 'moderator', + email: 'moderator@example.org' + }) + await factory.create('User', { + id: 'u3', + name: 'admin', + role: 'moderator', + email: 'admin@example.org' + }) + }) + + afterEach(async () => { + await factory.cleanDatabase() + }) + + const params = { + id: 'b1', + key: 'indiegogo_en_racoon', + type: 'crowdfunding', + status: 'permanent', + icon: '/img/badges/indiegogo_en_racoon.svg' + } + + describe('unauthenticated', () => { + let client + + it('throws authorization error', async () => { + client = new GraphQLClient(host) + let { id, key, type, status, icon } = params + await expect( + client.request(`mutation { + CreateBadge( + id: "${id}", + key: "${key}", + type: ${type}, + status: ${status}, + icon: "${icon}" + ) { id } + }`) + ).rejects.toThrow('Not Authorised') + }) + + describe('authenticated admin', () => { + let headers + let response + let { id, key, type, status, icon } = params + beforeEach(async () => { + headers = await login({ email: 'admin@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + response = await client.request(`mutation { + CreateBadge( + id: "${id}", + key: "${key}", + type: ${type}, + status: ${status}, + icon: "${icon}" + ) { id } + }`, + { headers } + ) + }) + it('creates a badge', () => { + let { id } = response.CreateBadge + expect(response).toEqual({ + CreateBadge: { id } + }) + }) + }) + }) +}) diff --git a/src/seed/factories/badges.js b/src/seed/factories/badges.js index b34442521..e24a67c21 100644 --- a/src/seed/factories/badges.js +++ b/src/seed/factories/badges.js @@ -10,14 +10,14 @@ export default function (params) { } = params return ` - mutation { - CreateBadge( - id: "${id}", - key: "${key}", - type: ${type}, - status: ${status}, - icon: "${icon}" - ) { id } - } + mutation { + CreateBadge( + id: "${id}", + key: "${key}", + type: ${type}, + status: ${status}, + icon: "${icon}" + ) { id } + } ` } From ec648113798b91d8bf96ffcc41c164a468b1ff2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Fri, 1 Mar 2019 13:17:07 +0100 Subject: [PATCH 453/554] Add to .gitignore `.DS_Store` --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b909223f8..81a29c8e6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ coverage.lcov .nyc_output/ public/uploads/* !.gitkeep + +# Apple macOS folder attribute file +.DS_Store \ No newline at end of file From 6271c6e8a37fd0cd4067e575aeec803d77505f6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Fri, 1 Mar 2019 13:38:14 +0100 Subject: [PATCH 454/554] Add to .gitignore `.DS_Store` (#196) --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b909223f8..81a29c8e6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ coverage.lcov .nyc_output/ public/uploads/* !.gitkeep + +# Apple macOS folder attribute file +.DS_Store \ No newline at end of file From 6937c60ef8de53458a8ea09e0ec311594462b217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Fri, 1 Mar 2019 15:49:11 +0100 Subject: [PATCH 455/554] Only admins are allowed to create badges --- src/middleware/permissionsMiddleware.js | 10 +++- src/resolvers/badges.spec.js | 79 ++++++++++++++++--------- 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 928137847..d2dc45094 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -16,8 +16,12 @@ const isModerator = rule()(async (parent, args, ctx, info) => { }) */ -const isMyOwn = rule({ cache: 'no_cache' })(async (parent, args, ctx, info) => { - return ctx.user.id === parent.id +const isAdmin = rule()(async (parent, args, { user }, info) => { + return user && (user.role === 'admin') +}) + +const isMyOwn = rule({ cache: 'no_cache' })(async (parent, args, context, info) => { + return context.user.id === parent.id }) // Permissions @@ -33,7 +37,7 @@ const permissions = shield({ // TODO UpdatePost: isOwner, // TODO DeletePost: isOwner, report: isAuthenticated, - CreateBadge: isAuthenticated + CreateBadge: isAdmin // addFruitToBasket: isAuthenticated // CreateUser: allow, }, diff --git a/src/resolvers/badges.spec.js b/src/resolvers/badges.spec.js index abaa85995..3574dae6d 100644 --- a/src/resolvers/badges.spec.js +++ b/src/resolvers/badges.spec.js @@ -4,22 +4,21 @@ import { host, login } from '../jest/helpers' const factory = Factory() -describe('report', () => { +describe('Badge', () => { beforeEach(async () => { await factory.create('User', { email: 'user@example.org', + role: 'user', password: '1234' }) await factory.create('User', { id: 'u2', - name: 'moderator', role: 'moderator', email: 'moderator@example.org' }) await factory.create('User', { id: 'u3', - name: 'admin', - role: 'moderator', + role: 'admin', email: 'admin@example.org' }) }) @@ -54,32 +53,56 @@ describe('report', () => { }`) ).rejects.toThrow('Not Authorised') }) + }) - describe('authenticated admin', () => { - let headers - let response - let { id, key, type, status, icon } = params - beforeEach(async () => { - headers = await login({ email: 'admin@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - response = await client.request(`mutation { - CreateBadge( - id: "${id}", - key: "${key}", - type: ${type}, - status: ${status}, - icon: "${icon}" - ) { id } - }`, - { headers } - ) - }) - it('creates a badge', () => { - let { id } = response.CreateBadge - expect(response).toEqual({ - CreateBadge: { id } - }) + describe('authenticated admin', () => { + let client + let headers + let response + let { id, key, type, status, icon } = params + beforeEach(async () => { + headers = await login({ email: 'admin@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + response = await client.request(`mutation { + CreateBadge( + id: "${id}", + key: "${key}", + type: ${type}, + status: ${status}, + icon: "${icon}" + ) { id } + }`, + { headers } + ) + }) + it('creates a badge', () => { + let { id } = response.CreateBadge + expect(response).toEqual({ + CreateBadge: { id } }) }) }) + + describe('authenticated moderator', () => { + let client + let headers + let { id, key, type, status, icon } = params + beforeEach(async () => { + headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + it('throws authorization error', async () => { + await expect(client.request(`mutation { + CreateBadge( + id: "${id}", + key: "${key}", + type: ${type}, + status: ${status}, + icon: "${icon}" + ) { id } + }`, + { headers } + )).rejects.toThrow('Not Authorised') + }) + }) }) From f25708875a8c75f36f3b88f20f7e302ee53261ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sun, 3 Mar 2019 14:01:50 +0100 Subject: [PATCH 456/554] Refactor badges test CC @Tirokk @grenzfrequence * the top level block should correspond with the name of the resolver * the block below should be `CreatePost` or `UpdatePost` * the arguments of client.request are `query/mutation`, `variables` but you passed in the `headers` which should go into `new GraphQlClient(host, options)` * re-use the very same mutation to avoid bugs in the tests * use `await expect(someAsyncMethod).resolves.toEqual(expected)` style for extra test assurance --- src/resolvers/badges.spec.js | 128 ++++++++++++++++------------------- 1 file changed, 57 insertions(+), 71 deletions(-) diff --git a/src/resolvers/badges.spec.js b/src/resolvers/badges.spec.js index 3574dae6d..f6d8c06dc 100644 --- a/src/resolvers/badges.spec.js +++ b/src/resolvers/badges.spec.js @@ -4,7 +4,7 @@ import { host, login } from '../jest/helpers' const factory = Factory() -describe('Badge', () => { +describe('badges', () => { beforeEach(async () => { await factory.create('User', { email: 'user@example.org', @@ -27,82 +27,68 @@ describe('Badge', () => { await factory.cleanDatabase() }) - const params = { - id: 'b1', - key: 'indiegogo_en_racoon', - type: 'crowdfunding', - status: 'permanent', - icon: '/img/badges/indiegogo_en_racoon.svg' - } + describe('CreateBadge', () => { + const params = { + id: 'b1', + key: 'indiegogo_en_racoon', + type: 'crowdfunding', + status: 'permanent', + icon: '/img/badges/indiegogo_en_racoon.svg' + } - describe('unauthenticated', () => { - let client + const mutation = ` + mutation( + $id: ID + $key: String! + $type: BadgeTypeEnum! + $status: BadgeStatusEnum! + $icon: String! + ) { + CreateBadge(id: $id, key: $key, type: $type, status: $status, icon: $icon) { + id + } + } + ` - it('throws authorization error', async () => { - client = new GraphQLClient(host) - let { id, key, type, status, icon } = params - await expect( - client.request(`mutation { - CreateBadge( - id: "${id}", - key: "${key}", - type: ${type}, - status: ${status}, - icon: "${icon}" - ) { id } - }`) - ).rejects.toThrow('Not Authorised') + describe('unauthenticated', () => { + let client + + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect( + client.request(mutation, params) + ).rejects.toThrow('Not Authorised') + }) }) - }) - describe('authenticated admin', () => { - let client - let headers - let response - let { id, key, type, status, icon } = params - beforeEach(async () => { - headers = await login({ email: 'admin@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - response = await client.request(`mutation { - CreateBadge( - id: "${id}", - key: "${key}", - type: ${type}, - status: ${status}, - icon: "${icon}" - ) { id } - }`, - { headers } - ) + describe('authenticated admin', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'admin@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + it('creates a badge', async () => { + const expected = { + CreateBadge: { + id: 'b1' + } + } + await expect(client.request(mutation, params)).resolves.toEqual(expected) + }) }) - it('creates a badge', () => { - let { id } = response.CreateBadge - expect(response).toEqual({ - CreateBadge: { id } + + describe('authenticated moderator', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect( + client.request(mutation, params) + ).rejects.toThrow('Not Authorised') }) }) }) - - describe('authenticated moderator', () => { - let client - let headers - let { id, key, type, status, icon } = params - beforeEach(async () => { - headers = await login({ email: 'moderator@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - }) - it('throws authorization error', async () => { - await expect(client.request(`mutation { - CreateBadge( - id: "${id}", - key: "${key}", - type: ${type}, - status: ${status}, - icon: "${icon}" - ) { id } - }`, - { headers } - )).rejects.toThrow('Not Authorised') - }) - }) }) From fb2b407be029f8e08cfaaf21be72cc6c088aff4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sun, 3 Mar 2019 14:32:29 +0100 Subject: [PATCH 457/554] Extend @Tirokk 's test to Create and Update --- src/resolvers/badges.spec.js | 141 +++++++++++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 6 deletions(-) diff --git a/src/resolvers/badges.spec.js b/src/resolvers/badges.spec.js index f6d8c06dc..e38f54381 100644 --- a/src/resolvers/badges.spec.js +++ b/src/resolvers/badges.spec.js @@ -28,7 +28,7 @@ describe('badges', () => { }) describe('CreateBadge', () => { - const params = { + const variables = { id: 'b1', key: 'indiegogo_en_racoon', type: 'crowdfunding', @@ -45,7 +45,11 @@ describe('badges', () => { $icon: String! ) { CreateBadge(id: $id, key: $key, type: $type, status: $status, icon: $icon) { - id + id, + key, + type, + status, + icon } } ` @@ -56,7 +60,7 @@ describe('badges', () => { it('throws authorization error', async () => { client = new GraphQLClient(host) await expect( - client.request(mutation, params) + client.request(mutation, variables) ).rejects.toThrow('Not Authorised') }) }) @@ -70,10 +74,14 @@ describe('badges', () => { it('creates a badge', async () => { const expected = { CreateBadge: { - id: 'b1' + icon: '/img/badges/indiegogo_en_racoon.svg', + id: 'b1', + key: 'indiegogo_en_racoon', + status: 'permanent', + type: 'crowdfunding' } } - await expect(client.request(mutation, params)).resolves.toEqual(expected) + await expect(client.request(mutation, variables)).resolves.toEqual(expected) }) }) @@ -86,9 +94,130 @@ describe('badges', () => { it('throws authorization error', async () => { await expect( - client.request(mutation, params) + client.request(mutation, variables) ).rejects.toThrow('Not Authorised') }) }) }) + + describe('UpdateBadge', () => { + beforeEach(async () => { + await factory.authenticateAs({ email: 'admin@example.org', password: '1234' }) + await factory.create('Badge', { id: 'b1' }) + }) + const variables = { + id: 'b1', + key: 'whatever' + } + + const mutation = ` + mutation($id: ID!, $key: String!) { + UpdateBadge(id: $id, key: $key) { + id + key + } + } + ` + + describe('unauthenticated', () => { + let client + + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect( + client.request(mutation, variables) + ).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated moderator', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect( + client.request(mutation, variables) + ).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated admin', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'admin@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + it('updates a badge', async () => { + const expected = { + UpdateBadge: { + id: 'b1', + key: 'whatever' + } + } + await expect(client.request(mutation, variables)).resolves.toEqual(expected) + }) + }) + }) + + describe('DeleteBadge', () => { + beforeEach(async () => { + await factory.authenticateAs({ email: 'admin@example.org', password: '1234' }) + await factory.create('Badge', { id: 'b1' }) + }) + const variables = { + id: 'b1' + } + + const mutation = ` + mutation($id: ID!) { + DeleteBadge(id: $id) { + id + } + } + ` + + describe('unauthenticated', () => { + let client + + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect( + client.request(mutation, variables) + ).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated moderator', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect( + client.request(mutation, variables) + ).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated admin', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'admin@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + it('deletes a badge', async () => { + const expected = { + DeleteBadge: { + id: 'b1' + } + } + await expect(client.request(mutation, variables)).resolves.toEqual(expected) + }) + }) + }) }) From 8d1eb6026a8b34ad82c22f6ab8d0c29dae8b4c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sun, 3 Mar 2019 14:35:08 +0100 Subject: [PATCH 458/554] Let all tests pass :green_heart: --- src/middleware/permissionsMiddleware.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index d2dc45094..f10b30cb6 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -37,7 +37,9 @@ const permissions = shield({ // TODO UpdatePost: isOwner, // TODO DeletePost: isOwner, report: isAuthenticated, - CreateBadge: isAdmin + CreateBadge: isAdmin, + UpdateBadge: isAdmin, + DeleteBadge: isAdmin // addFruitToBasket: isAuthenticated // CreateUser: allow, }, From 83b36e8e351a95f5be9276c18579e574c4e8edfb Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 3 Mar 2019 15:55:11 +0100 Subject: [PATCH 459/554] Output distinct counts --- src/schema.graphql | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index 1f9bcb477..20a0b3652 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -84,13 +84,13 @@ type User { updatedAt: String friends: [User]! @relation(name: "FRIENDS", direction: "BOTH") - friendsCount: Int! @cypher(statement: "MATCH (this)<-[:FRIENDS]->(r:User) RETURN COUNT(r)") + friendsCount: Int! @cypher(statement: "MATCH (this)<-[:FRIENDS]->(r:User) RETURN COUNT(DISTINCT r)") following: [User]! @relation(name: "FOLLOWS", direction: "OUT") - followingCount: Int! @cypher(statement: "MATCH (this)-[:FOLLOWS]->(r:User) RETURN COUNT(r)") + followingCount: Int! @cypher(statement: "MATCH (this)-[:FOLLOWS]->(r:User) RETURN COUNT(DISTINCT r)") followedBy: [User]! @relation(name: "FOLLOWS", direction: "IN") - followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(r)") + followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(DISTINCT r)") #contributions: [WrittenPost]! #contributions2(first: Int = 10, offset: Int = 0): [WrittenPost2]! @@ -109,7 +109,7 @@ type User { commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) WHERE NOT r.deleted = true RETURN COUNT(r)") shouted: [Post]! @relation(name: "SHOUTED", direction: "OUT") - shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)") + shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)") organizationsCreated: [Organization] @relation(name: "CREATED_ORGA", direction: "OUT") organizationsOwned: [Organization] @relation(name: "OWNING_ORGA", direction: "OUT") @@ -149,7 +149,7 @@ type Post { commentsCount: Int! @cypher(statement: "MATCH (this)<-[:COMMENTS]-(r:Comment) RETURN COUNT(r)") shoutedBy: [User]! @relation(name: "SHOUTED", direction: "IN") - shoutedCount: Int! @cypher(statement: "MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)") + shoutedCount: Int! @cypher(statement: "MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)") } type Comment { @@ -223,7 +223,7 @@ type Tag { name: String! taggedPosts: [Post]! @relation(name: "TAGGED", direction: "IN") taggedOrganizations: [Organization]! @relation(name: "TAGGED", direction: "IN") - taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p) RETURN COUNT(p)") + taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p) RETURN COUNT(DISTINCT p)") taggedCountUnique: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p)<-[:WROTE]-(u:User) RETURN COUNT(DISTINCT u)") deleted: Boolean disabled: Boolean From 257183ac3f4e702f56063ebea206d7fb7795d84d Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 3 Mar 2019 19:29:25 +0100 Subject: [PATCH 460/554] added currentUserId to cypher params --- package.json | 2 +- src/server.js | 5 ++++- yarn.lock | 52 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 570841630..2d6696164 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "lodash": "~4.17.11", "ms": "~2.1.1", "neo4j-driver": "~1.7.2", - "neo4j-graphql-js": "~2.3.1", + "neo4j-graphql-js": "~2.4.1", "node-fetch": "~2.3.0", "npm-run-all": "~4.1.5", "sanitize-html": "~1.20.0", diff --git a/src/server.js b/src/server.js index 2fc3af871..8e1cd36da 100644 --- a/src/server.js +++ b/src/server.js @@ -45,7 +45,10 @@ const createServer = (options) => { return { driver, user, - req: request + req: request, + cypherParams: { + currentUserId: user ? user.id : null + } } }, schema: schema, diff --git a/yarn.lock b/yarn.lock index fd3c53297..5e59726cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1092,6 +1092,14 @@ apollo-env@0.3.3: core-js "3.0.0-beta.13" node-fetch "^2.2.0" +apollo-errors@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/apollo-errors/-/apollo-errors-1.9.0.tgz#f1ed0ca0a6be5cd2f24e2eaa7b0860a10146ff51" + integrity sha512-XVukHd0KLvgY6tNjsPS3/Re3U6RQlTKrTbIpqqeTMo2N34uQMr+H1UheV21o8hOZBAFosvBORVricJiP5vfmrw== + dependencies: + assert "^1.4.1" + extendable-error "^0.1.5" + apollo-graphql@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.1.1.tgz#dc5eac3062abf9f063ac9869f0ef5c54fdc136e5" @@ -1378,6 +1386,13 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +assert@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + dependencies: + util "0.10.3" + assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -2800,6 +2815,11 @@ extend@^3.0.0, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +extendable-error@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/extendable-error/-/extendable-error-0.1.5.tgz#122308a7097bc89a263b2c4fbf089c78140e3b6d" + integrity sha1-EiMIpwl7yJomOyxPvwiceBQOO20= + external-editor@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" @@ -3155,6 +3175,15 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== +graphql-auth-directives@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/graphql-auth-directives/-/graphql-auth-directives-2.1.0.tgz#85b83817844e2ec5fba8fe5de444287d6dd0f85a" + integrity sha512-mRVsjeMeMABPyjxyzl9mhkcW02YBwSj7dnu7C6wy2dIhiby6xTKy6Q54C8KeqXSYsy6ua4VmBH++d7GKqpvIoA== + dependencies: + apollo-errors "^1.9.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" @@ -3588,6 +3617,11 @@ inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, i resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" @@ -4432,7 +4466,7 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= -jsonwebtoken@~8.5.0: +jsonwebtoken@^8.3.0, jsonwebtoken@~8.5.0: version "8.5.0" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#ebd0ca2a69797816e1c5af65b6c759787252947e" integrity sha512-IqEycp0znWHNA11TpYi77bVgyBO/pGESDh7Ajhas+u0ttkGkKYIIAjniL4Bw5+oVejVF+SYkaI7XKfwCCyeTuA== @@ -4941,12 +4975,13 @@ neo4j-driver@^1.7.2, neo4j-driver@~1.7.2: text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-graphql-js@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.3.1.tgz#9a5de7e312594d63481e947a0cbe4e08b05ffed3" - integrity sha512-9DExWXD2vFdDJOmqorT1ygFOUEos7KF8KyF8Wt3jYxejWUuq+a5fAFBu7+YDH8QbvA23paKPEX0Pn1nS+Q5C1A== +neo4j-graphql-js@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.4.1.tgz#a1de65340fb6f1ad0ae6aadab90a0bb78b490b32" + integrity sha512-Py6RJuMT7A03Hzoo6qfKyo6DUnHQgbZlBcgucnhgQjbeysAzvM3F02UAVn/HxEtOgowAeGWjyjJvwozoNtiiqQ== dependencies: graphql "^14.0.2" + graphql-auth-directives "^2.0.0" lodash "^4.17.11" neo4j-driver "^1.7.2" @@ -6962,6 +6997,13 @@ util.promisify@^1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" From f39e27c47c2a90fe72a0edd287d93f34d54d6de3 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Sun, 3 Mar 2019 19:29:40 +0100 Subject: [PATCH 461/554] Added followedByCurrentUser and shoutedByCurrentUser --- src/schema.graphql | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/schema.graphql b/src/schema.graphql index 20a0b3652..dd2bfde59 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -92,6 +92,12 @@ type User { followedBy: [User]! @relation(name: "FOLLOWS", direction: "IN") followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(DISTINCT r)") + "Is the currently logged in user following that user?" + followedByCurrentUser: Boolean! @cypher(statement: """ + MATCH (this)<-[:FOLLOWS]-(u:User {id: $cypherParams.currentUserId}) + RETURN COUNT(u) >= 1 + """) + #contributions: [WrittenPost]! #contributions2(first: Int = 10, offset: Int = 0): [WrittenPost2]! # @cypher( @@ -150,6 +156,12 @@ type Post { shoutedBy: [User]! @relation(name: "SHOUTED", direction: "IN") shoutedCount: Int! @cypher(statement: "MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)") + + "Has the currently logged in user shouted that post?" + shoutedByCurrentUser: Boolean! @cypher(statement: """ + MATCH (this)<-[:SHOUTED]-(u:User {id: $cypherParams.currentUserId}) + RETURN COUNT(u) >= 1 + """) } type Comment { From b23380d5938369f2f6cead131e2b6dc7519e1ecf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 4 Mar 2019 04:21:10 +0000 Subject: [PATCH 462/554] Bump eslint from 5.14.1 to 5.15.0 Bumps [eslint](https://github.com/eslint/eslint) from 5.14.1 to 5.15.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v5.14.1...v5.15.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 570841630..cefa46953 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "babel-eslint": "~10.0.1", "babel-jest": "~24.1.0", "chai": "~4.2.0", - "eslint": "~5.14.1", + "eslint": "~5.15.0", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.16.0", "eslint-plugin-jest": "~22.3.0", diff --git a/yarn.lock b/yarn.lock index fd3c53297..eb0f3efd9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2564,10 +2564,10 @@ eslint-scope@3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" - integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== +eslint-scope@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.2.tgz#5f10cd6cabb1965bf479fa65745673439e21cb0e" + integrity sha512-5q1+B/ogmHl8+paxtOKx38Z8LtWkVGuNt3+GQNErqwLl6ViNp/gdJGMCjZNxZ8j/VYjDNZ2Fo+eQc1TAVPIzbg== dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" @@ -2582,10 +2582,10 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@~5.14.1: - version "5.14.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.14.1.tgz#490a28906be313685c55ccd43a39e8d22efc04ba" - integrity sha512-CyUMbmsjxedx8B0mr79mNOqetvkbij/zrXnFeK2zc3pGRn3/tibjiNAv/3UxFEyfMDjh+ZqTrJrEGBFiGfD5Og== +eslint@~5.15.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.15.0.tgz#f313a2f7c7628d39adeefdba4a9c41f842012c9e" + integrity sha512-xwG7SS5JLeqkiR3iOmVgtF8Y6xPdtr6AAsN6ph7Q6R/fv+3UlKYoika8SmNzmb35qdRF+RfTY35kMEdtbi+9wg== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.9.1" @@ -2593,7 +2593,7 @@ eslint@~5.14.1: cross-spawn "^6.0.5" debug "^4.0.1" doctrine "^3.0.0" - eslint-scope "^4.0.0" + eslint-scope "^4.0.2" eslint-utils "^1.3.1" eslint-visitor-keys "^1.0.0" espree "^5.0.1" From b2520258a3c7454fdab8facdb261f4913e60b9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Mar 2019 18:35:02 +0100 Subject: [PATCH 463/554] Improve specification of posts resolver * only authors are alllowed to update/delete their own posts * set disabled+deleted to false if not provided --- src/resolvers/posts.spec.js | 195 +++++++++++++++++++++++++++++++----- 1 file changed, 168 insertions(+), 27 deletions(-) diff --git a/src/resolvers/posts.spec.js b/src/resolvers/posts.spec.js index a6c1d7e3e..5603683eb 100644 --- a/src/resolvers/posts.spec.js +++ b/src/resolvers/posts.spec.js @@ -3,6 +3,7 @@ import { GraphQLClient } from 'graphql-request' import { host, login } from '../jest/helpers' const factory = Factory() +let client beforeEach(async () => { await factory.create('User', { @@ -16,46 +17,186 @@ afterEach(async () => { }) describe('CreatePost', () => { + const mutation = ` + mutation { + CreatePost(title: "I am a title", content: "Some content") { + title + content + slug + disabled + deleted + } + } + ` + describe('unauthenticated', () => { - let client it('throws authorization error', async () => { client = new GraphQLClient(host) - await expect(client.request(`mutation { - CreatePost( - title: "I am a post", - content: "Some content" - ) { slug } - }`)).rejects.toThrow('Not Authorised') + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated', () => { + let headers + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) }) - describe('authenticated', () => { - let headers - let response - beforeEach(async () => { - headers = await login({ email: 'test@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - response = await client.request(`mutation { - CreatePost( - title: "A title", - content: "Some content" - ) { title, content } - }`, { headers }) - }) + it('creates a post', async () => { + const expected = { + CreatePost: { + title: 'I am a title', + content: 'Some content' + } + } + await expect(client.request(mutation)).resolves.toMatchObject(expected) + }) - it('creates a post', () => { - expect(response).toEqual({ CreatePost: { title: 'A title', content: 'Some content' } }) - }) - - it('assigns the authenticated user as author', async () => { - const { User } = await client.request(`{ + it('assigns the authenticated user as author', async () => { + await client.request(mutation) + const { User } = await client.request(`{ User(email:"test@example.org") { contributions { title } } }`, { headers }) - expect(User).toEqual([ { contributions: [ { title: 'A title' } ] } ]) + expect(User).toEqual([ { contributions: [ { title: 'I am a title' } ] } ]) + }) + + describe('disabled and deleted', () => { + it('initially false', async () => { + const expected = { CreatePost: { disabled: false, deleted: false } } + await expect(client.request(mutation)).resolves.toMatchObject(expected) }) }) }) }) + +describe('UpdatePost', () => { + const mutation = ` + mutation($id: ID!, $content: String) { + UpdatePost(id: $id, content: $content) { + id + content + } + } + ` + + let variables = { + id: 'p1', + content: 'New content' + } + + beforeEach(async () => { + const asAuthor = Factory() + await asAuthor.create('User', { + email: 'author@example.org', + password: '1234' + }) + await asAuthor.authenticateAs({ + email: 'author@example.org', + password: '1234' + }) + await asAuthor.create('Post', { + id: 'p1', + content: 'Old content' + }) + }) + + describe('unauthenticated', () => { + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated but not the author', () => { + let headers + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated as author', () => { + let headers + beforeEach(async () => { + headers = await login({ email: 'author@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('updates a post', async () => { + const expected = { UpdatePost: { id: 'p1', content: 'New content' } } + await expect(client.request(mutation, variables)).resolves.toEqual(expected) + }) + }) +}) + +describe('DeletePost', () => { + const mutation = ` + mutation($id: ID!) { + DeletePost(id: $id) { + id + content + } + } + ` + + let variables = { + id: 'p1' + } + + beforeEach(async () => { + const asAuthor = Factory() + await asAuthor.create('User', { + email: 'author@example.org', + password: '1234' + }) + await asAuthor.authenticateAs({ + email: 'author@example.org', + password: '1234' + }) + await asAuthor.create('Post', { + id: 'p1', + content: 'To be deleted' + }) + }) + + describe('unauthenticated', () => { + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated but not the author', () => { + let headers + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated as author', () => { + let headers + beforeEach(async () => { + headers = await login({ email: 'author@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('deletes a post', async () => { + const expected = { DeletePost: { id: 'p1', content: 'To be deleted' } } + await expect(client.request(mutation, variables)).resolves.toEqual(expected) + }) + }) +}) From c869724d29784ed9af282c4a590ddd7b231dacc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Mar 2019 18:36:56 +0100 Subject: [PATCH 464/554] Let all tests pass :green_heart: --- src/middleware/permissionsMiddleware.js | 2 -- src/middleware/softDeleteMiddleware.js | 3 +++ src/resolvers/posts.js | 33 +++++++++++++++++++++---- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 5515d5b7a..b755f3bab 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -34,8 +34,6 @@ const permissions = shield({ }, Mutation: { CreatePost: isAuthenticated, - // TODO UpdatePost: isOwner, - // TODO DeletePost: isOwner, report: isAuthenticated, CreateBadge: isAdmin, UpdateBadge: isAdmin, diff --git a/src/middleware/softDeleteMiddleware.js b/src/middleware/softDeleteMiddleware.js index bed7b6ca0..0c12e7a72 100644 --- a/src/middleware/softDeleteMiddleware.js +++ b/src/middleware/softDeleteMiddleware.js @@ -19,5 +19,8 @@ export default { User: async (resolve, root, args, context, info) => { return resolve(root, setDefaults(args), context, info) } + }, + Mutation: async (resolve, root, args, context, info) => { + return resolve(root, setDefaults(args), context, info) } } diff --git a/src/resolvers/posts.js b/src/resolvers/posts.js index 6a8a0c25f..f59050b5f 100644 --- a/src/resolvers/posts.js +++ b/src/resolvers/posts.js @@ -1,22 +1,45 @@ import { neo4jgraphql } from 'neo4j-graphql-js' +const isAuthor = async (params, { user, driver }) => { + if (!user) return false + const session = driver.session() + const { id: postId } = params + const result = await session.run(` + MATCH (post:Post {id: $postId})<-[:WROTE]-(author) + RETURN author + `, { postId }) + const [author] = result.records.map((record) => { + return record.get('author') + }) + const { properties: { id: authorId } } = author + session.close() + return authorId === user.id +} + export default { Mutation: { - CreatePost: async (object, params, ctx, resolveInfo) => { - const result = await neo4jgraphql(object, params, ctx, resolveInfo, false) + CreatePost: async (object, params, context, resolveInfo) => { + const result = await neo4jgraphql(object, params, context, resolveInfo, false) - const session = ctx.driver.session() + const session = context.driver.session() await session.run( 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + 'MERGE (post)<-[:WROTE]-(author) ' + 'RETURN author', { - userId: ctx.user.id, + userId: context.user.id, postId: result.id }) session.close() return result + }, + UpdatePost: async (object, params, context, resolveInfo) => { + if (!await isAuthor(params, context)) return Error('Not Authorised!') + return neo4jgraphql(object, params, context, resolveInfo, false) + }, + DeletePost: async (object, params, context, resolveInfo) => { + if (!await isAuthor(params, context)) return Error('Not Authorised!') + return neo4jgraphql(object, params, context, resolveInfo, false) } - } } From b64ea750115670aeead8441ba25f8b770eae0611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Mar 2019 18:38:36 +0100 Subject: [PATCH 465/554] Add a deleted post and a disabled post to seeds --- src/seed/seed-db.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index b2ee8fbdb..ed46a5716 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -82,12 +82,12 @@ import Factory from './factories' await Promise.all([ asAdmin.create('Post', { id: 'p0' }), asModerator.create('Post', { id: 'p1' }), - asUser.create('Post', { id: 'p2' }), + asUser.create('Post', { id: 'p2', deleted: true }), asTick.create('Post', { id: 'p3' }), asTrick.create('Post', { id: 'p4' }), asTrack.create('Post', { id: 'p5' }), asAdmin.create('Post', { id: 'p6' }), - asModerator.create('Post', { id: 'p7' }), + asModerator.create('Post', { id: 'p7', disabled: true }), asUser.create('Post', { id: 'p8' }), asTick.create('Post', { id: 'p9' }), asTrick.create('Post', { id: 'p10' }), From 180491c08caef423c48ee413faed7b6bb9fbd3e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Mar 2019 19:40:49 +0100 Subject: [PATCH 466/554] Put `isAuthor` in permissions middleware I find it dirty to access the database in a middleware, ie. I would like to put all access on the database as close to the resolver as possible. However, in this case that would mean to put the authorization check in the resolver, where nobody expects it to be. CC @appinteractive --- src/middleware/permissionsMiddleware.js | 18 ++++++++++++++++++ src/resolvers/posts.js | 24 ------------------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index b755f3bab..c40803e00 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -25,6 +25,22 @@ const onlyEnabledContent = rule({ cache: 'strict' })(async (parent, args, ctx, i return !(disabled || deleted) }) +const isAuthor = rule({ cache: 'no_cache' })(async (parent, args, { user, driver }) => { + if (!user) return false + const session = driver.session() + const { id: postId } = args + const result = await session.run(` + MATCH (post:Post {id: $postId})<-[:WROTE]-(author) + RETURN author + `, { postId }) + const [author] = result.records.map((record) => { + return record.get('author') + }) + const { properties: { id: authorId } } = author + session.close() + return authorId === user.id +}) + // Permissions const permissions = shield({ Query: { @@ -34,6 +50,8 @@ const permissions = shield({ }, Mutation: { CreatePost: isAuthenticated, + UpdatePost: isAuthor, + DeletePost: isAuthor, report: isAuthenticated, CreateBadge: isAdmin, UpdateBadge: isAdmin, diff --git a/src/resolvers/posts.js b/src/resolvers/posts.js index f59050b5f..abf91e047 100644 --- a/src/resolvers/posts.js +++ b/src/resolvers/posts.js @@ -1,21 +1,5 @@ import { neo4jgraphql } from 'neo4j-graphql-js' -const isAuthor = async (params, { user, driver }) => { - if (!user) return false - const session = driver.session() - const { id: postId } = params - const result = await session.run(` - MATCH (post:Post {id: $postId})<-[:WROTE]-(author) - RETURN author - `, { postId }) - const [author] = result.records.map((record) => { - return record.get('author') - }) - const { properties: { id: authorId } } = author - session.close() - return authorId === user.id -} - export default { Mutation: { CreatePost: async (object, params, context, resolveInfo) => { @@ -32,14 +16,6 @@ export default { session.close() return result - }, - UpdatePost: async (object, params, context, resolveInfo) => { - if (!await isAuthor(params, context)) return Error('Not Authorised!') - return neo4jgraphql(object, params, context, resolveInfo, false) - }, - DeletePost: async (object, params, context, resolveInfo) => { - if (!await isAuthor(params, context)) return Error('Not Authorised!') - return neo4jgraphql(object, params, context, resolveInfo, false) } } } From 0db91530fea70010d1f90983f743f0c71d20e940 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 5 Mar 2019 04:18:26 +0000 Subject: [PATCH 467/554] Bump eslint from 5.15.0 to 5.15.1 Bumps [eslint](https://github.com/eslint/eslint) from 5.15.0 to 5.15.1. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v5.15.0...v5.15.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index cefa46953..1c6e8f2ce 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "babel-eslint": "~10.0.1", "babel-jest": "~24.1.0", "chai": "~4.2.0", - "eslint": "~5.15.0", + "eslint": "~5.15.1", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.16.0", "eslint-plugin-jest": "~22.3.0", diff --git a/yarn.lock b/yarn.lock index eb0f3efd9..18d336c7a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2582,10 +2582,10 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@~5.15.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.15.0.tgz#f313a2f7c7628d39adeefdba4a9c41f842012c9e" - integrity sha512-xwG7SS5JLeqkiR3iOmVgtF8Y6xPdtr6AAsN6ph7Q6R/fv+3UlKYoika8SmNzmb35qdRF+RfTY35kMEdtbi+9wg== +eslint@~5.15.1: + version "5.15.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.15.1.tgz#8266b089fd5391e0009a047050795b1d73664524" + integrity sha512-NTcm6vQ+PTgN3UBsALw5BMhgO6i5EpIjQF/Xb5tIh3sk9QhrFafujUOczGz4J24JBlzWclSB9Vmx8d+9Z6bFCg== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.9.1" From e2add5a730ceafa6dff84ecce41db488549dcfe0 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 5 Mar 2019 10:56:47 +0100 Subject: [PATCH 468/554] Added (un)shout and (un)follow mutations --- src/schema.graphql | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/schema.graphql b/src/schema.graphql index dd2bfde59..e5a077f2d 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -1,12 +1,45 @@ type Query { isLoggedIn: Boolean! + "Get the currently logged in User based on the given JWT Token" currentUser: User + "Get the latest Network Statistics" statistics: Statistics! } type Mutation { + "Get a JWT Token for the given Email and password" login(email: String!, password: String!): String! signup(email: String!, password: String!): Boolean! report(resource: Resource!, description: String): Report + + "Shout the given Type and ID" + shout(id: ID!, type: ShoutTypeEnum): String! @cypher(statement: """ + MATCH (n {id: $id}) + WHERE $type IN labels(n) + MERGE (:User {id: $cypherParams.currentUserId})-[r:SHOUTED]->(n) + RETURN COUNT(r) > 0 + """) + "Unshout the given Type and ID" + unshout(id: ID!, type: ShoutTypeEnum): Boolean! @cypher(statement: """ + MATCH (:User {id: $cypherParams.currentUserId})-[r:SHOUTED]->(n {id: $id}) + WHERE $type IN labels(n) + DELETE r + RETURN COUNT(r) > 0 + """) + + "Follow the given Type and ID" + follow(id: ID!, type: FollowTypeEnum): Boolean! @cypher(statement: """ + MATCH (n {id: $id}) + WHERE $type IN labels(n) AND NOT $id = $cypherParams.currentUserId + MERGE (:User {id: $cypherParams.currentUserId})-[r:FOLLOWS]->(n) + RETURN COUNT(r) > 0 + """) + "Unfollow the given Type and ID" + unfollow(id: ID!, type: FollowTypeEnum): Boolean! @cypher(statement: """ + MATCH (:User {id: $cypherParams.currentUserId})-[r:FOLLOWS]->(n {id: $id}) + WHERE $type IN labels(n) + DELETE r + RETURN COUNT(r) > 0 + """) } type Statistics { @@ -214,6 +247,16 @@ enum BadgeStatusEnum { permanent temporary } +enum ShoutTypeEnum { + Post + Organization + Project +} +enum FollowTypeEnum { + User + Organization + Project +} type Organization { id: ID! From d7b1ea88c4dddd9de6df7cefdfb68e0ff2418038 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 5 Mar 2019 11:18:59 +0100 Subject: [PATCH 469/554] Fixed shouts and follows --- src/schema.graphql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index e5a077f2d..f95bbb18a 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -13,9 +13,9 @@ type Mutation { "Shout the given Type and ID" shout(id: ID!, type: ShoutTypeEnum): String! @cypher(statement: """ - MATCH (n {id: $id}) + MATCH (n {id: $id}), (u:User {id: $cypherParams.currentUserId}) WHERE $type IN labels(n) - MERGE (:User {id: $cypherParams.currentUserId})-[r:SHOUTED]->(n) + MERGE (u)-[r:SHOUTED]->(n) RETURN COUNT(r) > 0 """) "Unshout the given Type and ID" @@ -28,9 +28,9 @@ type Mutation { "Follow the given Type and ID" follow(id: ID!, type: FollowTypeEnum): Boolean! @cypher(statement: """ - MATCH (n {id: $id}) + MATCH (n {id: $id}), (u:User {id: $cypherParams.currentUserId}) WHERE $type IN labels(n) AND NOT $id = $cypherParams.currentUserId - MERGE (:User {id: $cypherParams.currentUserId})-[r:FOLLOWS]->(n) + MERGE (u)-[r:FOLLOWS]->(n) RETURN COUNT(r) > 0 """) "Unfollow the given Type and ID" From 45a004662f1fad9d206fc3ddf4fd7b5c3b0c614f Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 5 Mar 2019 14:18:22 +0100 Subject: [PATCH 470/554] Disable shouting of own content --- src/schema.graphql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index f95bbb18a..e6e2088f1 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -13,8 +13,8 @@ type Mutation { "Shout the given Type and ID" shout(id: ID!, type: ShoutTypeEnum): String! @cypher(statement: """ - MATCH (n {id: $id}), (u:User {id: $cypherParams.currentUserId}) - WHERE $type IN labels(n) + MATCH (n {id: $id})<-[:WROTE]-(wu:User), (u:User {id: $cypherParams.currentUserId}) + WHERE $type IN labels(n) AND NOT wu.id = $cypherParams.currentUserId MERGE (u)-[r:SHOUTED]->(n) RETURN COUNT(r) > 0 """) From f644507e4fc496a4e4ba0f6d2948d56d8a483bce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 5 Mar 2019 15:47:03 +0100 Subject: [PATCH 471/554] Intermediate commit --- src/middleware/softDeleteMiddleware.spec.js | 11 +++++++---- src/seed/factories/posts.js | 2 -- src/seed/seed-db.js | 7 ++++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/middleware/softDeleteMiddleware.spec.js b/src/middleware/softDeleteMiddleware.spec.js index 925a03ccc..c37e7d426 100644 --- a/src/middleware/softDeleteMiddleware.spec.js +++ b/src/middleware/softDeleteMiddleware.spec.js @@ -10,14 +10,17 @@ let action beforeEach(async () => { await Promise.all([ factory.create('User', { role: 'user', email: 'user@example.org', password: '1234' }), - factory.create('User', { role: 'moderator', email: 'moderator@example.org', password: '1234' }) + factory.create('User', { id: 'm1', role: 'moderator', email: 'moderator@example.org', password: '1234' }) ]) await factory.authenticateAs({ email: 'user@example.org', password: '1234' }) await Promise.all([ - factory.create('Post', { title: 'Deleted post', deleted: true, disabled: false }), - factory.create('Post', { title: 'Disabled post', deleted: false, disabled: true }), - factory.create('Post', { title: 'Publicly visible post', deleted: false, disabled: false }) + factory.create('Post', { title: 'Deleted post', deleted: true }), + factory.create('Post', { id: 'p2', title: 'Disabled post', deleted: false }), + factory.create('Post', { title: 'Publicly visible post', deleted: false }) ]) + const moderatorFactory = Factory() + await moderatorFactory.authenticateAs({ email: 'moderator@example.org', password: '1234'}) + await moderatorFactory.relate('Post', 'DisabledBy', { from: 'm1', to: 'p2'}) }) afterEach(async () => { diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index d96cf4f73..e2bc2ab66 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -14,7 +14,6 @@ export default function (params) { ].join('. '), image = faker.image.image(), visibility = 'public', - disabled = false, deleted = false } = params @@ -26,7 +25,6 @@ export default function (params) { content: "${content}", image: "${image}", visibility: ${visibility}, - disabled: ${disabled}, deleted: ${deleted} ) { title, content } } diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index ed46a5716..c20d524ef 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -87,7 +87,7 @@ import Factory from './factories' asTrick.create('Post', { id: 'p4' }), asTrack.create('Post', { id: 'p5' }), asAdmin.create('Post', { id: 'p6' }), - asModerator.create('Post', { id: 'p7', disabled: true }), + asModerator.create('Post', { id: 'p7' }), asUser.create('Post', { id: 'p8' }), asTick.create('Post', { id: 'p9' }), asTrick.create('Post', { id: 'p10' }), @@ -98,6 +98,11 @@ import Factory from './factories' asTick.create('Post', { id: 'p15' }) ]) + await asModerator.relate('Post', 'DisabledBy', { + from: 'u2', + to: 'p15' + }) + await Promise.all([ f.relate('Post', 'Categories', { from: 'p0', to: 'cat16' }), f.relate('Post', 'Categories', { from: 'p1', to: 'cat1' }), From 420ea8a4d60747b77e0c0da8b0c70f1dfb28a9e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 5 Mar 2019 16:15:31 +0100 Subject: [PATCH 472/554] Scaffold some tests for disabledBy relation --- src/resolvers/posts.spec.js | 46 +++++++++++++++++++++++++++++++++++++ src/schema.graphql | 1 + 2 files changed, 47 insertions(+) diff --git a/src/resolvers/posts.spec.js b/src/resolvers/posts.spec.js index 5603683eb..1601e3348 100644 --- a/src/resolvers/posts.spec.js +++ b/src/resolvers/posts.spec.js @@ -200,3 +200,49 @@ describe('DeletePost', () => { }) }) }) + +describe('AddPostDisabledBy', () => { + const mutation = ` + mutation { + AddPostDisabledBy(from: { id: "u8" }, to: { id: "p9" }) { + from { + id + } + to { + id + } + } + } + ` + it.todo('throws authorization error') + + describe('authenticated', () => { + it.todo('throws authorization error') + + describe('as moderator', () => { + it.todo('throws authorization error') + + describe('current user matches provided user', () => { + it.todo('sets current user') + it.todo('updates .disabled on post') + }) + }) + }) +}) + +describe('RemovePostDisabledBy', () => { + it.todo('throws authorization error') + + describe('authenticated', () => { + it.todo('throws authorization error') + + describe('as moderator', () => { + it.todo('throws authorization error') + + describe('current user matches provided user', () => { + it.todo('sets current user') + it.todo('updates .disabled on post') + }) + }) + }) +}) diff --git a/src/schema.graphql b/src/schema.graphql index 1f9bcb477..4c2a58505 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -133,6 +133,7 @@ type Post { visibility: VisibilityEnum deleted: Boolean disabled: Boolean + disabledBy: User! @relation(name: "DISABLED", direction: "IN") createdAt: String updatedAt: String From 85d9d7043eef6080673f52db806892e11e2881e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 5 Mar 2019 16:19:51 +0100 Subject: [PATCH 473/554] Setup isModerator permission for disable relation --- src/middleware/permissionsMiddleware.js | 5 ++- src/resolvers/posts.spec.js | 51 +++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index c40803e00..ec2261c5a 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -55,7 +55,10 @@ const permissions = shield({ report: isAuthenticated, CreateBadge: isAdmin, UpdateBadge: isAdmin, - DeleteBadge: isAdmin + DeleteBadge: isAdmin, + + AddPostDisabledBy: isModerator, + RemovePostDisabledBy: isModerator, // addFruitToBasket: isAuthenticated // CreateUser: allow, }, diff --git a/src/resolvers/posts.spec.js b/src/resolvers/posts.spec.js index 1601e3348..cbe836b21 100644 --- a/src/resolvers/posts.spec.js +++ b/src/resolvers/posts.spec.js @@ -214,10 +214,25 @@ describe('AddPostDisabledBy', () => { } } ` - it.todo('throws authorization error') + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) describe('authenticated', () => { - it.todo('throws authorization error') + let headers + beforeEach(async () => { + await factory.create('User', { + email: 'someUser@example.org', + password: '1234' + }) + headers = await login({ email: 'someUser@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) describe('as moderator', () => { it.todo('throws authorization error') @@ -231,10 +246,38 @@ describe('AddPostDisabledBy', () => { }) describe('RemovePostDisabledBy', () => { - it.todo('throws authorization error') + const mutation = ` + mutation { + AddPostDisabledBy(from: { id: "u8" }, to: { id: "p9" }) { + from { + id + } + to { + id + } + } + } + ` + + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) describe('authenticated', () => { - it.todo('throws authorization error') + let headers + beforeEach(async () => { + await factory.create('User', { + email: 'someUser@example.org', + password: '1234' + }) + headers = await login({ email: 'someUser@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) describe('as moderator', () => { it.todo('throws authorization error') From f2e7e515a4c1874bcb7df289b2d24f1c797a92f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 5 Mar 2019 16:46:39 +0100 Subject: [PATCH 474/554] Check from: User! matches the authenticated user --- src/middleware/permissionsMiddleware.js | 11 +- src/resolvers/posts.spec.js | 166 ++++++++++++++---------- 2 files changed, 109 insertions(+), 68 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index ec2261c5a..8cf35c2a3 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -1,4 +1,4 @@ -import { rule, shield, allow, or } from 'graphql-shield' +import { rule, shield, allow, and, or } from 'graphql-shield' /* * TODO: implement @@ -41,6 +41,11 @@ const isAuthor = rule({ cache: 'no_cache' })(async (parent, args, { user, driver return authorId === user.id }) +const fromUserMatchesCurrentUser = rule({ cache: 'no_cache' })(async (parent, args, { user, driver }) => { + const { from: { id: fromId } } = args + return user.id === fromId +}) + // Permissions const permissions = shield({ Query: { @@ -57,8 +62,8 @@ const permissions = shield({ UpdateBadge: isAdmin, DeleteBadge: isAdmin, - AddPostDisabledBy: isModerator, - RemovePostDisabledBy: isModerator, + AddPostDisabledBy: and(isModerator, fromUserMatchesCurrentUser), + RemovePostDisabledBy: and(isModerator, fromUserMatchesCurrentUser), // addFruitToBasket: isAuthenticated // CreateUser: allow, }, diff --git a/src/resolvers/posts.spec.js b/src/resolvers/posts.spec.js index cbe836b21..515216f34 100644 --- a/src/resolvers/posts.spec.js +++ b/src/resolvers/posts.spec.js @@ -201,52 +201,22 @@ describe('DeletePost', () => { }) }) -describe('AddPostDisabledBy', () => { - const mutation = ` - mutation { - AddPostDisabledBy(from: { id: "u8" }, to: { id: "p9" }) { - from { - id - } - to { - id - } - } + + + +describe('disabledBy relation', () => { + const setup = async (params = {}) => { + let headers = {} + const { email, password } = params + if (email && password) { + await factory.create('User', params) + headers = await login({email, password}) } - ` - it('throws authorization error', async () => { - client = new GraphQLClient(host) - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') - }) + client = new GraphQLClient(host, { headers }) + } - describe('authenticated', () => { - let headers - beforeEach(async () => { - await factory.create('User', { - email: 'someUser@example.org', - password: '1234' - }) - headers = await login({ email: 'someUser@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - }) - - it('throws authorization error', async () => { - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') - }) - - describe('as moderator', () => { - it.todo('throws authorization error') - - describe('current user matches provided user', () => { - it.todo('sets current user') - it.todo('updates .disabled on post') - }) - }) - }) -}) - -describe('RemovePostDisabledBy', () => { - const mutation = ` + describe('AddPostDisabledBy', () => { + const mutation = ` mutation { AddPostDisabledBy(from: { id: "u8" }, to: { id: "p9" }) { from { @@ -259,32 +229,98 @@ describe('RemovePostDisabledBy', () => { } ` - it('throws authorization error', async () => { - client = new GraphQLClient(host) - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') - }) - - describe('authenticated', () => { - let headers - beforeEach(async () => { - await factory.create('User', { - email: 'someUser@example.org', - password: '1234' - }) - headers = await login({ email: 'someUser@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - }) - it('throws authorization error', async () => { + await setup() await expect(client.request(mutation)).rejects.toThrow('Not Authorised') }) - describe('as moderator', () => { - it.todo('throws authorization error') + describe('authenticated', () => { + it('throws authorization error', async () => { + await setup({ + email: 'someUser@example.org', + password: '1234' + }) + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) - describe('current user matches provided user', () => { - it.todo('sets current user') - it.todo('updates .disabled on post') + describe('as moderator', () => { + it('throws authorization error', async () => { + await setup({ + email: 'attributedUserMismatch@example.org', + password: '1234', + role: 'moderator' + }) + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + describe('current user matches provided user', () => { + beforeEach(async () => { + await setup({ + id: 'u7', + email: 'moderator@example.org', + password: '1234', + role: 'moderator' + }) + }) + + it.todo('sets current user') + it.todo('updates .disabled on post') + }) + }) + }) + }) + + describe('RemovePostDisabledBy', () => { + const mutation = ` + mutation { + AddPostDisabledBy(from: { id: "u8" }, to: { id: "p9" }) { + from { + id + } + to { + id + } + } + } + ` + + it('throws authorization error', async () => { + await setup() + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { + it('throws authorization error', async () => { + await setup({ + email: 'someUser@example.org', + password: '1234' + }) + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + describe('as moderator', () => { + it('throws authorization error', async () => { + await setup({ + role: 'moderator', + email: 'someUser@example.org', + password: '1234' + }) + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + describe('current user matches provided user', () => { + beforeEach(async () => { + await setup({ + id: 'u7', + role: 'moderator', + email: 'someUser@example.org', + password: '1234' + }) + }) + + it.todo('sets current user') + it.todo('updates .disabled on post') + }) }) }) }) From 99cebc8d64b46766a7ff618afc1f30669f59adc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 5 Mar 2019 17:45:10 +0100 Subject: [PATCH 475/554] Implementation ready except disabled attr. --- src/middleware/permissionsMiddleware.js | 1 + src/resolvers/posts.spec.js | 64 ++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 8cf35c2a3..1c6e8310b 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -42,6 +42,7 @@ const isAuthor = rule({ cache: 'no_cache' })(async (parent, args, { user, driver }) const fromUserMatchesCurrentUser = rule({ cache: 'no_cache' })(async (parent, args, { user, driver }) => { + if (!user) return false const { from: { id: fromId } } = args return user.id === fromId }) diff --git a/src/resolvers/posts.spec.js b/src/resolvers/posts.spec.js index 515216f34..0715f221d 100644 --- a/src/resolvers/posts.spec.js +++ b/src/resolvers/posts.spec.js @@ -206,10 +206,16 @@ describe('DeletePost', () => { describe('disabledBy relation', () => { const setup = async (params = {}) => { + await factory.create('User', {email: 'author@example.org', password: '1234'}) + await factory.authenticateAs({email: 'author@example.org', password: '1234'}) + await factory.create('Post', { + id: 'p9' // that's the ID we will look for + }) + let headers = {} const { email, password } = params if (email && password) { - await factory.create('User', params) + const user = await factory.create('User', params) headers = await login({email, password}) } client = new GraphQLClient(host, { headers }) @@ -218,7 +224,7 @@ describe('disabledBy relation', () => { describe('AddPostDisabledBy', () => { const mutation = ` mutation { - AddPostDisabledBy(from: { id: "u8" }, to: { id: "p9" }) { + AddPostDisabledBy(from: { id: "u7" }, to: { id: "p9" }) { from { id } @@ -263,17 +269,47 @@ describe('disabledBy relation', () => { }) }) - it.todo('sets current user') - it.todo('updates .disabled on post') + it('returns created relation', async () => { + const expected = { + AddPostDisabledBy: { + from: { id: 'u7' }, + to: { id: 'p9' } + } + } + await expect(client.request(mutation)).resolves.toEqual(expected) + }) + + it('sets current user', async () => { + await client.request(mutation) + const query = `{ Post { id, disabledBy { id } } }` + const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } + await expect(client.request(query)).resolves.toEqual(expected) + }) + + it('updates .disabled on post', async () => { + await client.request(mutation) + const query = `{ Post { id disabled } }` + const expected = { Post: [ { id: 'p9', disabled: true } ] } + await expect(client.request(query)).resolves.toEqual(expected) + }) }) }) }) }) describe('RemovePostDisabledBy', () => { + beforeEach(async () => { + await factory.create('User', {email: 'anotherModerator@example.org', password: '1234', role: 'moderator'}) + await factory.authenticateAs({email: 'anotherModerator@example.org', password: '1234'}) + await factory.relate('Post', 'DisabledBy', { + from: 'u7', + to: 'p9' + }) + }) + const mutation = ` mutation { - AddPostDisabledBy(from: { id: "u8" }, to: { id: "p9" }) { + RemovePostDisabledBy(from: { id: "u7" }, to: { id: "p9" }) { from { id } @@ -318,8 +354,22 @@ describe('disabledBy relation', () => { }) }) - it.todo('sets current user') - it.todo('updates .disabled on post') + it('returns deleted relation', async () => { + const expected = { + RemovePostDisabledBy: { + from: { id: 'u7' }, + to: { id: 'p9' } + } + } + await expect(client.request(mutation)).resolves.toEqual(expected) + }) + + it('updates .disabled on post', async () => { + await client.request(mutation) + const query = `{ Post { id disabled } }` + const expected = { Post: [ { id: 'p9', disabled: false } ] } + await expect(client.request(query)).resolves.toEqual(expected) + }) }) }) }) From 592f25b978d4a6e38e4ec89504f4d59b73e6917c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 5 Mar 2019 18:14:25 +0100 Subject: [PATCH 476/554] Implement update of .disabled field --- src/resolvers/posts.js | 20 ++++ src/resolvers/posts.spec.js | 179 ++++++++++++++++++++---------------- 2 files changed, 120 insertions(+), 79 deletions(-) diff --git a/src/resolvers/posts.js b/src/resolvers/posts.js index abf91e047..33934699b 100644 --- a/src/resolvers/posts.js +++ b/src/resolvers/posts.js @@ -2,6 +2,26 @@ import { neo4jgraphql } from 'neo4j-graphql-js' export default { Mutation: { + AddPostDisabledBy: async (object, params, context, resolveInfo) => { + const { to: { id: postId } } = params + const session = context.driver.session() + await session.run(` + MATCH (p:Post {id: $postId}) + SET p.disabled = true`, { postId }) + session.close() + return neo4jgraphql(object, params, context, resolveInfo, false) + }, + + RemovePostDisabledBy: async (object, params, context, resolveInfo) => { + const { to: { id: postId } } = params + const session = context.driver.session() + await session.run(` + MATCH (p:Post {id: $postId}) + SET p.disabled = false`, { postId }) + session.close() + return neo4jgraphql(object, params, context, resolveInfo, false) + }, + CreatePost: async (object, params, context, resolveInfo) => { const result = await neo4jgraphql(object, params, context, resolveInfo, false) diff --git a/src/resolvers/posts.spec.js b/src/resolvers/posts.spec.js index 0715f221d..427a5d925 100644 --- a/src/resolvers/posts.spec.js +++ b/src/resolvers/posts.spec.js @@ -204,7 +204,7 @@ describe('DeletePost', () => { -describe('disabledBy relation', () => { +describe('AddPostDisabledBy', () => { const setup = async (params = {}) => { await factory.create('User', {email: 'author@example.org', password: '1234'}) await factory.authenticateAs({email: 'author@example.org', password: '1234'}) @@ -221,8 +221,7 @@ describe('disabledBy relation', () => { client = new GraphQLClient(host, { headers }) } - describe('AddPostDisabledBy', () => { - const mutation = ` + const mutation = ` mutation { AddPostDisabledBy(from: { id: "u7" }, to: { id: "p9" }) { from { @@ -235,79 +234,96 @@ describe('disabledBy relation', () => { } ` + it('throws authorization error', async () => { + await setup() + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { it('throws authorization error', async () => { - await setup() + await setup({ + email: 'someUser@example.org', + password: '1234' + }) await expect(client.request(mutation)).rejects.toThrow('Not Authorised') }) - describe('authenticated', () => { + describe('as moderator', () => { it('throws authorization error', async () => { await setup({ - email: 'someUser@example.org', - password: '1234' + email: 'attributedUserMismatch@example.org', + password: '1234', + role: 'moderator' }) await expect(client.request(mutation)).rejects.toThrow('Not Authorised') }) - describe('as moderator', () => { - it('throws authorization error', async () => { + describe('current user matches provided user', () => { + beforeEach(async () => { await setup({ - email: 'attributedUserMismatch@example.org', + id: 'u7', + email: 'moderator@example.org', password: '1234', role: 'moderator' }) - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') }) - describe('current user matches provided user', () => { - beforeEach(async () => { - await setup({ - id: 'u7', - email: 'moderator@example.org', - password: '1234', - role: 'moderator' - }) - }) - - it('returns created relation', async () => { - const expected = { - AddPostDisabledBy: { - from: { id: 'u7' }, - to: { id: 'p9' } - } + it('returns created relation', async () => { + const expected = { + AddPostDisabledBy: { + from: { id: 'u7' }, + to: { id: 'p9' } } - await expect(client.request(mutation)).resolves.toEqual(expected) - }) + } + await expect(client.request(mutation)).resolves.toEqual(expected) + }) - it('sets current user', async () => { - await client.request(mutation) - const query = `{ Post { id, disabledBy { id } } }` - const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } - await expect(client.request(query)).resolves.toEqual(expected) - }) + it('sets current user', async () => { + await client.request(mutation) + const query = `{ Post(disabled: true) { id, disabledBy { id } } }` + const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } + await expect(client.request(query)).resolves.toEqual(expected) + }) - it('updates .disabled on post', async () => { - await client.request(mutation) - const query = `{ Post { id disabled } }` - const expected = { Post: [ { id: 'p9', disabled: true } ] } - await expect(client.request(query)).resolves.toEqual(expected) - }) + it('updates .disabled on post', async () => { + const before = { Post: [ { id: 'p9', disabled: false } ] } + const expected = { Post: [ { id: 'p9', disabled: true } ] } + + await expect(client.request( + `{ Post { id disabled } }` + )).resolves.toEqual(before) + await client.request(mutation) // this updates .disabled + await expect(client.request( + `{ Post(disabled: true) { id disabled } }` + )).resolves.toEqual(expected) }) }) }) }) +}) - describe('RemovePostDisabledBy', () => { - beforeEach(async () => { - await factory.create('User', {email: 'anotherModerator@example.org', password: '1234', role: 'moderator'}) - await factory.authenticateAs({email: 'anotherModerator@example.org', password: '1234'}) - await factory.relate('Post', 'DisabledBy', { - from: 'u7', - to: 'p9' - }) +describe('RemovePostDisabledBy', () => { + const setup = async (params = {}) => { + await factory.create('User', {email: 'anotherModerator@example.org', password: '1234', id: 'u123', role: 'moderator'}) + await factory.authenticateAs({email: 'anotherModerator@example.org', password: '1234'}) + await factory.create('Post', { + id: 'p9' // that's the ID we will look for }) + await factory.relate('Post', 'DisabledBy', { + from: 'u123', + to: 'p9' + }) // that's we want to delete - const mutation = ` + let headers = {} + const { email, password } = params + if (email && password) { + const user = await factory.create('User', params) + headers = await login({email, password}) + } + client = new GraphQLClient(host, { headers }) + } + + const mutation = ` mutation { RemovePostDisabledBy(from: { id: "u7" }, to: { id: "p9" }) { from { @@ -320,56 +336,61 @@ describe('disabledBy relation', () => { } ` + it('throws authorization error', async () => { + await setup() + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { it('throws authorization error', async () => { - await setup() + await setup({ + email: 'someUser@example.org', + password: '1234' + }) await expect(client.request(mutation)).rejects.toThrow('Not Authorised') }) - describe('authenticated', () => { + describe('as moderator', () => { it('throws authorization error', async () => { await setup({ + role: 'moderator', email: 'someUser@example.org', password: '1234' }) await expect(client.request(mutation)).rejects.toThrow('Not Authorised') }) - describe('as moderator', () => { - it('throws authorization error', async () => { + describe('current user matches provided user', () => { + beforeEach(async () => { await setup({ + id: 'u7', role: 'moderator', email: 'someUser@example.org', password: '1234' }) - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') }) - describe('current user matches provided user', () => { - beforeEach(async () => { - await setup({ - id: 'u7', - role: 'moderator', - email: 'someUser@example.org', - password: '1234' - }) - }) - - it('returns deleted relation', async () => { - const expected = { - RemovePostDisabledBy: { - from: { id: 'u7' }, - to: { id: 'p9' } - } + it('returns deleted relation', async () => { + const expected = { + RemovePostDisabledBy: { + from: { id: 'u7' }, + to: { id: 'p9' } } - await expect(client.request(mutation)).resolves.toEqual(expected) - }) + } + await expect(client.request(mutation)).resolves.toEqual(expected) + }) - it('updates .disabled on post', async () => { - await client.request(mutation) - const query = `{ Post { id disabled } }` - const expected = { Post: [ { id: 'p9', disabled: false } ] } - await expect(client.request(query)).resolves.toEqual(expected) - }) + it('updates .disabled on post', async () => { + const before = { Post: [ { id: 'p9', disabled: true } ] } + const expected = { Post: [ { id: 'p9', disabled: false } ] } + + await expect(client.request( + `{ Post(disabled: true) { id disabled } }` + )).resolves.toEqual(before) + await client.request(mutation) // this updates .disabled + await expect(client.request( + `{ Post { id disabled } }` + )).resolves.toEqual(expected) }) }) }) From 2b7576521cf73fd247884e1f0338c4cb19004639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 5 Mar 2019 18:15:05 +0100 Subject: [PATCH 477/554] Fix lint + return more attributes in post factory for convenience --- src/middleware/permissionsMiddleware.js | 2 +- src/middleware/softDeleteMiddleware.spec.js | 4 +-- src/resolvers/posts.spec.js | 29 +++++++++------------ src/seed/factories/users.js | 3 +++ 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 1c6e8310b..44ed2ed34 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -64,7 +64,7 @@ const permissions = shield({ DeleteBadge: isAdmin, AddPostDisabledBy: and(isModerator, fromUserMatchesCurrentUser), - RemovePostDisabledBy: and(isModerator, fromUserMatchesCurrentUser), + RemovePostDisabledBy: and(isModerator, fromUserMatchesCurrentUser) // addFruitToBasket: isAuthenticated // CreateUser: allow, }, diff --git a/src/middleware/softDeleteMiddleware.spec.js b/src/middleware/softDeleteMiddleware.spec.js index c37e7d426..283e16eb0 100644 --- a/src/middleware/softDeleteMiddleware.spec.js +++ b/src/middleware/softDeleteMiddleware.spec.js @@ -19,8 +19,8 @@ beforeEach(async () => { factory.create('Post', { title: 'Publicly visible post', deleted: false }) ]) const moderatorFactory = Factory() - await moderatorFactory.authenticateAs({ email: 'moderator@example.org', password: '1234'}) - await moderatorFactory.relate('Post', 'DisabledBy', { from: 'm1', to: 'p2'}) + await moderatorFactory.authenticateAs({ email: 'moderator@example.org', password: '1234' }) + await moderatorFactory.relate('Post', 'DisabledBy', { from: 'm1', to: 'p2' }) }) afterEach(async () => { diff --git a/src/resolvers/posts.spec.js b/src/resolvers/posts.spec.js index 427a5d925..89fb1c8e4 100644 --- a/src/resolvers/posts.spec.js +++ b/src/resolvers/posts.spec.js @@ -201,13 +201,10 @@ describe('DeletePost', () => { }) }) - - - describe('AddPostDisabledBy', () => { const setup = async (params = {}) => { - await factory.create('User', {email: 'author@example.org', password: '1234'}) - await factory.authenticateAs({email: 'author@example.org', password: '1234'}) + await factory.create('User', { email: 'author@example.org', password: '1234' }) + await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) await factory.create('Post', { id: 'p9' // that's the ID we will look for }) @@ -215,8 +212,8 @@ describe('AddPostDisabledBy', () => { let headers = {} const { email, password } = params if (email && password) { - const user = await factory.create('User', params) - headers = await login({email, password}) + await factory.create('User', params) + headers = await login({ email, password }) } client = new GraphQLClient(host, { headers }) } @@ -280,7 +277,7 @@ describe('AddPostDisabledBy', () => { it('sets current user', async () => { await client.request(mutation) - const query = `{ Post(disabled: true) { id, disabledBy { id } } }` + const query = '{ Post(disabled: true) { id, disabledBy { id } } }' const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } await expect(client.request(query)).resolves.toEqual(expected) }) @@ -290,11 +287,11 @@ describe('AddPostDisabledBy', () => { const expected = { Post: [ { id: 'p9', disabled: true } ] } await expect(client.request( - `{ Post { id disabled } }` + '{ Post { id disabled } }' )).resolves.toEqual(before) await client.request(mutation) // this updates .disabled await expect(client.request( - `{ Post(disabled: true) { id disabled } }` + '{ Post(disabled: true) { id disabled } }' )).resolves.toEqual(expected) }) }) @@ -304,8 +301,8 @@ describe('AddPostDisabledBy', () => { describe('RemovePostDisabledBy', () => { const setup = async (params = {}) => { - await factory.create('User', {email: 'anotherModerator@example.org', password: '1234', id: 'u123', role: 'moderator'}) - await factory.authenticateAs({email: 'anotherModerator@example.org', password: '1234'}) + await factory.create('User', { email: 'anotherModerator@example.org', password: '1234', id: 'u123', role: 'moderator' }) + await factory.authenticateAs({ email: 'anotherModerator@example.org', password: '1234' }) await factory.create('Post', { id: 'p9' // that's the ID we will look for }) @@ -317,8 +314,8 @@ describe('RemovePostDisabledBy', () => { let headers = {} const { email, password } = params if (email && password) { - const user = await factory.create('User', params) - headers = await login({email, password}) + await factory.create('User', params) + headers = await login({ email, password }) } client = new GraphQLClient(host, { headers }) } @@ -385,11 +382,11 @@ describe('RemovePostDisabledBy', () => { const expected = { Post: [ { id: 'p9', disabled: false } ] } await expect(client.request( - `{ Post(disabled: true) { id disabled } }` + '{ Post(disabled: true) { id disabled } }' )).resolves.toEqual(before) await client.request(mutation) // this updates .disabled await expect(client.request( - `{ Post { id disabled } }` + '{ Post { id disabled } }' )).resolves.toEqual(expected) }) }) diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index 8e0ee693c..c27b2b1ce 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -25,10 +25,13 @@ export default function create (params) { disabled: ${disabled}, deleted: ${deleted} ) { + id name email avatar role + deleted + disabled } } ` From a292a522e9524f949f32fbd90fe913d0ce34fb60 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 5 Mar 2019 18:30:28 +0100 Subject: [PATCH 478/554] Fixed an issue and added basic testing for (un)shout --- src/resolvers/shout.spec.js | 97 +++++++++++++++++++++++++++++++++++++ src/schema.graphql | 2 +- 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 src/resolvers/shout.spec.js diff --git a/src/resolvers/shout.spec.js b/src/resolvers/shout.spec.js new file mode 100644 index 000000000..4f5ea6ed6 --- /dev/null +++ b/src/resolvers/shout.spec.js @@ -0,0 +1,97 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() +let clientUser1, clientUser2 + +const mutationShoutPost = (id) => ` + mutation { + shout(id: "${id}", type: Post) + } +` +const mutationUnshoutPost = (id) => ` + mutation { + unshout(id: "${id}", type: Post) + } +` + +beforeEach(async () => { + await factory.create('User', { + id: 'u1', + email: 'test@example.org', + password: '1234' + }) + await factory.create('User', { + id: 'u2', + email: 'test2@example.org', + password: '1234' + }) +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + + +describe('shout ', () => { + describe('(un)shout foreign post', () => { + let headersUser1, headersUser2 + beforeEach(async () => { + headersUser1 = await login({ email: 'test@example.org', password: '1234' }) + headersUser2 = await login({ email: 'test2@example.org', password: '1234' }) + clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) + clientUser2 = new GraphQLClient(host, { headers: headersUser2 }) + + await clientUser1.request(` + mutation { + CreatePost(id: "p1", title: "Post Title 1", content: "Some Post Content 1") { + id + title + } + } + `) + await clientUser2.request(` + mutation { + CreatePost(id: "p2", title: "Post Title 2", content: "Some Post Content 2") { + id + title + } + } + `) + }) + + it('I shout a post of another user', async () => { + const res = await clientUser1.request( + mutationShoutPost('p2') + ) + const expected = { + shout: true + } + expect(res).toMatchObject(expected) + }) + + it('I unshout a post of another user', async () => { + // shout + await clientUser1.request( + mutationShoutPost('p2') + ) + const expected = { + unshout: true + } + // unshout + const res = await clientUser1.request(mutationUnshoutPost('p2')) + expect(res).toMatchObject(expected) + }) + + it('I can`t shout my own post', async () => { + const res = await clientUser1.request( + mutationShoutPost('p1') + ) + const expected = { + shout: false + } + expect(res).toMatchObject(expected) + }) + }) +}) diff --git a/src/schema.graphql b/src/schema.graphql index e6e2088f1..b21773c00 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -12,7 +12,7 @@ type Mutation { report(resource: Resource!, description: String): Report "Shout the given Type and ID" - shout(id: ID!, type: ShoutTypeEnum): String! @cypher(statement: """ + shout(id: ID!, type: ShoutTypeEnum): Boolean! @cypher(statement: """ MATCH (n {id: $id})<-[:WROTE]-(wu:User), (u:User {id: $cypherParams.currentUserId}) WHERE $type IN labels(n) AND NOT wu.id = $cypherParams.currentUserId MERGE (u)-[r:SHOUTED]->(n) From 4fdb1562f9c58b63e58fc46a69f6fd06e84aba4c Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 5 Mar 2019 18:34:35 +0100 Subject: [PATCH 479/554] Added test for shoutedByCurrentUser flag on posts --- src/resolvers/shout.spec.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/resolvers/shout.spec.js b/src/resolvers/shout.spec.js index 4f5ea6ed6..440210720 100644 --- a/src/resolvers/shout.spec.js +++ b/src/resolvers/shout.spec.js @@ -69,6 +69,16 @@ describe('shout ', () => { shout: true } expect(res).toMatchObject(expected) + + const { Post } = await clientUser1.request(`{ + Post(id: "p2") { + shoutedByCurrentUser + } + }`) + const expected2 = { + shoutedByCurrentUser: true + } + expect(Post[0]).toMatchObject(expected2) }) it('I unshout a post of another user', async () => { @@ -82,6 +92,16 @@ describe('shout ', () => { // unshout const res = await clientUser1.request(mutationUnshoutPost('p2')) expect(res).toMatchObject(expected) + + const { Post } = await clientUser1.request(`{ + Post(id: "p2") { + shoutedByCurrentUser + } + }`) + const expected2 = { + shoutedByCurrentUser: false + } + expect(Post[0]).toMatchObject(expected2) }) it('I can`t shout my own post', async () => { @@ -92,6 +112,16 @@ describe('shout ', () => { shout: false } expect(res).toMatchObject(expected) + + const { Post } = await clientUser1.request(`{ + Post(id: "p1") { + shoutedByCurrentUser + } + }`) + const expected2 = { + shoutedByCurrentUser: false + } + expect(Post[0]).toMatchObject(expected2) }) }) }) From c2aea104f4ed3a9b4d9e1c5ed5ba3a195fece02d Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 5 Mar 2019 18:44:39 +0100 Subject: [PATCH 480/554] Added basic tests for follow mutation --- src/resolvers/follow.spec.js | 118 +++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/resolvers/follow.spec.js diff --git a/src/resolvers/follow.spec.js b/src/resolvers/follow.spec.js new file mode 100644 index 000000000..a7b0d3284 --- /dev/null +++ b/src/resolvers/follow.spec.js @@ -0,0 +1,118 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() +let clientUser1, clientUser2 + +const mutationFollowUser = (id) => ` + mutation { + follow(id: "${id}", type: User) + } +` +const mutationUnfollowUser = (id) => ` + mutation { + unfollow(id: "${id}", type: User) + } +` + +beforeEach(async () => { + await factory.create('User', { + id: 'u1', + email: 'test@example.org', + password: '1234' + }) + await factory.create('User', { + id: 'u2', + email: 'test2@example.org', + password: '1234' + }) +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + + +describe('follow ', () => { + describe('(un)follow user', () => { + let headersUser1, headersUser2 + beforeEach(async () => { + headersUser1 = await login({ email: 'test@example.org', password: '1234' }) + headersUser2 = await login({ email: 'test2@example.org', password: '1234' }) + clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) + clientUser2 = new GraphQLClient(host, { headers: headersUser2 }) + }) + + it('I can follow another user', async () => { + const res = await clientUser1.request( + mutationFollowUser('u2') + ) + const expected = { + follow: true + } + expect(res).toMatchObject(expected) + + const { User } = await clientUser1.request(`{ + User(id: "u2") { + followedBy { id } + followedByCurrentUser + } + }`) + const expected2 = { + followedBy: [ + { id: 'u1' } + ], + followedByCurrentUser: true + } + expect(User[0]).toMatchObject(expected2) + }) + + it('I can unfollow a user', async () => { + // follow + await clientUser1.request( + mutationFollowUser('u2') + ) + const expected = { + unfollow: true + } + // unfollow + const res = await clientUser1.request(mutationUnfollowUser('u2')) + expect(res).toMatchObject(expected) + + const { User } = await clientUser1.request(`{ + User(id: "u2") { + followedBy { id } + followedByCurrentUser + } + }`) + const expected2 = { + followedBy: [], + followedByCurrentUser: false + } + expect(User[0]).toMatchObject(expected2) + }) + + it('I can`t follow myself', async () => { + const res = await clientUser1.request( + mutationFollowUser('u1') + ) + const expected = { + follow: false + } + expect(res).toMatchObject(expected) + + const { User } = await clientUser1.request(`{ + User(id: "u1") { + followedBy { id } + followedByCurrentUser + } + }`) + const expected2 = { + followedBy: [], + followedByCurrentUser: false + } + expect(User[0]).toMatchObject(expected2) + }) + }) +}) From 865fdebc5f06257646631965d4793df9514b1222 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Tue, 5 Mar 2019 18:58:17 +0100 Subject: [PATCH 481/554] Fixed linting issues inside tests --- src/resolvers/follow.spec.js | 7 ++----- src/resolvers/shout.spec.js | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/resolvers/follow.spec.js b/src/resolvers/follow.spec.js index a7b0d3284..3c16560e5 100644 --- a/src/resolvers/follow.spec.js +++ b/src/resolvers/follow.spec.js @@ -3,7 +3,7 @@ import { GraphQLClient } from 'graphql-request' import { host, login } from '../jest/helpers' const factory = Factory() -let clientUser1, clientUser2 +let clientUser1 const mutationFollowUser = (id) => ` mutation { @@ -33,15 +33,12 @@ afterEach(async () => { await factory.cleanDatabase() }) - describe('follow ', () => { describe('(un)follow user', () => { - let headersUser1, headersUser2 + let headersUser1 beforeEach(async () => { headersUser1 = await login({ email: 'test@example.org', password: '1234' }) - headersUser2 = await login({ email: 'test2@example.org', password: '1234' }) clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) - clientUser2 = new GraphQLClient(host, { headers: headersUser2 }) }) it('I can follow another user', async () => { diff --git a/src/resolvers/shout.spec.js b/src/resolvers/shout.spec.js index 440210720..490191c7a 100644 --- a/src/resolvers/shout.spec.js +++ b/src/resolvers/shout.spec.js @@ -33,7 +33,6 @@ afterEach(async () => { await factory.cleanDatabase() }) - describe('shout ', () => { describe('(un)shout foreign post', () => { let headersUser1, headersUser2 From 0a73ddd46d1aceeb982c1d427839845615c3065a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 5 Mar 2019 23:59:54 +0100 Subject: [PATCH 482/554] Refactor: custom resolvers for moderation --- src/graphql-schema.js | 2 + src/middleware/permissionsMiddleware.js | 4 +- src/resolvers/moderation.js | 10 ++ src/resolvers/moderation.spec.js | 170 +++++++++++++++++++++ src/resolvers/posts.spec.js | 193 ------------------------ src/schema.graphql | 4 +- 6 files changed, 187 insertions(+), 196 deletions(-) create mode 100644 src/resolvers/moderation.js create mode 100644 src/resolvers/moderation.spec.js diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 6d10183c9..c2d96ce16 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -4,6 +4,7 @@ import userManagement from './resolvers/user_management.js' import statistics from './resolvers/statistics.js' import reports from './resolvers/reports.js' import posts from './resolvers/posts.js' +import moderation from './resolvers/moderation.js' export const typeDefs = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, 'schema.graphql')) @@ -17,6 +18,7 @@ export const resolvers = { Mutation: { ...userManagement.Mutation, ...reports.Mutation, + ...moderation.Mutation, ...posts.Mutation } } diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 44ed2ed34..dff11b888 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -63,8 +63,8 @@ const permissions = shield({ UpdateBadge: isAdmin, DeleteBadge: isAdmin, - AddPostDisabledBy: and(isModerator, fromUserMatchesCurrentUser), - RemovePostDisabledBy: and(isModerator, fromUserMatchesCurrentUser) + enable: isModerator, + disable: isModerator, // addFruitToBasket: isAuthenticated // CreateUser: allow, }, diff --git a/src/resolvers/moderation.js b/src/resolvers/moderation.js new file mode 100644 index 000000000..15fd291e9 --- /dev/null +++ b/src/resolvers/moderation.js @@ -0,0 +1,10 @@ +export default { + Mutation: { + disable: async (object, params, {user, driver}) => { + return true + }, + enable: async (object, params, {user, driver}) => { + return true + } + } +} diff --git a/src/resolvers/moderation.spec.js b/src/resolvers/moderation.spec.js new file mode 100644 index 000000000..b6249a8b7 --- /dev/null +++ b/src/resolvers/moderation.spec.js @@ -0,0 +1,170 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() +let client + +afterEach(async () => { + await factory.cleanDatabase() +}) + +describe('disable', () => { + const setup = async (params = {}) => { + await factory.create('User', { email: 'author@example.org', password: '1234' }) + await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) + await factory.create('Post', { + id: 'p9' // that's the ID we will look for + }) + + // create the user we use in the scenario below + let headers = {} + const { email, password } = params + if (email && password) { + await factory.create('User', params) + headers = await login({ email, password }) + } + client = new GraphQLClient(host, { headers }) + } + + const mutation = ` + mutation { + disable(resource: { + id: "p9" + type: contribution + }) + } + ` + + it('throws authorization error', async () => { + await setup() + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { + it('throws authorization error', async () => { + await setup({ + email: 'someUser@example.org', + password: '1234' + }) + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + describe('as moderator', () => { + beforeEach(async () => { + await setup({ + id: 'u7', + email: 'moderator@example.org', + password: '1234', + role: 'moderator' + }) + }) + + it('returns true', async () => { + const expected = { disable: true } + await expect(client.request(mutation)).resolves.toEqual(expected) + }) + + it('sets current user', async () => { + const before = { Post: [{ id: 'p9', disabledBy: null }] } + const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } + + await expect(client.request( + '{ Post { id, disabledBy { id } } }' + )).resolves.toEqual(before) + await client.request(mutation) + await expect(client.request( + '{ Post(disabled: true) { id, disabledBy { id } } }' + )).resolves.toEqual(expected) + }) + + it('updates .disabled on post', async () => { + const before = { Post: [ { id: 'p9', disabled: false } ] } + const expected = { Post: [ { id: 'p9', disabled: true } ] } + + await expect(client.request( + '{ Post { id disabled } }' + )).resolves.toEqual(before) + await client.request(mutation) // this updates .disabled + await expect(client.request( + '{ Post(disabled: true) { id disabled } }' + )).resolves.toEqual(expected) + }) + }) + }) +}) + +describe('enable', () => { + const setup = async (params = {}) => { + await factory.create('User', { email: 'anotherModerator@example.org', password: '1234', id: 'u123', role: 'moderator' }) + await factory.authenticateAs({ email: 'anotherModerator@example.org', password: '1234' }) + await factory.create('Post', { + id: 'p9' // that's the ID we will look for + }) + await factory.relate('Post', 'DisabledBy', { + from: 'u123', + to: 'p9' + }) // that's we want to delete + + let headers = {} + const { email, password } = params + if (email && password) { + await factory.create('User', params) + headers = await login({ email, password }) + } + client = new GraphQLClient(host, { headers }) + } + + + const mutation = ` + mutation { + enable(resource: { + id: "p9" + type: contribution + }) + } + ` + + it('throws authorization error', async () => { + await setup() + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { + it('throws authorization error', async () => { + await setup({ + email: 'someUser@example.org', + password: '1234' + }) + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + describe('as moderator', () => { + beforeEach(async () => { + await setup({ + role: 'moderator', + email: 'someUser@example.org', + password: '1234' + }) + }) + + it('returns true', async () => { + const expected = { enable: true } + await expect(client.request(mutation)).resolves.toEqual(expected) + }) + + it('updates .disabled on post', async () => { + const before = { Post: [ { id: 'p9', disabled: true } ] } + const expected = { Post: [ { id: 'p9', disabled: false } ] } + + await expect(client.request( + '{ Post(disabled: true) { id disabled } }' + )).resolves.toEqual(before) + await client.request(mutation) // this updates .disabled + await expect(client.request( + '{ Post { id disabled } }' + )).resolves.toEqual(expected) + }) + }) + }) +}) diff --git a/src/resolvers/posts.spec.js b/src/resolvers/posts.spec.js index 89fb1c8e4..5603683eb 100644 --- a/src/resolvers/posts.spec.js +++ b/src/resolvers/posts.spec.js @@ -200,196 +200,3 @@ describe('DeletePost', () => { }) }) }) - -describe('AddPostDisabledBy', () => { - const setup = async (params = {}) => { - await factory.create('User', { email: 'author@example.org', password: '1234' }) - await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) - await factory.create('Post', { - id: 'p9' // that's the ID we will look for - }) - - let headers = {} - const { email, password } = params - if (email && password) { - await factory.create('User', params) - headers = await login({ email, password }) - } - client = new GraphQLClient(host, { headers }) - } - - const mutation = ` - mutation { - AddPostDisabledBy(from: { id: "u7" }, to: { id: "p9" }) { - from { - id - } - to { - id - } - } - } - ` - - it('throws authorization error', async () => { - await setup() - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') - }) - - describe('authenticated', () => { - it('throws authorization error', async () => { - await setup({ - email: 'someUser@example.org', - password: '1234' - }) - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') - }) - - describe('as moderator', () => { - it('throws authorization error', async () => { - await setup({ - email: 'attributedUserMismatch@example.org', - password: '1234', - role: 'moderator' - }) - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') - }) - - describe('current user matches provided user', () => { - beforeEach(async () => { - await setup({ - id: 'u7', - email: 'moderator@example.org', - password: '1234', - role: 'moderator' - }) - }) - - it('returns created relation', async () => { - const expected = { - AddPostDisabledBy: { - from: { id: 'u7' }, - to: { id: 'p9' } - } - } - await expect(client.request(mutation)).resolves.toEqual(expected) - }) - - it('sets current user', async () => { - await client.request(mutation) - const query = '{ Post(disabled: true) { id, disabledBy { id } } }' - const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } - await expect(client.request(query)).resolves.toEqual(expected) - }) - - it('updates .disabled on post', async () => { - const before = { Post: [ { id: 'p9', disabled: false } ] } - const expected = { Post: [ { id: 'p9', disabled: true } ] } - - await expect(client.request( - '{ Post { id disabled } }' - )).resolves.toEqual(before) - await client.request(mutation) // this updates .disabled - await expect(client.request( - '{ Post(disabled: true) { id disabled } }' - )).resolves.toEqual(expected) - }) - }) - }) - }) -}) - -describe('RemovePostDisabledBy', () => { - const setup = async (params = {}) => { - await factory.create('User', { email: 'anotherModerator@example.org', password: '1234', id: 'u123', role: 'moderator' }) - await factory.authenticateAs({ email: 'anotherModerator@example.org', password: '1234' }) - await factory.create('Post', { - id: 'p9' // that's the ID we will look for - }) - await factory.relate('Post', 'DisabledBy', { - from: 'u123', - to: 'p9' - }) // that's we want to delete - - let headers = {} - const { email, password } = params - if (email && password) { - await factory.create('User', params) - headers = await login({ email, password }) - } - client = new GraphQLClient(host, { headers }) - } - - const mutation = ` - mutation { - RemovePostDisabledBy(from: { id: "u7" }, to: { id: "p9" }) { - from { - id - } - to { - id - } - } - } - ` - - it('throws authorization error', async () => { - await setup() - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') - }) - - describe('authenticated', () => { - it('throws authorization error', async () => { - await setup({ - email: 'someUser@example.org', - password: '1234' - }) - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') - }) - - describe('as moderator', () => { - it('throws authorization error', async () => { - await setup({ - role: 'moderator', - email: 'someUser@example.org', - password: '1234' - }) - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') - }) - - describe('current user matches provided user', () => { - beforeEach(async () => { - await setup({ - id: 'u7', - role: 'moderator', - email: 'someUser@example.org', - password: '1234' - }) - }) - - it('returns deleted relation', async () => { - const expected = { - RemovePostDisabledBy: { - from: { id: 'u7' }, - to: { id: 'p9' } - } - } - await expect(client.request(mutation)).resolves.toEqual(expected) - }) - - it('updates .disabled on post', async () => { - const before = { Post: [ { id: 'p9', disabled: true } ] } - const expected = { Post: [ { id: 'p9', disabled: false } ] } - - await expect(client.request( - '{ Post(disabled: true) { id disabled } }' - )).resolves.toEqual(before) - await client.request(mutation) // this updates .disabled - await expect(client.request( - '{ Post { id disabled } }' - )).resolves.toEqual(expected) - }) - }) - }) - }) -}) diff --git a/src/schema.graphql b/src/schema.graphql index 4c2a58505..ddafd880e 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -7,6 +7,8 @@ type Mutation { login(email: String!, password: String!): String! signup(email: String!, password: String!): Boolean! report(resource: Resource!, description: String): Report + disable(resource: Resource!): Boolean! + enable(resource: Resource!): Boolean! } type Statistics { @@ -133,7 +135,7 @@ type Post { visibility: VisibilityEnum deleted: Boolean disabled: Boolean - disabledBy: User! @relation(name: "DISABLED", direction: "IN") + disabledBy: User @relation(name: "DISABLED", direction: "IN") createdAt: String updatedAt: String From 5cff508bd6d9b553e0bf8d9fcc5e29143062583b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 6 Mar 2019 00:55:26 +0100 Subject: [PATCH 483/554] Disable/enable fullfills tests --- src/middleware/permissionsMiddleware.js | 10 ++----- src/middleware/softDeleteMiddleware.spec.js | 10 ++++++- src/resolvers/moderation.js | 28 ++++++++++++++++--- src/resolvers/moderation.spec.js | 31 ++++++++++++++++----- src/resolvers/posts.js | 20 ------------- src/seed/factories/index.js | 5 ++++ src/seed/seed-db.js | 13 ++++++--- 7 files changed, 73 insertions(+), 44 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index dff11b888..7fb6e75b8 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -1,4 +1,4 @@ -import { rule, shield, allow, and, or } from 'graphql-shield' +import { rule, shield, allow, or } from 'graphql-shield' /* * TODO: implement @@ -41,12 +41,6 @@ const isAuthor = rule({ cache: 'no_cache' })(async (parent, args, { user, driver return authorId === user.id }) -const fromUserMatchesCurrentUser = rule({ cache: 'no_cache' })(async (parent, args, { user, driver }) => { - if (!user) return false - const { from: { id: fromId } } = args - return user.id === fromId -}) - // Permissions const permissions = shield({ Query: { @@ -64,7 +58,7 @@ const permissions = shield({ DeleteBadge: isAdmin, enable: isModerator, - disable: isModerator, + disable: isModerator // addFruitToBasket: isAuthenticated // CreateUser: allow, }, diff --git a/src/middleware/softDeleteMiddleware.spec.js b/src/middleware/softDeleteMiddleware.spec.js index 283e16eb0..e9bc461f1 100644 --- a/src/middleware/softDeleteMiddleware.spec.js +++ b/src/middleware/softDeleteMiddleware.spec.js @@ -20,7 +20,15 @@ beforeEach(async () => { ]) const moderatorFactory = Factory() await moderatorFactory.authenticateAs({ email: 'moderator@example.org', password: '1234' }) - await moderatorFactory.relate('Post', 'DisabledBy', { from: 'm1', to: 'p2' }) + const disableMutation = ` + mutation { + disable(resource: { + id: "p2" + type: contribution + }) + } + ` + await moderatorFactory.mutate(disableMutation) }) afterEach(async () => { diff --git a/src/resolvers/moderation.js b/src/resolvers/moderation.js index 15fd291e9..8e171dbf6 100644 --- a/src/resolvers/moderation.js +++ b/src/resolvers/moderation.js @@ -1,10 +1,30 @@ export default { Mutation: { - disable: async (object, params, {user, driver}) => { - return true + disable: async (object, params, { user, driver }) => { + const { resource: { id: postId } } = params + const { id: userId } = user + const cypher = ` + MATCH (u:User {id: $userId}) + MATCH (p:Post {id: $postId}) + SET p.disabled = true + MERGE (p)<-[:DISABLED]-(u) + ` + const session = driver.session() + const res = await session.run(cypher, { postId, userId }) + session.close() + return Boolean(res) }, - enable: async (object, params, {user, driver}) => { - return true + enable: async (object, params, { user, driver }) => { + const { resource: { id: postId } } = params + const cypher = ` + MATCH (p:Post {id: $postId})<-[d:DISABLED]-() + SET p.disabled = false + DELETE d + ` + const session = driver.session() + const res = await session.run(cypher, { postId }) + session.close() + return Boolean(res) } } } diff --git a/src/resolvers/moderation.spec.js b/src/resolvers/moderation.spec.js index b6249a8b7..081d7c38d 100644 --- a/src/resolvers/moderation.spec.js +++ b/src/resolvers/moderation.spec.js @@ -65,8 +65,8 @@ describe('disable', () => { await expect(client.request(mutation)).resolves.toEqual(expected) }) - it('sets current user', async () => { - const before = { Post: [{ id: 'p9', disabledBy: null }] } + it('changes .disabledBy', async () => { + const before = { Post: [{ id: 'p9', disabledBy: null }] } const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } await expect(client.request( @@ -101,10 +101,15 @@ describe('enable', () => { await factory.create('Post', { id: 'p9' // that's the ID we will look for }) - await factory.relate('Post', 'DisabledBy', { - from: 'u123', - to: 'p9' - }) // that's we want to delete + const disableMutation = ` + mutation { + disable(resource: { + id: "p9" + type: contribution + }) + } + ` + await factory.mutate(disableMutation) // that's we want to delete let headers = {} const { email, password } = params @@ -115,7 +120,6 @@ describe('enable', () => { client = new GraphQLClient(host, { headers }) } - const mutation = ` mutation { enable(resource: { @@ -153,6 +157,19 @@ describe('enable', () => { await expect(client.request(mutation)).resolves.toEqual(expected) }) + it('changes .disabledBy', async () => { + const before = { Post: [{ id: 'p9', disabledBy: { id: 'u123' } }] } + const expected = { Post: [{ id: 'p9', disabledBy: null }] } + + await expect(client.request( + '{ Post(disabled: true) { id, disabledBy { id } } }' + )).resolves.toEqual(before) + await client.request(mutation) + await expect(client.request( + '{ Post { id, disabledBy { id } } }' + )).resolves.toEqual(expected) + }) + it('updates .disabled on post', async () => { const before = { Post: [ { id: 'p9', disabled: true } ] } const expected = { Post: [ { id: 'p9', disabled: false } ] } diff --git a/src/resolvers/posts.js b/src/resolvers/posts.js index 33934699b..abf91e047 100644 --- a/src/resolvers/posts.js +++ b/src/resolvers/posts.js @@ -2,26 +2,6 @@ import { neo4jgraphql } from 'neo4j-graphql-js' export default { Mutation: { - AddPostDisabledBy: async (object, params, context, resolveInfo) => { - const { to: { id: postId } } = params - const session = context.driver.session() - await session.run(` - MATCH (p:Post {id: $postId}) - SET p.disabled = true`, { postId }) - session.close() - return neo4jgraphql(object, params, context, resolveInfo, false) - }, - - RemovePostDisabledBy: async (object, params, context, resolveInfo) => { - const { to: { id: postId } } = params - const session = context.driver.session() - await session.run(` - MATCH (p:Post {id: $postId}) - SET p.disabled = false`, { postId }) - session.close() - return neo4jgraphql(object, params, context, resolveInfo, false) - }, - CreatePost: async (object, params, context, resolveInfo) => { const result = await neo4jgraphql(object, params, context, resolveInfo, false) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index ed35d2c3b..68dd99200 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -86,6 +86,10 @@ export default function Factory (options = {}) { this.lastResponse = await this.graphQLClient.request(mutation) return this }, + async mutate (mutation, variables) { + this.lastResponse = await this.graphQLClient.request(mutation, variables) + return this + }, async cleanDatabase () { this.lastResponse = await cleanDatabase({ driver: this.neo4jDriver }) return this @@ -94,6 +98,7 @@ export default function Factory (options = {}) { result.authenticateAs.bind(result) result.create.bind(result) result.relate.bind(result) + result.mutate.bind(result) result.cleanDatabase.bind(result) return result } diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index c20d524ef..310089ef7 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -98,10 +98,15 @@ import Factory from './factories' asTick.create('Post', { id: 'p15' }) ]) - await asModerator.relate('Post', 'DisabledBy', { - from: 'u2', - to: 'p15' - }) + const disableMutation = ` + mutation { + disable(resource: { + id: "p11" + type: contribution + }) + } + ` + await asModerator.mutate(disableMutation) await Promise.all([ f.relate('Post', 'Categories', { from: 'p0', to: 'cat16' }), From 09ec8c3602337b5ae0e5337acd99100c3bd7dc6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 6 Mar 2019 04:31:31 +0000 Subject: [PATCH 484/554] Bump apollo-link-http from 1.5.11 to 1.5.12 Bumps [apollo-link-http](https://github.com/apollographql/apollo-link) from 1.5.11 to 1.5.12. - [Release notes](https://github.com/apollographql/apollo-link/releases) - [Changelog](https://github.com/apollographql/apollo-link/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-link/compare/apollo-link-http@1.5.11...apollo-link-http@1.5.12) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 54 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 1c6e8f2ce..a0f745bf7 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "dependencies": { "apollo-cache-inmemory": "~1.5.1", "apollo-client": "~2.5.1", - "apollo-link-http": "~1.5.11", + "apollo-link-http": "~1.5.12", "apollo-server": "~2.4.8", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", diff --git a/yarn.lock b/yarn.lock index 18d336c7a..215a608ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1106,27 +1106,33 @@ apollo-link-dedup@^1.0.0: dependencies: apollo-link "^1.2.4" -apollo-link-http-common@^0.2.10: - version "0.2.10" - resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.10.tgz#b5bbf502ff40a81cc00281ba3b8543b7ad866dfe" - integrity sha512-KY9nhpAurw3z48OIYV0sCZFXrzWp/wjECsveK+Q9GUhhSe1kEbbUjFfmi+qigg+iELgdp5V8ioRJhinl1vPojw== +apollo-link-http-common@^0.2.11: + version "0.2.11" + resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.11.tgz#d4e494ed1e45ea0e0c0ed60f3df64541d0de682d" + integrity sha512-FjtzEDiG6blH/2MR4fpVNoxdZUFmddP0sez34qnoLaYz6ABFbTDlmRE/dVN79nPExM4Spfs/DtW7KRqyjJ3tOg== dependencies: - apollo-link "^1.2.8" + apollo-link "^1.2.9" + ts-invariant "^0.3.2" + tslib "^1.9.3" -apollo-link-http@~1.5.11: - version "1.5.11" - resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.11.tgz#1f72a377d03e874a08bc9eadb1ce7ecb166f1e56" - integrity sha512-wDG+I9UmpfaZRPIvTYBgkvqiCgmz6yWgvuzW/S24Q4r4Xrfe6sLpg2FmarhtdP+hdN+IXTLbFNCZ+Trgfpifow== +apollo-link-http@~1.5.12: + version "1.5.12" + resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.12.tgz#878d48bf9d8ae091752710529a222c4a5548118e" + integrity sha512-2tS36RIU6OdxzoWYTPrjvDTF2sCrnlaJ6SL7j0ILPn1Lmw4y6YLwKDsv/SWLwtodtVe9v1dLCGKIGMRMM/SdyA== dependencies: - apollo-link "^1.2.8" - apollo-link-http-common "^0.2.10" + apollo-link "^1.2.9" + apollo-link-http-common "^0.2.11" + tslib "^1.9.3" -apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.8.tgz#0f252adefd5047ac1a9f35ba9439d216587dcd84" - integrity sha512-lfzGRxhK9RmiH3HPFi7TIEBhhDY9M5a2ZDnllcfy5QDk7cCQHQ1WQArcw1FK0g1B+mV4Kl72DSrlvZHZJEolrA== +apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.9.tgz#40a8f0b90716ce3fd6beb27b7eae1108b92e0054" + integrity sha512-ZLUwthOFZq4lxchQ2jeBfVqS/UDdcVmmh8aUw6Ar9awZH4r+RgkcDeu2ooFLUfodWE3mZr7wIZuYsBas/MaNVA== dependencies: - zen-observable-ts "^0.8.15" + apollo-utilities "^1.2.1" + ts-invariant "^0.3.2" + tslib "^1.9.3" + zen-observable-ts "^0.8.16" apollo-server-caching@0.3.1: version "0.3.1" @@ -6781,6 +6787,13 @@ ts-invariant@^0.2.1: dependencies: tslib "^1.9.3" +ts-invariant@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.3.2.tgz#89a2ffeb70879b777258df1df1c59383c35209b0" + integrity sha512-QsY8BCaRnHiB5T6iE4DPlJMAKEG3gzMiUco9FEt1jUXQf0XP6zi0idT0i0rMTu8A326JqNSDsmlkA9dRSh1TRg== + dependencies: + tslib "^1.9.3" + tslib@^1.9.0, tslib@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -7257,11 +7270,12 @@ yup@^0.26.10: synchronous-promise "^2.0.5" toposort "^2.0.2" -zen-observable-ts@^0.8.15: - version "0.8.15" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.15.tgz#6cf7df6aa619076e4af2f707ccf8a6290d26699b" - integrity sha512-sXKPWiw6JszNEkRv5dQ+lQCttyjHM2Iks74QU5NP8mMPS/NrzTlHDr780gf/wOBqmHkPO6NCLMlsa+fAQ8VE8w== +zen-observable-ts@^0.8.16: + version "0.8.16" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.16.tgz#969367299074fe17422fe2f46ee417e9a30cf3fa" + integrity sha512-pQl75N7qwgybKVsh6WFO+WwPRijeQ52Gn1vSf4uvPFXald9CbVQXLa5QrOPEJhdZiC+CD4quqOVqSG+Ptz5XLA== dependencies: + tslib "^1.9.3" zen-observable "^0.8.0" zen-observable@^0.8.0: From 2813de4f8b79968b6c8d032295c4edb125df66ca Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Wed, 6 Mar 2019 13:20:33 +0100 Subject: [PATCH 485/554] Fixed organization seeder --- src/seed/factories/organizations.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seed/factories/organizations.js b/src/seed/factories/organizations.js index 783edac26..e0b2e52d4 100644 --- a/src/seed/factories/organizations.js +++ b/src/seed/factories/organizations.js @@ -4,7 +4,7 @@ import uuid from 'uuid/v4' export default function create (params) { const { id = uuid(), - name = faker.comany.companyName(), + name = faker.company.companyName(), description = faker.company.catchPhrase(), disabled = false, deleted = false From 1c34f10f967280ebc69f28dba48341dca80e02b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 6 Mar 2019 15:14:08 +0100 Subject: [PATCH 486/554] Test refactoring: Check comments + posts --- src/resolvers/moderation.spec.js | 418 ++++++++++++++++++++++--------- 1 file changed, 303 insertions(+), 115 deletions(-) diff --git a/src/resolvers/moderation.spec.js b/src/resolvers/moderation.spec.js index 081d7c38d..6107074ef 100644 --- a/src/resolvers/moderation.spec.js +++ b/src/resolvers/moderation.spec.js @@ -5,54 +5,76 @@ import { host, login } from '../jest/helpers' const factory = Factory() let client +const setupAuthenticateClient = (params) => { + const authenticateClient = async () => { + await factory.create('User', params) + const headers = await login(params) + client = new GraphQLClient(host, { headers }) + } + return authenticateClient +} + +let setup +const runSetup = async () => { + await setup.createResource() + await setup.authenticateClient() +} + +beforeEach(() => { + setup = { + createResource: () => { + }, + authenticateClient: () => { + client = new GraphQLClient(host) + } + } +}) + afterEach(async () => { await factory.cleanDatabase() }) describe('disable', () => { - const setup = async (params = {}) => { - await factory.create('User', { email: 'author@example.org', password: '1234' }) - await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) - await factory.create('Post', { - id: 'p9' // that's the ID we will look for - }) - - // create the user we use in the scenario below - let headers = {} - const { email, password } = params - if (email && password) { - await factory.create('User', params) - headers = await login({ email, password }) - } - client = new GraphQLClient(host, { headers }) - } - const mutation = ` - mutation { - disable(resource: { - id: "p9" - type: contribution - }) + mutation($id: ID!, $type: ResourceEnum!) { + disable(resource: { id: $id, type: $type }) } ` + let variables + + beforeEach(() => { + // our defaul set of variables + variables = { + id: 'blabla', + type: 'contribution' + } + }) + + const action = async () => { + return client.request(mutation, variables) + } it('throws authorization error', async () => { - await setup() - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + await runSetup() + await expect(action()).rejects.toThrow('Not Authorised') }) describe('authenticated', () => { - it('throws authorization error', async () => { - await setup({ - email: 'someUser@example.org', + beforeEach(() => { + setup.authenticateClient = setupAuthenticateClient({ + email: 'user@example.org', password: '1234' }) - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + it('throws authorization error', async () => { + await runSetup() + await expect(action()).rejects.toThrow('Not Authorised') }) describe('as moderator', () => { - beforeEach(async () => { - await setup({ + beforeEach(() => { + setup.authenticateClient = setupAuthenticateClient({ id: 'u7', email: 'moderator@example.org', password: '1234', @@ -60,127 +82,293 @@ describe('disable', () => { }) }) - it('returns true', async () => { - const expected = { disable: true } - await expect(client.request(mutation)).resolves.toEqual(expected) + describe('on a comment', () => { + beforeEach(async () => { + variables = { + id: 'c47', + type: 'comment' + } + + setup.createResource = async () => { + await factory.create('User', { id: 'u45', email: 'commenter@example.org', password: '1234' }) + await factory.authenticateAs({ email: 'commenter@example.org', password: '1234' }) + await factory.create('Post', { + id: 'p3' + }) + await factory.create('Comment', { + id: 'c47' + }) + await Promise.all([ + factory.relate('Comment', 'Author', { from: 'u45', to: 'c47' }), + factory.relate('Comment', 'Post', { from: 'c47', to: 'p3' }) + ]) + } + }) + + it('returns true', async () => { + const expected = { disable: true } + await runSetup() + await expect(action()).resolves.toEqual(expected) + }) + + it('changes .disabledBy', async () => { + const before = { Comment: [{ id: 'c47', disabledBy: null }] } + const expected = { Comment: [{ id: 'c47', disabledBy: { id: 'u7' } }] } + + await runSetup() + await expect(client.request( + '{ Comment { id, disabledBy { id } } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Comment(disabled: true) { id, disabledBy { id } } }' + )).resolves.toEqual(expected) + }) + + it('updates .disabled on comment', async () => { + const before = { Comment: [ { id: 'c47', disabled: false } ] } + const expected = { Comment: [ { id: 'c47', disabled: true } ] } + + await runSetup() + await expect(client.request( + '{ Comment { id disabled } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Comment(disabled: true) { id disabled } }' + )).resolves.toEqual(expected) + }) }) - it('changes .disabledBy', async () => { - const before = { Post: [{ id: 'p9', disabledBy: null }] } - const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } + describe('on a post', () => { + beforeEach(async () => { + variables = { + id: 'p9', + type: 'contribution' + } - await expect(client.request( - '{ Post { id, disabledBy { id } } }' - )).resolves.toEqual(before) - await client.request(mutation) - await expect(client.request( - '{ Post(disabled: true) { id, disabledBy { id } } }' - )).resolves.toEqual(expected) - }) + setup.createResource = async () => { + await factory.create('User', { email: 'author@example.org', password: '1234' }) + await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) + await factory.create('Post', { + id: 'p9' // that's the ID we will look for + }) + } + }) - it('updates .disabled on post', async () => { - const before = { Post: [ { id: 'p9', disabled: false } ] } - const expected = { Post: [ { id: 'p9', disabled: true } ] } + it('returns true', async () => { + const expected = { disable: true } + await runSetup() + await expect(action()).resolves.toEqual(expected) + }) - await expect(client.request( - '{ Post { id disabled } }' - )).resolves.toEqual(before) - await client.request(mutation) // this updates .disabled - await expect(client.request( - '{ Post(disabled: true) { id disabled } }' - )).resolves.toEqual(expected) + it('changes .disabledBy', async () => { + const before = { Post: [{ id: 'p9', disabledBy: null }] } + const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } + + await runSetup() + await expect(client.request( + '{ Post { id, disabledBy { id } } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Post(disabled: true) { id, disabledBy { id } } }' + )).resolves.toEqual(expected) + }) + + it('updates .disabled on post', async () => { + const before = { Post: [ { id: 'p9', disabled: false } ] } + const expected = { Post: [ { id: 'p9', disabled: true } ] } + + await runSetup() + await expect(client.request( + '{ Post { id disabled } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Post(disabled: true) { id disabled } }' + )).resolves.toEqual(expected) + }) }) }) }) }) describe('enable', () => { - const setup = async (params = {}) => { - await factory.create('User', { email: 'anotherModerator@example.org', password: '1234', id: 'u123', role: 'moderator' }) - await factory.authenticateAs({ email: 'anotherModerator@example.org', password: '1234' }) - await factory.create('Post', { - id: 'p9' // that's the ID we will look for - }) - const disableMutation = ` - mutation { - disable(resource: { - id: "p9" - type: contribution - }) - } - ` - await factory.mutate(disableMutation) // that's we want to delete - - let headers = {} - const { email, password } = params - if (email && password) { - await factory.create('User', params) - headers = await login({ email, password }) - } - client = new GraphQLClient(host, { headers }) - } - const mutation = ` - mutation { - enable(resource: { - id: "p9" - type: contribution - }) + mutation($id: ID!, $type: ResourceEnum!) { + enable(resource: { id: $id, type: $type }) } ` + let variables + + const action = async () => { + return client.request(mutation, variables) + } + + beforeEach(() => { + // our defaul set of variables + variables = { + id: 'blabla', + type: 'contribution' + } + }) it('throws authorization error', async () => { - await setup() - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + await runSetup() + await expect(action()).rejects.toThrow('Not Authorised') }) describe('authenticated', () => { - it('throws authorization error', async () => { - await setup({ - email: 'someUser@example.org', + beforeEach(() => { + setup.authenticateClient = setupAuthenticateClient({ + email: 'user@example.org', password: '1234' }) - await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + + it('throws authorization error', async () => { + await runSetup() + await expect(action()).rejects.toThrow('Not Authorised') }) describe('as moderator', () => { beforeEach(async () => { - await setup({ + setup.authenticateClient = setupAuthenticateClient({ role: 'moderator', email: 'someUser@example.org', password: '1234' }) }) - it('returns true', async () => { - const expected = { enable: true } - await expect(client.request(mutation)).resolves.toEqual(expected) + describe('on a comment', () => { + beforeEach(async () => { + variables = { + id: 'c456', + type: 'comment' + } + + setup.createResource = async () => { + await factory.create('User', { id: 'u123', email: 'author@example.org', password: '1234' }) + await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) + await factory.create('Post', { + id: 'p9' // that's the ID we will look for + }) + + await factory.create('Comment', { + id: 'c456' + }) + await Promise.all([ + factory.relate('Comment', 'Author', { from: 'u123', to: 'c456' }), + factory.relate('Comment', 'Post', { from: 'c456', to: 'p9' }) + ]) + + const disableMutation = ` + mutation { + disable(resource: { + id: "c456" + type: comment + }) + } + ` + await factory.mutate(disableMutation) // that's we want to delete + } + }) + + it('returns true', async () => { + const expected = { enable: true } + await runSetup() + await expect(action()).resolves.toEqual(expected) + }) + + it('changes .disabledBy', async () => { + const before = { Comment: [{ id: 'c456', disabledBy: { id: 'u123' } }] } + const expected = { Comment: [{ id: 'c456', disabledBy: null }] } + + await runSetup() + await expect(client.request( + '{ Comment(disabled: true) { id, disabledBy { id } } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Comment { id, disabledBy { id } } }' + )).resolves.toEqual(expected) + }) + + it('updates .disabled on post', async () => { + const before = { Comment: [ { id: 'c456', disabled: true } ] } + const expected = { Comment: [ { id: 'c456', disabled: false } ] } + + await runSetup() + await expect(client.request( + '{ Comment(disabled: true) { id disabled } }' + )).resolves.toEqual(before) + await action() // this updates .disabled + await expect(client.request( + '{ Comment { id disabled } }' + )).resolves.toEqual(expected) + }) }) - it('changes .disabledBy', async () => { - const before = { Post: [{ id: 'p9', disabledBy: { id: 'u123' } }] } - const expected = { Post: [{ id: 'p9', disabledBy: null }] } + describe('on a post', () => { + beforeEach(async () => { + variables = { + id: 'p9', + type: 'contribution' + } - await expect(client.request( - '{ Post(disabled: true) { id, disabledBy { id } } }' - )).resolves.toEqual(before) - await client.request(mutation) - await expect(client.request( - '{ Post { id, disabledBy { id } } }' - )).resolves.toEqual(expected) - }) + setup.createResource = async () => { + await factory.create('User', { id: 'u123', email: 'author@example.org', password: '1234' }) + await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) + await factory.create('Post', { + id: 'p9' // that's the ID we will look for + }) - it('updates .disabled on post', async () => { - const before = { Post: [ { id: 'p9', disabled: true } ] } - const expected = { Post: [ { id: 'p9', disabled: false } ] } + const disableMutation = ` + mutation { + disable(resource: { + id: "p9" + type: contribution + }) + } + ` + await factory.mutate(disableMutation) // that's we want to delete + } + }) - await expect(client.request( - '{ Post(disabled: true) { id disabled } }' - )).resolves.toEqual(before) - await client.request(mutation) // this updates .disabled - await expect(client.request( - '{ Post { id disabled } }' - )).resolves.toEqual(expected) + it('returns true', async () => { + const expected = { enable: true } + await runSetup() + await expect(action()).resolves.toEqual(expected) + }) + + it('changes .disabledBy', async () => { + const before = { Post: [{ id: 'p9', disabledBy: { id: 'u123' } }] } + const expected = { Post: [{ id: 'p9', disabledBy: null }] } + + await runSetup() + await expect(client.request( + '{ Post(disabled: true) { id, disabledBy { id } } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Post { id, disabledBy { id } } }' + )).resolves.toEqual(expected) + }) + + it('updates .disabled on post', async () => { + const before = { Post: [ { id: 'p9', disabled: true } ] } + const expected = { Post: [ { id: 'p9', disabled: false } ] } + + await runSetup() + await expect(client.request( + '{ Post(disabled: true) { id disabled } }' + )).resolves.toEqual(before) + await action() // this updates .disabled + await expect(client.request( + '{ Post { id disabled } }' + )).resolves.toEqual(expected) + }) }) }) }) From f40a67b7a85c6aa24ea7d005e62cf6ce29fb82ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 6 Mar 2019 17:12:30 +0100 Subject: [PATCH 487/554] Implement disabling of comments+users+posts --- src/resolvers/moderation.js | 16 ++++++++-------- src/schema.graphql | 2 ++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/resolvers/moderation.js b/src/resolvers/moderation.js index 8e171dbf6..10046dd03 100644 --- a/src/resolvers/moderation.js +++ b/src/resolvers/moderation.js @@ -1,28 +1,28 @@ export default { Mutation: { disable: async (object, params, { user, driver }) => { - const { resource: { id: postId } } = params + const { resource: { id } } = params const { id: userId } = user const cypher = ` MATCH (u:User {id: $userId}) - MATCH (p:Post {id: $postId}) - SET p.disabled = true - MERGE (p)<-[:DISABLED]-(u) + MATCH (r {id: $id}) + SET r.disabled = true + MERGE (r)<-[:DISABLED]-(u) ` const session = driver.session() - const res = await session.run(cypher, { postId, userId }) + const res = await session.run(cypher, { id, userId }) session.close() return Boolean(res) }, enable: async (object, params, { user, driver }) => { - const { resource: { id: postId } } = params + const { resource: { id } } = params const cypher = ` - MATCH (p:Post {id: $postId})<-[d:DISABLED]-() + MATCH (p {id: $id})<-[d:DISABLED]-() SET p.disabled = false DELETE d ` const session = driver.session() - const res = await session.run(cypher, { postId }) + const res = await session.run(cypher, { id }) session.close() return Boolean(res) } diff --git a/src/schema.graphql b/src/schema.graphql index ddafd880e..5e58d5f1d 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -76,6 +76,7 @@ type User { avatar: String deleted: Boolean disabled: Boolean + disabledBy: User @relation(name: "DISABLED", direction: "IN") role: UserGroupEnum location: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l") @@ -165,6 +166,7 @@ type Comment { updatedAt: String deleted: Boolean disabled: Boolean + disabledBy: User @relation(name: "DISABLED", direction: "IN") } type Report { From 80729394586e6923cde23f8480e75dd4d5dcedad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 6 Mar 2019 17:21:49 +0100 Subject: [PATCH 488/554] Tiny performance improvement --- src/resolvers/moderation.js | 4 ++-- src/resolvers/moderation.spec.js | 21 ++++++++------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/resolvers/moderation.js b/src/resolvers/moderation.js index 10046dd03..db44790b9 100644 --- a/src/resolvers/moderation.js +++ b/src/resolvers/moderation.js @@ -17,8 +17,8 @@ export default { enable: async (object, params, { user, driver }) => { const { resource: { id } } = params const cypher = ` - MATCH (p {id: $id})<-[d:DISABLED]-() - SET p.disabled = false + MATCH (r {id: $id})<-[d:DISABLED]-() + SET r.disabled = false DELETE d ` const session = driver.session() diff --git a/src/resolvers/moderation.spec.js b/src/resolvers/moderation.spec.js index 6107074ef..c1d4a75fe 100644 --- a/src/resolvers/moderation.spec.js +++ b/src/resolvers/moderation.spec.js @@ -92,12 +92,10 @@ describe('disable', () => { setup.createResource = async () => { await factory.create('User', { id: 'u45', email: 'commenter@example.org', password: '1234' }) await factory.authenticateAs({ email: 'commenter@example.org', password: '1234' }) - await factory.create('Post', { - id: 'p3' - }) - await factory.create('Comment', { - id: 'c47' - }) + await Promise.all([ + factory.create('Post', { id: 'p3' }), + factory.create('Comment', { id: 'c47' }) + ]) await Promise.all([ factory.relate('Comment', 'Author', { from: 'u45', to: 'c47' }), factory.relate('Comment', 'Post', { from: 'c47', to: 'p3' }) @@ -251,13 +249,10 @@ describe('enable', () => { setup.createResource = async () => { await factory.create('User', { id: 'u123', email: 'author@example.org', password: '1234' }) await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) - await factory.create('Post', { - id: 'p9' // that's the ID we will look for - }) - - await factory.create('Comment', { - id: 'c456' - }) + await Promise.all([ + factory.create('Post', { id: 'p9' }), + factory.create('Comment', { id: 'c456' }) + ]) await Promise.all([ factory.relate('Comment', 'Author', { from: 'u123', to: 'c456' }), factory.relate('Comment', 'Post', { from: 'c456', to: 'p9' }) From d16a1f62ff751a567924ee1a28371fc0f9b238ac Mon Sep 17 00:00:00 2001 From: Armin Date: Thu, 7 Mar 2019 15:22:34 +0100 Subject: [PATCH 489/554] Refactoring + adding helmet for some basic security --- package.json | 3 +- src/activitypub/ActivityPub.js | 33 +---- src/activitypub/NitroDataSource.js | 10 +- .../routes/{webfinger.js => webFinger.js} | 0 src/activitypub/utils/activity.js | 38 ++++-- src/graphql-schema.js | 55 ++++---- src/seed/factories/index.js | 28 ++-- src/server.js | 2 + test/features/world.js | 2 +- yarn.lock | 123 +++++++++++++++++- 10 files changed, 201 insertions(+), 93 deletions(-) rename src/activitypub/routes/{webfinger.js => webFinger.js} (100%) diff --git a/package.json b/package.json index 85dfac6a2..d876b77d1 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "start": "node dist/", "dev": "nodemon --exec babel-node src/", "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "lint": "eslint src --config .eslintrc.js", + "lint": "eslint src --config .eslintrc.js --fix", "test": "nyc --reporter=text-lcov yarn test:jest", "test:cypress": "run-p --race test:before:*", "test:before:server": "cross-env GRAPHQL_URI=http://localhost:4123 GRAPHQL_PORT=4123 babel-node src/ 2> /dev/null", @@ -57,6 +57,7 @@ "graphql-shield": "~5.3.0", "graphql-tag": "~2.10.1", "graphql-yoga": "~1.17.4", + "helmet": "^3.15.1", "jsonwebtoken": "~8.5.0", "linkifyjs": "~2.1.8", "lodash": "~4.17.11", diff --git a/src/activitypub/ActivityPub.js b/src/activitypub/ActivityPub.js index 4bdbc9563..9cbf5b52e 100644 --- a/src/activitypub/ActivityPub.js +++ b/src/activitypub/ActivityPub.js @@ -8,19 +8,14 @@ import { sendAcceptActivity, sendRejectActivity } from './utils/activity' -import cluster from 'cluster' -import os from 'os' import request from 'request' import as from 'activitystrea.ms' import NitroDataSource from './NitroDataSource' import router from './routes' import dotenv from 'dotenv' -import express from 'express' -import http from 'http' import { resolve } from 'path' import Collections from './Collections' const debug = require('debug')('ea') -const numCPUs = os.cpus().length let activityPub = null @@ -39,30 +34,10 @@ export default class ActivityPub { const port = process.env.ACTIVITYPUB_PORT activityPub = new ActivityPub(process.env.ACTIVITYPUB_DOMAIN || 'localhost', port || 4100) - if (server) { - // integrated into "server" express framework - server.express.set('ap', activityPub) - server.express.use(router) - debug('ActivityPub middleware added to the express service') - } else { - // standalone clustered ActivityPub service - if (cluster.isMaster) { - debug(`master with pid = ${process.pid} is running`) - for (let i = 0; i < numCPUs; i++) { - cluster.fork() - } - cluster.on('exit', (worker, code, signal) => { - debug(`worker ${worker.process.pid} died with code ${code} and signal ${signal}`) - }) - } else { - const app = express() - app.set('ap', activityPub) - app.use(router) - http.createServer(app).listen(port, () => { - debug(`ActivityPub express service listening on port ${port}`) - }) - } - } + // integrated into "server" express framework + server.express.set('ap', activityPub) + server.express.use(router) + debug('ActivityPub middleware added to the express service') } else { debug('ActivityPub middleware already added to the express service') } diff --git a/src/activitypub/NitroDataSource.js b/src/activitypub/NitroDataSource.js index 20339ec62..d43dc40a6 100644 --- a/src/activitypub/NitroDataSource.js +++ b/src/activitypub/NitroDataSource.js @@ -9,7 +9,7 @@ import { createOrderedCollectionPage } from './utils/collection' import { - createArticleActivity, + createArticleObject, isPublicAddressed } from './utils/activity' import crypto from 'crypto' @@ -221,6 +221,7 @@ export default class NitroDataSource { query: gql` query { User(slug:"${slug}") { + actorId contributions { id title @@ -242,8 +243,8 @@ export default class NitroDataSource { const outboxCollection = createOrderedCollectionPage(slug, 'outbox') outboxCollection.totalItems = posts.length await Promise.all( - posts.map((post) => { - outboxCollection.orderedItems.push(createArticleActivity(post.content, slug, post.id, post.createdAt)) + posts.map(async (post) => { + outboxCollection.orderedItems.push(await createArticleObject(post.activityId, post.objectId, post.content, extractNameFromId(post.id), post.id, post.createdAt)) }) ) @@ -335,11 +336,10 @@ export default class NitroDataSource { } const title = postObject.summary ? postObject.summary : postObject.content.split(' ').slice(0, 5).join(' ') const postId = extractIdFromActivityId(postObject.id) - const activityId = extractIdFromActivityId(activity.id) let result = await this.client.mutate({ mutation: gql` mutation { - CreatePost(content: "${postObject.content}", contentExcerpt: "${trunc(postObject.content, 120)}", title: "${title}", id: "${postId}", activityId: "${activityId}") { + CreatePost(content: "${postObject.content}", contentExcerpt: "${trunc(postObject.content, 120)}", title: "${title}", id: "${postId}", objectId: "${postObject.id}", activityId: "${activity.id}") { id } } diff --git a/src/activitypub/routes/webfinger.js b/src/activitypub/routes/webFinger.js similarity index 100% rename from src/activitypub/routes/webfinger.js rename to src/activitypub/routes/webFinger.js diff --git a/src/activitypub/utils/activity.js b/src/activitypub/utils/activity.js index afe13dfca..00a91813d 100644 --- a/src/activitypub/utils/activity.js +++ b/src/activitypub/utils/activity.js @@ -1,10 +1,12 @@ -import crypto from 'crypto' import { activityPub } from '../ActivityPub' +import { signAndSend, throwErrorIfApolloErrorOccurred } from './index' + +import crypto from 'crypto' import as from 'activitystrea.ms' -import { signAndSend } from './index' +import gql from 'graphql-tag' const debug = require('debug')('ea:utils:activity') -export function createNoteActivity (text, name, id, published) { +export function createNoteObject (text, name, id, published) { const createUuid = crypto.randomBytes(16).toString('hex') return { @@ -23,25 +25,43 @@ export function createNoteActivity (text, name, id, published) { } } -export function createArticleActivity (text, name, id, published) { - const createUuid = crypto.randomBytes(16).toString('hex') +export async function createArticleObject (activityId, objectId, text, name, id, published) { + const actorId = await getActorId(name) return { '@context': 'https://www.w3.org/ns/activitystreams', - 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${createUuid}`, + 'id': `${activityId}`, 'type': 'Create', - 'actor': `https://${activityPub.domain}/activitypub/users/${name}`, + 'actor': `${actorId}`, 'object': { - 'id': `https://${activityPub.domain}/activitypub/users/${name}/status/${id}`, + 'id': `${objectId}`, 'type': 'Article', 'published': published, - 'attributedTo': `https://${activityPub.domain}/activitypub/users/${name}`, + 'attributedTo': `${actorId}`, 'content': text, 'to': 'https://www.w3.org/ns/activitystreams#Public' } } } +export async function getActorId (name) { + const result = await activityPub.dataSource.client.query({ + query: gql` + query { + User(slug: "${name}") { + actorId + } + } + ` + }) + throwErrorIfApolloErrorOccurred(result) + if (Array.isArray(result.data.User) && result.data.User[0]) { + return result.data.User[0].actorId + } else { + throw Error(`No user with name: ${name}`) + } +} + export function sendAcceptActivity (theBody, name, targetDomain, url) { as.accept() .id(`https://${activityPub.domain}/activitypub/users/${name}/status/` + crypto.randomBytes(16).toString('hex')) diff --git a/src/graphql-schema.js b/src/graphql-schema.js index bdf72c0a0..5ddf08492 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -6,6 +6,8 @@ import uuid from 'uuid/v4' import { fixUrl } from './middleware/fixImageUrlsMiddleware' import { AuthenticationError } from 'apollo-server' import { neo4jgraphql } from 'neo4j-graphql-js' +import { activityPub } from './activitypub/ActivityPub' +import as from 'activitystrea.ms' /* import as from 'activitystrea.ms' import request from 'request' @@ -174,14 +176,15 @@ export const resolvers = { debug(`user = ${JSON.stringify(ctx.user, null, 2)}`) const session = ctx.driver.session() const author = await session.run( - 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + + 'MATCH (author:User {slug: $slug}), (post:Post {id: $postId}) ' + 'MERGE (post)<-[:WROTE]-(author) ' + 'RETURN author', { - userId: ctx.user.id, + slug: ctx.user.slug, postId: result.id }) - debug(`author = ${JSON.stringify(author, null, 2)}`) - /* if (Array.isArray(author.records) && author.records.length > 0) { + // debug(`result = ${JSON.stringify(author, null, 2)}`) + debug(`actorId = ${author.records[0]._fields[0].properties.actorId}`) + if (Array.isArray(author.records) && author.records.length > 0) { const actorId = author.records[0]._fields[0].properties.actorId const createActivity = await new Promise((resolve, reject) => { as.create() @@ -195,36 +198,22 @@ export const resolvers = { .publishedNow() .attributedTo(`${actorId}`) ).prettyWrite((err, doc) => { - if (err) { - reject(err) - } else { - debug(doc) - const parsedDoc = JSON.parse(doc) - parsedDoc.send = true - resolve(JSON.stringify(parsedDoc)) - } - }) + if (err) { + reject(err) + } else { + debug(doc) + const parsedDoc = JSON.parse(doc) + parsedDoc.send = true + resolve(JSON.stringify(parsedDoc)) + } + }) }) - session.close() - // try sending post via ActivityPub - await new Promise((resolve) => { - const url = new URL(actorId) - request(`${url.origin}/activitypub/inbox`, { - method: 'POST', - headers: { - 'Content-Type': 'application/activity+json' - }, - body: createActivity - }, (err) => { - if (err) { - debug(`error = ${JSON.stringify(err, null, 2)}`) - resolve(err) - } - resolve(null) - }) - }) - return result - } */ + try { + await activityPub.sendActivity(createActivity) + } catch (e) { + debug(`error sending post activity = ${JSON.stringify(e, null, 2)}`) + } + } } } } diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 752ae3369..d9bbd700c 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -1,14 +1,14 @@ import { GraphQLClient, request } from 'graphql-request' import { getDriver } from '../../bootstrap/neo4j' -import createBadge from './badges.js' -import createUser from './users.js' +import createBadge from './badges.js' +import createUser from './users.js' import createOrganization from './organizations.js' -import createPost from './posts.js' -import createComment from './comments.js' -import createCategory from './categories.js' -import createTag from './tags.js' -import createReport from './reports.js' +import createPost from './posts.js' +import createComment from './comments.js' +import createCategory from './categories.js' +import createTag from './tags.js' +import createReport from './reports.js' export const seedServerHost = 'http://127.0.0.1:4001' @@ -25,14 +25,14 @@ const authenticatedHeaders = async ({ email, password }, host) => { } } const factories = { - 'Badge': createBadge, - 'User': createUser, + 'Badge': createBadge, + 'User': createUser, 'Organization': createOrganization, - 'Post': createPost, - 'Comment': createComment, - 'Category': createCategory, - 'Tag': createTag, - 'Report': createReport + 'Post': createPost, + 'Comment': createComment, + 'Category': createCategory, + 'Tag': createTag, + 'Report': createReport } export const cleanDatabase = async (options = {}) => { diff --git a/src/server.js b/src/server.js index 5867e6952..10fdf291c 100644 --- a/src/server.js +++ b/src/server.js @@ -12,6 +12,7 @@ import { getDriver } from './bootstrap/neo4j' import passport from 'passport' import jwtStrategy from './jwt/strategy' import jwt from 'jsonwebtoken' +import helmet from 'helmet' dotenv.config() // check env and warn @@ -66,6 +67,7 @@ const createServer = (options) => { const server = new GraphQLServer(Object.assign({}, defaults, options)) passport.use('jwt', jwtStrategy(driver)) + server.express.use(helmet()) server.express.use(passport.initialize()) server.express.use(express.static('public')) diff --git a/test/features/world.js b/test/features/world.js index 9a27bd154..1b96e0761 100644 --- a/test/features/world.js +++ b/test/features/world.js @@ -5,7 +5,7 @@ const debug = require('debug')('ea:test:world') class CustomWorld { constructor () { - // webfinger.feature + // webFinger.feature this.lastResponses = [] this.lastContentType = null this.lastInboxUrl = null diff --git a/yarn.lock b/yarn.lock index 05299ad6e..52fb19cde 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1789,6 +1789,11 @@ camelcase@^5.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== +camelize@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" + integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= + caniuse-lite@^1.0.30000912: version "1.0.30000916" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000916.tgz#3428d3f529f0a7b2bfaaec65e796037bdd433aab" @@ -2053,6 +2058,11 @@ content-disposition@0.5.2: resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= +content-security-policy-builder@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/content-security-policy-builder/-/content-security-policy-builder-2.0.0.tgz#8749a1d542fcbe82237281ea9f716ce68b394dd2" + integrity sha512-j+Nhmj1yfZAikJLImCvPJFE29x/UuBi+/MWqggGGc515JKaZrjuei2RhULJmy0MsstW3E3htl002bwmBNMKr7w== + content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" @@ -2261,6 +2271,11 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +dasherize@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dasherize/-/dasherize-2.0.0.tgz#6d809c9cd0cf7bb8952d80fc84fa13d47ddb1308" + integrity sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg= + data-urls@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" @@ -2369,6 +2384,11 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -2412,6 +2432,11 @@ diff@^3.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +dns-prefetch-control@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz#60ddb457774e178f1f9415f0cabb0e85b0b300b2" + integrity sha1-YN20V3dOF48flBXwyrsOhbCzALI= + doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -2475,6 +2500,11 @@ domutils@^1.5.1: dom-serializer "0" domelementtype "1" +dont-sniff-mimetype@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz#5932890dc9f4e2f19e5eb02a20026e5e5efc8f58" + integrity sha1-WTKJDcn04vGeXrAqIAJuXl78j1g= + dot-prop@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" @@ -2716,7 +2746,7 @@ eslint-plugin-import@~2.16.0: read-pkg-up "^2.0.0" resolve "^1.9.0" -eslint-plugin-jest@~22.3.0: +eslint-plugin-jest@^22.3.0: version "22.3.0" resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.3.0.tgz#a10f10dedfc92def774ec9bb5bfbd2fb8e1c96d2" integrity sha512-P1mYVRNlOEoO5T9yTqOfucjOYf1ktmJ26NjwjH8sxpCFQa6IhBGr5TpKl3hcAAT29hOsRJVuMWmTsHoUVo9FoA== @@ -2920,6 +2950,11 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expect-ct@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/expect-ct/-/expect-ct-0.1.1.tgz#de84476a2dbcb85000d5903737e9bc8a5ba7b897" + integrity sha512-ngXzTfoRGG7fYens3/RMb6yYoVLvLMfmsSllP/mZPxNHgFq41TmPSLF/nLY7fwoclI2vElvAmILFWGUYqdjfCg== + expect@^24.1.0: version "24.1.0" resolved "https://registry.yarnpkg.com/expect/-/expect-24.1.0.tgz#88e73301c4c785cde5f16da130ab407bdaf8c0f2" @@ -3047,6 +3082,11 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" +feature-policy@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/feature-policy/-/feature-policy-0.2.0.tgz#22096de49ab240176878ffe2bde2f6ff04d48c43" + integrity sha512-2hGrlv6efG4hscYVZeaYjpzpT6I2OZgYqE2yDUzeAcKj2D1SH0AsEzqJNXzdoglEddcIXQQYop3lD97XpG75Jw== + figures@2.0.0, figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -3184,6 +3224,11 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" +frameguard@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/frameguard/-/frameguard-3.0.0.tgz#7bcad469ee7b96e91d12ceb3959c78235a9272e9" + integrity sha1-e8rUae57lukdEs6zlZx4I1qScuk= + fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -3610,6 +3655,47 @@ he@0.5.0: resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" integrity sha1-LAX/rvkLaOhg8/0rVO9YCYknfuI= +helmet-crossdomain@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/helmet-crossdomain/-/helmet-crossdomain-0.3.0.tgz#707e2df930f13ad61f76ed08e1bb51ab2b2e85fa" + integrity sha512-YiXhj0E35nC4Na5EPE4mTfoXMf9JTGpN4OtB4aLqShKuH9d2HNaJX5MQoglO6STVka0uMsHyG5lCut5Kzsy7Lg== + +helmet-csp@2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/helmet-csp/-/helmet-csp-2.7.1.tgz#e8e0b5186ffd4db625cfcce523758adbfadb9dca" + integrity sha512-sCHwywg4daQ2mY0YYwXSZRsgcCeerUwxMwNixGA7aMLkVmPTYBl7gJoZDHOZyXkqPrtuDT3s2B1A+RLI7WxSdQ== + dependencies: + camelize "1.0.0" + content-security-policy-builder "2.0.0" + dasherize "2.0.0" + platform "1.3.5" + +helmet@^3.15.1: + version "3.15.1" + resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.15.1.tgz#2c80d1a59138b6f23929605afca4b1c88b3298ec" + integrity sha512-hgoNe/sjKlKNvJ3g9Gz149H14BjMMWOCmW/DTXl7IfyKGtIK37GePwZrHNfr4aPXdKVyXcTj26RgRFbPKDy9lw== + dependencies: + depd "2.0.0" + dns-prefetch-control "0.1.0" + dont-sniff-mimetype "1.0.0" + expect-ct "0.1.1" + feature-policy "0.2.0" + frameguard "3.0.0" + helmet-crossdomain "0.3.0" + helmet-csp "2.7.1" + hide-powered-by "1.0.0" + hpkp "2.0.0" + hsts "2.1.0" + ienoopen "1.0.0" + nocache "2.0.0" + referrer-policy "1.1.0" + x-xss-protection "1.1.0" + +hide-powered-by@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hide-powered-by/-/hide-powered-by-1.0.0.tgz#4a85ad65881f62857fc70af7174a1184dccce32b" + integrity sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys= + hoek@5.x.x: version "5.0.4" resolved "https://registry.yarnpkg.com/hoek/-/hoek-5.0.4.tgz#0f7fa270a1cafeb364a4b2ddfaa33f864e4157da" @@ -3637,6 +3723,16 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== +hpkp@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hpkp/-/hpkp-2.0.0.tgz#10e142264e76215a5d30c44ec43de64dee6d1672" + integrity sha1-EOFCJk52IVpdMMROxD3mTe5tFnI= + +hsts@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/hsts/-/hsts-2.1.0.tgz#cbd6c918a2385fee1dd5680bfb2b3a194c0121cc" + integrity sha512-zXhh/DqgrTXJ7erTN6Fh5k/xjMhDGXCqdYN3wvxUvGUQvnxcFfUd8E+6vLg/nk3ss1TYMb+DhRl25fYABioTvA== + html-encoding-sniffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" @@ -3710,6 +3806,11 @@ ieee754@^1.1.4: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== +ienoopen@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ienoopen/-/ienoopen-1.0.0.tgz#346a428f474aac8f50cf3784ea2d0f16f62bda6b" + integrity sha1-NGpCj0dKrI9QzzeE6i0PFvYr2ms= + ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" @@ -5243,6 +5344,11 @@ no-case@^2.2.0: dependencies: lower-case "^1.1.1" +nocache@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nocache/-/nocache-2.0.0.tgz#202b48021a0c4cbde2df80de15a17443c8b43980" + integrity sha1-ICtIAhoMTL3i34DeFaF0Q8i0OYA= + node-fetch@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" @@ -5863,6 +5969,11 @@ pkginfo@~0.4.0: resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff" integrity sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8= +platform@1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.5.tgz#fb6958c696e07e2918d2eeda0f0bc9448d733444" + integrity sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q== + pn@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" @@ -6160,6 +6271,11 @@ reasoner@2.0.0: vocabs-rdfs "^0.11.1" vocabs-xsd "^0.11.1" +referrer-policy@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/referrer-policy/-/referrer-policy-1.1.0.tgz#35774eb735bf50fb6c078e83334b472350207d79" + integrity sha1-NXdOtzW/UPtsB46DM0tHI1AgfXk= + regenerate-unicode-properties@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" @@ -7668,6 +7784,11 @@ ws@^6.0.0: dependencies: async-limiter "~1.0.0" +x-xss-protection@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/x-xss-protection/-/x-xss-protection-1.1.0.tgz#4f1898c332deb1e7f2be1280efb3e2c53d69c1a7" + integrity sha512-rx3GzJlgEeZ08MIcDsU2vY2B1QEriUKJTSiNHHUIem6eg9pzVOr2TL3Y4Pd6TMAM5D5azGjcxqI62piITBDHVg== + xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" From 1377455cda0f178d345696f4f09ae2e26c064908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 7 Mar 2019 18:31:54 +0100 Subject: [PATCH 490/554] Disable/enable should return the Resource --- src/resolvers/moderation.spec.js | 20 ++++++++++---------- src/schema.graphql | 9 +++++++-- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/resolvers/moderation.spec.js b/src/resolvers/moderation.spec.js index c1d4a75fe..005996ec7 100644 --- a/src/resolvers/moderation.spec.js +++ b/src/resolvers/moderation.spec.js @@ -37,7 +37,7 @@ afterEach(async () => { describe('disable', () => { const mutation = ` mutation($id: ID!, $type: ResourceEnum!) { - disable(resource: { id: $id, type: $type }) + disable(resource: { id: $id, type: $type }) { id type } } ` let variables @@ -103,8 +103,8 @@ describe('disable', () => { } }) - it('returns true', async () => { - const expected = { disable: true } + it('returns disabled Resource', async () => { + const expected = { disable: { id: 'c47', type: 'comment' } } await runSetup() await expect(action()).resolves.toEqual(expected) }) @@ -154,8 +154,8 @@ describe('disable', () => { } }) - it('returns true', async () => { - const expected = { disable: true } + it('returns disabled Resource', async () => { + const expected = { disable: { id: 'p9', type: 'contribution' } } await runSetup() await expect(action()).resolves.toEqual(expected) }) @@ -195,7 +195,7 @@ describe('disable', () => { describe('enable', () => { const mutation = ` mutation($id: ID!, $type: ResourceEnum!) { - enable(resource: { id: $id, type: $type }) + enable(resource: { id: $id, type: $type }) { id type } } ` let variables @@ -270,8 +270,8 @@ describe('enable', () => { } }) - it('returns true', async () => { - const expected = { enable: true } + it('returns disabled Resource', async () => { + const expected = { enable: { id: 'c456', type: 'comment' } } await runSetup() await expect(action()).resolves.toEqual(expected) }) @@ -331,8 +331,8 @@ describe('enable', () => { } }) - it('returns true', async () => { - const expected = { enable: true } + it('returns disabled Resource', async () => { + const expected = { enable: { id: 'p9', type: 'contribution' } } await runSetup() await expect(action()).resolves.toEqual(expected) }) diff --git a/src/schema.graphql b/src/schema.graphql index 5e58d5f1d..e284b6c52 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -7,8 +7,8 @@ type Mutation { login(email: String!, password: String!): String! signup(email: String!, password: String!): Boolean! report(resource: Resource!, description: String): Report - disable(resource: Resource!): Boolean! - enable(resource: Resource!): Boolean! + disable(resource: Resource!): ResourcePayload! + enable(resource: Resource!): ResourcePayload! } type Statistics { @@ -32,6 +32,11 @@ input Resource { type: ResourceEnum! } +type ResourcePayload { + id: ID!, + type: ResourceEnum! +} + enum ResourceEnum { contribution comment From 4596041186704065d2c5d5ff332e30b89825e211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 7 Mar 2019 19:21:47 +0100 Subject: [PATCH 491/554] Refactor mutations without Resource type --- src/middleware/softDeleteMiddleware.spec.js | 5 +- src/resolvers/moderation.js | 26 +++++++---- src/resolvers/moderation.spec.js | 52 ++++++++------------- src/schema.graphql | 23 ++------- src/seed/seed-db.js | 9 +--- 5 files changed, 43 insertions(+), 72 deletions(-) diff --git a/src/middleware/softDeleteMiddleware.spec.js b/src/middleware/softDeleteMiddleware.spec.js index e9bc461f1..ed132104e 100644 --- a/src/middleware/softDeleteMiddleware.spec.js +++ b/src/middleware/softDeleteMiddleware.spec.js @@ -22,10 +22,9 @@ beforeEach(async () => { await moderatorFactory.authenticateAs({ email: 'moderator@example.org', password: '1234' }) const disableMutation = ` mutation { - disable(resource: { + disable( id: "p2" - type: contribution - }) + ) } ` await moderatorFactory.mutate(disableMutation) diff --git a/src/resolvers/moderation.js b/src/resolvers/moderation.js index db44790b9..33af83bb6 100644 --- a/src/resolvers/moderation.js +++ b/src/resolvers/moderation.js @@ -1,30 +1,38 @@ export default { Mutation: { disable: async (object, params, { user, driver }) => { - const { resource: { id } } = params + const { id } = params const { id: userId } = user const cypher = ` MATCH (u:User {id: $userId}) - MATCH (r {id: $id}) - SET r.disabled = true - MERGE (r)<-[:DISABLED]-(u) + MATCH (resource {id: $id}) + SET resource.disabled = true + MERGE (resource)<-[:DISABLED]-(u) + RETURN resource {.id} ` const session = driver.session() const res = await session.run(cypher, { id, userId }) + const [resource] = res.records.map((record) => { + return record.get('resource') + }) session.close() - return Boolean(res) + return resource.id }, enable: async (object, params, { user, driver }) => { - const { resource: { id } } = params + const { id } = params const cypher = ` - MATCH (r {id: $id})<-[d:DISABLED]-() - SET r.disabled = false + MATCH (resource {id: $id})<-[d:DISABLED]-() + SET resource.disabled = false DELETE d + RETURN resource {.id} ` const session = driver.session() const res = await session.run(cypher, { id }) + const [resource] = res.records.map((record) => { + return record.get('resource') + }) session.close() - return Boolean(res) + return resource.id } } } diff --git a/src/resolvers/moderation.spec.js b/src/resolvers/moderation.spec.js index 005996ec7..3b2ace1cc 100644 --- a/src/resolvers/moderation.spec.js +++ b/src/resolvers/moderation.spec.js @@ -36,8 +36,8 @@ afterEach(async () => { describe('disable', () => { const mutation = ` - mutation($id: ID!, $type: ResourceEnum!) { - disable(resource: { id: $id, type: $type }) { id type } + mutation($id: ID!) { + disable(id: $id) } ` let variables @@ -45,8 +45,7 @@ describe('disable', () => { beforeEach(() => { // our defaul set of variables variables = { - id: 'blabla', - type: 'contribution' + id: 'blabla' } }) @@ -85,8 +84,7 @@ describe('disable', () => { describe('on a comment', () => { beforeEach(async () => { variables = { - id: 'c47', - type: 'comment' + id: 'c47' } setup.createResource = async () => { @@ -103,8 +101,8 @@ describe('disable', () => { } }) - it('returns disabled Resource', async () => { - const expected = { disable: { id: 'c47', type: 'comment' } } + it('returns disabled resource id', async () => { + const expected = { disable: 'c47' } await runSetup() await expect(action()).resolves.toEqual(expected) }) @@ -141,8 +139,7 @@ describe('disable', () => { describe('on a post', () => { beforeEach(async () => { variables = { - id: 'p9', - type: 'contribution' + id: 'p9' } setup.createResource = async () => { @@ -154,8 +151,8 @@ describe('disable', () => { } }) - it('returns disabled Resource', async () => { - const expected = { disable: { id: 'p9', type: 'contribution' } } + it('returns disabled resource id', async () => { + const expected = { disable: 'p9' } await runSetup() await expect(action()).resolves.toEqual(expected) }) @@ -194,8 +191,8 @@ describe('disable', () => { describe('enable', () => { const mutation = ` - mutation($id: ID!, $type: ResourceEnum!) { - enable(resource: { id: $id, type: $type }) { id type } + mutation($id: ID!) { + enable(id: $id) } ` let variables @@ -207,8 +204,7 @@ describe('enable', () => { beforeEach(() => { // our defaul set of variables variables = { - id: 'blabla', - type: 'contribution' + id: 'blabla' } }) @@ -242,8 +238,7 @@ describe('enable', () => { describe('on a comment', () => { beforeEach(async () => { variables = { - id: 'c456', - type: 'comment' + id: 'c456' } setup.createResource = async () => { @@ -260,18 +255,15 @@ describe('enable', () => { const disableMutation = ` mutation { - disable(resource: { - id: "c456" - type: comment - }) + disable(id: "c456") } ` await factory.mutate(disableMutation) // that's we want to delete } }) - it('returns disabled Resource', async () => { - const expected = { enable: { id: 'c456', type: 'comment' } } + it('returns disabled resource id', async () => { + const expected = { enable: 'c456' } await runSetup() await expect(action()).resolves.toEqual(expected) }) @@ -308,8 +300,7 @@ describe('enable', () => { describe('on a post', () => { beforeEach(async () => { variables = { - id: 'p9', - type: 'contribution' + id: 'p9' } setup.createResource = async () => { @@ -321,18 +312,15 @@ describe('enable', () => { const disableMutation = ` mutation { - disable(resource: { - id: "p9" - type: contribution - }) + disable(id: "p9") } ` await factory.mutate(disableMutation) // that's we want to delete } }) - it('returns disabled Resource', async () => { - const expected = { enable: { id: 'p9', type: 'contribution' } } + it('returns disabled resource id', async () => { + const expected = { enable: 'p9' } await runSetup() await expect(action()).resolves.toEqual(expected) }) diff --git a/src/schema.graphql b/src/schema.graphql index e284b6c52..74d042933 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -6,9 +6,9 @@ type Query { type Mutation { login(email: String!, password: String!): String! signup(email: String!, password: String!): Boolean! - report(resource: Resource!, description: String): Report - disable(resource: Resource!): ResourcePayload! - enable(resource: Resource!): ResourcePayload! + report(id: ID!, description: String): Report + disable(id: ID!): ID! + enable(id: ID!): ID! } type Statistics { @@ -27,22 +27,6 @@ scalar Date scalar Time scalar DateTime -input Resource { - id: ID!, - type: ResourceEnum! -} - -type ResourcePayload { - id: ID!, - type: ResourceEnum! -} - -enum ResourceEnum { - contribution - comment - user -} - enum VisibilityEnum { public friends @@ -178,7 +162,6 @@ type Report { id: ID! reporter: User @relation(name: "REPORTED", direction: "IN") description: String - type: ResourceEnum! createdAt: String comment: Comment @relation(name: "REPORTED", direction: "OUT") contribution: Post @relation(name: "REPORTED", direction: "OUT") diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 310089ef7..5f5b764a4 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -98,14 +98,7 @@ import Factory from './factories' asTick.create('Post', { id: 'p15' }) ]) - const disableMutation = ` - mutation { - disable(resource: { - id: "p11" - type: contribution - }) - } - ` + const disableMutation = 'mutation { disable( id: "p11") }' await asModerator.mutate(disableMutation) await Promise.all([ From 95e9c14cc693bfaaf6cb4830d263c0b92b5b1a20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 7 Mar 2019 20:13:39 +0100 Subject: [PATCH 492/554] Refactor report mutation/type to reduce redundancy We don't need to save the type of the reported resource. We can derive it. --- src/resolvers/reports.js | 53 +++++++++++---------------------- src/resolvers/reports.spec.js | 55 +++++++++++++++-------------------- src/schema.graphql | 1 + src/seed/factories/reports.js | 7 ++--- src/seed/seed-db.js | 6 ++-- 5 files changed, 47 insertions(+), 75 deletions(-) diff --git a/src/resolvers/reports.js b/src/resolvers/reports.js index c471d7b7a..79bab6646 100644 --- a/src/resolvers/reports.js +++ b/src/resolvers/reports.js @@ -2,50 +2,31 @@ import uuid from 'uuid/v4' export default { Mutation: { - report: async (parent, { resource, description }, { driver, req, user }, resolveInfo) => { - const contextId = uuid() + report: async (parent, { id, description }, { driver, req, user }, resolveInfo) => { + const reportId = uuid() const session = driver.session() - const data = { - id: contextId, - type: resource.type, + const reportData = { + id: reportId, createdAt: (new Date()).toISOString(), - description: resource.description + description: description } - await session.run( - 'CREATE (r:Report $report) ' + - 'RETURN r.id, r.type, r.description', { - report: data - } - ) - let contentType - - switch (resource.type) { - case 'post': - case 'contribution': - contentType = 'Post' - break - case 'comment': - contentType = 'Comment' - break - case 'user': - contentType = 'User' - break + await session.run(` + MATCH (author:User {id: $userId}) + MATCH (resource {id: $resourceId}) + CREATE (report:Report $reportData) + MERGE (resource)<-[:REPORTED]-(report) + MERGE (report)<-[:REPORTED]-(author) + RETURN report + `, { + resourceId: id, + userId: user.id, + reportData } - - await session.run( - `MATCH (author:User {id: $userId}), (context:${contentType} {id: $resourceId}), (report:Report {id: $contextId}) ` + - 'MERGE (report)<-[:REPORTED]-(author) ' + - 'MERGE (context)<-[:REPORTED]-(report) ' + - 'RETURN context', { - resourceId: resource.id, - userId: user.id, - contextId: contextId - } ) session.close() // TODO: output Report compatible object - return data + return reportData } } } diff --git a/src/resolvers/reports.spec.js b/src/resolvers/reports.spec.js index 253cdadcc..07cfc92eb 100644 --- a/src/resolvers/reports.spec.js +++ b/src/resolvers/reports.spec.js @@ -22,45 +22,38 @@ describe('report', () => { await factory.cleanDatabase() }) + const mutation = ` + mutation { + report( + id: "u2", + description: "I don't like this user" + ) { description } + } + ` + let headers + beforeEach(async () => { + headers = {} + }) + + let client + const action = () => { + client = new GraphQLClient(host, { headers }) + return client.request(mutation) + } + describe('unauthenticated', () => { - let client it('throws authorization error', async () => { - client = new GraphQLClient(host) - await expect( - client.request(`mutation { - report( - description: "I don't like this user", - resource: { - id: "u2", - type: user - } - ) { id, createdAt } - }`) - ).rejects.toThrow('Not Authorised') + await expect(action()).rejects.toThrow('Not Authorised') }) describe('authenticated', () => { - let headers - let response beforeEach(async () => { headers = await login({ email: 'test@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - response = await client.request(`mutation { - report( - description: "I don't like this user", - resource: { - id: "u2", - type: user - } - ) { id, createdAt } - }`, - { headers } - ) }) - it('creates a report', () => { - let { id, createdAt } = response.report - expect(response).toEqual({ - report: { id, createdAt } + + it('creates a report', async () => { + await expect(action()).resolves.toEqual({ + report: { description: 'I don\'t like this user' } }) }) }) diff --git a/src/schema.graphql b/src/schema.graphql index 74d042933..65e11fe19 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -162,6 +162,7 @@ type Report { id: ID! reporter: User @relation(name: "REPORTED", direction: "IN") description: String + type: String! @cypher(statement: "MATCH (resource)<-[:REPORTED]-(this) RETURN labels(resource)[0]") createdAt: String comment: Comment @relation(name: "REPORTED", direction: "OUT") contribution: Post @relation(name: "REPORTED", direction: "OUT") diff --git a/src/seed/factories/reports.js b/src/seed/factories/reports.js index 4dcd479f1..ccf5299bd 100644 --- a/src/seed/factories/reports.js +++ b/src/seed/factories/reports.js @@ -3,17 +3,14 @@ import faker from 'faker' export default function create (params) { const { description = faker.lorem.sentence(), - resource: { id: resourceId, type } + id } = params return ` mutation { report( description: "${description}", - resource: { - id: "${resourceId}", - type: ${type} - } + id: "${id}", ) { id, createdAt diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 5f5b764a4..b4ecd6d7f 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -173,9 +173,9 @@ import Factory from './factories' ]) await Promise.all([ - asTick.create('Report', { description: 'I don\'t like this comment', resource: { id: 'c1', type: 'comment' } }), - asTrick.create('Report', { description: 'I don\'t like this post', resource: { id: 'p1', type: 'contribution' } }), - asTrack.create('Report', { description: 'I don\'t like this user', resource: { id: 'u1', type: 'user' } }) + asTick.create('Report', { description: 'I don\'t like this comment', id: 'c1' }), + asTrick.create('Report', { description: 'I don\'t like this post', id: 'p1' }), + asTrack.create('Report', { description: 'I don\'t like this user', id: 'u1' }) ]) await Promise.all([ From 61a45d39eafbadddd9642473567dc0b74f280989 Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Thu, 7 Mar 2019 17:43:00 -0300 Subject: [PATCH 493/554] Respond with reporter, resource --- src/resolvers/reports.js | 21 +++++++++-- src/resolvers/reports.spec.js | 71 ++++++++++++++++++++++++++++------- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/src/resolvers/reports.js b/src/resolvers/reports.js index 79bab6646..7c60bb88f 100644 --- a/src/resolvers/reports.js +++ b/src/resolvers/reports.js @@ -10,23 +10,38 @@ export default { createdAt: (new Date()).toISOString(), description: description } - await session.run(` + + const res = await session.run(` MATCH (author:User {id: $userId}) MATCH (resource {id: $resourceId}) CREATE (report:Report $reportData) MERGE (resource)<-[:REPORTED]-(report) MERGE (report)<-[:REPORTED]-(author) - RETURN report + RETURN report, author, resource `, { resourceId: id, userId: user.id, reportData } ) + const [{ report, author, resource }] = res.records.map(r => { + return { + report: r.get('report'), + author: r.get('author'), + resource: r.get('resource') + } + }) session.close() + console.log(report) + console.log(author) // TODO: output Report compatible object - return reportData + return { + ...report.properties, + reporter: author.properties, + user: resource.properties, + type: 'blablabla' + } } } } diff --git a/src/resolvers/reports.spec.js b/src/resolvers/reports.spec.js index 07cfc92eb..eebc335bc 100644 --- a/src/resolvers/reports.spec.js +++ b/src/resolvers/reports.spec.js @@ -5,8 +5,12 @@ import { host, login } from '../jest/helpers' const factory = Factory() describe('report', () => { + let mutation + let headers beforeEach(async () => { + headers = {} await factory.create('User', { + id: 'u1', email: 'test@example.org', password: '1234' }) @@ -16,25 +20,20 @@ describe('report', () => { role: 'user', email: 'abusive-user@example.org' }) + mutation = ` + mutation { + report( + id: "u2", + description: "I don't like this user" + ) { description } + } + ` }) afterEach(async () => { await factory.cleanDatabase() }) - const mutation = ` - mutation { - report( - id: "u2", - description: "I don't like this user" - ) { description } - } - ` - let headers - beforeEach(async () => { - headers = {} - }) - let client const action = () => { client = new GraphQLClient(host, { headers }) @@ -56,6 +55,52 @@ describe('report', () => { report: { description: 'I don\'t like this user' } }) }) + + it('returns the reporter', async () => { + mutation = ` + mutation { + report( + id: "u2", + description: "I don't like this user" + ) { reporter { + email + } } + } + ` + await expect(action()).resolves.toEqual({ + report: { reporter: { email: 'test@example.org' } } + }) + }) + + it('returns type', async () => { + mutation = ` + mutation { + report( + id: "u2", + description: "I don't like this user" + ) { type } + } + ` + await expect(action()).resolves.toEqual({ + report: { type: 'User' } + }) + }) + + it('returns user', async () => { + mutation = ` + mutation { + report( + id: "u2", + description: "I don't like this user" + ) { user { + name + } } + } + ` + await expect(action()).resolves.toEqual({ + report: { user: { name: 'abusive-user' } } + }) + }) }) }) }) From 0529e2b2b06aa2ad98e57d5be2b77d78be6063d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 7 Mar 2019 22:42:32 +0100 Subject: [PATCH 494/554] Refactor `report` mutation, return a proper Report --- src/resolvers/reports.js | 43 ++++++---- src/resolvers/reports.spec.js | 148 ++++++++++++++++++++++------------ src/schema.graphql | 4 +- 3 files changed, 128 insertions(+), 67 deletions(-) diff --git a/src/resolvers/reports.js b/src/resolvers/reports.js index 7c60bb88f..86d2af394 100644 --- a/src/resolvers/reports.js +++ b/src/resolvers/reports.js @@ -12,36 +12,51 @@ export default { } const res = await session.run(` - MATCH (author:User {id: $userId}) + MATCH (submitter:User {id: $userId}) MATCH (resource {id: $resourceId}) CREATE (report:Report $reportData) MERGE (resource)<-[:REPORTED]-(report) - MERGE (report)<-[:REPORTED]-(author) - RETURN report, author, resource + MERGE (report)<-[:REPORTED]-(submitter) + RETURN report, submitter, resource, labels(resource)[0] as type `, { resourceId: id, userId: user.id, reportData } ) - const [{ report, author, resource }] = res.records.map(r => { + session.close() + + const [dbResponse] = res.records.map(r => { return { report: r.get('report'), - author: r.get('author'), - resource: r.get('resource') + submitter: r.get('submitter'), + resource: r.get('resource'), + type: r.get('type') } }) - session.close() - console.log(report) - console.log(author) + if(!dbResponse) return null + const { report, submitter, resource, type } = dbResponse - // TODO: output Report compatible object - return { + let response = { ...report.properties, - reporter: author.properties, - user: resource.properties, - type: 'blablabla' + post: null, + comment: null, + user: null, + submitter: submitter.properties, + type } + switch(type){ + case "Post": + response.post = resource.properties + break; + case "Comment": + response.comment = resource.properties + break; + case "User": + response.user = resource.properties + break; + } + return response } } } diff --git a/src/resolvers/reports.spec.js b/src/resolvers/reports.spec.js index eebc335bc..7e9a55d1e 100644 --- a/src/resolvers/reports.spec.js +++ b/src/resolvers/reports.spec.js @@ -7,6 +7,9 @@ const factory = Factory() describe('report', () => { let mutation let headers + let returnedObject + let variables + beforeEach(async () => { headers = {} await factory.create('User', { @@ -20,14 +23,6 @@ describe('report', () => { role: 'user', email: 'abusive-user@example.org' }) - mutation = ` - mutation { - report( - id: "u2", - description: "I don't like this user" - ) { description } - } - ` }) afterEach(async () => { @@ -36,8 +31,17 @@ describe('report', () => { let client const action = () => { + mutation = ` + mutation($id: ID!) { + report( + id: $id, + description: "Violates code of conduct" + ) ${returnedObject || '{ description }'} + } + ` + variables = variables || { id: 'whatever' } client = new GraphQLClient(host, { headers }) - return client.request(mutation) + return client.request(mutation, variables) } describe('unauthenticated', () => { @@ -50,55 +54,97 @@ describe('report', () => { headers = await login({ email: 'test@example.org', password: '1234' }) }) - it('creates a report', async () => { - await expect(action()).resolves.toEqual({ - report: { description: 'I don\'t like this user' } + describe('invalid resource id', () => { + it('returns null', async () => { + await expect(action()).resolves.toEqual({ + report: null + }) }) }) - it('returns the reporter', async () => { - mutation = ` - mutation { - report( - id: "u2", - description: "I don't like this user" - ) { reporter { - email - } } - } - ` - await expect(action()).resolves.toEqual({ - report: { reporter: { email: 'test@example.org' } } + describe('valid resource id', () => { + beforeEach(async () => { + variables = {id: 'u2'} }) - }) - it('returns type', async () => { - mutation = ` - mutation { - report( - id: "u2", - description: "I don't like this user" - ) { type } - } - ` - await expect(action()).resolves.toEqual({ - report: { type: 'User' } + it('creates a report', async () => { + await expect(action()).resolves.toEqual({ + report: { description: 'Violates code of conduct' } + }) }) - }) - it('returns user', async () => { - mutation = ` - mutation { - report( - id: "u2", - description: "I don't like this user" - ) { user { - name - } } - } - ` - await expect(action()).resolves.toEqual({ - report: { user: { name: 'abusive-user' } } + it('returns the submitter', async () => { + returnedObject = '{ submitter { email } }' + await expect(action()).resolves.toEqual({ + report: { submitter: { email: 'test@example.org' } } + }) + }) + + describe('reported resource is a user', () => { + it('returns type "User"', async () => { + returnedObject = '{ type }' + await expect(action()).resolves.toEqual({ + report: { type: 'User' } + }) + }) + + it('returns resource in user attribute', async () => { + returnedObject = '{ user { name } }' + await expect(action()).resolves.toEqual({ + report: { user: { name: 'abusive-user' } } + }) + }) + }) + + describe('reported resource is a post', () => { + beforeEach(async () => { + await factory.authenticateAs({email: 'test@example.org', password: '1234'}) + await factory.create('Post', {id: 'p23', title: 'Matt and Robert having a pair-programming' }) + variables = { id: 'p23' } + }) + + it('returns type "Post"', async () => { + returnedObject = '{ type }' + await expect(action()).resolves.toEqual({ + report: { type: 'Post' } + }) + }) + + it('returns resource in post attribute', async () => { + returnedObject = '{ post { title } }' + await expect(action()).resolves.toEqual({ + report: { post: { title: 'Matt and Robert having a pair-programming' } } + }) + }) + + it('returns null in user attribute', async () => { + returnedObject = '{ user { name } }' + await expect(action()).resolves.toEqual({ + report: { user: null } + }) + }) + }) + + describe('reported resource is a comment', () => { + beforeEach(async () => { + await factory.authenticateAs({email: 'test@example.org', password: '1234'}) + await factory.create('Comment', {id: 'c34', content: 'Robert getting tired.' }) + variables = { id: 'c34' } + }) + + it('returns type "Comment"', async () => { + returnedObject = '{ type }' + await expect(action()).resolves.toEqual({ + report: { type: 'Comment' } + }) + }) + + it('returns resource in comment attribute', async () => { + returnedObject = '{ comment { content } }' + await expect(action()).resolves.toEqual({ + report: { comment: { content: 'Robert getting tired.' } } + }) + }) }) }) }) diff --git a/src/schema.graphql b/src/schema.graphql index 65e11fe19..a00afd53b 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -160,12 +160,12 @@ type Comment { type Report { id: ID! - reporter: User @relation(name: "REPORTED", direction: "IN") + submitter: User @relation(name: "REPORTED", direction: "IN") description: String type: String! @cypher(statement: "MATCH (resource)<-[:REPORTED]-(this) RETURN labels(resource)[0]") createdAt: String comment: Comment @relation(name: "REPORTED", direction: "OUT") - contribution: Post @relation(name: "REPORTED", direction: "OUT") + post: Post @relation(name: "REPORTED", direction: "OUT") user: User @relation(name: "REPORTED", direction: "OUT") } From f68e289016a903aac53c40ff1c2d60f750b48454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 7 Mar 2019 22:44:43 +0100 Subject: [PATCH 495/554] Fix lint --- src/resolvers/reports.js | 22 +++++++++++----------- src/resolvers/reports.spec.js | 10 +++++----- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/resolvers/reports.js b/src/resolvers/reports.js index 86d2af394..acac516e0 100644 --- a/src/resolvers/reports.js +++ b/src/resolvers/reports.js @@ -34,7 +34,7 @@ export default { type: r.get('type') } }) - if(!dbResponse) return null + if (!dbResponse) return null const { report, submitter, resource, type } = dbResponse let response = { @@ -45,16 +45,16 @@ export default { submitter: submitter.properties, type } - switch(type){ - case "Post": - response.post = resource.properties - break; - case "Comment": - response.comment = resource.properties - break; - case "User": - response.user = resource.properties - break; + switch (type) { + case 'Post': + response.post = resource.properties + break + case 'Comment': + response.comment = resource.properties + break + case 'User': + response.user = resource.properties + break } return response } diff --git a/src/resolvers/reports.spec.js b/src/resolvers/reports.spec.js index 7e9a55d1e..ac45235ac 100644 --- a/src/resolvers/reports.spec.js +++ b/src/resolvers/reports.spec.js @@ -64,7 +64,7 @@ describe('report', () => { describe('valid resource id', () => { beforeEach(async () => { - variables = {id: 'u2'} + variables = { id: 'u2' } }) it('creates a report', async () => { @@ -98,8 +98,8 @@ describe('report', () => { describe('reported resource is a post', () => { beforeEach(async () => { - await factory.authenticateAs({email: 'test@example.org', password: '1234'}) - await factory.create('Post', {id: 'p23', title: 'Matt and Robert having a pair-programming' }) + await factory.authenticateAs({ email: 'test@example.org', password: '1234' }) + await factory.create('Post', { id: 'p23', title: 'Matt and Robert having a pair-programming' }) variables = { id: 'p23' } }) @@ -127,8 +127,8 @@ describe('report', () => { describe('reported resource is a comment', () => { beforeEach(async () => { - await factory.authenticateAs({email: 'test@example.org', password: '1234'}) - await factory.create('Comment', {id: 'c34', content: 'Robert getting tired.' }) + await factory.authenticateAs({ email: 'test@example.org', password: '1234' }) + await factory.create('Comment', { id: 'c34', content: 'Robert getting tired.' }) variables = { id: 'c34' } }) From 13d7f677e81cd4da5c4a5c9f35614b9aa1b31250 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 8 Mar 2019 04:23:50 +0000 Subject: [PATCH 496/554] Bump babel-jest from 24.1.0 to 24.3.1 Bumps [babel-jest](https://github.com/facebook/jest/tree/HEAD/packages/babel-jest) from 24.1.0 to 24.3.1. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/commits/v24.3.1/packages/babel-jest) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 261 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 246 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index a0f745bf7..a182fb2b7 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "apollo-server-testing": "~2.4.8", "babel-core": "~7.0.0-0", "babel-eslint": "~10.0.1", - "babel-jest": "~24.1.0", + "babel-jest": "~24.3.1", "chai": "~4.2.0", "eslint": "~5.15.1", "eslint-config-standard": "~12.0.0", diff --git a/yarn.lock b/yarn.lock index 215a608ab..1b0ec799d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -299,7 +299,7 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.3.tgz#092d450db02bdb6ccb1ca8ffd47d8774a91aef87" integrity sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg== -"@babel/parser@^7.3.4": +"@babel/parser@^7.1.0", "@babel/parser@^7.3.4": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.4.tgz#a43357e4bbf4b92a437fb9e465c192848287f27c" integrity sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ== @@ -721,7 +721,7 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" -"@babel/types@^7.3.4": +"@babel/types@^7.3.0", "@babel/types@^7.3.4": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.4.tgz#bf482eaeaffb367a28abbf9357a94963235d90ed" integrity sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ== @@ -730,6 +730,81 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" +"@cnakazawa/watch@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" + integrity sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + +"@jest/console@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.3.0.tgz#7bd920d250988ba0bf1352c4493a48e1cb97671e" + integrity sha512-NaCty/OOei6rSDcbPdMiCbYCI0KGFGPgGO6B09lwWt5QTxnkuhKYET9El5u5z1GAcSxkQmSMtM63e24YabCWqA== + dependencies: + "@jest/source-map" "^24.3.0" + "@types/node" "*" + chalk "^2.0.1" + slash "^2.0.0" + +"@jest/fake-timers@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.3.0.tgz#0a7f8b877b78780c3fa5c3f8683cc0aaf9488331" + integrity sha512-rHwVI17dGMHxHzfAhnZ04+wFznjFfZ246QugeBnbiYr7/bDosPD2P1qeNjWnJUUcfl0HpS6kkr+OB/mqSJxQFg== + dependencies: + "@jest/types" "^24.3.0" + "@types/node" "*" + jest-message-util "^24.3.0" + jest-mock "^24.3.0" + +"@jest/source-map@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28" + integrity sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.1.15" + source-map "^0.6.0" + +"@jest/test-result@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.3.0.tgz#4c0b1c9716212111920f7cf8c4329c69bc81924a" + integrity sha512-j7UZ49T8C4CVipEY99nLttnczVTtLyVzFfN20OiBVn7awOs0U3endXSTq7ouPrLR5y4YjI5GDcbcvDUjgeamzg== + dependencies: + "@jest/console" "^24.3.0" + "@jest/types" "^24.3.0" + "@types/istanbul-lib-coverage" "^1.1.0" + +"@jest/transform@^24.3.1": + version "24.3.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.3.1.tgz#ce9e1329eb5e640f493bcd5c8eb9970770959bfc" + integrity sha512-PpjylI5goT4Si69+qUjEeHuKjex0LjjrqJzrMYzlOZn/+SCumGKuGC0UQFeEPThyGsFvWH1Q4gj0R66eOHnIpw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^24.3.0" + babel-plugin-istanbul "^5.1.0" + chalk "^2.0.1" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.15" + jest-haste-map "^24.3.1" + jest-regex-util "^24.3.0" + jest-util "^24.3.0" + micromatch "^3.1.10" + realpath-native "^1.1.0" + slash "^2.0.0" + source-map "^0.6.1" + write-file-atomic "2.4.1" + +"@jest/types@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.3.0.tgz#3f6e117e47248a9a6b5f1357ec645bd364f7ad23" + integrity sha512-VoO1F5tU2n/93QN/zaZ7Q8SeV/Rj+9JJOgbvKbBwy4lenvmdj1iDaQEPXGTKrO6OSvDeb2drTFipZJYxgo6kIQ== + dependencies: + "@types/istanbul-lib-coverage" "^1.1.0" + "@types/yargs" "^12.0.9" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -790,6 +865,39 @@ dependencies: "@types/node" "*" +"@types/babel__core@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.0.tgz#710f2487dda4dcfd010ca6abb2b4dc7394365c51" + integrity sha512-wJTeJRt7BToFx3USrCDs2BhEi4ijBInTQjOIukj6a/5tEkwpFMVZ+1ppgmE+Q/FQyc5P/VWUbx7I9NELrKruHA== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.0.2.tgz#d2112a6b21fad600d7674274293c85dce0cb47fc" + integrity sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" + integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.6.tgz#328dd1a8fc4cfe3c8458be9477b219ea158fd7b2" + integrity sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw== + dependencies: + "@babel/types" "^7.3.0" + "@types/body-parser@*", "@types/body-parser@1.17.0": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" @@ -854,6 +962,11 @@ resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-14.0.3.tgz#389e2e5b83ecdb376d9f98fae2094297bc112c1c" integrity sha512-TcFkpEjcQK7w8OcrQcd7iIBPjU0rdyi3ldj6d0iJ4PPSzbWqPBvXj9KSwO14hTOX2dm9RoiH7VuxksJLNYdXUQ== +"@types/istanbul-lib-coverage@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz#2cc2ca41051498382b43157c8227fea60363f94a" + integrity sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ== + "@types/long@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" @@ -882,6 +995,11 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" +"@types/stack-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" + integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== + "@types/ws@^6.0.0": version "6.0.1" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28" @@ -890,6 +1008,11 @@ "@types/events" "*" "@types/node" "*" +"@types/yargs@^12.0.9": + version "12.0.9" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.9.tgz#693e76a52f61a2f1e7fb48c0eef167b95ea4ffd0" + integrity sha512-sCZy4SxP9rN2w30Hlmg5dtdRwgYQfYRiLo9usw8X9cxlf+H4FqM1xX7+sNH7NNKVdbXMJWqva7iyy+fxh/V7fA== + "@types/zen-observable@^0.5.3": version "0.5.4" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.4.tgz#b863a4191e525206819e008097ebf0fb2e3a1cdc" @@ -1494,13 +1617,16 @@ babel-eslint@~10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-jest@^24.1.0, babel-jest@~24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.1.0.tgz#441e23ef75ded3bd547e300ac3194cef87b55190" - integrity sha512-MLcagnVrO9ybQGLEfZUqnOzv36iQzU7Bj4elm39vCukumLVSfoX+tRy3/jW7lUKc7XdpRmB/jech6L/UCsSZjw== +babel-jest@^24.1.0, babel-jest@~24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.3.1.tgz#168468a37e90426520c5293da4f55e1a512063b0" + integrity sha512-6KaXyUevY0KAxD5Ba+EBhyfwvc+R2f7JV7BpBZ5T8yJGgj0M1hYDfRhDq35oD5MzprMf/ggT81nEuLtMyxfDIg== dependencies: + "@jest/transform" "^24.3.1" + "@jest/types" "^24.3.0" + "@types/babel__core" "^7.1.0" babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.1.0" + babel-preset-jest "^24.3.0" chalk "^2.4.2" slash "^2.0.0" @@ -1513,18 +1639,20 @@ babel-plugin-istanbul@^5.1.0: istanbul-lib-instrument "^3.0.0" test-exclude "^5.0.0" -babel-plugin-jest-hoist@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.1.0.tgz#dfecc491fb15e2668abbd690a697a8fd1411a7f8" - integrity sha512-gljYrZz8w1b6fJzKcsfKsipSru2DU2DmQ39aB6nV3xQ0DDv3zpIzKGortA5gknrhNnPN8DweaEgrnZdmbGmhnw== +babel-plugin-jest-hoist@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.3.0.tgz#f2e82952946f6e40bb0a75d266a3790d854c8b5b" + integrity sha512-nWh4N1mVH55Tzhx2isvUN5ebM5CDUvIpXPZYMRazQughie/EqGnbR+czzoQlhUmJG9pPJmYDRhvocotb2THl1w== + dependencies: + "@types/babel__traverse" "^7.0.6" -babel-preset-jest@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.1.0.tgz#83bc564fdcd4903641af65ec63f2f5de6b04132e" - integrity sha512-FfNLDxFWsNX9lUmtwY7NheGlANnagvxq8LZdl5PKnVG3umP+S/g0XbVBfwtA4Ai3Ri/IMkWabBz3Tyk9wdspcw== +babel-preset-jest@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.3.0.tgz#db88497e18869f15b24d9c0e547d8e0ab950796d" + integrity sha512-VGTV2QYBa/Kn3WCOKdfS31j9qomaXSgJqi65B6o05/1GsJyj9LVhSljM9ro4S+IBGj/ENhNBuH9bpqzztKAQSw== dependencies: "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.1.0" + babel-plugin-jest-hoist "^24.3.0" babel-runtime@^6.26.0: version "6.26.0" @@ -2695,6 +2823,11 @@ exec-sh@^0.2.0: dependencies: merge "^1.2.0" +exec-sh@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" + integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg== + execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -4124,6 +4257,21 @@ jest-haste-map@^24.0.0: micromatch "^3.1.10" sane "^3.0.0" +jest-haste-map@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.3.1.tgz#b4a66dbe1e6bc45afb9cd19c083bff81cdd535a1" + integrity sha512-OTMQle+astr1lWKi62Ccmk2YWn6OtUoU/8JpJdg8zdsnpFIry/k0S4sQ4nWocdM07PFdvqcthWc78CkCE6sXvA== + dependencies: + "@jest/types" "^24.3.0" + fb-watchman "^2.0.0" + graceful-fs "^4.1.15" + invariant "^2.2.4" + jest-serializer "^24.3.0" + jest-util "^24.3.0" + jest-worker "^24.3.1" + micromatch "^3.1.10" + sane "^4.0.3" + jest-jasmine2@^24.1.0: version "24.1.0" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.1.0.tgz#8377324b967037c440f0a549ee0bbd9912055db6" @@ -4170,16 +4318,42 @@ jest-message-util@^24.0.0: slash "^2.0.0" stack-utils "^1.0.1" +jest-message-util@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.3.0.tgz#e8f64b63ebc75b1a9c67ee35553752596e70d4a9" + integrity sha512-lXM0YgKYGqN5/eH1NGw4Ix+Pk2I9Y77beyRas7xM24n+XTTK3TbT0VkT3L/qiyS7WkW0YwyxoXnnAaGw4hsEDA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" + "@types/stack-utils" "^1.0.1" + chalk "^2.0.1" + micromatch "^3.1.10" + slash "^2.0.0" + stack-utils "^1.0.1" + jest-mock@^24.0.0: version "24.0.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.0.0.tgz#9a4b53e01d66a0e780f7d857462d063e024c617d" integrity sha512-sQp0Hu5fcf5NZEh1U9eIW2qD0BwJZjb63Yqd98PQJFvf/zzUTBoUAwv/Dc/HFeNHIw1f3hl/48vNn+j3STaI7A== +jest-mock@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.3.0.tgz#95a86b6ad474e3e33227e6dd7c4ff6b07e18d3cb" + integrity sha512-AhAo0qjbVWWGvcbW5nChFjR0ObQImvGtU6DodprNziDOt+pP0CBdht/sYcNIOXeim8083QUi9bC8QdKB8PTK4Q== + dependencies: + "@jest/types" "^24.3.0" + jest-regex-util@^24.0.0: version "24.0.0" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.0.0.tgz#4feee8ec4a358f5bee0a654e94eb26163cb9089a" integrity sha512-Jv/uOTCuC+PY7WpJl2mpoI+WbY2ut73qwwO9ByJJNwOCwr1qWhEW2Lyi2S9ZewUdJqeVpEBisdEVZSI+Zxo58Q== +jest-regex-util@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36" + integrity sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg== + jest-resolve-dependencies@^24.1.0: version "24.1.0" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.1.0.tgz#78f738a2ec59ff4d00751d9da56f176e3f589f6c" @@ -4250,6 +4424,11 @@ jest-serializer@^24.0.0: resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0.tgz#522c44a332cdd194d8c0531eb06a1ee5afb4256b" integrity sha512-9FKxQyrFgHtx3ozU+1a8v938ILBE7S8Ko3uiAVjT8Yfi2o91j/fj81jacCQZ/Ihjiff/VsUCXVgQ+iF1XdImOw== +jest-serializer@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.3.0.tgz#074e307300d1451617cf2630d11543ee4f74a1c8" + integrity sha512-RiSpqo2OFbVLJN/PgAOwQIUeHDfss6NBUDTLhjiJM8Bb5rMrwRqHfkaqahIsOf9cXXB5UjcqDCzbQ7AIoMqWkg== + jest-snapshot@^24.1.0: version "24.1.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.1.0.tgz#85e22f810357aa5994ab61f236617dc2205f2f5b" @@ -4280,6 +4459,25 @@ jest-util@^24.0.0: slash "^2.0.0" source-map "^0.6.0" +jest-util@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.3.0.tgz#a549ae9910fedbd4c5912b204bb1bcc122ea0057" + integrity sha512-eKIAC+MTKWZthUUVOwZ3Tc5a0cKMnxalQHr6qZ4kPzKn6k09sKvsmjCygqZ1SxVVfUKoa8Sfn6XDv9uTJ1iXTg== + dependencies: + "@jest/console" "^24.3.0" + "@jest/fake-timers" "^24.3.0" + "@jest/source-map" "^24.3.0" + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" + "@types/node" "*" + callsites "^3.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.15" + is-ci "^2.0.0" + mkdirp "^0.5.1" + slash "^2.0.0" + source-map "^0.6.0" + jest-validate@^24.0.0: version "24.0.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.0.0.tgz#aa8571a46983a6538328fef20406b4a496b6c020" @@ -4309,6 +4507,15 @@ jest-worker@^24.0.0: merge-stream "^1.0.1" supports-color "^6.1.0" +jest-worker@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.3.1.tgz#c1759dd2b1d5541b09a2e5e1bc3288de6c9d8632" + integrity sha512-ZCoAe/iGLzTJvWHrO8fyx3bmEQhpL16SILJmWHKe8joHhyF3z00psF1sCRT54DoHw5GJG0ZpUtGy+ylvwA4haA== + dependencies: + "@types/node" "*" + merge-stream "^1.0.1" + supports-color "^6.1.0" + jest@~24.1.0: version "24.1.0" resolved "https://registry.yarnpkg.com/jest/-/jest-24.1.0.tgz#b1e1135caefcf2397950ecf7f90e395fde866fd2" @@ -5818,6 +6025,13 @@ realpath-native@^1.0.0, realpath-native@^1.0.2: dependencies: util.promisify "^1.0.0" +realpath-native@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" + integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== + dependencies: + util.promisify "^1.0.0" + regenerate-unicode-properties@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" @@ -6099,6 +6313,21 @@ sane@^3.0.0: optionalDependencies: fsevents "^1.2.3" +sane@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.0.3.tgz#e878c3f19e25cc57fbb734602f48f8a97818b181" + integrity sha512-hSLkC+cPHiBQs7LSyXkotC3UUtyn8C4FMn50TNaacRyvBlI+3ebcxMpqckmTdtXVtel87YS7GXN3UIOj7NiGVQ== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^1.2.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + sanitize-html@~1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.20.0.tgz#9a602beb1c9faf960fb31f9890f61911cc4d9156" From dfc28acfe5ac854ac9dfe14c4601a025a0bc931d Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 8 Mar 2019 11:56:15 +0100 Subject: [PATCH 497/554] Do nodemon restart on .js and .graphql files --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a182fb2b7..f18eed87a 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "scripts": { "build": "babel src/ -d dist/ --copy-files", "start": "node dist/", - "dev": "nodemon --exec babel-node src/", - "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", + "dev": "nodemon --exec babel-node src/ -e js,graphql", + "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js -e js,graphql", "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", "test:cypress": "run-p --race test:before:*", From c8ba2f6558956464f7eb8b278e2933830d0e2f21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 8 Mar 2019 10:59:31 +0000 Subject: [PATCH 498/554] Bump jest from 24.1.0 to 24.3.1 Bumps [jest](https://github.com/facebook/jest) from 24.1.0 to 24.3.1. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/compare/v24.1.0...v24.3.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 612 ++++++++++++++++++++++++--------------------------- 2 files changed, 294 insertions(+), 320 deletions(-) diff --git a/package.json b/package.json index f18eed87a..671e3406b 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", "graphql-request": "~1.8.2", - "jest": "~24.1.0", + "jest": "~24.3.1", "nodemon": "~1.18.10", "nyc": "~13.3.0", "supertest": "~3.4.2" diff --git a/yarn.lock b/yarn.lock index 1b0ec799d..3ee900990 100644 --- a/yarn.lock +++ b/yarn.lock @@ -748,6 +748,50 @@ chalk "^2.0.1" slash "^2.0.0" +"@jest/core@^24.3.1": + version "24.3.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.3.1.tgz#9811596d9fcc6dbb3d4062c67e4c4867bc061585" + integrity sha512-orucOIBKfXgm1IJirtPT0ToprqDVGYKUNJKNc9a6v1Lww6qLPq+xj5OfxyhpJb2rWOgzEkATW1bfZzg3oqV70w== + dependencies: + "@jest/console" "^24.3.0" + "@jest/reporters" "^24.3.1" + "@jest/test-result" "^24.3.0" + "@jest/transform" "^24.3.1" + "@jest/types" "^24.3.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-changed-files "^24.3.0" + jest-config "^24.3.1" + jest-haste-map "^24.3.1" + jest-message-util "^24.3.0" + jest-regex-util "^24.3.0" + jest-resolve-dependencies "^24.3.1" + jest-runner "^24.3.1" + jest-runtime "^24.3.1" + jest-snapshot "^24.3.1" + jest-util "^24.3.0" + jest-validate "^24.3.1" + jest-watcher "^24.3.0" + micromatch "^3.1.10" + p-each-series "^1.0.0" + pirates "^4.0.1" + realpath-native "^1.1.0" + rimraf "^2.5.4" + strip-ansi "^5.0.0" + +"@jest/environment@^24.3.1": + version "24.3.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.3.1.tgz#1fbda3ec8fb8ffbaee665d314da91d662227e11e" + integrity sha512-M8bqEkQqPwZVhMMFMqqCnzqIZtuM5vDMfFQ9ZvnEfRT+2T1zTA4UAOH/V4HagEi6S3BCd/mdxFdYmPgXf7GKCA== + dependencies: + "@jest/fake-timers" "^24.3.0" + "@jest/transform" "^24.3.1" + "@jest/types" "^24.3.0" + "@types/node" "*" + jest-mock "^24.3.0" + "@jest/fake-timers@^24.3.0": version "24.3.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.3.0.tgz#0a7f8b877b78780c3fa5c3f8683cc0aaf9488331" @@ -758,6 +802,32 @@ jest-message-util "^24.3.0" jest-mock "^24.3.0" +"@jest/reporters@^24.3.1": + version "24.3.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.3.1.tgz#68e4abc8d4233acd0dd87287f3bd270d81066248" + integrity sha512-jEIDJcvk20ReUW1Iqb+prlAcFV+kfFhQ/01poCq8X9As7/l/2y1GqVwJ3+6SaPTZuCXh0d0LVDy86zDAa8zlVA== + dependencies: + "@jest/environment" "^24.3.1" + "@jest/test-result" "^24.3.0" + "@jest/transform" "^24.3.1" + "@jest/types" "^24.3.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + istanbul-api "^2.1.1" + istanbul-lib-coverage "^2.0.2" + istanbul-lib-instrument "^3.0.1" + istanbul-lib-source-maps "^3.0.1" + jest-haste-map "^24.3.1" + jest-resolve "^24.3.1" + jest-runtime "^24.3.1" + jest-util "^24.3.0" + jest-worker "^24.3.1" + node-notifier "^5.2.1" + slash "^2.0.0" + source-map "^0.6.0" + string-length "^2.0.0" + "@jest/source-map@^24.3.0": version "24.3.0" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28" @@ -1008,7 +1078,7 @@ "@types/events" "*" "@types/node" "*" -"@types/yargs@^12.0.9": +"@types/yargs@^12.0.2", "@types/yargs@^12.0.9": version "12.0.9" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.9.tgz#693e76a52f61a2f1e7fb48c0eef167b95ea4ffd0" integrity sha512-sCZy4SxP9rN2w30Hlmg5dtdRwgYQfYRiLo9usw8X9cxlf+H4FqM1xX7+sNH7NNKVdbXMJWqva7iyy+fxh/V7fA== @@ -1617,7 +1687,7 @@ babel-eslint@~10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-jest@^24.1.0, babel-jest@~24.3.1: +babel-jest@^24.3.1, babel-jest@~24.3.1: version "24.3.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.3.1.tgz#168468a37e90426520c5293da4f55e1a512063b0" integrity sha512-6KaXyUevY0KAxD5Ba+EBhyfwvc+R2f7JV7BpBZ5T8yJGgj0M1hYDfRhDq35oD5MzprMf/ggT81nEuLtMyxfDIg== @@ -2415,10 +2485,10 @@ dicer@0.2.5: readable-stream "1.1.x" streamsearch "0.1.2" -diff-sequences@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.0.0.tgz#cdf8e27ed20d8b8d3caccb4e0c0d8fe31a173013" - integrity sha512-46OkIuVGBBnrC0soO/4LHu5LHGHx0uhP65OVz8XOrAJpqiCB2aVIuESvjI1F9oqebuvY8lekS1pt6TN7vt7qsw== +diff-sequences@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975" + integrity sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw== doctrine@1.5.0: version "1.5.0" @@ -2816,13 +2886,6 @@ events@1.1.1: resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= -exec-sh@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" - integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== - dependencies: - merge "^1.2.0" - exec-sh@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" @@ -2872,16 +2935,17 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.1.0.tgz#88e73301c4c785cde5f16da130ab407bdaf8c0f2" - integrity sha512-lVcAPhaYkQcIyMS+F8RVwzbm1jro20IG8OkvxQ6f1JfqhVZyyudCwYogQ7wnktlf14iF3ii7ArIUO/mqvrW9Gw== +expect@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.3.1.tgz#7c42507da231a91a8099d065bc8dc9322dc85fc0" + integrity sha512-xnmobSlaqhg4FKqjb5REk4AobQzFMJoctDdREKfSGqrtzRfCWYbfqt3WmikAvQz/J8mCNQhORgYdEjPMJbMQPQ== dependencies: + "@jest/types" "^24.3.0" ansi-styles "^3.2.0" - jest-get-type "^24.0.0" - jest-matcher-utils "^24.0.0" - jest-message-util "^24.0.0" - jest-regex-util "^24.0.0" + jest-get-type "^24.3.0" + jest-matcher-utils "^24.3.1" + jest-message-util "^24.3.0" + jest-regex-util "^24.3.0" express@^4.0.0, express@^4.16.3: version "4.16.4" @@ -3166,14 +3230,6 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== - dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" - fsevents@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" @@ -4045,10 +4101,10 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-api@^2.0.8: - version "2.1.0" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.0.tgz#37ab0c2c3e83065462f5254b94749d6157846c4e" - integrity sha512-+Ygg4t1StoiNlBGc6x0f8q/Bv26FbZqP/+jegzfNpU7Q8o+4ZRoJxJPhBkgE/UonpAjtxnE4zCZIyJX+MwLRMQ== +istanbul-api@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.1.tgz#194b773f6d9cbc99a9258446848b0f988951c4d0" + integrity sha512-kVmYrehiwyeBAk/wE71tW6emzLiHGjYIiDrc8sfyty4F8M02/lrgXSm+R1kXysmF20zArvmZXjlE/mg24TVPJw== dependencies: async "^2.6.1" compare-versions "^3.2.1" @@ -4058,7 +4114,7 @@ istanbul-api@^2.0.8: istanbul-lib-instrument "^3.1.0" istanbul-lib-report "^2.0.4" istanbul-lib-source-maps "^3.0.2" - istanbul-reports "^2.1.0" + istanbul-reports "^2.1.1" js-yaml "^3.12.0" make-dir "^1.3.0" minimatch "^3.0.4" @@ -4109,7 +4165,7 @@ istanbul-lib-source-maps@^3.0.1, istanbul-lib-source-maps@^3.0.2: rimraf "^2.6.2" source-map "^0.6.1" -istanbul-reports@^2.1.0, istanbul-reports@^2.1.1: +istanbul-reports@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.1.1.tgz#72ef16b4ecb9a4a7bd0e2001e00f95d1eec8afa9" integrity sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw== @@ -4121,141 +4177,111 @@ iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2: resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== -jest-changed-files@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.0.0.tgz#c02c09a8cc9ca93f513166bc773741bd39898ff7" - integrity sha512-nnuU510R9U+UX0WNb5XFEcsrMqriSiRLeO9KWDFgPrpToaQm60prfQYpxsXigdClpvNot5bekDY440x9dNGnsQ== +jest-changed-files@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.3.0.tgz#7050ae29aaf1d59437c80f21d5b3cd354e88a499" + integrity sha512-fTq0YAUR6644fgsqLC7Zi2gXA/bAplMRvfXQdutmkwgrCKK6upkj+sgXqsUfUZRm15CVr3YSojr/GRNn71IMvg== dependencies: + "@jest/types" "^24.3.0" execa "^1.0.0" throat "^4.0.0" -jest-cli@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.1.0.tgz#f7cc98995f36e7210cce3cbb12974cbf60940843" - integrity sha512-U/iyWPwOI0T1CIxVLtk/2uviOTJ/OiSWJSe8qt6X1VkbbgP+nrtLJlmT9lPBe4lK78VNFJtrJ7pttcNv/s7yCw== +jest-cli@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.3.1.tgz#52e4ae5f11044b41e06ca39fc7a7302fbbcb1661" + integrity sha512-HdwMgigvDQdlWX7gwM2QMkJJRqSk7tTYKq7kVplblK28RarqquJMWV/lOCN8CukuG9u3DZTeXpCDXR7kpGfB3w== dependencies: - ansi-escapes "^3.0.0" + "@jest/core" "^24.3.1" + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" chalk "^2.0.1" exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.1.15" import-local "^2.0.0" is-ci "^2.0.0" - istanbul-api "^2.0.8" - istanbul-lib-coverage "^2.0.2" - istanbul-lib-instrument "^3.0.1" - istanbul-lib-source-maps "^3.0.1" - jest-changed-files "^24.0.0" - jest-config "^24.1.0" - jest-environment-jsdom "^24.0.0" - jest-get-type "^24.0.0" - jest-haste-map "^24.0.0" - jest-message-util "^24.0.0" - jest-regex-util "^24.0.0" - jest-resolve-dependencies "^24.1.0" - jest-runner "^24.1.0" - jest-runtime "^24.1.0" - jest-snapshot "^24.1.0" - jest-util "^24.0.0" - jest-validate "^24.0.0" - jest-watcher "^24.0.0" - jest-worker "^24.0.0" - micromatch "^3.1.10" - node-notifier "^5.2.1" - p-each-series "^1.0.0" - pirates "^4.0.0" + jest-config "^24.3.1" + jest-util "^24.3.0" + jest-validate "^24.3.1" prompts "^2.0.1" - realpath-native "^1.0.0" - rimraf "^2.5.4" - slash "^2.0.0" - string-length "^2.0.0" - strip-ansi "^5.0.0" - which "^1.2.12" + realpath-native "^1.1.0" yargs "^12.0.2" -jest-config@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.1.0.tgz#6ea6881cfdd299bc86cc144ee36d937c97c3850c" - integrity sha512-FbbRzRqtFC6eGjG5VwsbW4E5dW3zqJKLWYiZWhB0/4E5fgsMw8GODLbGSrY5t17kKOtCWb/Z7nsIThRoDpuVyg== +jest-config@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.3.1.tgz#271aff2d3aeabf1ff92512024eeca3323cd31a07" + integrity sha512-ujHQywsM//vKFvJwEC02KNZgKAGOzGz1bFPezmTQtuj8XdfsAVq8p6N/dw4yodXV11gSf6TJ075i4ehM+mKatA== dependencies: "@babel/core" "^7.1.0" - babel-jest "^24.1.0" + "@jest/types" "^24.3.0" + babel-jest "^24.3.1" chalk "^2.0.1" glob "^7.1.1" - jest-environment-jsdom "^24.0.0" - jest-environment-node "^24.0.0" - jest-get-type "^24.0.0" - jest-jasmine2 "^24.1.0" - jest-regex-util "^24.0.0" - jest-resolve "^24.1.0" - jest-util "^24.0.0" - jest-validate "^24.0.0" + jest-environment-jsdom "^24.3.1" + jest-environment-node "^24.3.1" + jest-get-type "^24.3.0" + jest-jasmine2 "^24.3.1" + jest-regex-util "^24.3.0" + jest-resolve "^24.3.1" + jest-util "^24.3.0" + jest-validate "^24.3.1" micromatch "^3.1.10" - pretty-format "^24.0.0" - realpath-native "^1.0.2" + pretty-format "^24.3.1" + realpath-native "^1.1.0" -jest-diff@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.0.0.tgz#a3e5f573dbac482f7d9513ac9cfa21644d3d6b34" - integrity sha512-XY5wMpRaTsuMoU+1/B2zQSKQ9RdE9gsLkGydx3nvApeyPijLA8GtEvIcPwISRCer+VDf9W1mStTYYq6fPt8ryA== +jest-diff@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.3.1.tgz#87952e5ea1548567da91df398fa7bf7977d3f96a" + integrity sha512-YRVzDguyzShP3Pb9wP/ykBkV7Z+O4wltrMZ2P4LBtNxrHNpxwI2DECrpD9XevxWubRy5jcE8sSkxyX3bS7W+rA== dependencies: chalk "^2.0.1" - diff-sequences "^24.0.0" - jest-get-type "^24.0.0" - pretty-format "^24.0.0" + diff-sequences "^24.3.0" + jest-get-type "^24.3.0" + pretty-format "^24.3.1" -jest-docblock@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.0.0.tgz#54d77a188743e37f62181a91a01eb9222289f94e" - integrity sha512-KfAKZ4SN7CFOZpWg4i7g7MSlY0M+mq7K0aMqENaG2vHuhC9fc3vkpU/iNN9sOus7v3h3Y48uEjqz3+Gdn2iptA== +jest-docblock@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.3.0.tgz#b9c32dac70f72e4464520d2ba4aec02ab14db5dd" + integrity sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg== dependencies: detect-newline "^2.1.0" -jest-each@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.0.0.tgz#10987a06b21c7ffbfb7706c89d24c52ed864be55" - integrity sha512-gFcbY4Cu55yxExXMkjrnLXov3bWO3dbPAW7HXb31h/DNWdNc/6X8MtxGff8nh3/MjkF9DpVqnj0KsPKuPK0cpA== +jest-each@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.3.1.tgz#ed8fe8b9f92a835a6625ca8c7ee06bc904440316" + integrity sha512-GTi+nxDaWwSgOPLiiqb/p4LURy0mv3usoqsA2eoTYSmRsLgjgZ6VUyRpUBH5JY9EMBx33suNFXk0iyUm29WRpw== dependencies: + "@jest/types" "^24.3.0" chalk "^2.0.1" - jest-get-type "^24.0.0" - jest-util "^24.0.0" - pretty-format "^24.0.0" + jest-get-type "^24.3.0" + jest-util "^24.3.0" + pretty-format "^24.3.1" -jest-environment-jsdom@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.0.0.tgz#5affa0654d6e44cd798003daa1a8701dbd6e4d11" - integrity sha512-1YNp7xtxajTRaxbylDc2pWvFnfDTH5BJJGyVzyGAKNt/lEULohwEV9zFqTgG4bXRcq7xzdd+sGFws+LxThXXOw== +jest-environment-jsdom@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.3.1.tgz#49826bcf12fb3e38895f1e2aaeb52bde603cc2e4" + integrity sha512-rz2OSYJiQerDqWDwjisqRwhVNpwkqFXdtyMzEuJ47Ip9NRpRQ+qy7/+zFujPUy/Z+zjWRO5seHLB/dOD4VpEVg== dependencies: - jest-mock "^24.0.0" - jest-util "^24.0.0" + "@jest/environment" "^24.3.1" + "@jest/fake-timers" "^24.3.0" + "@jest/types" "^24.3.0" + jest-mock "^24.3.0" + jest-util "^24.3.0" jsdom "^11.5.1" -jest-environment-node@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.0.0.tgz#330948980656ed8773ce2e04eb597ed91e3c7190" - integrity sha512-62fOFcaEdU0VLaq8JL90TqwI7hLn0cOKOl8vY2n477vRkCJRojiRRtJVRzzCcgFvs6gqU97DNqX5R0BrBP6Rxg== +jest-environment-node@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.3.1.tgz#333d864c569b27658a96bb3b10e02e7172125415" + integrity sha512-Xy+/yFem/yUs9OkzbcawQT237vwDjBhAVLjac1KYAMYVjGb0Vb/Ovw4g61PunVdrEIpfcXNtRUltM4+9c7lARQ== dependencies: - jest-mock "^24.0.0" - jest-util "^24.0.0" + "@jest/environment" "^24.3.1" + "@jest/fake-timers" "^24.3.0" + "@jest/types" "^24.3.0" + jest-mock "^24.3.0" + jest-util "^24.3.0" -jest-get-type@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.0.0.tgz#36e72930b78e33da59a4f63d44d332188278940b" - integrity sha512-z6/Eyf6s9ZDGz7eOvl+fzpuJmN9i0KyTt1no37/dHu8galssxz5ZEgnc1KaV8R31q1khxyhB4ui/X5ZjjPk77w== - -jest-haste-map@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0.tgz#e9ef51b2c9257384b4d6beb83bd48c65b37b5e6e" - integrity sha512-CcViJyUo41IQqttLxXVdI41YErkzBKbE6cS6dRAploCeutePYfUimWd3C9rQEWhX0YBOQzvNsC0O9nYxK2nnxQ== - dependencies: - fb-watchman "^2.0.0" - graceful-fs "^4.1.15" - invariant "^2.2.4" - jest-serializer "^24.0.0" - jest-util "^24.0.0" - jest-worker "^24.0.0" - micromatch "^3.1.10" - sane "^3.0.0" +jest-get-type@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.3.0.tgz#582cfd1a4f91b5cdad1d43d2932f816d543c65da" + integrity sha512-HYF6pry72YUlVcvUx3sEpMRwXEWGEPlJ0bSPVnB3b3n++j4phUEoSPcS6GC0pPJ9rpyPSe4cb5muFo6D39cXow== jest-haste-map@^24.3.1: version "24.3.1" @@ -4272,51 +4298,44 @@ jest-haste-map@^24.3.1: micromatch "^3.1.10" sane "^4.0.3" -jest-jasmine2@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.1.0.tgz#8377324b967037c440f0a549ee0bbd9912055db6" - integrity sha512-H+o76SdSNyCh9fM5K8upK45YTo/DiFx5w2YAzblQebSQmukDcoVBVeXynyr7DDnxh+0NTHYRCLwJVf3tC518wg== +jest-jasmine2@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.3.1.tgz#127d628d3ac0829bd3c0fccacb87193e543b420b" + integrity sha512-STo6ar1IyPlIPq9jPxDQhM7lC0dAX7KKN0LmCLMlgJeXwX+1XiVdtZDv1a4zyg6qhNdpo1arOBGY0BcovUK7ug== dependencies: "@babel/traverse" "^7.1.0" + "@jest/environment" "^24.3.1" + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" chalk "^2.0.1" co "^4.6.0" - expect "^24.1.0" + expect "^24.3.1" is-generator-fn "^2.0.0" - jest-each "^24.0.0" - jest-matcher-utils "^24.0.0" - jest-message-util "^24.0.0" - jest-snapshot "^24.1.0" - jest-util "^24.0.0" - pretty-format "^24.0.0" + jest-each "^24.3.1" + jest-matcher-utils "^24.3.1" + jest-message-util "^24.3.0" + jest-runtime "^24.3.1" + jest-snapshot "^24.3.1" + jest-util "^24.3.0" + pretty-format "^24.3.1" throat "^4.0.0" -jest-leak-detector@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.0.0.tgz#78280119fd05ee98317daee62cddb3aa537a31c6" - integrity sha512-ZYHJYFeibxfsDSKowjDP332pStuiFT2xfc5R67Rjm/l+HFJWJgNIOCOlQGeXLCtyUn3A23+VVDdiCcnB6dTTrg== +jest-leak-detector@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.3.1.tgz#ed89d05ca07e91b2b51dac1f676ab354663aa8da" + integrity sha512-GncRwEtAw/SohdSyY4bk2RE06Ac1dZrtQGZQ2j35hSuN4gAAAKSYMszJS2WDixsAEaFN+GHBHG+d8pjVGklKyw== dependencies: - pretty-format "^24.0.0" + pretty-format "^24.3.1" -jest-matcher-utils@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.0.0.tgz#fc9c41cfc49b2c3ec14e576f53d519c37729d579" - integrity sha512-LQTDmO+aWRz1Tf9HJg+HlPHhDh1E1c65kVwRFo5mwCVp5aQDzlkz4+vCvXhOKFjitV2f0kMdHxnODrXVoi+rlA== +jest-matcher-utils@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.3.1.tgz#025e1cd9c54a5fde68e74b12428775d06d123aa8" + integrity sha512-P5VIsUTJeI0FYvWVMwEHjxK1L83vEkDiKMV0XFPIrT2jzWaWPB2+dPCHkP2ID9z4eUKElaHqynZnJiOdNVHfXQ== dependencies: chalk "^2.0.1" - jest-diff "^24.0.0" - jest-get-type "^24.0.0" - pretty-format "^24.0.0" - -jest-message-util@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.0.0.tgz#a07a141433b2c992dbaec68d4cbfe470ba289619" - integrity sha512-J9ROJIwz/IeC+eV1XSwnRK4oAwPuhmxEyYx1+K5UI+pIYwFZDSrfZaiWTdq0d2xYFw4Xiu+0KQWsdsQpgJMf3Q== - dependencies: - "@babel/code-frame" "^7.0.0" - chalk "^2.0.1" - micromatch "^3.1.10" - slash "^2.0.0" - stack-utils "^1.0.1" + jest-diff "^24.3.1" + jest-get-type "^24.3.0" + pretty-format "^24.3.1" jest-message-util@^24.3.0: version "24.3.0" @@ -4332,11 +4351,6 @@ jest-message-util@^24.3.0: slash "^2.0.0" stack-utils "^1.0.1" -jest-mock@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.0.0.tgz#9a4b53e01d66a0e780f7d857462d063e024c617d" - integrity sha512-sQp0Hu5fcf5NZEh1U9eIW2qD0BwJZjb63Yqd98PQJFvf/zzUTBoUAwv/Dc/HFeNHIw1f3hl/48vNn+j3STaI7A== - jest-mock@^24.3.0: version "24.3.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.3.0.tgz#95a86b6ad474e3e33227e6dd7c4ff6b07e18d3cb" @@ -4344,121 +4358,107 @@ jest-mock@^24.3.0: dependencies: "@jest/types" "^24.3.0" -jest-regex-util@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.0.0.tgz#4feee8ec4a358f5bee0a654e94eb26163cb9089a" - integrity sha512-Jv/uOTCuC+PY7WpJl2mpoI+WbY2ut73qwwO9ByJJNwOCwr1qWhEW2Lyi2S9ZewUdJqeVpEBisdEVZSI+Zxo58Q== - jest-regex-util@^24.3.0: version "24.3.0" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36" integrity sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg== -jest-resolve-dependencies@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.1.0.tgz#78f738a2ec59ff4d00751d9da56f176e3f589f6c" - integrity sha512-2VwPsjd3kRPu7qe2cpytAgowCObk5AKeizfXuuiwgm1a9sijJDZe8Kh1sFj6FKvSaNEfCPlBVkZEJa2482m/Uw== +jest-resolve-dependencies@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.3.1.tgz#a22839d611ba529a74594ee274ce2b77d046bea9" + integrity sha512-9JUejNImGnJjbNR/ttnod+zQIWANpsrYMPt18s2tYGK6rP191qFsyEQ2BhAQMdYDRkTmi8At+Co9tL+jTPqdpw== dependencies: - jest-regex-util "^24.0.0" - jest-snapshot "^24.1.0" + "@jest/types" "^24.3.0" + jest-regex-util "^24.3.0" + jest-snapshot "^24.3.1" -jest-resolve@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.1.0.tgz#42ff0169b0ea47bfdbd0c52a0067ca7d022c7688" - integrity sha512-TPiAIVp3TG6zAxH28u/6eogbwrvZjBMWroSLBDkwkHKrqxB/RIdwkWDye4uqPlZIXWIaHtifY3L0/eO5Z0f2wg== +jest-resolve@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.3.1.tgz#103dbd438b59618ea428ec4acbd65c56495ba397" + integrity sha512-N+Q3AcVuKxpn/kjQMxUVLwBk32ZE1diP4MPcHyjVwcKpCUuKrktfRR3Mqe/T2HoD25wyccstaqcPUKIudl41bg== dependencies: + "@jest/types" "^24.3.0" browser-resolve "^1.11.3" chalk "^2.0.1" - realpath-native "^1.0.0" + realpath-native "^1.1.0" -jest-runner@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.1.0.tgz#3686a2bb89ce62800da23d7fdc3da2c32792943b" - integrity sha512-CDGOkT3AIFl16BLL/OdbtYgYvbAprwJ+ExKuLZmGSCSldwsuU2dEGauqkpvd9nphVdAnJUcP12e/EIlnTX0QXg== +jest-runner@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.3.1.tgz#5488566fa60cdb4b00a89c734ad6b54b9561415d" + integrity sha512-Etc9hQ5ruwg+q7DChm+E8qzHHdNTLeUdlo+whPQRSpNSgl0AEgc2r2mT4lxODREqmnHg9A8JHA44pIG4GE0Gzg== dependencies: + "@jest/console" "^24.3.0" + "@jest/environment" "^24.3.1" + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" chalk "^2.4.2" exit "^0.1.2" graceful-fs "^4.1.15" - jest-config "^24.1.0" - jest-docblock "^24.0.0" - jest-haste-map "^24.0.0" - jest-jasmine2 "^24.1.0" - jest-leak-detector "^24.0.0" - jest-message-util "^24.0.0" - jest-runtime "^24.1.0" - jest-util "^24.0.0" - jest-worker "^24.0.0" + jest-config "^24.3.1" + jest-docblock "^24.3.0" + jest-haste-map "^24.3.1" + jest-jasmine2 "^24.3.1" + jest-leak-detector "^24.3.1" + jest-message-util "^24.3.0" + jest-resolve "^24.3.1" + jest-runtime "^24.3.1" + jest-util "^24.3.0" + jest-worker "^24.3.1" source-map-support "^0.5.6" throat "^4.0.0" -jest-runtime@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.1.0.tgz#7c157a2e776609e8cf552f956a5a19ec9c985214" - integrity sha512-59/BY6OCuTXxGeDhEMU7+N33dpMQyXq7MLK07cNSIY/QYt2QZgJ7Tjx+rykBI0skAoigFl0A5tmT8UdwX92YuQ== +jest-runtime@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.3.1.tgz#2798230b4fbed594b375a13e395278694d4751e2" + integrity sha512-Qz/tJWbZ2naFJ2Kvy1p+RhhRgsPYh4e6wddVRy6aHBr32FTt3Ja33bfV7pkMFWXFbVuAsJMJVdengbvdhWzq4A== dependencies: - "@babel/core" "^7.1.0" - babel-plugin-istanbul "^5.1.0" + "@jest/console" "^24.3.0" + "@jest/environment" "^24.3.1" + "@jest/source-map" "^24.3.0" + "@jest/transform" "^24.3.1" + "@jest/types" "^24.3.0" + "@types/yargs" "^12.0.2" chalk "^2.0.1" - convert-source-map "^1.4.0" exit "^0.1.2" - fast-json-stable-stringify "^2.0.0" glob "^7.1.3" graceful-fs "^4.1.15" - jest-config "^24.1.0" - jest-haste-map "^24.0.0" - jest-message-util "^24.0.0" - jest-regex-util "^24.0.0" - jest-resolve "^24.1.0" - jest-snapshot "^24.1.0" - jest-util "^24.0.0" - jest-validate "^24.0.0" - micromatch "^3.1.10" - realpath-native "^1.0.0" + jest-config "^24.3.1" + jest-haste-map "^24.3.1" + jest-message-util "^24.3.0" + jest-mock "^24.3.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.3.1" + jest-snapshot "^24.3.1" + jest-util "^24.3.0" + jest-validate "^24.3.1" + realpath-native "^1.1.0" slash "^2.0.0" strip-bom "^3.0.0" - write-file-atomic "2.4.1" yargs "^12.0.2" -jest-serializer@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0.tgz#522c44a332cdd194d8c0531eb06a1ee5afb4256b" - integrity sha512-9FKxQyrFgHtx3ozU+1a8v938ILBE7S8Ko3uiAVjT8Yfi2o91j/fj81jacCQZ/Ihjiff/VsUCXVgQ+iF1XdImOw== - jest-serializer@^24.3.0: version "24.3.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.3.0.tgz#074e307300d1451617cf2630d11543ee4f74a1c8" integrity sha512-RiSpqo2OFbVLJN/PgAOwQIUeHDfss6NBUDTLhjiJM8Bb5rMrwRqHfkaqahIsOf9cXXB5UjcqDCzbQ7AIoMqWkg== -jest-snapshot@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.1.0.tgz#85e22f810357aa5994ab61f236617dc2205f2f5b" - integrity sha512-th6TDfFqEmXvuViacU1ikD7xFb7lQsPn2rJl7OEmnfIVpnrx3QNY2t3PE88meeg0u/mQ0nkyvmC05PBqO4USFA== +jest-snapshot@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.3.1.tgz#0f22a86c1b8c87e823f5ad095e82c19d9ed93d72" + integrity sha512-7wbNJWh0sBjmoaexTOWqS7nleTQME7o2W9XKU6CHCxG49Thjct4aVPC/QPNF5NHnvf4M/VDmudIDbwz6noJTRA== dependencies: "@babel/types" "^7.0.0" + "@jest/types" "^24.3.0" chalk "^2.0.1" - jest-diff "^24.0.0" - jest-matcher-utils "^24.0.0" - jest-message-util "^24.0.0" - jest-resolve "^24.1.0" + expect "^24.3.1" + jest-diff "^24.3.1" + jest-matcher-utils "^24.3.1" + jest-message-util "^24.3.0" + jest-resolve "^24.3.1" mkdirp "^0.5.1" natural-compare "^1.4.0" - pretty-format "^24.0.0" + pretty-format "^24.3.1" semver "^5.5.0" -jest-util@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.0.0.tgz#fd38fcafd6dedbd0af2944d7a227c0d91b68f7d6" - integrity sha512-QxsALc4wguYS7cfjdQSOr5HTkmjzkHgmZvIDkcmPfl1ib8PNV8QUWLwbKefCudWS0PRKioV+VbQ0oCUPC691fQ== - dependencies: - callsites "^3.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.15" - is-ci "^2.0.0" - jest-message-util "^24.0.0" - mkdirp "^0.5.1" - slash "^2.0.0" - source-map "^0.6.0" - jest-util@^24.3.0: version "24.3.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.3.0.tgz#a549ae9910fedbd4c5912b204bb1bcc122ea0057" @@ -4478,35 +4478,32 @@ jest-util@^24.3.0: slash "^2.0.0" source-map "^0.6.0" -jest-validate@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.0.0.tgz#aa8571a46983a6538328fef20406b4a496b6c020" - integrity sha512-vMrKrTOP4BBFIeOWsjpsDgVXATxCspC9S1gqvbJ3Tnn/b9ACsJmteYeVx9830UMV28Cob1RX55x96Qq3Tfad4g== +jest-validate@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.3.1.tgz#9359eea5a767a3d20b4fa7a5764fd78330ba8312" + integrity sha512-ww3+IPNCOEMi1oKlrHdSnBXetXtdrrdSh0bqLNTVkWglduhORf94RJWd1ko9oEPU2TcEQS5QIPacYziQIUzc4A== dependencies: + "@jest/types" "^24.3.0" camelcase "^5.0.0" chalk "^2.0.1" - jest-get-type "^24.0.0" + jest-get-type "^24.3.0" leven "^2.1.0" - pretty-format "^24.0.0" + pretty-format "^24.3.1" -jest-watcher@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.0.0.tgz#20d44244d10b0b7312410aefd256c1c1eef68890" - integrity sha512-GxkW2QrZ4YxmW1GUWER05McjVDunBlKMFfExu+VsGmXJmpej1saTEKvONdx5RJBlVdpPI5x6E3+EDQSIGgl53g== +jest-watcher@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.3.0.tgz#ee51c6afbe4b35a12fcf1107556db6756d7b9290" + integrity sha512-EpJS/aUG8D3DMuy9XNA4fnkKWy3DQdoWhY92ZUdlETIeEn1xya4Np/96MBSh4II5YvxwKe6JKwbu3Bnzfwa7vA== dependencies: + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" + "@types/node" "*" + "@types/yargs" "^12.0.9" ansi-escapes "^3.0.0" chalk "^2.0.1" - jest-util "^24.0.0" + jest-util "^24.3.0" string-length "^2.0.0" -jest-worker@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0.tgz#3d3483b077bf04f412f47654a27bba7e947f8b6d" - integrity sha512-s64/OThpfQvoCeHG963MiEZOAAxu8kHsaL/rCMF7lpdzo7vgF0CtPml9hfguOMgykgH/eOm4jFP4ibfHLruytg== - dependencies: - merge-stream "^1.0.1" - supports-color "^6.1.0" - jest-worker@^24.3.1: version "24.3.1" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.3.1.tgz#c1759dd2b1d5541b09a2e5e1bc3288de6c9d8632" @@ -4516,13 +4513,13 @@ jest-worker@^24.3.1: merge-stream "^1.0.1" supports-color "^6.1.0" -jest@~24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.1.0.tgz#b1e1135caefcf2397950ecf7f90e395fde866fd2" - integrity sha512-+q91L65kypqklvlRFfXfdzUKyngQLOcwGhXQaLmVHv+d09LkNXuBuGxlofTFW42XMzu3giIcChchTsCNUjQ78A== +jest@~24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.3.1.tgz#81959de0d57b2df923510f4fafe266712d37dcca" + integrity sha512-SqZguEbYNcZ3r0KUUBN+IkKfyPS1VBbIUiK4Wrc0AiGUR52gJa0fmlWSOCL3x25908QrfoQwkVDu5jCsfXb2ig== dependencies: import-local "^2.0.0" - jest-cli "^24.1.0" + jest-cli "^24.3.1" jmespath@0.15.0: version "0.15.0" @@ -4976,11 +4973,6 @@ merge-stream@^1.0.1: dependencies: readable-stream "^2.0.1" -merge@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" - integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== - methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -5726,6 +5718,13 @@ pirates@^4.0.0: dependencies: node-modules-regexp "^1.0.0" +pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== + dependencies: + node-modules-regexp "^1.0.0" + pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -5769,13 +5768,15 @@ prepend-http@^1.0.1: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -pretty-format@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0.tgz#cb6599fd73ac088e37ed682f61291e4678f48591" - integrity sha512-LszZaKG665djUcqg5ZQq+XzezHLKrxsA86ZABTozp+oNhkdqa+tG2dX4qa6ERl5c/sRDrAa3lHmwnvKoP+OG/g== +pretty-format@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.3.1.tgz#ae4a98e93d73d86913a8a7dd1a7c3c900f8fda59" + integrity sha512-NZGH1NWS6o4i9pvRWLsxIK00JB9pqOUzVrO7yWT6vjI2thdxwvxefBJO6O5T24UAhI8P5dMceZ7x5wphgVI7Mg== dependencies: + "@jest/types" "^24.3.0" ansi-regex "^4.0.0" ansi-styles "^3.2.0" + react-is "^16.8.4" private@^0.1.6: version "0.1.8" @@ -5933,6 +5934,11 @@ react-dom@^16.4.2: prop-types "^15.6.2" scheduler "^0.11.2" +react-is@^16.8.4: + version "16.8.4" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.4.tgz#90f336a68c3a29a096a3d648ab80e87ec61482a2" + integrity sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA== + react@^16.4.2: version "16.6.3" resolved "https://registry.yarnpkg.com/react/-/react-16.6.3.tgz#25d77c91911d6bbdd23db41e70fb094cc1e0871c" @@ -6018,13 +6024,6 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -realpath-native@^1.0.0, realpath-native@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560" - integrity sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g== - dependencies: - util.promisify "^1.0.0" - realpath-native@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" @@ -6296,23 +6295,6 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sane@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-3.1.0.tgz#995193b7dc1445ef1fe41ddfca2faf9f111854c6" - integrity sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q== - dependencies: - anymatch "^2.0.0" - capture-exit "^1.2.0" - exec-sh "^0.2.0" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - watch "~0.18.0" - optionalDependencies: - fsevents "^1.2.3" - sane@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/sane/-/sane-4.0.3.tgz#e878c3f19e25cc57fbb734602f48f8a97818b181" @@ -7273,14 +7255,6 @@ walker@~1.0.5: dependencies: makeerror "1.0.x" -watch@~0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" - integrity sha1-KAlUdsbffJDJYxOJkMClQj60uYY= - dependencies: - exec-sh "^0.2.0" - minimist "^1.2.0" - webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -7326,7 +7300,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.12, which@^1.2.9, which@^1.3.0: +which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== From f86fc7507c1cf1f487f7ecce418076e153cf43de Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 8 Mar 2019 16:49:43 +0100 Subject: [PATCH 499/554] Fixed shout and follow seeding --- src/seed/factories/index.js | 26 ++++++++++++++++ src/seed/seed-db.js | 59 +++++++++++++++++++++++++++---------- 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 68dd99200..2629ce8b6 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -90,6 +90,32 @@ export default function Factory (options = {}) { this.lastResponse = await this.graphQLClient.request(mutation, variables) return this }, + async shout (properties) { + const { id, type } = properties + const mutation = ` + mutation { + shout( + id: "${id}", + type: ${type} + ) + } + ` + this.lastResponse = await this.graphQLClient.request(mutation) + return this + }, + async follow (properties) { + const { id, type } = properties + const mutation = ` + mutation { + follow( + id: "${id}", + type: ${type} + ) + } + ` + this.lastResponse = await this.graphQLClient.request(mutation) + return this + }, async cleanDatabase () { this.lastResponse = await cleanDatabase({ driver: this.neo4jDriver }) return this diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 310089ef7..51a456126 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -23,6 +23,15 @@ import Factory from './factories' f.create('User', { id: 'u7', name: 'Dagobert', role: 'user', email: 'dagobert@example.org' }) ]) + const [ asAdmin, asModerator, asUser, asTick, asTrick, asTrack ] = await Promise.all([ + Factory().authenticateAs({ email: 'admin@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'moderator@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'user@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'tick@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'trick@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'track@example.org', password: '1234' }) + ]) + await Promise.all([ f.relate('User', 'Badges', { from: 'b6', to: 'u1' }), f.relate('User', 'Badges', { from: 'b5', to: 'u2' }), @@ -30,12 +39,6 @@ import Factory from './factories' f.relate('User', 'Badges', { from: 'b3', to: 'u4' }), f.relate('User', 'Badges', { from: 'b2', to: 'u5' }), f.relate('User', 'Badges', { from: 'b1', to: 'u6' }), - f.relate('User', 'Following', { from: 'u1', to: 'u2' }), - f.relate('User', 'Following', { from: 'u2', to: 'u3' }), - f.relate('User', 'Following', { from: 'u3', to: 'u4' }), - f.relate('User', 'Following', { from: 'u4', to: 'u5' }), - f.relate('User', 'Following', { from: 'u5', to: 'u6' }), - f.relate('User', 'Following', { from: 'u6', to: 'u7' }), f.relate('User', 'Friends', { from: 'u1', to: 'u2' }), f.relate('User', 'Friends', { from: 'u1', to: 'u3' }), f.relate('User', 'Friends', { from: 'u2', to: 'u3' }), @@ -44,6 +47,21 @@ import Factory from './factories' f.relate('User', 'Blacklisted', { from: 'u7', to: 'u6' }) ]) + await Promise.all([ + asAdmin + .follow({ id: 'u3', type: 'User' }), + asModerator + .follow({ id: 'u4', type: 'User' }), + asUser + .follow({ id: 'u4', type: 'User' }), + asTick + .follow({ id: 'u6', type: 'User' }), + asTrick + .follow({ id: 'u4', type: 'User' }), + asTrack + .follow({ id: 'u3', type: 'User' }) + ]) + await Promise.all([ f.create('Category', { id: 'cat1', name: 'Just For Fun', slug: 'justforfun', icon: 'smile' }), f.create('Category', { id: 'cat2', name: 'Happyness & Values', slug: 'happyness-values', icon: 'heart-o' }), @@ -70,15 +88,6 @@ import Factory from './factories' f.create('Tag', { id: 't4', name: 'Freiheit' }) ]) - const [ asAdmin, asModerator, asUser, asTick, asTrick, asTrack ] = await Promise.all([ - Factory().authenticateAs({ email: 'admin@example.org', password: '1234' }), - Factory().authenticateAs({ email: 'moderator@example.org', password: '1234' }), - Factory().authenticateAs({ email: 'user@example.org', password: '1234' }), - Factory().authenticateAs({ email: 'tick@example.org', password: '1234' }), - Factory().authenticateAs({ email: 'trick@example.org', password: '1234' }), - Factory().authenticateAs({ email: 'track@example.org', password: '1234' }) - ]) - await Promise.all([ asAdmin.create('Post', { id: 'p0' }), asModerator.create('Post', { id: 'p1' }), @@ -151,6 +160,26 @@ import Factory from './factories' f.relate('User', 'Shouted', { from: 'u3', to: 'p4' }), f.relate('User', 'Shouted', { from: 'u4', to: 'p1' }) ]) + await Promise.all([ + asAdmin + .shout({ id: 'p2', type: 'Post' }), + asAdmin + .shout({ id: 'p6', type: 'Post' }), + asModerator + .shout({ id: 'p0', type: 'Post' }), + asModerator + .shout({ id: 'p6', type: 'Post' }), + asUser + .shout({ id: 'p6', type: 'Post' }), + asUser + .shout({ id: 'p7', type: 'Post' }), + asTick + .shout({ id: 'p8', type: 'Post' }), + asTick + .shout({ id: 'p9', type: 'Post' }), + asTrack + .shout({ id: 'p10', type: 'Post' }) + ]) await Promise.all([ f.create('Comment', { id: 'c1' }), From 9260705611a7b20717a53b6f4e4bca7c537345e8 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 8 Mar 2019 17:03:59 +0100 Subject: [PATCH 500/554] Fixed shout seeding --- src/seed/seed-db.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 51a456126..b16e9f323 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -152,14 +152,7 @@ import Factory from './factories' f.relate('Post', 'Tags', { from: 'p14', to: 't2' }), f.relate('Post', 'Tags', { from: 'p15', to: 't3' }) ]) - await Promise.all([ - f.relate('User', 'Shouted', { from: 'u1', to: 'p2' }), - f.relate('User', 'Shouted', { from: 'u1', to: 'p3' }), - f.relate('User', 'Shouted', { from: 'u2', to: 'p1' }), - f.relate('User', 'Shouted', { from: 'u3', to: 'p1' }), - f.relate('User', 'Shouted', { from: 'u3', to: 'p4' }), - f.relate('User', 'Shouted', { from: 'u4', to: 'p1' }) - ]) + await Promise.all([ asAdmin .shout({ id: 'p2', type: 'Post' }), From f792ad3c026fee3159a1d4cba35bb80595763bbe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 8 Mar 2019 17:17:57 +0000 Subject: [PATCH 501/554] Bump neo4j-driver from 1.7.2 to 1.7.3 Bumps [neo4j-driver](https://github.com/neo4j/neo4j-javascript-driver) from 1.7.2 to 1.7.3. - [Release notes](https://github.com/neo4j/neo4j-javascript-driver/releases) - [Commits](https://github.com/neo4j/neo4j-javascript-driver/compare/1.7.2...1.7.3) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 24580fd3b..166ba7fce 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "linkifyjs": "~2.1.8", "lodash": "~4.17.11", "ms": "~2.1.1", - "neo4j-driver": "~1.7.2", + "neo4j-driver": "~1.7.3", "neo4j-graphql-js": "~2.4.1", "node-fetch": "~2.3.0", "npm-run-all": "~4.1.5", diff --git a/yarn.lock b/yarn.lock index bcb5fce76..38e52cad9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5171,10 +5171,10 @@ negotiator@0.6.1: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= -neo4j-driver@^1.7.2, neo4j-driver@~1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.2.tgz#c72a6dfa6bd2106b00a42794dc52a82b227b48e0" - integrity sha512-0IvCFYhcP9hb5JveZk33epbReDKpFTn2u5vAa8zzGG344i6yFqZrBo0mtC114ciP9zFjAtfNOP72mRm8+NV0Fg== +neo4j-driver@^1.7.2, neo4j-driver@~1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.3.tgz#1c1108ab26b7243975f1b20045daf31d8f685207" + integrity sha512-UCNOFiQdouq14PvZGTr+psy657BJsBpO6O2cJpP+NprZnEF4APrDzAcydPZSFxE1nfooLNc50vfuZ0q54UyY2Q== dependencies: babel-runtime "^6.26.0" text-encoding "^0.6.4" From eb5c561675702280ff1c9cb67fd310b4010c5723 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 8 Mar 2019 17:44:58 +0000 Subject: [PATCH 502/554] Bump neo4j-graphql-js from 2.3.1 to 2.4.2 Bumps [neo4j-graphql-js](https://github.com/neo4j-graphql/neo4j-graphql-js) from 2.3.1 to 2.4.2. - [Release notes](https://github.com/neo4j-graphql/neo4j-graphql-js/releases) - [Changelog](https://github.com/neo4j-graphql/neo4j-graphql-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/neo4j-graphql/neo4j-graphql-js/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 21 +++++++-------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 166ba7fce..8d426c6ae 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "lodash": "~4.17.11", "ms": "~2.1.1", "neo4j-driver": "~1.7.3", - "neo4j-graphql-js": "~2.4.1", + "neo4j-graphql-js": "~2.4.2", "node-fetch": "~2.3.0", "npm-run-all": "~4.1.5", "sanitize-html": "~1.20.0", diff --git a/yarn.lock b/yarn.lock index 38e52cad9..f8babfaf6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3370,7 +3370,7 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== -graphql-auth-directives@^2.0.0: +graphql-auth-directives@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/graphql-auth-directives/-/graphql-auth-directives-2.1.0.tgz#85b83817844e2ec5fba8fe5de444287d6dd0f85a" integrity sha512-mRVsjeMeMABPyjxyzl9mhkcW02YBwSj7dnu7C6wy2dIhiby6xTKy6Q54C8KeqXSYsy6ua4VmBH++d7GKqpvIoA== @@ -3538,14 +3538,7 @@ graphql-yoga@~1.17.4: graphql-tools "^4.0.0" subscriptions-transport-ws "^0.9.8" -"graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0", graphql@^14.0.2: - version "14.0.2" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.0.2.tgz#7dded337a4c3fd2d075692323384034b357f5650" - integrity sha512-gUC4YYsaiSJT1h40krG3J+USGlwhzNTXSb4IOZljn9ag5Tj+RkoXrWp+Kh7WyE3t1NCfab5kzCuxBIvOMERMXw== - dependencies: - iterall "^1.2.2" - -graphql@~14.1.1: +"graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0", graphql@^14.0.2, graphql@~14.1.1: version "14.1.1" resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.1.1.tgz#d5d77df4b19ef41538d7215d1e7a28834619fac0" integrity sha512-C5zDzLqvfPAgTtP8AUPIt9keDabrdRAqSWjj2OPRKrKxI9Fb65I36s1uCs1UUBFnSWTdO7hyHi7z1ZbwKMKF6Q== @@ -5180,13 +5173,13 @@ neo4j-driver@^1.7.2, neo4j-driver@~1.7.3: text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-graphql-js@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.4.1.tgz#a1de65340fb6f1ad0ae6aadab90a0bb78b490b32" - integrity sha512-Py6RJuMT7A03Hzoo6qfKyo6DUnHQgbZlBcgucnhgQjbeysAzvM3F02UAVn/HxEtOgowAeGWjyjJvwozoNtiiqQ== +neo4j-graphql-js@~2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.4.2.tgz#0acf1d0b3a8a1da516c29dbc6b7c90ef1d0c82bd" + integrity sha512-K1A61T6ZaEePXg2wZ4plYsQYxo7cxjHtZ6wZX7JXiX4y96c82J5VcD++FXcUys2jG4z4Bz40YS0Ce7ybMjsmUg== dependencies: graphql "^14.0.2" - graphql-auth-directives "^2.0.0" + graphql-auth-directives "^2.1.0" lodash "^4.17.11" neo4j-driver "^1.7.2" From 5c91962808d640d219451ec0eba524ba227143d3 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 8 Mar 2019 20:50:58 +0100 Subject: [PATCH 503/554] Merged master in and updated what had to be updated --- LICENSE.md | 21 ++ docker-compose.cypress.yml | 18 + humanconnection.png | Bin 0 -> 132723 bytes src/jwt/decode.js | 29 ++ src/jwt/encode.js | 17 + src/middleware/softDeleteMiddleware.spec.js | 130 +++++++ src/resolvers/badges.spec.js | 223 ++++++++++++ src/resolvers/follow.spec.js | 115 ++++++ src/resolvers/moderation.js | 30 ++ src/resolvers/moderation.spec.js | 370 ++++++++++++++++++++ src/resolvers/posts.js | 63 ++++ src/resolvers/posts.spec.js | 202 +++++++++++ src/resolvers/reports.js | 51 +++ src/resolvers/reports.spec.js | 68 ++++ src/resolvers/shout.spec.js | 126 +++++++ src/resolvers/statistics.js | 67 ++++ src/resolvers/user_management.js | 51 +++ src/resolvers/user_management.spec.js | 179 ++++++++++ 18 files changed, 1760 insertions(+) create mode 100644 LICENSE.md create mode 100644 docker-compose.cypress.yml create mode 100644 humanconnection.png create mode 100644 src/jwt/decode.js create mode 100644 src/jwt/encode.js create mode 100644 src/middleware/softDeleteMiddleware.spec.js create mode 100644 src/resolvers/badges.spec.js create mode 100644 src/resolvers/follow.spec.js create mode 100644 src/resolvers/moderation.js create mode 100644 src/resolvers/moderation.spec.js create mode 100644 src/resolvers/posts.js create mode 100644 src/resolvers/posts.spec.js create mode 100644 src/resolvers/reports.js create mode 100644 src/resolvers/reports.spec.js create mode 100644 src/resolvers/shout.spec.js create mode 100644 src/resolvers/statistics.js create mode 100644 src/resolvers/user_management.js create mode 100644 src/resolvers/user_management.spec.js diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..9d4508b38 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Human-Connection gGmbH + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/docker-compose.cypress.yml b/docker-compose.cypress.yml new file mode 100644 index 000000000..3d577e638 --- /dev/null +++ b/docker-compose.cypress.yml @@ -0,0 +1,18 @@ +version: "3.7" + +services: + neo4j: + environment: + - NEO4J_AUTH=none + ports: + - 7687:7687 + - 7474:7474 + backend: + ports: + - 4001:4001 + - 4123:4123 + image: humanconnection/nitro-backend:builder + build: + context: . + target: builder + command: yarn run test:cypress diff --git a/humanconnection.png b/humanconnection.png new file mode 100644 index 0000000000000000000000000000000000000000..f0576413ff0663ce0c79b6a0ef8ccd2ffbc77594 GIT binary patch literal 132723 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∈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�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 iz4^aRaB;J9wD { + if (!authorizationHeader) return null + const token = authorizationHeader.replace('Bearer ', '') + let id = null + try { + const decoded = await jwt.verify(token, process.env.JWT_SECRET) + id = decoded.sub + } catch { + return null + } + const session = driver.session() + const query = ` + MATCH (user:User {id: {id} }) + RETURN user {.id, .slug, .name, .avatar, .email, .role} as user + LIMIT 1 + ` + const result = await session.run(query, { id }) + session.close() + const [currentUser] = await result.records.map((record) => { + return record.get('user') + }) + if (!currentUser) return null + return { + token, + ...currentUser + } +} diff --git a/src/jwt/encode.js b/src/jwt/encode.js new file mode 100644 index 000000000..f32fc12da --- /dev/null +++ b/src/jwt/encode.js @@ -0,0 +1,17 @@ + +import jwt from 'jsonwebtoken' +import ms from 'ms' + +// Generate an Access Token for the given User ID +export default function encode (user) { + const token = jwt.sign(user, process.env.JWT_SECRET, { + expiresIn: ms('1d'), + issuer: process.env.GRAPHQL_URI, + audience: process.env.CLIENT_URI, + subject: user.id.toString() + }) + // jwt.verifySignature(token, process.env.JWT_SECRET, (err, data) => { + // console.log('token verification:', err, data) + // }) + return token +} diff --git a/src/middleware/softDeleteMiddleware.spec.js b/src/middleware/softDeleteMiddleware.spec.js new file mode 100644 index 000000000..e9bc461f1 --- /dev/null +++ b/src/middleware/softDeleteMiddleware.spec.js @@ -0,0 +1,130 @@ +import Factory from '../seed/factories' +import { host, login } from '../jest/helpers' +import { GraphQLClient } from 'graphql-request' + +const factory = Factory() +let client +let query +let action + +beforeEach(async () => { + await Promise.all([ + factory.create('User', { role: 'user', email: 'user@example.org', password: '1234' }), + factory.create('User', { id: 'm1', role: 'moderator', email: 'moderator@example.org', password: '1234' }) + ]) + await factory.authenticateAs({ email: 'user@example.org', password: '1234' }) + await Promise.all([ + factory.create('Post', { title: 'Deleted post', deleted: true }), + factory.create('Post', { id: 'p2', title: 'Disabled post', deleted: false }), + factory.create('Post', { title: 'Publicly visible post', deleted: false }) + ]) + const moderatorFactory = Factory() + await moderatorFactory.authenticateAs({ email: 'moderator@example.org', password: '1234' }) + const disableMutation = ` + mutation { + disable(resource: { + id: "p2" + type: contribution + }) + } + ` + await moderatorFactory.mutate(disableMutation) +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + +describe('softDeleteMiddleware', () => { + describe('Post', () => { + action = () => { + return client.request(query) + } + + beforeEach(() => { + query = '{ Post { title } }' + }) + + describe('as user', () => { + beforeEach(async () => { + const headers = await login({ email: 'user@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('hides deleted or disabled posts', async () => { + const expected = { Post: [{ title: 'Publicly visible post' }] } + await expect(action()).resolves.toEqual(expected) + }) + }) + + describe('as moderator', () => { + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('hides deleted or disabled posts', async () => { + const expected = { Post: [{ title: 'Publicly visible post' }] } + await expect(action()).resolves.toEqual(expected) + }) + }) + + describe('filter (deleted: true)', () => { + beforeEach(() => { + query = '{ Post(deleted: true) { title } }' + }) + + describe('as user', () => { + beforeEach(async () => { + const headers = await login({ email: 'user@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorisation error', async () => { + await expect(action()).rejects.toThrow('Not Authorised!') + }) + }) + + describe('as moderator', () => { + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('shows deleted posts', async () => { + const expected = { Post: [{ title: 'Deleted post' }] } + await expect(action()).resolves.toEqual(expected) + }) + }) + }) + + describe('filter (disabled: true)', () => { + beforeEach(() => { + query = '{ Post(disabled: true) { title } }' + }) + + describe('as user', () => { + beforeEach(async () => { + const headers = await login({ email: 'user@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorisation error', async () => { + await expect(action()).rejects.toThrow('Not Authorised!') + }) + }) + + describe('as moderator', () => { + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('shows disabled posts', async () => { + const expected = { Post: [{ title: 'Disabled post' }] } + await expect(action()).resolves.toEqual(expected) + }) + }) + }) + }) +}) diff --git a/src/resolvers/badges.spec.js b/src/resolvers/badges.spec.js new file mode 100644 index 000000000..e38f54381 --- /dev/null +++ b/src/resolvers/badges.spec.js @@ -0,0 +1,223 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() + +describe('badges', () => { + beforeEach(async () => { + await factory.create('User', { + email: 'user@example.org', + role: 'user', + password: '1234' + }) + await factory.create('User', { + id: 'u2', + role: 'moderator', + email: 'moderator@example.org' + }) + await factory.create('User', { + id: 'u3', + role: 'admin', + email: 'admin@example.org' + }) + }) + + afterEach(async () => { + await factory.cleanDatabase() + }) + + describe('CreateBadge', () => { + const variables = { + id: 'b1', + key: 'indiegogo_en_racoon', + type: 'crowdfunding', + status: 'permanent', + icon: '/img/badges/indiegogo_en_racoon.svg' + } + + const mutation = ` + mutation( + $id: ID + $key: String! + $type: BadgeTypeEnum! + $status: BadgeStatusEnum! + $icon: String! + ) { + CreateBadge(id: $id, key: $key, type: $type, status: $status, icon: $icon) { + id, + key, + type, + status, + icon + } + } + ` + + describe('unauthenticated', () => { + let client + + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect( + client.request(mutation, variables) + ).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated admin', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'admin@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + it('creates a badge', async () => { + const expected = { + CreateBadge: { + icon: '/img/badges/indiegogo_en_racoon.svg', + id: 'b1', + key: 'indiegogo_en_racoon', + status: 'permanent', + type: 'crowdfunding' + } + } + await expect(client.request(mutation, variables)).resolves.toEqual(expected) + }) + }) + + describe('authenticated moderator', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect( + client.request(mutation, variables) + ).rejects.toThrow('Not Authorised') + }) + }) + }) + + describe('UpdateBadge', () => { + beforeEach(async () => { + await factory.authenticateAs({ email: 'admin@example.org', password: '1234' }) + await factory.create('Badge', { id: 'b1' }) + }) + const variables = { + id: 'b1', + key: 'whatever' + } + + const mutation = ` + mutation($id: ID!, $key: String!) { + UpdateBadge(id: $id, key: $key) { + id + key + } + } + ` + + describe('unauthenticated', () => { + let client + + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect( + client.request(mutation, variables) + ).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated moderator', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect( + client.request(mutation, variables) + ).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated admin', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'admin@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + it('updates a badge', async () => { + const expected = { + UpdateBadge: { + id: 'b1', + key: 'whatever' + } + } + await expect(client.request(mutation, variables)).resolves.toEqual(expected) + }) + }) + }) + + describe('DeleteBadge', () => { + beforeEach(async () => { + await factory.authenticateAs({ email: 'admin@example.org', password: '1234' }) + await factory.create('Badge', { id: 'b1' }) + }) + const variables = { + id: 'b1' + } + + const mutation = ` + mutation($id: ID!) { + DeleteBadge(id: $id) { + id + } + } + ` + + describe('unauthenticated', () => { + let client + + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect( + client.request(mutation, variables) + ).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated moderator', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect( + client.request(mutation, variables) + ).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated admin', () => { + let client + beforeEach(async () => { + const headers = await login({ email: 'admin@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + it('deletes a badge', async () => { + const expected = { + DeleteBadge: { + id: 'b1' + } + } + await expect(client.request(mutation, variables)).resolves.toEqual(expected) + }) + }) + }) +}) diff --git a/src/resolvers/follow.spec.js b/src/resolvers/follow.spec.js new file mode 100644 index 000000000..3c16560e5 --- /dev/null +++ b/src/resolvers/follow.spec.js @@ -0,0 +1,115 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() +let clientUser1 + +const mutationFollowUser = (id) => ` + mutation { + follow(id: "${id}", type: User) + } +` +const mutationUnfollowUser = (id) => ` + mutation { + unfollow(id: "${id}", type: User) + } +` + +beforeEach(async () => { + await factory.create('User', { + id: 'u1', + email: 'test@example.org', + password: '1234' + }) + await factory.create('User', { + id: 'u2', + email: 'test2@example.org', + password: '1234' + }) +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + +describe('follow ', () => { + describe('(un)follow user', () => { + let headersUser1 + beforeEach(async () => { + headersUser1 = await login({ email: 'test@example.org', password: '1234' }) + clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) + }) + + it('I can follow another user', async () => { + const res = await clientUser1.request( + mutationFollowUser('u2') + ) + const expected = { + follow: true + } + expect(res).toMatchObject(expected) + + const { User } = await clientUser1.request(`{ + User(id: "u2") { + followedBy { id } + followedByCurrentUser + } + }`) + const expected2 = { + followedBy: [ + { id: 'u1' } + ], + followedByCurrentUser: true + } + expect(User[0]).toMatchObject(expected2) + }) + + it('I can unfollow a user', async () => { + // follow + await clientUser1.request( + mutationFollowUser('u2') + ) + const expected = { + unfollow: true + } + // unfollow + const res = await clientUser1.request(mutationUnfollowUser('u2')) + expect(res).toMatchObject(expected) + + const { User } = await clientUser1.request(`{ + User(id: "u2") { + followedBy { id } + followedByCurrentUser + } + }`) + const expected2 = { + followedBy: [], + followedByCurrentUser: false + } + expect(User[0]).toMatchObject(expected2) + }) + + it('I can`t follow myself', async () => { + const res = await clientUser1.request( + mutationFollowUser('u1') + ) + const expected = { + follow: false + } + expect(res).toMatchObject(expected) + + const { User } = await clientUser1.request(`{ + User(id: "u1") { + followedBy { id } + followedByCurrentUser + } + }`) + const expected2 = { + followedBy: [], + followedByCurrentUser: false + } + expect(User[0]).toMatchObject(expected2) + }) + }) +}) diff --git a/src/resolvers/moderation.js b/src/resolvers/moderation.js new file mode 100644 index 000000000..db44790b9 --- /dev/null +++ b/src/resolvers/moderation.js @@ -0,0 +1,30 @@ +export default { + Mutation: { + disable: async (object, params, { user, driver }) => { + const { resource: { id } } = params + const { id: userId } = user + const cypher = ` + MATCH (u:User {id: $userId}) + MATCH (r {id: $id}) + SET r.disabled = true + MERGE (r)<-[:DISABLED]-(u) + ` + const session = driver.session() + const res = await session.run(cypher, { id, userId }) + session.close() + return Boolean(res) + }, + enable: async (object, params, { user, driver }) => { + const { resource: { id } } = params + const cypher = ` + MATCH (r {id: $id})<-[d:DISABLED]-() + SET r.disabled = false + DELETE d + ` + const session = driver.session() + const res = await session.run(cypher, { id }) + session.close() + return Boolean(res) + } + } +} diff --git a/src/resolvers/moderation.spec.js b/src/resolvers/moderation.spec.js new file mode 100644 index 000000000..c1d4a75fe --- /dev/null +++ b/src/resolvers/moderation.spec.js @@ -0,0 +1,370 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() +let client + +const setupAuthenticateClient = (params) => { + const authenticateClient = async () => { + await factory.create('User', params) + const headers = await login(params) + client = new GraphQLClient(host, { headers }) + } + return authenticateClient +} + +let setup +const runSetup = async () => { + await setup.createResource() + await setup.authenticateClient() +} + +beforeEach(() => { + setup = { + createResource: () => { + }, + authenticateClient: () => { + client = new GraphQLClient(host) + } + } +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + +describe('disable', () => { + const mutation = ` + mutation($id: ID!, $type: ResourceEnum!) { + disable(resource: { id: $id, type: $type }) + } + ` + let variables + + beforeEach(() => { + // our defaul set of variables + variables = { + id: 'blabla', + type: 'contribution' + } + }) + + const action = async () => { + return client.request(mutation, variables) + } + + it('throws authorization error', async () => { + await runSetup() + await expect(action()).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { + beforeEach(() => { + setup.authenticateClient = setupAuthenticateClient({ + email: 'user@example.org', + password: '1234' + }) + }) + + it('throws authorization error', async () => { + await runSetup() + await expect(action()).rejects.toThrow('Not Authorised') + }) + + describe('as moderator', () => { + beforeEach(() => { + setup.authenticateClient = setupAuthenticateClient({ + id: 'u7', + email: 'moderator@example.org', + password: '1234', + role: 'moderator' + }) + }) + + describe('on a comment', () => { + beforeEach(async () => { + variables = { + id: 'c47', + type: 'comment' + } + + setup.createResource = async () => { + await factory.create('User', { id: 'u45', email: 'commenter@example.org', password: '1234' }) + await factory.authenticateAs({ email: 'commenter@example.org', password: '1234' }) + await Promise.all([ + factory.create('Post', { id: 'p3' }), + factory.create('Comment', { id: 'c47' }) + ]) + await Promise.all([ + factory.relate('Comment', 'Author', { from: 'u45', to: 'c47' }), + factory.relate('Comment', 'Post', { from: 'c47', to: 'p3' }) + ]) + } + }) + + it('returns true', async () => { + const expected = { disable: true } + await runSetup() + await expect(action()).resolves.toEqual(expected) + }) + + it('changes .disabledBy', async () => { + const before = { Comment: [{ id: 'c47', disabledBy: null }] } + const expected = { Comment: [{ id: 'c47', disabledBy: { id: 'u7' } }] } + + await runSetup() + await expect(client.request( + '{ Comment { id, disabledBy { id } } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Comment(disabled: true) { id, disabledBy { id } } }' + )).resolves.toEqual(expected) + }) + + it('updates .disabled on comment', async () => { + const before = { Comment: [ { id: 'c47', disabled: false } ] } + const expected = { Comment: [ { id: 'c47', disabled: true } ] } + + await runSetup() + await expect(client.request( + '{ Comment { id disabled } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Comment(disabled: true) { id disabled } }' + )).resolves.toEqual(expected) + }) + }) + + describe('on a post', () => { + beforeEach(async () => { + variables = { + id: 'p9', + type: 'contribution' + } + + setup.createResource = async () => { + await factory.create('User', { email: 'author@example.org', password: '1234' }) + await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) + await factory.create('Post', { + id: 'p9' // that's the ID we will look for + }) + } + }) + + it('returns true', async () => { + const expected = { disable: true } + await runSetup() + await expect(action()).resolves.toEqual(expected) + }) + + it('changes .disabledBy', async () => { + const before = { Post: [{ id: 'p9', disabledBy: null }] } + const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } + + await runSetup() + await expect(client.request( + '{ Post { id, disabledBy { id } } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Post(disabled: true) { id, disabledBy { id } } }' + )).resolves.toEqual(expected) + }) + + it('updates .disabled on post', async () => { + const before = { Post: [ { id: 'p9', disabled: false } ] } + const expected = { Post: [ { id: 'p9', disabled: true } ] } + + await runSetup() + await expect(client.request( + '{ Post { id disabled } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Post(disabled: true) { id disabled } }' + )).resolves.toEqual(expected) + }) + }) + }) + }) +}) + +describe('enable', () => { + const mutation = ` + mutation($id: ID!, $type: ResourceEnum!) { + enable(resource: { id: $id, type: $type }) + } + ` + let variables + + const action = async () => { + return client.request(mutation, variables) + } + + beforeEach(() => { + // our defaul set of variables + variables = { + id: 'blabla', + type: 'contribution' + } + }) + + it('throws authorization error', async () => { + await runSetup() + await expect(action()).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { + beforeEach(() => { + setup.authenticateClient = setupAuthenticateClient({ + email: 'user@example.org', + password: '1234' + }) + }) + + it('throws authorization error', async () => { + await runSetup() + await expect(action()).rejects.toThrow('Not Authorised') + }) + + describe('as moderator', () => { + beforeEach(async () => { + setup.authenticateClient = setupAuthenticateClient({ + role: 'moderator', + email: 'someUser@example.org', + password: '1234' + }) + }) + + describe('on a comment', () => { + beforeEach(async () => { + variables = { + id: 'c456', + type: 'comment' + } + + setup.createResource = async () => { + await factory.create('User', { id: 'u123', email: 'author@example.org', password: '1234' }) + await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) + await Promise.all([ + factory.create('Post', { id: 'p9' }), + factory.create('Comment', { id: 'c456' }) + ]) + await Promise.all([ + factory.relate('Comment', 'Author', { from: 'u123', to: 'c456' }), + factory.relate('Comment', 'Post', { from: 'c456', to: 'p9' }) + ]) + + const disableMutation = ` + mutation { + disable(resource: { + id: "c456" + type: comment + }) + } + ` + await factory.mutate(disableMutation) // that's we want to delete + } + }) + + it('returns true', async () => { + const expected = { enable: true } + await runSetup() + await expect(action()).resolves.toEqual(expected) + }) + + it('changes .disabledBy', async () => { + const before = { Comment: [{ id: 'c456', disabledBy: { id: 'u123' } }] } + const expected = { Comment: [{ id: 'c456', disabledBy: null }] } + + await runSetup() + await expect(client.request( + '{ Comment(disabled: true) { id, disabledBy { id } } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Comment { id, disabledBy { id } } }' + )).resolves.toEqual(expected) + }) + + it('updates .disabled on post', async () => { + const before = { Comment: [ { id: 'c456', disabled: true } ] } + const expected = { Comment: [ { id: 'c456', disabled: false } ] } + + await runSetup() + await expect(client.request( + '{ Comment(disabled: true) { id disabled } }' + )).resolves.toEqual(before) + await action() // this updates .disabled + await expect(client.request( + '{ Comment { id disabled } }' + )).resolves.toEqual(expected) + }) + }) + + describe('on a post', () => { + beforeEach(async () => { + variables = { + id: 'p9', + type: 'contribution' + } + + setup.createResource = async () => { + await factory.create('User', { id: 'u123', email: 'author@example.org', password: '1234' }) + await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) + await factory.create('Post', { + id: 'p9' // that's the ID we will look for + }) + + const disableMutation = ` + mutation { + disable(resource: { + id: "p9" + type: contribution + }) + } + ` + await factory.mutate(disableMutation) // that's we want to delete + } + }) + + it('returns true', async () => { + const expected = { enable: true } + await runSetup() + await expect(action()).resolves.toEqual(expected) + }) + + it('changes .disabledBy', async () => { + const before = { Post: [{ id: 'p9', disabledBy: { id: 'u123' } }] } + const expected = { Post: [{ id: 'p9', disabledBy: null }] } + + await runSetup() + await expect(client.request( + '{ Post(disabled: true) { id, disabledBy { id } } }' + )).resolves.toEqual(before) + await action() + await expect(client.request( + '{ Post { id, disabledBy { id } } }' + )).resolves.toEqual(expected) + }) + + it('updates .disabled on post', async () => { + const before = { Post: [ { id: 'p9', disabled: true } ] } + const expected = { Post: [ { id: 'p9', disabled: false } ] } + + await runSetup() + await expect(client.request( + '{ Post(disabled: true) { id disabled } }' + )).resolves.toEqual(before) + await action() // this updates .disabled + await expect(client.request( + '{ Post { id disabled } }' + )).resolves.toEqual(expected) + }) + }) + }) + }) +}) diff --git a/src/resolvers/posts.js b/src/resolvers/posts.js new file mode 100644 index 000000000..c813ec3f1 --- /dev/null +++ b/src/resolvers/posts.js @@ -0,0 +1,63 @@ +import { neo4jgraphql } from 'neo4j-graphql-js' +import { activityPub } from '../activitypub/ActivityPub' +import uuid from 'uuid/v4' +import as from 'activitystrea.ms' +/* +import as from 'activitystrea.ms' +import request from 'request' +*/ + +const debug = require('debug')('backend:schema') + +export default { + Mutation: { + CreatePost: async (object, params, context, resolveInfo) => { + params.activityId = uuid() + const result = await neo4jgraphql(object, params, context, resolveInfo, false) + + const session = context.driver.session() + const author = await session.run( + 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + + 'MERGE (post)<-[:WROTE]-(author) ' + + 'RETURN author', { + userId: context.user.id, + postId: result.id + }) + + debug(`actorId = ${author.records[0]._fields[0].properties.actorId}`) + if (Array.isArray(author.records) && author.records.length > 0) { + const actorId = author.records[0]._fields[0].properties.actorId + const createActivity = await new Promise((resolve, reject) => { + as.create() + .id(`${actorId}/status/${params.activityId}`) + .actor(`${actorId}`) + .object( + as.article() + .id(`${actorId}/status/${result.id}`) + .content(result.content) + .to('https://www.w3.org/ns/activitystreams#Public') + .publishedNow() + .attributedTo(`${actorId}`) + ).prettyWrite((err, doc) => { + if (err) { + reject(err) + } else { + debug(doc) + const parsedDoc = JSON.parse(doc) + parsedDoc.send = true + resolve(JSON.stringify(parsedDoc)) + } + }) + }) + try { + await activityPub.sendActivity(createActivity) + } catch (e) { + debug(`error sending post activity = ${JSON.stringify(e, null, 2)}`) + } + } + session.close() + + return result + } + } +} diff --git a/src/resolvers/posts.spec.js b/src/resolvers/posts.spec.js new file mode 100644 index 000000000..5603683eb --- /dev/null +++ b/src/resolvers/posts.spec.js @@ -0,0 +1,202 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() +let client + +beforeEach(async () => { + await factory.create('User', { + email: 'test@example.org', + password: '1234' + }) +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + +describe('CreatePost', () => { + const mutation = ` + mutation { + CreatePost(title: "I am a title", content: "Some content") { + title + content + slug + disabled + deleted + } + } + ` + + describe('unauthenticated', () => { + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect(client.request(mutation)).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated', () => { + let headers + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('creates a post', async () => { + const expected = { + CreatePost: { + title: 'I am a title', + content: 'Some content' + } + } + await expect(client.request(mutation)).resolves.toMatchObject(expected) + }) + + it('assigns the authenticated user as author', async () => { + await client.request(mutation) + const { User } = await client.request(`{ + User(email:"test@example.org") { + contributions { + title + } + } + }`, { headers }) + expect(User).toEqual([ { contributions: [ { title: 'I am a title' } ] } ]) + }) + + describe('disabled and deleted', () => { + it('initially false', async () => { + const expected = { CreatePost: { disabled: false, deleted: false } } + await expect(client.request(mutation)).resolves.toMatchObject(expected) + }) + }) + }) +}) + +describe('UpdatePost', () => { + const mutation = ` + mutation($id: ID!, $content: String) { + UpdatePost(id: $id, content: $content) { + id + content + } + } + ` + + let variables = { + id: 'p1', + content: 'New content' + } + + beforeEach(async () => { + const asAuthor = Factory() + await asAuthor.create('User', { + email: 'author@example.org', + password: '1234' + }) + await asAuthor.authenticateAs({ + email: 'author@example.org', + password: '1234' + }) + await asAuthor.create('Post', { + id: 'p1', + content: 'Old content' + }) + }) + + describe('unauthenticated', () => { + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated but not the author', () => { + let headers + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated as author', () => { + let headers + beforeEach(async () => { + headers = await login({ email: 'author@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('updates a post', async () => { + const expected = { UpdatePost: { id: 'p1', content: 'New content' } } + await expect(client.request(mutation, variables)).resolves.toEqual(expected) + }) + }) +}) + +describe('DeletePost', () => { + const mutation = ` + mutation($id: ID!) { + DeletePost(id: $id) { + id + content + } + } + ` + + let variables = { + id: 'p1' + } + + beforeEach(async () => { + const asAuthor = Factory() + await asAuthor.create('User', { + email: 'author@example.org', + password: '1234' + }) + await asAuthor.authenticateAs({ + email: 'author@example.org', + password: '1234' + }) + await asAuthor.create('Post', { + id: 'p1', + content: 'To be deleted' + }) + }) + + describe('unauthenticated', () => { + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated but not the author', () => { + let headers + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorization error', async () => { + await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') + }) + }) + + describe('authenticated as author', () => { + let headers + beforeEach(async () => { + headers = await login({ email: 'author@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('deletes a post', async () => { + const expected = { DeletePost: { id: 'p1', content: 'To be deleted' } } + await expect(client.request(mutation, variables)).resolves.toEqual(expected) + }) + }) +}) diff --git a/src/resolvers/reports.js b/src/resolvers/reports.js new file mode 100644 index 000000000..c471d7b7a --- /dev/null +++ b/src/resolvers/reports.js @@ -0,0 +1,51 @@ +import uuid from 'uuid/v4' + +export default { + Mutation: { + report: async (parent, { resource, description }, { driver, req, user }, resolveInfo) => { + const contextId = uuid() + const session = driver.session() + const data = { + id: contextId, + type: resource.type, + createdAt: (new Date()).toISOString(), + description: resource.description + } + await session.run( + 'CREATE (r:Report $report) ' + + 'RETURN r.id, r.type, r.description', { + report: data + } + ) + let contentType + + switch (resource.type) { + case 'post': + case 'contribution': + contentType = 'Post' + break + case 'comment': + contentType = 'Comment' + break + case 'user': + contentType = 'User' + break + } + + await session.run( + `MATCH (author:User {id: $userId}), (context:${contentType} {id: $resourceId}), (report:Report {id: $contextId}) ` + + 'MERGE (report)<-[:REPORTED]-(author) ' + + 'MERGE (context)<-[:REPORTED]-(report) ' + + 'RETURN context', { + resourceId: resource.id, + userId: user.id, + contextId: contextId + } + ) + session.close() + + // TODO: output Report compatible object + return data + } + } +} diff --git a/src/resolvers/reports.spec.js b/src/resolvers/reports.spec.js new file mode 100644 index 000000000..253cdadcc --- /dev/null +++ b/src/resolvers/reports.spec.js @@ -0,0 +1,68 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() + +describe('report', () => { + beforeEach(async () => { + await factory.create('User', { + email: 'test@example.org', + password: '1234' + }) + await factory.create('User', { + id: 'u2', + name: 'abusive-user', + role: 'user', + email: 'abusive-user@example.org' + }) + }) + + afterEach(async () => { + await factory.cleanDatabase() + }) + + describe('unauthenticated', () => { + let client + it('throws authorization error', async () => { + client = new GraphQLClient(host) + await expect( + client.request(`mutation { + report( + description: "I don't like this user", + resource: { + id: "u2", + type: user + } + ) { id, createdAt } + }`) + ).rejects.toThrow('Not Authorised') + }) + + describe('authenticated', () => { + let headers + let response + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + response = await client.request(`mutation { + report( + description: "I don't like this user", + resource: { + id: "u2", + type: user + } + ) { id, createdAt } + }`, + { headers } + ) + }) + it('creates a report', () => { + let { id, createdAt } = response.report + expect(response).toEqual({ + report: { id, createdAt } + }) + }) + }) + }) +}) diff --git a/src/resolvers/shout.spec.js b/src/resolvers/shout.spec.js new file mode 100644 index 000000000..490191c7a --- /dev/null +++ b/src/resolvers/shout.spec.js @@ -0,0 +1,126 @@ +import Factory from '../seed/factories' +import { GraphQLClient } from 'graphql-request' +import { host, login } from '../jest/helpers' + +const factory = Factory() +let clientUser1, clientUser2 + +const mutationShoutPost = (id) => ` + mutation { + shout(id: "${id}", type: Post) + } +` +const mutationUnshoutPost = (id) => ` + mutation { + unshout(id: "${id}", type: Post) + } +` + +beforeEach(async () => { + await factory.create('User', { + id: 'u1', + email: 'test@example.org', + password: '1234' + }) + await factory.create('User', { + id: 'u2', + email: 'test2@example.org', + password: '1234' + }) +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + +describe('shout ', () => { + describe('(un)shout foreign post', () => { + let headersUser1, headersUser2 + beforeEach(async () => { + headersUser1 = await login({ email: 'test@example.org', password: '1234' }) + headersUser2 = await login({ email: 'test2@example.org', password: '1234' }) + clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) + clientUser2 = new GraphQLClient(host, { headers: headersUser2 }) + + await clientUser1.request(` + mutation { + CreatePost(id: "p1", title: "Post Title 1", content: "Some Post Content 1") { + id + title + } + } + `) + await clientUser2.request(` + mutation { + CreatePost(id: "p2", title: "Post Title 2", content: "Some Post Content 2") { + id + title + } + } + `) + }) + + it('I shout a post of another user', async () => { + const res = await clientUser1.request( + mutationShoutPost('p2') + ) + const expected = { + shout: true + } + expect(res).toMatchObject(expected) + + const { Post } = await clientUser1.request(`{ + Post(id: "p2") { + shoutedByCurrentUser + } + }`) + const expected2 = { + shoutedByCurrentUser: true + } + expect(Post[0]).toMatchObject(expected2) + }) + + it('I unshout a post of another user', async () => { + // shout + await clientUser1.request( + mutationShoutPost('p2') + ) + const expected = { + unshout: true + } + // unshout + const res = await clientUser1.request(mutationUnshoutPost('p2')) + expect(res).toMatchObject(expected) + + const { Post } = await clientUser1.request(`{ + Post(id: "p2") { + shoutedByCurrentUser + } + }`) + const expected2 = { + shoutedByCurrentUser: false + } + expect(Post[0]).toMatchObject(expected2) + }) + + it('I can`t shout my own post', async () => { + const res = await clientUser1.request( + mutationShoutPost('p1') + ) + const expected = { + shout: false + } + expect(res).toMatchObject(expected) + + const { Post } = await clientUser1.request(`{ + Post(id: "p1") { + shoutedByCurrentUser + } + }`) + const expected2 = { + shoutedByCurrentUser: false + } + expect(Post[0]).toMatchObject(expected2) + }) + }) +}) diff --git a/src/resolvers/statistics.js b/src/resolvers/statistics.js new file mode 100644 index 000000000..17c4be956 --- /dev/null +++ b/src/resolvers/statistics.js @@ -0,0 +1,67 @@ +export const query = (cypher, session) => { + return new Promise((resolve, reject) => { + let data = [] + session + .run(cypher) + .subscribe({ + onNext: function (record) { + let item = {} + record.keys.forEach(key => { + item[key] = record.get(key) + }) + data.push(item) + }, + onCompleted: function () { + session.close() + resolve(data) + }, + onError: function (error) { + reject(error) + } + }) + }) +} +const queryOne = (cypher, session) => { + return new Promise((resolve, reject) => { + query(cypher, session) + .then(res => { + resolve(res.length ? res.pop() : {}) + }) + .catch(err => { + reject(err) + }) + }) +} + +export default { + Query: { + statistics: async (parent, args, { driver, user }) => { + return new Promise(async (resolve) => { + const session = driver.session() + const queries = { + countUsers: 'MATCH (r:User) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countUsers', + countPosts: 'MATCH (r:Post) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countPosts', + countComments: 'MATCH (r:Comment) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countComments', + countNotifications: 'MATCH (r:Notification) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countNotifications', + countOrganizations: 'MATCH (r:Organization) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countOrganizations', + countProjects: 'MATCH (r:Project) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countProjects', + countInvites: 'MATCH (r:Invite) WHERE r.wasUsed <> true OR NOT exists(r.wasUsed) RETURN COUNT(r) AS countInvites', + countFollows: 'MATCH (:User)-[r:FOLLOWS]->(:User) RETURN COUNT(r) AS countFollows', + countShouts: 'MATCH (:User)-[r:SHOUTED]->(:Post) RETURN COUNT(r) AS countShouts' + } + let data = { + countUsers: (await queryOne(queries.countUsers, session)).countUsers.low, + countPosts: (await queryOne(queries.countPosts, session)).countPosts.low, + countComments: (await queryOne(queries.countComments, session)).countComments.low, + countNotifications: (await queryOne(queries.countNotifications, session)).countNotifications.low, + countOrganizations: (await queryOne(queries.countOrganizations, session)).countOrganizations.low, + countProjects: (await queryOne(queries.countProjects, session)).countProjects.low, + countInvites: (await queryOne(queries.countInvites, session)).countInvites.low, + countFollows: (await queryOne(queries.countFollows, session)).countFollows.low, + countShouts: (await queryOne(queries.countShouts, session)).countShouts.low + } + resolve(data) + }) + } + } +} diff --git a/src/resolvers/user_management.js b/src/resolvers/user_management.js new file mode 100644 index 000000000..ec4ae7ce2 --- /dev/null +++ b/src/resolvers/user_management.js @@ -0,0 +1,51 @@ +import encode from '../jwt/encode' +import bcrypt from 'bcryptjs' +import { AuthenticationError } from 'apollo-server' +import { neo4jgraphql } from 'neo4j-graphql-js' + +export default { + Query: { + isLoggedIn: (parent, args, { driver, user }) => { + return Boolean(user && user.id) + }, + currentUser: async (object, params, ctx, resolveInfo) => { + const { user } = ctx + if (!user) return null + return neo4jgraphql(object, { id: user.id }, ctx, resolveInfo, false) + } + }, + Mutation: { + signup: async (parent, { email, password }, { req }) => { + // if (data[email]) { + // throw new Error('Another User with same email exists.') + // } + // data[email] = { + // password: await bcrypt.hashSync(password, 10), + // } + + return true + }, + login: async (parent, { email, password }, { driver, req, user }) => { + // if (user && user.id) { + // throw new Error('Already logged in.') + // } + const session = driver.session() + return session.run( + 'MATCH (user:User {email: $userEmail}) ' + + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', { + userEmail: email + }) + .then(async (result) => { + session.close() + const [currentUser] = await result.records.map(function (record) { + return record.get('user') + }) + + if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { + delete currentUser.password + return encode(currentUser) + } else throw new AuthenticationError('Incorrect email address or password.') + }) + } + } +} diff --git a/src/resolvers/user_management.spec.js b/src/resolvers/user_management.spec.js new file mode 100644 index 000000000..a3bf6fdd0 --- /dev/null +++ b/src/resolvers/user_management.spec.js @@ -0,0 +1,179 @@ +import Factory from '../seed/factories' +import { GraphQLClient, request } from 'graphql-request' +import jwt from 'jsonwebtoken' +import { host, login } from '../jest/helpers' + +const factory = Factory() + +// here is the decoded JWT token: +// { +// role: 'user', +// locationName: null, +// name: 'Jenny Rostock', +// about: null, +// avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/sasha_shestakov/128.jpg', +// id: 'u3', +// email: 'user@example.org', +// slug: 'jenny-rostock', +// iat: 1550846680, +// exp: 1637246680, +// aud: 'http://localhost:3000', +// iss: 'http://localhost:4000', +// sub: 'u3' +// } +const jennyRostocksHeaders = { authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoidXNlciIsImxvY2F0aW9uTmFtZSI6bnVsbCwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJhYm91dCI6bnVsbCwiYXZhdGFyIjoiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3VpZmFjZXMvZmFjZXMvdHdpdHRlci9zYXNoYV9zaGVzdGFrb3YvMTI4LmpwZyIsImlkIjoidTMiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5vcmciLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTU1MDg0NjY4MCwiZXhwIjoxNjM3MjQ2NjgwLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.eZ_mVKas4Wzoc_JrQTEWXyRn7eY64cdIg4vqQ-F_7Jc' } + +beforeEach(async () => { + await factory.create('User', { + avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', + id: 'acb2d923-f3af-479e-9f00-61b12e864666', + name: 'Matilde Hermiston', + slug: 'matilde-hermiston', + role: 'user', + email: 'test@example.org', + password: '1234' + }) +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + +describe('isLoggedIn', () => { + const query = '{ isLoggedIn }' + describe('unauthenticated', () => { + it('returns false', async () => { + await expect(request(host, query)).resolves.toEqual({ isLoggedIn: false }) + }) + }) + + describe('with malformed JWT Bearer token', () => { + const headers = { authorization: 'blah' } + const client = new GraphQLClient(host, { headers }) + + it('returns false', async () => { + await expect(client.request(query)).resolves.toEqual({ isLoggedIn: false }) + }) + }) + + describe('with valid JWT Bearer token', () => { + const client = new GraphQLClient(host, { headers: jennyRostocksHeaders }) + + it('returns false', async () => { + await expect(client.request(query)).resolves.toEqual({ isLoggedIn: false }) + }) + + describe('and a corresponding user in the database', () => { + it('returns true', async () => { + // see the decoded token above + await factory.create('User', { id: 'u3' }) + await expect(client.request(query)).resolves.toEqual({ isLoggedIn: true }) + }) + }) + }) +}) + +describe('currentUser', () => { + const query = `{ + currentUser { + id + slug + name + avatar + email + role + } + }` + + describe('unauthenticated', () => { + it('returns null', async () => { + const expected = { currentUser: null } + await expect(request(host, query)).resolves.toEqual(expected) + }) + }) + + describe('with valid JWT Bearer Token', () => { + let client + let headers + + describe('but no corresponding user in the database', () => { + beforeEach(async () => { + client = new GraphQLClient(host, { headers: jennyRostocksHeaders }) + }) + + it('returns null', async () => { + const expected = { currentUser: null } + await expect(client.request(query)).resolves.toEqual(expected) + }) + }) + + describe('and corresponding user in the database', () => { + beforeEach(async () => { + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('returns the whole user object', async () => { + const expected = { + currentUser: { + avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', + email: 'test@example.org', + id: 'acb2d923-f3af-479e-9f00-61b12e864666', + name: 'Matilde Hermiston', + slug: 'matilde-hermiston', + role: 'user' + } + } + await expect(client.request(query)).resolves.toEqual(expected) + }) + }) + }) +}) + +describe('login', () => { + const mutation = (params) => { + const { email, password } = params + return ` + mutation { + login(email:"${email}", password:"${password}") + }` + } + + describe('ask for a `token`', () => { + describe('with valid email/password combination', () => { + it('responds with a JWT token', async () => { + const data = await request(host, mutation({ + email: 'test@example.org', + password: '1234' + })) + const token = data.login + jwt.verify(token, process.env.JWT_SECRET, (err, data) => { + expect(data.email).toEqual('test@example.org') + expect(err).toBeNull() + }) + }) + }) + + describe('with a valid email but incorrect password', () => { + it('responds with "Incorrect email address or password."', async () => { + await expect( + request(host, mutation({ + email: 'test@example.org', + password: 'wrong' + })) + ).rejects.toThrow('Incorrect email address or password.') + }) + }) + + describe('with a non-existing email', () => { + it('responds with "Incorrect email address or password."', async () => { + await expect( + request(host, mutation({ + email: 'non-existent@example.org', + password: 'wrong' + })) + ).rejects.toThrow('Incorrect email address or password.') + }) + }) + }) +}) From 45cf16d07da42fa09c931bb00340c67eac7cd722 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 8 Mar 2019 20:51:43 +0100 Subject: [PATCH 504/554] Updates to get in line with master --- .env.template | 2 + .gitignore | 3 + README.md | 17 +- docker-compose.travis.yml | 4 - package.json | 50 +- src/activitypub/NitroDataSource.js | 4 +- src/graphql-schema.js | 216 +--- src/graphql-schema.spec.js | 184 --- src/jest/helpers.js | 6 +- src/jwt/generateToken.js | 17 - src/jwt/strategy.js | 42 - src/middleware/dateTimeMiddleware.js | 8 - src/middleware/permissionsMiddleware.js | 62 +- src/middleware/softDeleteMiddleware.js | 46 +- src/schema.graphql | 85 +- src/seed/factories/badges.js | 18 +- src/seed/factories/index.js | 37 +- src/seed/factories/organizations.js | 2 +- src/seed/factories/posts.js | 2 - src/seed/factories/users.js | 3 + src/seed/seed-db.js | 76 +- src/server.js | 30 +- yarn.lock | 1463 ++++++++++++++--------- 23 files changed, 1192 insertions(+), 1185 deletions(-) delete mode 100644 src/graphql-schema.spec.js delete mode 100644 src/jwt/generateToken.js delete mode 100644 src/jwt/strategy.js diff --git a/.env.template b/.env.template index 42211b184..abc62b2dc 100644 --- a/.env.template +++ b/.env.template @@ -8,3 +8,5 @@ MOCK=false JWT_SECRET="b/&&7b78BF&fv/Vd" MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ" + +PRIVATE_KEY_PASSPHRASE="a7dsf78sadg87ad87sfagsadg78" diff --git a/.gitignore b/.gitignore index b909223f8..81a29c8e6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ coverage.lcov .nyc_output/ public/uploads/* !.gitkeep + +# Apple macOS folder attribute file +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index fc175dfb2..1f4755cc2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ -# Human-Connection - NITRO Backend -[![Build Status](https://travis-ci.com/Human-Connection/Nitro-Backend.svg?branch=master)](https://travis-ci.com/Human-Connection/Nitro-Backend) +

+ Human Connection +

+ +# NITRO Backend +[![Build Status](https://img.shields.io/travis/com/Human-Connection/Nitro-Backend/master.svg)](https://travis-ci.com/Human-Connection/Nitro-Backend) +[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Human-Connection/Nitro-Backend/blob/backend/LICENSE.md) +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend?ref=badge_shield) +[![Discord Channel](https://img.shields.io/discord/489522408076738561.svg)](https://discord.gg/6ub73U3) > This Prototype tries to resolve the biggest hurdle of connecting > our services together. This is not possible in a sane way using @@ -158,9 +165,13 @@ npm run test:cucumber - [x] add jwt authentication - [ ] get directives working correctly (@toLower, @auth, @role, etc.) -- [ ] check if search is working +- [x] check if search is working - [x] check if sorting is working - [x] check if pagination is working - [ ] check if upload is working (using graphql-yoga?) - [x] evaluate middleware - [ ] ignore Posts and Comments by blacklisted Users + + +## License +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FHuman-Connection%2FNitro-Backend?ref=badge_large) diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml index 3d577e638..e1998f6dd 100644 --- a/docker-compose.travis.yml +++ b/docker-compose.travis.yml @@ -8,11 +8,7 @@ services: - 7687:7687 - 7474:7474 backend: - ports: - - 4001:4001 - - 4123:4123 image: humanconnection/nitro-backend:builder build: context: . target: builder - command: yarn run test:cypress diff --git a/package.json b/package.json index d876b77d1..df4d9c94c 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,9 @@ "scripts": { "build": "babel src/ -d dist/ --copy-files", "start": "node dist/", - "dev": "nodemon --exec babel-node src/", - "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", - "lint": "eslint src --config .eslintrc.js --fix", + "dev": "nodemon --exec babel-node src/ -e js,graphql", + "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js -e js,graphql", + "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn test:jest", "test:cypress": "run-p --race test:before:*", "test:before:server": "cross-env GRAPHQL_URI=http://localhost:4123 GRAPHQL_PORT=4123 babel-node src/ 2> /dev/null", @@ -36,19 +36,19 @@ ] }, "dependencies": { - "activitystrea.ms": "^2.1.3", - "apollo-cache-inmemory": "~1.4.3", - "apollo-client": "~2.4.13", - "apollo-link-context": "^1.0.14", - "apollo-link-http": "~1.5.11", - "apollo-server": "~2.4.2", + "activitystrea.ms": "~2.1.3", + "apollo-cache-inmemory": "~1.5.1", + "apollo-client": "~2.5.1", + "apollo-link-context": "~1.0.14", + "apollo-link-http": "~1.5.12", + "apollo-server": "~2.4.8", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", - "cors": "^2.8.5", + "cors": "~2.8.5", "cross-env": "~5.2.0", "date-fns": "2.0.0-alpha.26", "dotenv": "~6.2.0", - "express": "^4.16.4", + "express": "~4.16.4", "faker": "~4.1.0", "graphql": "~14.1.1", "graphql-custom-directives": "~0.2.14", @@ -57,39 +57,37 @@ "graphql-shield": "~5.3.0", "graphql-tag": "~2.10.1", "graphql-yoga": "~1.17.4", - "helmet": "^3.15.1", + "helmet": "~3.15.1", "jsonwebtoken": "~8.5.0", "linkifyjs": "~2.1.8", "lodash": "~4.17.11", "ms": "~2.1.1", - "neo4j-driver": "~1.7.2", - "neo4j-graphql-js": "~2.3.1", + "neo4j-driver": "~1.7.3", + "neo4j-graphql-js": "~2.4.1", "node-fetch": "~2.3.0", "npm-run-all": "~4.1.5", - "passport": "~0.4.0", - "passport-jwt": "~4.0.0", - "request": "^2.88.0", + "request": "~2.88.0", "sanitize-html": "~1.20.0", "slug": "~1.0.0", "trunc-html": "~1.1.2", - "uuid": "^3.3.2", + "uuid": "~3.3.2", "wait-on": "~3.2.0" }, "devDependencies": { "@babel/cli": "~7.2.3", - "@babel/core": "~7.3.3", + "@babel/core": "~7.3.4", "@babel/node": "~7.2.2", "@babel/plugin-proposal-throw-expressions": "^7.2.0", - "@babel/preset-env": "~7.3.1", + "@babel/preset-env": "~7.3.4", "@babel/register": "~7.0.0", - "apollo-server-testing": "~2.4.2", + "apollo-server-testing": "~2.4.8", "babel-core": "~7.0.0-0", "babel-eslint": "~10.0.1", - "babel-jest": "~24.1.0", + "babel-jest": "~24.3.1", "chai": "~4.2.0", - "cucumber": "^5.1.0", - "debug": "^4.1.1", - "eslint": "~5.13.0", + "cucumber": "~5.1.0", + "debug": "~4.1.1", + "eslint": "~5.15.1", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.16.0", "eslint-plugin-jest": "~22.3.0", @@ -97,7 +95,7 @@ "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", "graphql-request": "~1.8.2", - "jest": "~24.1.0", + "jest": "~24.3.1", "nodemon": "~1.18.10", "nyc": "~13.3.0", "supertest": "~3.4.2" diff --git a/src/activitypub/NitroDataSource.js b/src/activitypub/NitroDataSource.js index d43dc40a6..a8b65b27e 100644 --- a/src/activitypub/NitroDataSource.js +++ b/src/activitypub/NitroDataSource.js @@ -21,7 +21,7 @@ import fetch from 'node-fetch' import { ApolloClient } from 'apollo-client' import dotenv from 'dotenv' import uuid from 'uuid' -import generateJwtToken from '../jwt/generateToken' +import encode from '../jwt/encode' import { resolve } from 'path' import trunc from 'trunc-html' const debug = require('debug')('ea:nitro-datasource') @@ -41,7 +41,7 @@ export default class NitroDataSource { const cache = new InMemoryCache() const authLink = setContext((_, { headers }) => { // generate the authentication token (maybe from env? Which user?) - const token = generateJwtToken({ name: 'ActivityPub', id: uuid() }) + const token = encode({ name: 'ActivityPub', id: uuid() }) // return the headers to the context so httpLink can read them return { headers: { diff --git a/src/graphql-schema.js b/src/graphql-schema.js index 5ddf08492..0c7dcc876 100644 --- a/src/graphql-schema.js +++ b/src/graphql-schema.js @@ -1,219 +1,25 @@ import fs from 'fs' import path from 'path' -import bcrypt from 'bcryptjs' -import generateJwt from './jwt/generateToken' -import uuid from 'uuid/v4' -import { fixUrl } from './middleware/fixImageUrlsMiddleware' -import { AuthenticationError } from 'apollo-server' -import { neo4jgraphql } from 'neo4j-graphql-js' -import { activityPub } from './activitypub/ActivityPub' -import as from 'activitystrea.ms' -/* -import as from 'activitystrea.ms' -import request from 'request' -*/ -const debug = require('debug')('backend:schema') +import userManagement from './resolvers/user_management.js' +import statistics from './resolvers/statistics.js' +import reports from './resolvers/reports.js' +import posts from './resolvers/posts.js' +import moderation from './resolvers/moderation.js' export const typeDefs = fs.readFileSync(process.env.GRAPHQL_SCHEMA || path.join(__dirname, 'schema.graphql')) .toString('utf-8') -export const query = (cypher, session) => { - return new Promise((resolve, reject) => { - let data = [] - session - .run(cypher) - .subscribe({ - onNext: function (record) { - let item = {} - record.keys.forEach(key => { - item[key] = record.get(key) - }) - data.push(item) - }, - onCompleted: function () { - session.close() - resolve(data) - }, - onError: function (error) { - reject(error) - } - }) - }) -} -const queryOne = (cypher, session) => { - return new Promise((resolve, reject) => { - query(cypher, session) - .then(res => { - resolve(res.length ? res.pop() : {}) - }) - .catch(err => { - reject(err) - }) - }) -} - export const resolvers = { Query: { - isLoggedIn: (parent, args, { driver, user }) => { - return Boolean(user && user.id) - }, - statistics: async (parent, args, { driver, user }) => { - return new Promise(async (resolve) => { - const session = driver.session() - const queries = { - countUsers: 'MATCH (r:User) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countUsers', - countPosts: 'MATCH (r:Post) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countPosts', - countComments: 'MATCH (r:Comment) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countComments', - countNotifications: 'MATCH (r:Notification) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countNotifications', - countOrganizations: 'MATCH (r:Organization) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countOrganizations', - countProjects: 'MATCH (r:Project) WHERE r.deleted <> true OR NOT exists(r.deleted) RETURN COUNT(r) AS countProjects', - countInvites: 'MATCH (r:Invite) WHERE r.wasUsed <> true OR NOT exists(r.wasUsed) RETURN COUNT(r) AS countInvites', - countFollows: 'MATCH (:User)-[r:FOLLOWS]->(:User) RETURN COUNT(r) AS countFollows', - countShouts: 'MATCH (:User)-[r:SHOUTED]->(:Post) RETURN COUNT(r) AS countShouts' - } - let data = { - countUsers: (await queryOne(queries.countUsers, session)).countUsers.low, - countPosts: (await queryOne(queries.countPosts, session)).countPosts.low, - countComments: (await queryOne(queries.countComments, session)).countComments.low, - countNotifications: (await queryOne(queries.countNotifications, session)).countNotifications.low, - countOrganizations: (await queryOne(queries.countOrganizations, session)).countOrganizations.low, - countProjects: (await queryOne(queries.countProjects, session)).countProjects.low, - countInvites: (await queryOne(queries.countInvites, session)).countInvites.low, - countFollows: (await queryOne(queries.countFollows, session)).countFollows.low, - countShouts: (await queryOne(queries.countShouts, session)).countShouts.low - } - resolve(data) - }) - } - // usersBySubstring: neo4jgraphql + ...statistics.Query, + ...userManagement.Query }, Mutation: { - signup: async (parent, { email, password }, { req }) => { - // if (data[email]) { - // throw new Error('Another User with same email exists.') - // } - // data[email] = { - // password: await bcrypt.hashSync(password, 10), - // } - - return true - }, - login: async (parent, { email, password }, { driver, req, user }) => { - // if (user && user.id) { - // throw new Error('Already logged in.') - // } - const session = driver.session() - return session.run( - 'MATCH (user:User {email: $userEmail}) ' + - 'RETURN user {.id, .slug, .name, .avatar, .locationName, .about, .email, .password, .role} as user LIMIT 1', { - userEmail: email - }) - .then(async (result) => { - session.close() - const [currentUser] = await result.records.map(function (record) { - return record.get('user') - }) - - if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { - delete currentUser.password - currentUser.avatar = fixUrl(currentUser.avatar) - return Object.assign(currentUser, { - token: generateJwt(currentUser) - }) - } else throw new AuthenticationError('Incorrect email address or password.') - }) - }, - report: async (parent, { resource, description }, { driver, req, user }, resolveInfo) => { - const contextId = uuid() - const session = driver.session() - const data = { - id: contextId, - type: resource.type, - createdAt: (new Date()).toISOString(), - description: resource.description - } - await session.run( - 'CREATE (r:Report $report) ' + - 'RETURN r.id, r.type, r.description', { - report: data - } - ) - let contentType - - switch (resource.type) { - case 'post': - case 'contribution': - contentType = 'Post' - break - case 'comment': - contentType = 'Comment' - break - case 'user': - contentType = 'User' - break - } - - await session.run( - `MATCH (author:User {id: $userId}), (context:${contentType} {id: $resourceId}), (report:Report {id: $contextId}) ` + - 'MERGE (report)<-[:REPORTED]-(author) ' + - 'MERGE (context)<-[:REPORTED]-(report) ' + - 'RETURN context', { - resourceId: resource.id, - userId: user.id, - contextId: contextId - } - ) - session.close() - - // TODO: output Report compatible object - return data - }, - CreatePost: async (object, params, ctx, resolveInfo) => { - params.activityId = uuid() - const result = await neo4jgraphql(object, params, ctx, resolveInfo, false) - debug(`user = ${JSON.stringify(ctx.user, null, 2)}`) - const session = ctx.driver.session() - const author = await session.run( - 'MATCH (author:User {slug: $slug}), (post:Post {id: $postId}) ' + - 'MERGE (post)<-[:WROTE]-(author) ' + - 'RETURN author', { - slug: ctx.user.slug, - postId: result.id - }) - // debug(`result = ${JSON.stringify(author, null, 2)}`) - debug(`actorId = ${author.records[0]._fields[0].properties.actorId}`) - if (Array.isArray(author.records) && author.records.length > 0) { - const actorId = author.records[0]._fields[0].properties.actorId - const createActivity = await new Promise((resolve, reject) => { - as.create() - .id(`${actorId}/status/${params.activityId}`) - .actor(`${actorId}`) - .object( - as.article() - .id(`${actorId}/status/${result.id}`) - .content(result.content) - .to('https://www.w3.org/ns/activitystreams#Public') - .publishedNow() - .attributedTo(`${actorId}`) - ).prettyWrite((err, doc) => { - if (err) { - reject(err) - } else { - debug(doc) - const parsedDoc = JSON.parse(doc) - parsedDoc.send = true - resolve(JSON.stringify(parsedDoc)) - } - }) - }) - try { - await activityPub.sendActivity(createActivity) - } catch (e) { - debug(`error sending post activity = ${JSON.stringify(e, null, 2)}`) - } - } - } + ...userManagement.Mutation, + ...reports.Mutation, + ...moderation.Mutation, + ...posts.Mutation } } diff --git a/src/graphql-schema.spec.js b/src/graphql-schema.spec.js deleted file mode 100644 index 7aa47835f..000000000 --- a/src/graphql-schema.spec.js +++ /dev/null @@ -1,184 +0,0 @@ -import Factory from './seed/factories' -import { GraphQLClient, request } from 'graphql-request' -import jwt from 'jsonwebtoken' -import { host, login } from './jest/helpers' - -const factory = Factory() - -beforeEach(async () => { - await factory.create('User', { - email: 'test@example.org', - password: '1234' - }) -}) - -afterEach(async () => { - await factory.cleanDatabase() -}) - -describe('isLoggedIn', () => { - describe('unauthenticated', () => { - it('returns false', async () => { - const query = '{ isLoggedIn }' - await expect(request(host, query)).resolves.toEqual({ isLoggedIn: false }) - }) - }) -}) - -describe('login', () => { - const mutation = (params) => { - const { email, password } = params - return ` - mutation { - login(email:"${email}", password:"${password}"){ - token - } - }` - } - - describe('ask for a `token`', () => { - describe('with valid email/password combination', () => { - it('responds with a JWT token', async () => { - const data = await request(host, mutation({ - email: 'test@example.org', - password: '1234' - })) - const { token } = data.login - jwt.verify(token, process.env.JWT_SECRET, (err, data) => { - expect(data.email).toEqual('test@example.org') - expect(err).toBeNull() - }) - }) - }) - - describe('with a valid email but incorrect password', () => { - it('responds with "Incorrect email address or password."', async () => { - await expect( - request(host, mutation({ - email: 'test@example.org', - password: 'wrong' - })) - ).rejects.toThrow('Incorrect email address or password.') - }) - }) - - describe('with a non-existing email', () => { - it('responds with "Incorrect email address or password."', async () => { - await expect( - request(host, mutation({ - email: 'non-existent@example.org', - password: 'wrong' - })) - ).rejects.toThrow('Incorrect email address or password.') - }) - }) - }) -}) - -describe('CreatePost', () => { - describe('unauthenticated', () => { - let client - it('throws authorization error', async () => { - client = new GraphQLClient(host) - await expect(client.request(`mutation { - CreatePost( - title: "I am a post", - content: "Some content" - ) { slug } - }`)).rejects.toThrow('Not Authorised') - }) - - describe('authenticated', () => { - let headers - let response - beforeEach(async () => { - headers = await login({ email: 'test@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - response = await client.request(`mutation { - CreatePost( - title: "A title", - content: "Some content" - ) { title, content } - }`, { headers }) - }) - - it('creates a post', () => { - expect(response).toEqual({ CreatePost: { title: 'A title', content: 'Some content' } }) - }) - - it('assigns the authenticated user as author', async () => { - const { User } = await client.request(`{ - User(email:"test@example.org") { - contributions { - title - } - } - }`, { headers }) - expect(User).toEqual([ { contributions: [ { title: 'A title' } ] } ]) - }) - }) - }) -}) - -describe('report', () => { - beforeEach(async () => { - await factory.create('User', { - email: 'test@example.org', - password: '1234' - }) - await factory.create('User', { - id: 'u2', - name: 'abusive-user', - role: 'user', - email: 'abusive-user@example.org' - }) - }) - - afterEach(async () => { - await factory.cleanDatabase() - }) - - describe('unauthenticated', () => { - let client - it('throws authorization error', async () => { - client = new GraphQLClient(host) - await expect( - client.request(`mutation { - report( - description: "I don't like this user", - resource: { - id: "u2", - type: user - } - ) { id, createdAt } - }`) - ).rejects.toThrow('Not Authorised') - }) - - describe('authenticated', () => { - let headers - let response - beforeEach(async () => { - headers = await login({ email: 'test@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - response = await client.request(`mutation { - report( - description: "I don't like this user", - resource: { - id: "u2", - type: user - } - ) { id, createdAt } - }`, - { headers } - ) - }) - it('creates a report', () => { - let { id, createdAt } = response.report - expect(response).toEqual({ - report: { id, createdAt } - }) - }) - }) - }) -}) diff --git a/src/jest/helpers.js b/src/jest/helpers.js index ff6a535e2..0d358ed40 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -7,12 +7,10 @@ export const host = 'http://127.0.0.1:4123' export async function login ({ email, password }) { const mutation = ` mutation { - login(email:"${email}", password:"${password}"){ - token - } + login(email:"${email}", password:"${password}") }` const response = await request(host, mutation) return { - authorization: `Bearer ${response.login.token}` + authorization: `Bearer ${response.login}` } } diff --git a/src/jwt/generateToken.js b/src/jwt/generateToken.js deleted file mode 100644 index fb61bb4ac..000000000 --- a/src/jwt/generateToken.js +++ /dev/null @@ -1,17 +0,0 @@ - -import jwt from 'jsonwebtoken' -import ms from 'ms' - -// Generate an Access Token for the given User ID -export default function generateJwt (user) { - const token = jwt.sign(user, process.env.JWT_SECRET, { - expiresIn: ms('1d'), - issuer: process.env.GRAPHQL_URI, - audience: process.env.CLIENT_URI, - subject: user.id.toString() - }) - // jwt.verifySignature(token, process.env.JWT_SECRET, (err, data) => { - // console.log('token verification:', err, data) - // }) - return token -} diff --git a/src/jwt/strategy.js b/src/jwt/strategy.js deleted file mode 100644 index 5b1ea1231..000000000 --- a/src/jwt/strategy.js +++ /dev/null @@ -1,42 +0,0 @@ -import { Strategy } from 'passport-jwt' -import { fixUrl } from '../middleware/fixImageUrlsMiddleware' - -const cookieExtractor = (req) => { - var token = null - if (req && req.cookies) { - token = req.cookies['jwt'] - } - return token -} - -export default (driver) => { - const options = { - jwtFromRequest: cookieExtractor, - secretOrKey: process.env.JWT_SECRET, - issuer: process.env.GRAPHQL_URI, - audience: process.env.CLIENT_URI - } - - return new Strategy(options, - async (JWTPayload, next) => { - const session = driver.session() - const result = await session.run( - 'MATCH (user:User {id: $userId}) ' + - 'RETURN user {.id, .slug, .name, .avatar, .email, .role} as user LIMIT 1', - { - userId: JWTPayload.id - } - ) - session.close() - const [currentUser] = await result.records.map((record) => { - return record.get('user') - }) - - if (currentUser) { - currentUser.avatar = fixUrl(currentUser.avatar) - return next(null, currentUser) - } else { - return next(null, false) - } - }) -} diff --git a/src/middleware/dateTimeMiddleware.js b/src/middleware/dateTimeMiddleware.js index 97e6e2767..473dbf444 100644 --- a/src/middleware/dateTimeMiddleware.js +++ b/src/middleware/dateTimeMiddleware.js @@ -2,29 +2,21 @@ export default { Mutation: { CreateUser: async (resolve, root, args, context, info) => { args.createdAt = (new Date()).toISOString() - args.disabled = false - args.deleted = false const result = await resolve(root, args, context, info) return result }, CreatePost: async (resolve, root, args, context, info) => { args.createdAt = (new Date()).toISOString() - args.disabled = false - args.deleted = false const result = await resolve(root, args, context, info) return result }, CreateComment: async (resolve, root, args, context, info) => { args.createdAt = (new Date()).toISOString() - args.disabled = false - args.deleted = false const result = await resolve(root, args, context, info) return result }, CreateOrganization: async (resolve, root, args, context, info) => { args.createdAt = (new Date()).toISOString() - args.disabled = false - args.deleted = false const result = await resolve(root, args, context, info) return result }, diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 1a3f04ceb..7fb6e75b8 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -1,4 +1,4 @@ -import { rule, shield, allow } from 'graphql-shield' +import { rule, shield, allow, or } from 'graphql-shield' /* * TODO: implement @@ -7,31 +7,58 @@ import { rule, shield, allow } from 'graphql-shield' const isAuthenticated = rule()(async (parent, args, ctx, info) => { return ctx.user !== null }) -/* -const isAdmin = rule()(async (parent, args, ctx, info) => { - return ctx.user.role === 'ADMIN' -}) -const isModerator = rule()(async (parent, args, ctx, info) => { - return ctx.user.role === 'MODERATOR' -}) -*/ -const isMyOwn = rule({ cache: 'no_cache' })(async (parent, args, ctx, info) => { - return ctx.user.id === parent.id +const isModerator = rule()(async (parent, args, { user }, info) => { + return user && (user.role === 'moderator' || user.role === 'admin') +}) + +const isAdmin = rule()(async (parent, args, { user }, info) => { + return user && (user.role === 'admin') +}) + +const isMyOwn = rule({ cache: 'no_cache' })(async (parent, args, context, info) => { + return context.user.id === parent.id +}) + +const onlyEnabledContent = rule({ cache: 'strict' })(async (parent, args, ctx, info) => { + const { disabled, deleted } = args + return !(disabled || deleted) +}) + +const isAuthor = rule({ cache: 'no_cache' })(async (parent, args, { user, driver }) => { + if (!user) return false + const session = driver.session() + const { id: postId } = args + const result = await session.run(` + MATCH (post:Post {id: $postId})<-[:WROTE]-(author) + RETURN author + `, { postId }) + const [author] = result.records.map((record) => { + return record.get('author') + }) + const { properties: { id: authorId } } = author + session.close() + return authorId === user.id }) // Permissions const permissions = shield({ Query: { - statistics: allow - // fruits: and(isAuthenticated, or(isAdmin, isModerator)), - // customers: and(isAuthenticated, isAdmin) + statistics: allow, + currentUser: allow, + Post: or(onlyEnabledContent, isModerator) }, Mutation: { CreatePost: isAuthenticated, - // TODO UpdatePost: isOwner, - // TODO DeletePost: isOwner, - report: isAuthenticated + UpdatePost: isAuthor, + DeletePost: isAuthor, + report: isAuthenticated, + CreateBadge: isAdmin, + UpdateBadge: isAdmin, + DeleteBadge: isAdmin, + + enable: isModerator, + disable: isModerator // addFruitToBasket: isAuthenticated // CreateUser: allow, }, @@ -39,7 +66,6 @@ const permissions = shield({ email: isMyOwn, password: isMyOwn } - // Post: isAuthenticated }) export default permissions diff --git a/src/middleware/softDeleteMiddleware.js b/src/middleware/softDeleteMiddleware.js index 79e4a7d08..0c12e7a72 100644 --- a/src/middleware/softDeleteMiddleware.js +++ b/src/middleware/softDeleteMiddleware.js @@ -1,38 +1,26 @@ +const setDefaults = (args) => { + if (typeof args.deleted !== 'boolean') { + args.deleted = false + } + if (typeof args.disabled !== 'boolean') { + args.disabled = false + } + return args +} + export default { Query: { - Post: async (resolve, root, args, context, info) => { - if (typeof args.deleted !== 'boolean') { - args.deleted = false - } - if (typeof args.disabled !== 'boolean') { - args.disabled = false - } - const result = await resolve(root, args, context, info) - return result + Post: (resolve, root, args, context, info) => { + return resolve(root, setDefaults(args), context, info) }, Comment: async (resolve, root, args, context, info) => { - if (typeof args.deleted !== 'boolean') { - args.deleted = false - } - if (typeof args.disabled !== 'boolean') { - args.disabled = false - } - const result = await resolve(root, args, context, info) - return result + return resolve(root, setDefaults(args), context, info) }, User: async (resolve, root, args, context, info) => { - if (typeof args.deleted !== 'boolean') { - args.deleted = false - } - if (typeof args.disabled !== 'boolean') { - args.disabled = false - } - // console.log('ROOT', root) - // console.log('ARGS', args) - // console.log('CONTEXT', context) - // console.log('info', info.fieldNodes[0].arguments) - const result = await resolve(root, args, context, info) - return result + return resolve(root, setDefaults(args), context, info) } + }, + Mutation: async (resolve, root, args, context, info) => { + return resolve(root, setDefaults(args), context, info) } } diff --git a/src/schema.graphql b/src/schema.graphql index eacbab55f..d566be159 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -1,22 +1,46 @@ type Query { isLoggedIn: Boolean! + "Get the currently logged in User based on the given JWT Token" + currentUser: User + "Get the latest Network Statistics" statistics: Statistics! } type Mutation { - login(email: String!, password: String!): LoggedInUser + "Get a JWT Token for the given Email and password" + login(email: String!, password: String!): String! signup(email: String!, password: String!): Boolean! report(resource: Resource!, description: String): Report -} -type LoggedInUser { - id: ID! - slug: String! - name: String! - avatar:String! - email: String! - role: String! - locationName: String - about: String - token: String! + "Shout the given Type and ID" + shout(id: ID!, type: ShoutTypeEnum): Boolean! @cypher(statement: """ + MATCH (n {id: $id})<-[:WROTE]-(wu:User), (u:User {id: $cypherParams.currentUserId}) + WHERE $type IN labels(n) AND NOT wu.id = $cypherParams.currentUserId + MERGE (u)-[r:SHOUTED]->(n) + RETURN COUNT(r) > 0 + """) + "Unshout the given Type and ID" + unshout(id: ID!, type: ShoutTypeEnum): Boolean! @cypher(statement: """ + MATCH (:User {id: $cypherParams.currentUserId})-[r:SHOUTED]->(n {id: $id}) + WHERE $type IN labels(n) + DELETE r + RETURN COUNT(r) > 0 + """) + + "Follow the given Type and ID" + follow(id: ID!, type: FollowTypeEnum): Boolean! @cypher(statement: """ + MATCH (n {id: $id}), (u:User {id: $cypherParams.currentUserId}) + WHERE $type IN labels(n) AND NOT $id = $cypherParams.currentUserId + MERGE (u)-[r:FOLLOWS]->(n) + RETURN COUNT(r) > 0 + """) + "Unfollow the given Type and ID" + unfollow(id: ID!, type: FollowTypeEnum): Boolean! @cypher(statement: """ + MATCH (:User {id: $cypherParams.currentUserId})-[r:FOLLOWS]->(n {id: $id}) + WHERE $type IN labels(n) + DELETE r + RETURN COUNT(r) > 0 + """) + disable(resource: Resource!): Boolean! + enable(resource: Resource!): Boolean! } type Statistics { @@ -85,6 +109,7 @@ type User { avatar: String deleted: Boolean disabled: Boolean + disabledBy: User @relation(name: "DISABLED", direction: "IN") role: UserGroupEnum publicKey: String privateKey: String @@ -97,13 +122,19 @@ type User { updatedAt: String friends: [User]! @relation(name: "FRIENDS", direction: "BOTH") - friendsCount: Int! @cypher(statement: "MATCH (this)<-[:FRIENDS]->(r:User) RETURN COUNT(r)") + friendsCount: Int! @cypher(statement: "MATCH (this)<-[:FRIENDS]->(r:User) RETURN COUNT(DISTINCT r)") following: [User]! @relation(name: "FOLLOWS", direction: "OUT") - followingCount: Int! @cypher(statement: "MATCH (this)-[:FOLLOWS]->(r:User) RETURN COUNT(r)") + followingCount: Int! @cypher(statement: "MATCH (this)-[:FOLLOWS]->(r:User) RETURN COUNT(DISTINCT r)") followedBy: [User]! @relation(name: "FOLLOWS", direction: "IN") - followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(r)") + followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(DISTINCT r)") + + "Is the currently logged in user following that user?" + followedByCurrentUser: Boolean! @cypher(statement: """ + MATCH (this)<-[:FOLLOWS]-(u:User {id: $cypherParams.currentUserId}) + RETURN COUNT(u) >= 1 + """) #contributions: [WrittenPost]! #contributions2(first: Int = 10, offset: Int = 0): [WrittenPost2]! @@ -122,7 +153,7 @@ type User { commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) WHERE NOT r.deleted = true RETURN COUNT(r)") shouted: [Post]! @relation(name: "SHOUTED", direction: "OUT") - shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)") + shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)") organizationsCreated: [Organization] @relation(name: "CREATED_ORGA", direction: "OUT") organizationsOwned: [Organization] @relation(name: "OWNING_ORGA", direction: "OUT") @@ -147,6 +178,7 @@ type Post { visibility: VisibilityEnum deleted: Boolean disabled: Boolean + disabledBy: User @relation(name: "DISABLED", direction: "IN") createdAt: String updatedAt: String @@ -163,7 +195,13 @@ type Post { commentsCount: Int! @cypher(statement: "MATCH (this)<-[:COMMENTS]-(r:Comment) RETURN COUNT(r)") shoutedBy: [User]! @relation(name: "SHOUTED", direction: "IN") - shoutedCount: Int! @cypher(statement: "MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)") + shoutedCount: Int! @cypher(statement: "MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)") + + "Has the currently logged in user shouted that post?" + shoutedByCurrentUser: Boolean! @cypher(statement: """ + MATCH (this)<-[:SHOUTED]-(u:User {id: $cypherParams.currentUserId}) + RETURN COUNT(u) >= 1 + """) } type Comment { @@ -177,6 +215,7 @@ type Comment { updatedAt: String deleted: Boolean disabled: Boolean + disabledBy: User @relation(name: "DISABLED", direction: "IN") } type Report { @@ -217,6 +256,16 @@ enum BadgeStatusEnum { permanent temporary } +enum ShoutTypeEnum { + Post + Organization + Project +} +enum FollowTypeEnum { + User + Organization + Project +} type Organization { id: ID! @@ -238,7 +287,7 @@ type Tag { name: String! taggedPosts: [Post]! @relation(name: "TAGGED", direction: "IN") taggedOrganizations: [Organization]! @relation(name: "TAGGED", direction: "IN") - taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p) RETURN COUNT(p)") + taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p) RETURN COUNT(DISTINCT p)") taggedCountUnique: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p)<-[:WROTE]-(u:User) RETURN COUNT(DISTINCT u)") deleted: Boolean disabled: Boolean diff --git a/src/seed/factories/badges.js b/src/seed/factories/badges.js index b34442521..e24a67c21 100644 --- a/src/seed/factories/badges.js +++ b/src/seed/factories/badges.js @@ -10,14 +10,14 @@ export default function (params) { } = params return ` - mutation { - CreateBadge( - id: "${id}", - key: "${key}", - type: ${type}, - status: ${status}, - icon: "${icon}" - ) { id } - } + mutation { + CreateBadge( + id: "${id}", + key: "${key}", + type: ${type}, + status: ${status}, + icon: "${icon}" + ) { id } + } ` } diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index d9bbd700c..2629ce8b6 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -15,13 +15,11 @@ export const seedServerHost = 'http://127.0.0.1:4001' const authenticatedHeaders = async ({ email, password }, host) => { const mutation = ` mutation { - login(email:"${email}", password:"${password}"){ - token - } + login(email:"${email}", password:"${password}") }` const response = await request(host, mutation) return { - authorization: `Bearer ${response.login.token}` + authorization: `Bearer ${response.login}` } } const factories = { @@ -88,6 +86,36 @@ export default function Factory (options = {}) { this.lastResponse = await this.graphQLClient.request(mutation) return this }, + async mutate (mutation, variables) { + this.lastResponse = await this.graphQLClient.request(mutation, variables) + return this + }, + async shout (properties) { + const { id, type } = properties + const mutation = ` + mutation { + shout( + id: "${id}", + type: ${type} + ) + } + ` + this.lastResponse = await this.graphQLClient.request(mutation) + return this + }, + async follow (properties) { + const { id, type } = properties + const mutation = ` + mutation { + follow( + id: "${id}", + type: ${type} + ) + } + ` + this.lastResponse = await this.graphQLClient.request(mutation) + return this + }, async cleanDatabase () { this.lastResponse = await cleanDatabase({ driver: this.neo4jDriver }) return this @@ -96,6 +124,7 @@ export default function Factory (options = {}) { result.authenticateAs.bind(result) result.create.bind(result) result.relate.bind(result) + result.mutate.bind(result) result.cleanDatabase.bind(result) return result } diff --git a/src/seed/factories/organizations.js b/src/seed/factories/organizations.js index 783edac26..e0b2e52d4 100644 --- a/src/seed/factories/organizations.js +++ b/src/seed/factories/organizations.js @@ -4,7 +4,7 @@ import uuid from 'uuid/v4' export default function create (params) { const { id = uuid(), - name = faker.comany.companyName(), + name = faker.company.companyName(), description = faker.company.catchPhrase(), disabled = false, deleted = false diff --git a/src/seed/factories/posts.js b/src/seed/factories/posts.js index d96cf4f73..e2bc2ab66 100644 --- a/src/seed/factories/posts.js +++ b/src/seed/factories/posts.js @@ -14,7 +14,6 @@ export default function (params) { ].join('. '), image = faker.image.image(), visibility = 'public', - disabled = false, deleted = false } = params @@ -26,7 +25,6 @@ export default function (params) { content: "${content}", image: "${image}", visibility: ${visibility}, - disabled: ${disabled}, deleted: ${deleted} ) { title, content } } diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index 8e0ee693c..c27b2b1ce 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -25,10 +25,13 @@ export default function create (params) { disabled: ${disabled}, deleted: ${deleted} ) { + id name email avatar role + deleted + disabled } } ` diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index b2ee8fbdb..b16e9f323 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -23,6 +23,15 @@ import Factory from './factories' f.create('User', { id: 'u7', name: 'Dagobert', role: 'user', email: 'dagobert@example.org' }) ]) + const [ asAdmin, asModerator, asUser, asTick, asTrick, asTrack ] = await Promise.all([ + Factory().authenticateAs({ email: 'admin@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'moderator@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'user@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'tick@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'trick@example.org', password: '1234' }), + Factory().authenticateAs({ email: 'track@example.org', password: '1234' }) + ]) + await Promise.all([ f.relate('User', 'Badges', { from: 'b6', to: 'u1' }), f.relate('User', 'Badges', { from: 'b5', to: 'u2' }), @@ -30,12 +39,6 @@ import Factory from './factories' f.relate('User', 'Badges', { from: 'b3', to: 'u4' }), f.relate('User', 'Badges', { from: 'b2', to: 'u5' }), f.relate('User', 'Badges', { from: 'b1', to: 'u6' }), - f.relate('User', 'Following', { from: 'u1', to: 'u2' }), - f.relate('User', 'Following', { from: 'u2', to: 'u3' }), - f.relate('User', 'Following', { from: 'u3', to: 'u4' }), - f.relate('User', 'Following', { from: 'u4', to: 'u5' }), - f.relate('User', 'Following', { from: 'u5', to: 'u6' }), - f.relate('User', 'Following', { from: 'u6', to: 'u7' }), f.relate('User', 'Friends', { from: 'u1', to: 'u2' }), f.relate('User', 'Friends', { from: 'u1', to: 'u3' }), f.relate('User', 'Friends', { from: 'u2', to: 'u3' }), @@ -44,6 +47,21 @@ import Factory from './factories' f.relate('User', 'Blacklisted', { from: 'u7', to: 'u6' }) ]) + await Promise.all([ + asAdmin + .follow({ id: 'u3', type: 'User' }), + asModerator + .follow({ id: 'u4', type: 'User' }), + asUser + .follow({ id: 'u4', type: 'User' }), + asTick + .follow({ id: 'u6', type: 'User' }), + asTrick + .follow({ id: 'u4', type: 'User' }), + asTrack + .follow({ id: 'u3', type: 'User' }) + ]) + await Promise.all([ f.create('Category', { id: 'cat1', name: 'Just For Fun', slug: 'justforfun', icon: 'smile' }), f.create('Category', { id: 'cat2', name: 'Happyness & Values', slug: 'happyness-values', icon: 'heart-o' }), @@ -70,19 +88,10 @@ import Factory from './factories' f.create('Tag', { id: 't4', name: 'Freiheit' }) ]) - const [ asAdmin, asModerator, asUser, asTick, asTrick, asTrack ] = await Promise.all([ - Factory().authenticateAs({ email: 'admin@example.org', password: '1234' }), - Factory().authenticateAs({ email: 'moderator@example.org', password: '1234' }), - Factory().authenticateAs({ email: 'user@example.org', password: '1234' }), - Factory().authenticateAs({ email: 'tick@example.org', password: '1234' }), - Factory().authenticateAs({ email: 'trick@example.org', password: '1234' }), - Factory().authenticateAs({ email: 'track@example.org', password: '1234' }) - ]) - await Promise.all([ asAdmin.create('Post', { id: 'p0' }), asModerator.create('Post', { id: 'p1' }), - asUser.create('Post', { id: 'p2' }), + asUser.create('Post', { id: 'p2', deleted: true }), asTick.create('Post', { id: 'p3' }), asTrick.create('Post', { id: 'p4' }), asTrack.create('Post', { id: 'p5' }), @@ -98,6 +107,16 @@ import Factory from './factories' asTick.create('Post', { id: 'p15' }) ]) + const disableMutation = ` + mutation { + disable(resource: { + id: "p11" + type: contribution + }) + } + ` + await asModerator.mutate(disableMutation) + await Promise.all([ f.relate('Post', 'Categories', { from: 'p0', to: 'cat16' }), f.relate('Post', 'Categories', { from: 'p1', to: 'cat1' }), @@ -133,13 +152,26 @@ import Factory from './factories' f.relate('Post', 'Tags', { from: 'p14', to: 't2' }), f.relate('Post', 'Tags', { from: 'p15', to: 't3' }) ]) + await Promise.all([ - f.relate('User', 'Shouted', { from: 'u1', to: 'p2' }), - f.relate('User', 'Shouted', { from: 'u1', to: 'p3' }), - f.relate('User', 'Shouted', { from: 'u2', to: 'p1' }), - f.relate('User', 'Shouted', { from: 'u3', to: 'p1' }), - f.relate('User', 'Shouted', { from: 'u3', to: 'p4' }), - f.relate('User', 'Shouted', { from: 'u4', to: 'p1' }) + asAdmin + .shout({ id: 'p2', type: 'Post' }), + asAdmin + .shout({ id: 'p6', type: 'Post' }), + asModerator + .shout({ id: 'p0', type: 'Post' }), + asModerator + .shout({ id: 'p6', type: 'Post' }), + asUser + .shout({ id: 'p6', type: 'Post' }), + asUser + .shout({ id: 'p7', type: 'Post' }), + asTick + .shout({ id: 'p8', type: 'Post' }), + asTick + .shout({ id: 'p9', type: 'Post' }), + asTrack + .shout({ id: 'p10', type: 'Post' }) ]) await Promise.all([ diff --git a/src/server.js b/src/server.js index 10fdf291c..c546c74c3 100644 --- a/src/server.js +++ b/src/server.js @@ -8,11 +8,8 @@ import middleware from './middleware' import applyDirectives from './bootstrap/directives' import applyScalars from './bootstrap/scalars' import { getDriver } from './bootstrap/neo4j' - -import passport from 'passport' -import jwtStrategy from './jwt/strategy' -import jwt from 'jsonwebtoken' import helmet from 'helmet' +import decode from './jwt/decode' dotenv.config() // check env and warn @@ -43,20 +40,17 @@ schema = applyScalars(applyDirectives(schema)) const createServer = (options) => { const defaults = { - context: async (req) => { - const payload = { + context: async ({ request }) => { + const authorizationHeader = request.headers.authorization || '' + const user = await decode(driver, authorizationHeader) + return { driver, - user: null, - req: req.request + user, + req: request, + cypherParams: { + currentUserId: user ? user.id : null + } } - try { - const token = payload.req.headers.authorization.replace('Bearer ', '') - payload.user = await jwt.verify(token, process.env.JWT_SECRET) - } catch (err) { - // nothing - } - - return payload }, schema: schema, debug: debug, @@ -66,12 +60,8 @@ const createServer = (options) => { } const server = new GraphQLServer(Object.assign({}, defaults, options)) - passport.use('jwt', jwtStrategy(driver)) server.express.use(helmet()) - server.express.use(passport.initialize()) server.express.use(express.static('public')) - - server.express.post('/graphql', passport.authenticate(['jwt'], { session: false })) return server } diff --git a/yarn.lock b/yarn.lock index 52fb19cde..b2224310d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38,7 +38,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.1.0", "@babel/core@~7.3.3": +"@babel/core@^7.1.0": version "7.3.3" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.3.tgz#d090d157b7c5060d05a05acaebc048bd2b037947" integrity sha512-w445QGI2qd0E0GlSnq6huRZWPMmQGCp5gd5ZWS4hagn0EiwzxD5QMFkpchyusAyVC1n27OKXzQ0/88aVU9n4xQ== @@ -58,6 +58,26 @@ semver "^5.4.1" source-map "^0.5.0" +"@babel/core@~7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.4.tgz#921a5a13746c21e32445bf0798680e9d11a6530b" + integrity sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.3.4" + "@babel/helpers" "^7.2.0" + "@babel/parser" "^7.3.4" + "@babel/template" "^7.2.2" + "@babel/traverse" "^7.3.4" + "@babel/types" "^7.3.4" + convert-source-map "^1.1.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.11" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + "@babel/generator@^7.0.0", "@babel/generator@^7.2.2", "@babel/generator@^7.3.3": version "7.3.3" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.3.tgz#185962ade59a52e00ca2bdfcfd1d58e528d4e39e" @@ -69,6 +89,17 @@ source-map "^0.5.0" trim-right "^1.0.1" +"@babel/generator@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.4.tgz#9aa48c1989257877a9d971296e5b73bfe72e446e" + integrity sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg== + dependencies: + "@babel/types" "^7.3.4" + jsesc "^2.5.1" + lodash "^4.17.11" + source-map "^0.5.0" + trim-right "^1.0.1" + "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" @@ -199,6 +230,16 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-replace-supers@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.3.4.tgz#a795208e9b911a6eeb08e5891faacf06e7013e13" + integrity sha512-pvObL9WVf2ADs+ePg0jrqlhHoxRXlOa+SHRHzAXIz2xkYuOHfGl+fKxPMaS4Fq+uje8JQPobnertBBvyrWnQ1A== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.3.4" + "@babel/types" "^7.3.4" + "@babel/helper-simple-access@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" @@ -258,6 +299,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.3.tgz#092d450db02bdb6ccb1ca8ffd47d8774a91aef87" integrity sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg== +"@babel/parser@^7.1.0", "@babel/parser@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.4.tgz#a43357e4bbf4b92a437fb9e465c192848287f27c" + integrity sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ== + "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" @@ -275,10 +321,10 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-json-strings" "^7.2.0" -"@babel/plugin-proposal-object-rest-spread@^7.3.1": - version "7.3.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.2.tgz#6d1859882d4d778578e41f82cc5d7bf3d5daf6c1" - integrity sha512-DjeMS+J2+lpANkYLLO+m6GjoTMygYglKmRe6cDTbFv3L9i6mmiE8fe6B8MtCSLZpVXscD5kn7s6SgtHrDoBWoA== +"@babel/plugin-proposal-object-rest-spread@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.4.tgz#47f73cf7f2a721aad5c0261205405c642e424654" + integrity sha512-j7VQmbbkA+qrzNqbKHrBsW3ddFnOeva6wzSe/zB7T+xaxGc+RCpwo44wCmRixAIGRoIpmVgvzFzNJqQcO3/9RA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -350,10 +396,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-async-to-generator@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz#68b8a438663e88519e65b776f8938f3445b1a2ff" - integrity sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ== +"@babel/plugin-transform-async-to-generator@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.3.4.tgz#4e45408d3c3da231c0e7b823f407a53a7eb3048c" + integrity sha512-Y7nCzv2fw/jEZ9f678MuKdMo99MFDJMT/PvD9LisrR5JDFcJH6vYeH6RnjVt3p5tceyGRvTtEN0VOlU+rgHZjA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -366,25 +412,25 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-block-scoping@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz#f17c49d91eedbcdf5dd50597d16f5f2f770132d4" - integrity sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q== +"@babel/plugin-transform-block-scoping@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.3.4.tgz#5c22c339de234076eee96c8783b2fed61202c5c4" + integrity sha512-blRr2O8IOZLAOJklXLV4WhcEzpYafYQKSGT3+R26lWG41u/FODJuBggehtOwilVAcFu393v3OFj+HmaE6tVjhA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.10" + lodash "^4.17.11" -"@babel/plugin-transform-classes@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.0.tgz#374f8876075d7d21fea55aeb5c53561259163f96" - integrity sha512-aPCEkrhJYebDXcGTAP+cdUENkH7zqOlgbKwLbghjjHpJRJBWM/FSlCjMoPGA8oUdiMfOrk3+8EFPLLb5r7zj2w== +"@babel/plugin-transform-classes@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.3.4.tgz#dc173cb999c6c5297e0b5f2277fdaaec3739d0cc" + integrity sha512-J9fAvCFBkXEvBimgYxCjvaVDzL6thk0j0dBvCeZmIUDBwyt+nv6HfbImsSrWsYXfDNDivyANgJlFXDUWRTZBuA== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-define-map" "^7.1.0" "@babel/helper-function-name" "^7.1.0" "@babel/helper-optimise-call-expression" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" + "@babel/helper-replace-supers" "^7.3.4" "@babel/helper-split-export-declaration" "^7.0.0" globals "^11.1.0" @@ -465,10 +511,10 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" -"@babel/plugin-transform-modules-systemjs@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.2.0.tgz#912bfe9e5ff982924c81d0937c92d24994bb9068" - integrity sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ== +"@babel/plugin-transform-modules-systemjs@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.3.4.tgz#813b34cd9acb6ba70a84939f3680be0eb2e58861" + integrity sha512-VZ4+jlGOF36S7TjKs8g4ojp4MEI+ebCQZdswWb/T9I4X84j8OtFAyjXjt/M16iIm5RIZn0UMQgg/VgIwo/87vw== dependencies: "@babel/helper-hoist-variables" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -512,12 +558,12 @@ "@babel/helper-get-function-arity" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-regenerator@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz#5b41686b4ed40bef874d7ed6a84bdd849c13e0c1" - integrity sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw== +"@babel/plugin-transform-regenerator@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.3.4.tgz#1601655c362f5b38eead6a52631f5106b29fa46a" + integrity sha512-hvJg8EReQvXT6G9H2MvNPXkv9zK36Vxa1+csAVTpE1J3j0zlHplw76uudEbJxgvqZzAq9Yh45FLD4pk5mKRFQA== dependencies: - regenerator-transform "^0.13.3" + regenerator-transform "^0.13.4" "@babel/plugin-transform-shorthand-properties@^7.2.0": version "7.2.0" @@ -581,16 +627,16 @@ core-js "^2.5.7" regenerator-runtime "^0.12.0" -"@babel/preset-env@~7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.1.tgz#389e8ca6b17ae67aaf9a2111665030be923515db" - integrity sha512-FHKrD6Dxf30e8xgHQO0zJZpUPfVZg+Xwgz5/RdSWCbza9QLNk4Qbp40ctRoqDxml3O8RMzB1DU55SXeDG6PqHQ== +"@babel/preset-env@~7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.4.tgz#887cf38b6d23c82f19b5135298bdb160062e33e1" + integrity sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-async-generator-functions" "^7.2.0" "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.3.1" + "@babel/plugin-proposal-object-rest-spread" "^7.3.4" "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" "@babel/plugin-proposal-unicode-property-regex" "^7.2.0" "@babel/plugin-syntax-async-generators" "^7.2.0" @@ -598,10 +644,10 @@ "@babel/plugin-syntax-object-rest-spread" "^7.2.0" "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" "@babel/plugin-transform-arrow-functions" "^7.2.0" - "@babel/plugin-transform-async-to-generator" "^7.2.0" + "@babel/plugin-transform-async-to-generator" "^7.3.4" "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.2.0" - "@babel/plugin-transform-classes" "^7.2.0" + "@babel/plugin-transform-block-scoping" "^7.3.4" + "@babel/plugin-transform-classes" "^7.3.4" "@babel/plugin-transform-computed-properties" "^7.2.0" "@babel/plugin-transform-destructuring" "^7.2.0" "@babel/plugin-transform-dotall-regex" "^7.2.0" @@ -612,13 +658,13 @@ "@babel/plugin-transform-literals" "^7.2.0" "@babel/plugin-transform-modules-amd" "^7.2.0" "@babel/plugin-transform-modules-commonjs" "^7.2.0" - "@babel/plugin-transform-modules-systemjs" "^7.2.0" + "@babel/plugin-transform-modules-systemjs" "^7.3.4" "@babel/plugin-transform-modules-umd" "^7.2.0" "@babel/plugin-transform-named-capturing-groups-regex" "^7.3.0" "@babel/plugin-transform-new-target" "^7.0.0" "@babel/plugin-transform-object-super" "^7.2.0" "@babel/plugin-transform-parameters" "^7.2.0" - "@babel/plugin-transform-regenerator" "^7.0.0" + "@babel/plugin-transform-regenerator" "^7.3.4" "@babel/plugin-transform-shorthand-properties" "^7.2.0" "@babel/plugin-transform-spread" "^7.2.0" "@babel/plugin-transform-sticky-regex" "^7.2.0" @@ -674,6 +720,21 @@ globals "^11.1.0" lodash "^4.17.10" +"@babel/traverse@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.3.4.tgz#1330aab72234f8dea091b08c4f8b9d05c7119e06" + integrity sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.3.4" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/parser" "^7.3.4" + "@babel/types" "^7.3.4" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.11" + "@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.3": version "7.3.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.3.tgz#6c44d1cdac2a7625b624216657d5bc6c107ab436" @@ -683,6 +744,160 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" +"@babel/types@^7.3.0", "@babel/types@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.4.tgz#bf482eaeaffb367a28abbf9357a94963235d90ed" + integrity sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ== + dependencies: + esutils "^2.0.2" + lodash "^4.17.11" + to-fast-properties "^2.0.0" + +"@cnakazawa/watch@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" + integrity sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + +"@jest/console@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.3.0.tgz#7bd920d250988ba0bf1352c4493a48e1cb97671e" + integrity sha512-NaCty/OOei6rSDcbPdMiCbYCI0KGFGPgGO6B09lwWt5QTxnkuhKYET9El5u5z1GAcSxkQmSMtM63e24YabCWqA== + dependencies: + "@jest/source-map" "^24.3.0" + "@types/node" "*" + chalk "^2.0.1" + slash "^2.0.0" + +"@jest/core@^24.3.1": + version "24.3.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.3.1.tgz#9811596d9fcc6dbb3d4062c67e4c4867bc061585" + integrity sha512-orucOIBKfXgm1IJirtPT0ToprqDVGYKUNJKNc9a6v1Lww6qLPq+xj5OfxyhpJb2rWOgzEkATW1bfZzg3oqV70w== + dependencies: + "@jest/console" "^24.3.0" + "@jest/reporters" "^24.3.1" + "@jest/test-result" "^24.3.0" + "@jest/transform" "^24.3.1" + "@jest/types" "^24.3.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-changed-files "^24.3.0" + jest-config "^24.3.1" + jest-haste-map "^24.3.1" + jest-message-util "^24.3.0" + jest-regex-util "^24.3.0" + jest-resolve-dependencies "^24.3.1" + jest-runner "^24.3.1" + jest-runtime "^24.3.1" + jest-snapshot "^24.3.1" + jest-util "^24.3.0" + jest-validate "^24.3.1" + jest-watcher "^24.3.0" + micromatch "^3.1.10" + p-each-series "^1.0.0" + pirates "^4.0.1" + realpath-native "^1.1.0" + rimraf "^2.5.4" + strip-ansi "^5.0.0" + +"@jest/environment@^24.3.1": + version "24.3.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.3.1.tgz#1fbda3ec8fb8ffbaee665d314da91d662227e11e" + integrity sha512-M8bqEkQqPwZVhMMFMqqCnzqIZtuM5vDMfFQ9ZvnEfRT+2T1zTA4UAOH/V4HagEi6S3BCd/mdxFdYmPgXf7GKCA== + dependencies: + "@jest/fake-timers" "^24.3.0" + "@jest/transform" "^24.3.1" + "@jest/types" "^24.3.0" + "@types/node" "*" + jest-mock "^24.3.0" + +"@jest/fake-timers@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.3.0.tgz#0a7f8b877b78780c3fa5c3f8683cc0aaf9488331" + integrity sha512-rHwVI17dGMHxHzfAhnZ04+wFznjFfZ246QugeBnbiYr7/bDosPD2P1qeNjWnJUUcfl0HpS6kkr+OB/mqSJxQFg== + dependencies: + "@jest/types" "^24.3.0" + "@types/node" "*" + jest-message-util "^24.3.0" + jest-mock "^24.3.0" + +"@jest/reporters@^24.3.1": + version "24.3.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.3.1.tgz#68e4abc8d4233acd0dd87287f3bd270d81066248" + integrity sha512-jEIDJcvk20ReUW1Iqb+prlAcFV+kfFhQ/01poCq8X9As7/l/2y1GqVwJ3+6SaPTZuCXh0d0LVDy86zDAa8zlVA== + dependencies: + "@jest/environment" "^24.3.1" + "@jest/test-result" "^24.3.0" + "@jest/transform" "^24.3.1" + "@jest/types" "^24.3.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + istanbul-api "^2.1.1" + istanbul-lib-coverage "^2.0.2" + istanbul-lib-instrument "^3.0.1" + istanbul-lib-source-maps "^3.0.1" + jest-haste-map "^24.3.1" + jest-resolve "^24.3.1" + jest-runtime "^24.3.1" + jest-util "^24.3.0" + jest-worker "^24.3.1" + node-notifier "^5.2.1" + slash "^2.0.0" + source-map "^0.6.0" + string-length "^2.0.0" + +"@jest/source-map@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28" + integrity sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.1.15" + source-map "^0.6.0" + +"@jest/test-result@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.3.0.tgz#4c0b1c9716212111920f7cf8c4329c69bc81924a" + integrity sha512-j7UZ49T8C4CVipEY99nLttnczVTtLyVzFfN20OiBVn7awOs0U3endXSTq7ouPrLR5y4YjI5GDcbcvDUjgeamzg== + dependencies: + "@jest/console" "^24.3.0" + "@jest/types" "^24.3.0" + "@types/istanbul-lib-coverage" "^1.1.0" + +"@jest/transform@^24.3.1": + version "24.3.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.3.1.tgz#ce9e1329eb5e640f493bcd5c8eb9970770959bfc" + integrity sha512-PpjylI5goT4Si69+qUjEeHuKjex0LjjrqJzrMYzlOZn/+SCumGKuGC0UQFeEPThyGsFvWH1Q4gj0R66eOHnIpw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^24.3.0" + babel-plugin-istanbul "^5.1.0" + chalk "^2.0.1" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.15" + jest-haste-map "^24.3.1" + jest-regex-util "^24.3.0" + jest-util "^24.3.0" + micromatch "^3.1.10" + realpath-native "^1.1.0" + slash "^2.0.0" + source-map "^0.6.1" + write-file-atomic "2.4.1" + +"@jest/types@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.3.0.tgz#3f6e117e47248a9a6b5f1357ec645bd364f7ad23" + integrity sha512-VoO1F5tU2n/93QN/zaZ7Q8SeV/Rj+9JJOgbvKbBwy4lenvmdj1iDaQEPXGTKrO6OSvDeb2drTFipZJYxgo6kIQ== + dependencies: + "@types/istanbul-lib-coverage" "^1.1.0" + "@types/yargs" "^12.0.9" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -743,6 +958,39 @@ dependencies: "@types/node" "*" +"@types/babel__core@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.0.tgz#710f2487dda4dcfd010ca6abb2b4dc7394365c51" + integrity sha512-wJTeJRt7BToFx3USrCDs2BhEi4ijBInTQjOIukj6a/5tEkwpFMVZ+1ppgmE+Q/FQyc5P/VWUbx7I9NELrKruHA== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.0.2.tgz#d2112a6b21fad600d7674274293c85dce0cb47fc" + integrity sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" + integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.6.tgz#328dd1a8fc4cfe3c8458be9477b219ea158fd7b2" + integrity sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw== + dependencies: + "@babel/types" "^7.3.0" + "@types/body-parser@*", "@types/body-parser@1.17.0": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" @@ -807,6 +1055,11 @@ resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-14.0.3.tgz#389e2e5b83ecdb376d9f98fae2094297bc112c1c" integrity sha512-TcFkpEjcQK7w8OcrQcd7iIBPjU0rdyi3ldj6d0iJ4PPSzbWqPBvXj9KSwO14hTOX2dm9RoiH7VuxksJLNYdXUQ== +"@types/istanbul-lib-coverage@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz#2cc2ca41051498382b43157c8227fea60363f94a" + integrity sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ== + "@types/long@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" @@ -835,6 +1088,11 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" +"@types/stack-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" + integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== + "@types/ws@^6.0.0": version "6.0.1" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28" @@ -843,6 +1101,11 @@ "@types/events" "*" "@types/node" "*" +"@types/yargs@^12.0.2", "@types/yargs@^12.0.9": + version "12.0.9" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.9.tgz#693e76a52f61a2f1e7fb48c0eef167b95ea4ffd0" + integrity sha512-sCZy4SxP9rN2w30Hlmg5dtdRwgYQfYRiLo9usw8X9cxlf+H4FqM1xX7+sNH7NNKVdbXMJWqva7iyy+fxh/V7fA== + "@types/zen-observable@^0.5.3": version "0.5.4" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.4.tgz#b863a4191e525206819e008097ebf0fb2e3a1cdc" @@ -894,12 +1157,17 @@ acorn@^5.5.3: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== -acorn@^6.0.1, acorn@^6.0.2: +acorn@^6.0.1: version "6.0.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== -activitystrea.ms@^2.1.3: +acorn@^6.0.7: + version "6.1.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.0.tgz#b0a3be31752c97a0f7013c5f4903b71a05db6818" + integrity sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw== + +activitystrea.ms@~2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/activitystrea.ms/-/activitystrea.ms-2.1.3.tgz#553548733e367dc0b6a7badc25fa6f8996cd80c3" integrity sha512-iiG5g5fYgfdaaqqFPaFIZC/KX8/4mOWkvniK+BNwJY6XDDKdIu56wmc9r0x1INHVnbFOTGuM8mZEntaM3I+YXw== @@ -926,10 +1194,10 @@ activitystreams-context@>=3.0.0, activitystreams-context@^3.0.0: resolved "https://registry.yarnpkg.com/activitystreams-context/-/activitystreams-context-3.1.0.tgz#28334e129f17cfb937e8c702c52c1bcb1d2830c7" integrity sha512-KBQ+igwf1tezMXGVw5MvRSEm0gp97JI1hTZ45I6MEkWv25lEgNoA9L6wqfaOiCX8wnMRWw9pwRsPZKypdtxAtg== -ajv@^6.5.3, ajv@^6.5.5, ajv@^6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.1.tgz#6360f5ed0d80f232cc2b294c362d5dc2e538dd61" - integrity sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww== +ajv@^6.5.5, ajv@^6.9.1: + version "6.9.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.9.2.tgz#4927adb83e7f48e5a32b45729744c71ec39c9c7b" + integrity sha512-4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -948,6 +1216,11 @@ ansi-escapes@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -983,13 +1256,13 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -apollo-cache-control@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.5.1.tgz#db7e86cd7ede6cad0a2e0ea97488d9fb5c33d913" - integrity sha512-82hzX7/fFiu5dODLS8oGieEE4jLjMIhIkQ4JTsWj9drv8PZJltl0xqORtU2jA/FottjxfYab8+ebi3BgGPOaqw== +apollo-cache-control@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.5.2.tgz#47931ede0b11c64d45429850c274b30d19322362" + integrity sha512-uehXDUrd3Qim+nzxqqN7XT1YTbNSyumW3/FY5BxbKZTI8d4oPG4eyVQKqaggooSjswKQnOoIQVes3+qg9tGAkw== dependencies: apollo-server-env "2.2.0" - graphql-extensions "0.5.2" + graphql-extensions "0.5.4" apollo-cache-control@^0.1.0: version "0.1.1" @@ -998,35 +1271,37 @@ apollo-cache-control@^0.1.0: dependencies: graphql-extensions "^0.0.x" -apollo-cache-inmemory@~1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.4.3.tgz#aded4fb8b3de9e2fb2573a6c03591b07ef98ed36" - integrity sha512-p9KGtEZ9Mlb+FS0UEaxR8WvKOijYV0c+TXlhC/XZ3/ltYvP1zL3b1ozSOLGR9SawN2895Fc7QDV5nzPpihV0rA== +apollo-cache-inmemory@~1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.5.1.tgz#265d1ee67b0bf0aca9c37629d410bfae44e62953" + integrity sha512-D3bdpPmWfaKQkWy8lfwUg+K8OBITo3sx0BHLs1B/9vIdOIZ7JNCKq3EUcAgAfInomJUdN0QG1yOfi8M8hxkN1g== dependencies: - apollo-cache "^1.1.26" - apollo-utilities "^1.1.3" + apollo-cache "^1.2.1" + apollo-utilities "^1.2.1" optimism "^0.6.9" + ts-invariant "^0.2.1" tslib "^1.9.3" -apollo-cache@1.1.26, apollo-cache@^1.1.26: - version "1.1.26" - resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.1.26.tgz#5afe023270effbc2063d90f51d8e56bce274ab37" - integrity sha512-JKFHijwkhXpcQ3jOat+ctwiXyjDhQgy0p6GSaj7zG+or+ZSalPqUnPzFRgRwFLVbYxBKJgHCkWX+2VkxWTZzQQ== +apollo-cache@1.2.1, apollo-cache@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.2.1.tgz#aae71eb4a11f1f7322adc343f84b1a39b0693644" + integrity sha512-nzFmep/oKlbzUuDyz6fS6aYhRmfpcHWqNkkA9Bbxwk18RD6LXC4eZkuE0gXRX0IibVBHNjYVK+Szi0Yied4SpQ== dependencies: - apollo-utilities "^1.1.3" + apollo-utilities "^1.2.1" tslib "^1.9.3" -apollo-client@~2.4.13: - version "2.4.13" - resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.4.13.tgz#09829fcbd68e069de9840d0a10764d7c6a3d0787" - integrity sha512-7mBdW/CW1qHB8Mj4EFAG3MTtbRc6S8aUUntUdrKfRWV1rZdWa0NovxsgVD/R4HZWZjRQ2UOM4ENsHdM5g1uXOQ== +apollo-client@~2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.5.1.tgz#36126ed1d32edd79c3713c6684546a3bea80e6d1" + integrity sha512-MNcQKiqLHdGmNJ0rZ0NXaHrToXapJgS/5kPk0FygXt+/FmDCdzqcujI7OPxEC6e9Yw5S/8dIvOXcRNuOMElHkA== dependencies: "@types/zen-observable" "^0.8.0" - apollo-cache "1.1.26" + apollo-cache "1.2.1" apollo-link "^1.0.0" apollo-link-dedup "^1.0.0" - apollo-utilities "1.1.3" + apollo-utilities "1.2.1" symbol-observable "^1.0.2" + ts-invariant "^0.2.1" tslib "^1.9.3" zen-observable "^0.8.0" @@ -1045,17 +1320,17 @@ apollo-engine-reporting-protobuf@0.2.1: dependencies: protobufjs "^6.8.6" -apollo-engine-reporting@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.0.2.tgz#5dd5411f17d76e6788a1166367a2ab7b52794224" - integrity sha512-g6JkO5WaMuqXfn3WoZMQyyFzpxfHsw/f7P7XTHSEqTSd/M4uk7/uih/xcqmgBGt4ET30KbaGFz2l4FJzO06A5w== +apollo-engine-reporting@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.0.7.tgz#d326b51b12b1f71a40885b8189dbcd162171c953" + integrity sha512-mFsXvd+1/o5jSa9tI2RoXYGcvCLcwwcfLwchjSTxqUd4ViB8RbqYKynzEZ+Omji7PBRM0azioBm43f7PSsQPqA== dependencies: apollo-engine-reporting-protobuf "0.2.1" apollo-graphql "^0.1.0" - apollo-server-core "2.4.2" + apollo-server-core "2.4.8" apollo-server-env "2.2.0" async-retry "^1.2.1" - graphql-extensions "0.5.2" + graphql-extensions "0.5.7" apollo-env@0.3.3: version "0.3.3" @@ -1065,6 +1340,14 @@ apollo-env@0.3.3: core-js "3.0.0-beta.13" node-fetch "^2.2.0" +apollo-errors@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/apollo-errors/-/apollo-errors-1.9.0.tgz#f1ed0ca0a6be5cd2f24e2eaa7b0860a10146ff51" + integrity sha512-XVukHd0KLvgY6tNjsPS3/Re3U6RQlTKrTbIpqqeTMo2N34uQMr+H1UheV21o8hOZBAFosvBORVricJiP5vfmrw== + dependencies: + assert "^1.4.1" + extendable-error "^0.1.5" + apollo-graphql@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.1.1.tgz#dc5eac3062abf9f063ac9869f0ef5c54fdc136e5" @@ -1072,12 +1355,13 @@ apollo-graphql@^0.1.0: dependencies: lodash.sortby "^4.7.0" -apollo-link-context@^1.0.14: - version "1.0.14" - resolved "https://registry.yarnpkg.com/apollo-link-context/-/apollo-link-context-1.0.14.tgz#6265eef49bedadddbbcff4026d04cd351094cd6c" - integrity sha512-l6SIN7Fwqhgg5C5eA8xSrt8gulHBmYTE3J4z5/Q2hP/8Kok0rQ/z5q3uy42/hkdYlnaktOvpz+ZIwEFzcXwujQ== +apollo-link-context@~1.0.14: + version "1.0.15" + resolved "https://registry.yarnpkg.com/apollo-link-context/-/apollo-link-context-1.0.15.tgz#9e5dc3eb874b3ed975f0bb0062a65aa946fd30a2" + integrity sha512-CkUB0CaaNGCsiNxG6GImPSsXHL8f+lQZukl2TLdpDKao3EyCuPC9gSWvclUagwZ1TDnY8O+wJnNBDGymQiZTsA== dependencies: - apollo-link "^1.2.8" + apollo-link "^1.2.9" + tslib "^1.9.3" apollo-link-dedup@^1.0.0: version "1.0.11" @@ -1086,27 +1370,33 @@ apollo-link-dedup@^1.0.0: dependencies: apollo-link "^1.2.4" -apollo-link-http-common@^0.2.10: - version "0.2.10" - resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.10.tgz#b5bbf502ff40a81cc00281ba3b8543b7ad866dfe" - integrity sha512-KY9nhpAurw3z48OIYV0sCZFXrzWp/wjECsveK+Q9GUhhSe1kEbbUjFfmi+qigg+iELgdp5V8ioRJhinl1vPojw== +apollo-link-http-common@^0.2.11: + version "0.2.11" + resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.11.tgz#d4e494ed1e45ea0e0c0ed60f3df64541d0de682d" + integrity sha512-FjtzEDiG6blH/2MR4fpVNoxdZUFmddP0sez34qnoLaYz6ABFbTDlmRE/dVN79nPExM4Spfs/DtW7KRqyjJ3tOg== dependencies: - apollo-link "^1.2.8" + apollo-link "^1.2.9" + ts-invariant "^0.3.2" + tslib "^1.9.3" -apollo-link-http@~1.5.11: - version "1.5.11" - resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.11.tgz#1f72a377d03e874a08bc9eadb1ce7ecb166f1e56" - integrity sha512-wDG+I9UmpfaZRPIvTYBgkvqiCgmz6yWgvuzW/S24Q4r4Xrfe6sLpg2FmarhtdP+hdN+IXTLbFNCZ+Trgfpifow== +apollo-link-http@~1.5.12: + version "1.5.12" + resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.12.tgz#878d48bf9d8ae091752710529a222c4a5548118e" + integrity sha512-2tS36RIU6OdxzoWYTPrjvDTF2sCrnlaJ6SL7j0ILPn1Lmw4y6YLwKDsv/SWLwtodtVe9v1dLCGKIGMRMM/SdyA== dependencies: - apollo-link "^1.2.8" - apollo-link-http-common "^0.2.10" + apollo-link "^1.2.9" + apollo-link-http-common "^0.2.11" + tslib "^1.9.3" -apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.8.tgz#0f252adefd5047ac1a9f35ba9439d216587dcd84" - integrity sha512-lfzGRxhK9RmiH3HPFi7TIEBhhDY9M5a2ZDnllcfy5QDk7cCQHQ1WQArcw1FK0g1B+mV4Kl72DSrlvZHZJEolrA== +apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.9.tgz#40a8f0b90716ce3fd6beb27b7eae1108b92e0054" + integrity sha512-ZLUwthOFZq4lxchQ2jeBfVqS/UDdcVmmh8aUw6Ar9awZH4r+RgkcDeu2ooFLUfodWE3mZr7wIZuYsBas/MaNVA== dependencies: - zen-observable-ts "^0.8.15" + apollo-utilities "^1.2.1" + ts-invariant "^0.3.2" + tslib "^1.9.3" + zen-observable-ts "^0.8.16" apollo-server-caching@0.3.1: version "0.3.1" @@ -1115,24 +1405,24 @@ apollo-server-caching@0.3.1: dependencies: lru-cache "^5.0.0" -apollo-server-core@2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.4.2.tgz#916d98636b1bf576a84b4a469006c1c73741e03a" - integrity sha512-IOWhqjjI1sH38sj7ycjke0dXXEgaqOkb2hDpLBTSiVWKBIqFfo4gchWK5wcWW9jReDpf/+G2wogH+UvONs2ejg== +apollo-server-core@2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.4.8.tgz#47e503a345e314222725597c889773e018d8c67a" + integrity sha512-N+5UOzHhMOnHizEiArJtNvEe/cGhSHQyTn5tlU4RJ36FDBJ/WlYZfPbGDMLISSUCJ6t+aP8GLL4Mnudt9d2PDQ== dependencies: "@apollographql/apollo-tools" "^0.3.3" "@apollographql/graphql-playground-html" "^1.6.6" "@types/ws" "^6.0.0" - apollo-cache-control "0.5.1" + apollo-cache-control "0.5.2" apollo-datasource "0.3.1" - apollo-engine-reporting "1.0.2" + apollo-engine-reporting "1.0.7" apollo-server-caching "0.3.1" apollo-server-env "2.2.0" - apollo-server-errors "2.2.0" - apollo-server-plugin-base "0.3.2" - apollo-tracing "0.5.1" + apollo-server-errors "2.2.1" + apollo-server-plugin-base "0.3.7" + apollo-tracing "0.5.2" fast-json-stable-stringify "^2.0.0" - graphql-extensions "0.5.2" + graphql-extensions "0.5.7" graphql-subscriptions "^1.0.0" graphql-tag "^2.9.2" graphql-tools "^4.0.0" @@ -1158,15 +1448,15 @@ apollo-server-env@2.2.0: node-fetch "^2.1.2" util.promisify "^1.0.0" -apollo-server-errors@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" - integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== +apollo-server-errors@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.1.tgz#f68a3f845929768057da7e1c6d30517db5872205" + integrity sha512-wY/YE3iJVMYC+WYIf8QODBjIP4jhI+oc7kiYo9mrz7LdYPKAgxr/he+NteGcqn/0Ea9K5/ZFTGJDbEstSMeP8g== -apollo-server-express@2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.4.2.tgz#870daf04fd9b727a54b1339cdb55066450b3e05a" - integrity sha512-Q5/unCAi6a2dT39LQaIiLC1d8O4fmBDU2CrRhVhPWP8I344xPgNOcrs7MsNN7Ecb56UGbgDKxBoWowFG65ulKw== +apollo-server-express@2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.4.8.tgz#ec9eb61a87324555d49097e9fade3c7d142eb6cb" + integrity sha512-i60l32mfVe33jnKDPNYgUKUKu4Al0xEm2HLOSMgtJ9Wbpe/MbOx5X8M5F27fnHYdM+G5XfAErsakAyRGnQJ48Q== dependencies: "@apollographql/graphql-playground-html" "^1.6.6" "@types/accepts" "^1.3.5" @@ -1174,7 +1464,7 @@ apollo-server-express@2.4.2: "@types/cors" "^2.8.4" "@types/express" "4.16.1" accepts "^1.3.5" - apollo-server-core "2.4.2" + apollo-server-core "2.4.8" body-parser "^1.18.3" cors "^2.8.4" graphql-subscriptions "^1.0.0" @@ -1202,36 +1492,36 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0: resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec" integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA== -apollo-server-plugin-base@0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.2.tgz#4609c9a9d154568401d84b7ac17d1e30e3529104" - integrity sha512-yzXrkVSPBoux2uPgbTGROGh7W0axRWopMZM+KT9aF9H/+yMCwtt0EhGOGyNUDMOFA4rT3z+cLVvYuZr1rSQWcg== +apollo-server-plugin-base@0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.7.tgz#bfa4932fc9481bb36221545578d311db464af5a6" + integrity sha512-hW1jaLKf9qNOxMTwRq2CSqz3eqXsZuEiCc8/mmEtOciiVBq1GMtxFf19oIYM9HQuPvQU2RWpns1VrYN59L3vbg== -apollo-server-testing@~2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.4.2.tgz#5c87b34b0b6a1a3e5a1784cadc16bc495dded2e1" - integrity sha512-WZ901nh7uG75342lMukJvuxFF/w3W5JDyWElY8KDhXfaDLbMKqhRqaWRIiEEX4YvciO5ACSzqKt+957/y1yUUQ== +apollo-server-testing@~2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.4.8.tgz#eb929a431e059723c298919688355434d53e3ea8" + integrity sha512-AmNn5pDn9FJ9AJbmc7gwsUFaUt4uf44IFHaCfZow/jkAeY2JZnIozt8LYC8Koidy+Lfb+i/HsjkgbBodElbGMQ== dependencies: - apollo-server-core "2.4.2" + apollo-server-core "2.4.8" -apollo-server@~2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.4.2.tgz#6ca42906664918c32d8be391db1178c6eaa8dc54" - integrity sha512-oFwHUhJtJedIPCtZ2ftvRWrVA3KpmeWsgDBs4e5jW/7f5ozkUF22h7L3iy8rEljppiEa2X/GgSi11SVxIOL8gw== +apollo-server@~2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.4.8.tgz#b18ec24e6356dd2a191a6fa0f1429b07ef7c89e3" + integrity sha512-IU6RekO2dqrDdC+5hU6aeVvGg/2t/f01inBMjDhAn1a7hoITUXEh8Sa57TgmYEZ5uAtDuWW7cdiZN2j0cMI3/w== dependencies: - apollo-server-core "2.4.2" - apollo-server-express "2.4.2" + apollo-server-core "2.4.8" + apollo-server-express "2.4.8" express "^4.0.0" graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" -apollo-tracing@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.5.1.tgz#16be201bc276120f0f8b7aa180201ee89d57e3bd" - integrity sha512-5gb8OWzkGaJFsmQdyMyZnOjcq6weMTkqJSGj0hfR7uX99X4SBFAzZV4nTeK4z0XkXO2I12xSTJoS4gxbFjgeaA== +apollo-tracing@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.5.2.tgz#cc49936fb435fa98d19c841514cfe05237c85b33" + integrity sha512-2FdwRvPIq9uuF6OzONroXep6VBGqzHOkP6LlcFQe7SdwxfRP+SD/ycHNSC1acVg2b8d+am9Kzqg2vV54UpOIKA== dependencies: apollo-server-env "2.2.0" - graphql-extensions "0.5.2" + graphql-extensions "0.5.4" apollo-tracing@^0.1.0: version "0.1.4" @@ -1250,12 +1540,13 @@ apollo-upload-server@^7.0.0: http-errors "^1.7.0" object-path "^0.11.4" -apollo-utilities@1.1.3, apollo-utilities@^1.0.1, apollo-utilities@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.3.tgz#a8883c0392f6b46eac0d366204ebf34be9307c87" - integrity sha512-pF9abhiClX5gfj/WFWZh8DiI33nOLGxRhXH9ZMquaM1V8bhq1WLFPt2QjShWH3kGQVeIGUK+FQefnhe+ZaaAYg== +apollo-utilities@1.2.1, apollo-utilities@^1.0.1, apollo-utilities@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.2.1.tgz#1c3a1ebf5607d7c8efe7636daaf58e7463b41b3c" + integrity sha512-Zv8Udp9XTSFiN8oyXOjf6PMHepD4yxxReLsl6dPUy5Ths7jti3nmlBzZUOxuTWRwZn0MoclqL7RQ5UEJN8MAxg== dependencies: fast-json-stable-stringify "^2.0.0" + ts-invariant "^0.2.1" tslib "^1.9.3" append-transform@^1.0.0: @@ -1357,6 +1648,13 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +assert@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + dependencies: + util "0.10.3" + assertion-error-formatter@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/assertion-error-formatter/-/assertion-error-formatter-2.0.1.tgz#6bbdffaec8e2fa9e2b0eb158bfe353132d7c0a9b" @@ -1481,13 +1779,16 @@ babel-eslint@~10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-jest@^24.1.0, babel-jest@~24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.1.0.tgz#441e23ef75ded3bd547e300ac3194cef87b55190" - integrity sha512-MLcagnVrO9ybQGLEfZUqnOzv36iQzU7Bj4elm39vCukumLVSfoX+tRy3/jW7lUKc7XdpRmB/jech6L/UCsSZjw== +babel-jest@^24.3.1, babel-jest@~24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.3.1.tgz#168468a37e90426520c5293da4f55e1a512063b0" + integrity sha512-6KaXyUevY0KAxD5Ba+EBhyfwvc+R2f7JV7BpBZ5T8yJGgj0M1hYDfRhDq35oD5MzprMf/ggT81nEuLtMyxfDIg== dependencies: + "@jest/transform" "^24.3.1" + "@jest/types" "^24.3.0" + "@types/babel__core" "^7.1.0" babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.1.0" + babel-preset-jest "^24.3.0" chalk "^2.4.2" slash "^2.0.0" @@ -1500,18 +1801,20 @@ babel-plugin-istanbul@^5.1.0: istanbul-lib-instrument "^3.0.0" test-exclude "^5.0.0" -babel-plugin-jest-hoist@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.1.0.tgz#dfecc491fb15e2668abbd690a697a8fd1411a7f8" - integrity sha512-gljYrZz8w1b6fJzKcsfKsipSru2DU2DmQ39aB6nV3xQ0DDv3zpIzKGortA5gknrhNnPN8DweaEgrnZdmbGmhnw== +babel-plugin-jest-hoist@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.3.0.tgz#f2e82952946f6e40bb0a75d266a3790d854c8b5b" + integrity sha512-nWh4N1mVH55Tzhx2isvUN5ebM5CDUvIpXPZYMRazQughie/EqGnbR+czzoQlhUmJG9pPJmYDRhvocotb2THl1w== + dependencies: + "@types/babel__traverse" "^7.0.6" -babel-preset-jest@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.1.0.tgz#83bc564fdcd4903641af65ec63f2f5de6b04132e" - integrity sha512-FfNLDxFWsNX9lUmtwY7NheGlANnagvxq8LZdl5PKnVG3umP+S/g0XbVBfwtA4Ai3Ri/IMkWabBz3Tyk9wdspcw== +babel-preset-jest@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.3.0.tgz#db88497e18869f15b24d9c0e547d8e0ab950796d" + integrity sha512-VGTV2QYBa/Kn3WCOKdfS31j9qomaXSgJqi65B6o05/1GsJyj9LVhSljM9ro4S+IBGj/ENhNBuH9bpqzztKAQSw== dependencies: "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.1.0" + babel-plugin-jest-hoist "^24.3.0" babel-runtime@^6.26.0: version "6.26.0" @@ -1827,16 +2130,7 @@ chai@~4.2.0: pathval "^1.1.0" type-detect "^4.0.5" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1901,11 +2195,6 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -circular-json@^0.3.1: - version "0.3.3" - resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" - integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== - class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -2119,7 +2408,7 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cors@^2.8.4, cors@^2.8.5: +cors@^2.8.4, cors@~2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== @@ -2222,7 +2511,7 @@ cucumber-tag-expressions@^1.1.1: resolved "https://registry.yarnpkg.com/cucumber-tag-expressions/-/cucumber-tag-expressions-1.1.1.tgz#7f5c7b70009bc2b666591bfe64854578bedee85a" integrity sha1-f1x7cACbwrZmWRv+ZIVFeL7e6Fo= -cucumber@^5.1.0: +cucumber@~5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cucumber/-/cucumber-5.1.0.tgz#7b166812c255bec7eac4b0df7007a40d089c895d" integrity sha512-zrl2VYTBRgvxucwV2GKAvLqcfA1Naeax8plPvWgPEzl3SCJiuPPv3WxBHIRHtPYcEdbHDR6oqLpZP4bJ8UIdmA== @@ -2304,7 +2593,7 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -2422,10 +2711,10 @@ dicer@0.2.5: readable-stream "1.1.x" streamsearch "0.1.2" -diff-sequences@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.0.0.tgz#cdf8e27ed20d8b8d3caccb4e0c0d8fe31a173013" - integrity sha512-46OkIuVGBBnrC0soO/4LHu5LHGHx0uhP65OVz8XOrAJpqiCB2aVIuESvjI1F9oqebuvY8lekS1pt6TN7vt7qsw== +diff-sequences@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975" + integrity sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw== diff@^3.0.0: version "3.5.0" @@ -2445,10 +2734,10 @@ doctrine@1.5.0: esutils "^2.0.2" isarray "^1.0.0" -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" @@ -2570,6 +2859,11 @@ elliptic@=3.0.3: hash.js "^1.0.0" inherits "^2.0.1" +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -2746,7 +3040,7 @@ eslint-plugin-import@~2.16.0: read-pkg-up "^2.0.0" resolve "^1.9.0" -eslint-plugin-jest@^22.3.0: +eslint-plugin-jest@~22.3.0: version "22.3.0" resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.3.0.tgz#a10f10dedfc92def774ec9bb5bfbd2fb8e1c96d2" integrity sha512-P1mYVRNlOEoO5T9yTqOfucjOYf1ktmJ26NjwjH8sxpCFQa6IhBGr5TpKl3hcAAT29hOsRJVuMWmTsHoUVo9FoA== @@ -2781,10 +3075,10 @@ eslint-scope@3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" - integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== +eslint-scope@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.2.tgz#5f10cd6cabb1965bf479fa65745673439e21cb0e" + integrity sha512-5q1+B/ogmHl8+paxtOKx38Z8LtWkVGuNt3+GQNErqwLl6ViNp/gdJGMCjZNxZ8j/VYjDNZ2Fo+eQc1TAVPIzbg== dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" @@ -2799,35 +3093,35 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@~5.13.0: - version "5.13.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.13.0.tgz#ce71cc529c450eed9504530939aa97527861ede9" - integrity sha512-nqD5WQMisciZC5EHZowejLKQjWGuFS5c70fxqSKlnDME+oz9zmE8KTlX+lHSg+/5wsC/kf9Q9eMkC8qS3oM2fg== +eslint@~5.15.1: + version "5.15.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.15.1.tgz#8266b089fd5391e0009a047050795b1d73664524" + integrity sha512-NTcm6vQ+PTgN3UBsALw5BMhgO6i5EpIjQF/Xb5tIh3sk9QhrFafujUOczGz4J24JBlzWclSB9Vmx8d+9Z6bFCg== dependencies: "@babel/code-frame" "^7.0.0" - ajv "^6.5.3" + ajv "^6.9.1" chalk "^2.1.0" cross-spawn "^6.0.5" debug "^4.0.1" - doctrine "^2.1.0" - eslint-scope "^4.0.0" + doctrine "^3.0.0" + eslint-scope "^4.0.2" eslint-utils "^1.3.1" eslint-visitor-keys "^1.0.0" - espree "^5.0.0" + espree "^5.0.1" esquery "^1.0.1" esutils "^2.0.2" - file-entry-cache "^2.0.0" + file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" glob "^7.1.2" globals "^11.7.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^6.1.0" + inquirer "^6.2.2" js-yaml "^3.12.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.17.5" + lodash "^4.17.11" minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" @@ -2838,15 +3132,15 @@ eslint@~5.13.0: semver "^5.5.1" strip-ansi "^4.0.0" strip-json-comments "^2.0.1" - table "^5.0.2" + table "^5.2.3" text-table "^0.2.0" -espree@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.0.tgz#fc7f984b62b36a0f543b13fb9cd7b9f4a7f5b65c" - integrity sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA== +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== dependencies: - acorn "^6.0.2" + acorn "^6.0.7" acorn-jsx "^5.0.0" eslint-visitor-keys "^1.0.0" @@ -2899,12 +3193,10 @@ events@1.1.1: resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= -exec-sh@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" - integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== - dependencies: - merge "^1.2.0" +exec-sh@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" + integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg== execa@^0.7.0: version "0.7.0" @@ -2955,18 +3247,19 @@ expect-ct@0.1.1: resolved "https://registry.yarnpkg.com/expect-ct/-/expect-ct-0.1.1.tgz#de84476a2dbcb85000d5903737e9bc8a5ba7b897" integrity sha512-ngXzTfoRGG7fYens3/RMb6yYoVLvLMfmsSllP/mZPxNHgFq41TmPSLF/nLY7fwoclI2vElvAmILFWGUYqdjfCg== -expect@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.1.0.tgz#88e73301c4c785cde5f16da130ab407bdaf8c0f2" - integrity sha512-lVcAPhaYkQcIyMS+F8RVwzbm1jro20IG8OkvxQ6f1JfqhVZyyudCwYogQ7wnktlf14iF3ii7ArIUO/mqvrW9Gw== +expect@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.3.1.tgz#7c42507da231a91a8099d065bc8dc9322dc85fc0" + integrity sha512-xnmobSlaqhg4FKqjb5REk4AobQzFMJoctDdREKfSGqrtzRfCWYbfqt3WmikAvQz/J8mCNQhORgYdEjPMJbMQPQ== dependencies: + "@jest/types" "^24.3.0" ansi-styles "^3.2.0" - jest-get-type "^24.0.0" - jest-matcher-utils "^24.0.0" - jest-message-util "^24.0.0" - jest-regex-util "^24.0.0" + jest-get-type "^24.3.0" + jest-matcher-utils "^24.3.1" + jest-message-util "^24.3.0" + jest-regex-util "^24.3.0" -express@^4.0.0, express@^4.16.3, express@^4.16.4: +express@^4.0.0, express@^4.16.3, express@~4.16.4: version "4.16.4" resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== @@ -3022,7 +3315,12 @@ extend@^3.0.0, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^3.0.0: +extendable-error@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/extendable-error/-/extendable-error-0.1.5.tgz#122308a7097bc89a263b2c4fbf089c78140e3b6d" + integrity sha1-EiMIpwl7yJomOyxPvwiceBQOO20= + +external-editor@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== @@ -3094,13 +3392,12 @@ figures@2.0.0, figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== dependencies: - flat-cache "^1.2.1" - object-assign "^4.0.1" + flat-cache "^2.0.1" fileset@^2.0.3: version "2.0.3" @@ -3165,15 +3462,19 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -flat-cache@^1.2.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" - integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== dependencies: - circular-json "^0.3.1" - graceful-fs "^4.1.2" - rimraf "~2.6.2" - write "^0.2.1" + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" + integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== fn-name@~2.0.1: version "2.0.1" @@ -3256,14 +3557,6 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== - dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" - fsevents@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" @@ -3394,6 +3687,15 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= +graphql-auth-directives@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/graphql-auth-directives/-/graphql-auth-directives-2.1.0.tgz#85b83817844e2ec5fba8fe5de444287d6dd0f85a" + integrity sha512-mRVsjeMeMABPyjxyzl9mhkcW02YBwSj7dnu7C6wy2dIhiby6xTKy6Q54C8KeqXSYsy6ua4VmBH++d7GKqpvIoA== + dependencies: + apollo-errors "^1.9.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" @@ -3409,10 +3711,17 @@ graphql-deduplicator@^2.0.1: resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3" integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA== -graphql-extensions@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.2.tgz#cdced94c1931c9983fffcc144e336d6cd4d8b02b" - integrity sha512-D/FAvjYEZ8GM3vfALxRvItozy5iLUfzyoauE2lli+0OuUBCAZDLP0fgqeTFK93NnQX/XSjBVGhcuDWBB7JesEw== +graphql-extensions@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.4.tgz#18a9674f9adb11aa6c0737485887ea8877914cff" + integrity sha512-qLThJGVMqcItE7GDf/xX/E40m/aeqFheEKiR5bfra4q5eHxQKGjnIc20P9CVqjOn9I0FkEiU9ypOobfmIf7t6g== + dependencies: + "@apollographql/apollo-tools" "^0.3.3" + +graphql-extensions@0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.5.7.tgz#2b647e4e36997dc85b7f58ebd64324a5250fb2cf" + integrity sha512-HrU6APE1PiehZ46scMB3S5DezSeCATd8v+e4mmg2bqszMyCFkmAnmK6hR1b5VjHxhzt5/FX21x1WsXfqF4FwdQ== dependencies: "@apollographql/apollo-tools" "^0.3.3" @@ -3670,7 +3979,7 @@ helmet-csp@2.7.1: dasherize "2.0.0" platform "1.3.5" -helmet@^3.15.1: +helmet@~3.15.1: version "3.15.1" resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.15.1.tgz#2c80d1a59138b6f23929605afca4b1c88b3298ec" integrity sha512-hgoNe/sjKlKNvJ3g9Gz149H14BjMMWOCmW/DTXl7IfyKGtIK37GePwZrHNfr4aPXdKVyXcTj26RgRFbPKDy9lw== @@ -3882,7 +4191,7 @@ inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, i resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -inherits@=2.0.1: +inherits@2.0.1, inherits@=2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= @@ -3892,21 +4201,21 @@ ini@^1.3.4, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== -inquirer@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52" - integrity sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg== +inquirer@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406" + integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA== dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" + ansi-escapes "^3.2.0" + chalk "^2.4.2" cli-cursor "^2.1.0" cli-width "^2.0.0" - external-editor "^3.0.0" + external-editor "^3.0.3" figures "^2.0.0" - lodash "^4.17.10" + lodash "^4.17.11" mute-stream "0.0.7" run-async "^2.2.0" - rxjs "^6.1.0" + rxjs "^6.4.0" string-width "^2.1.0" strip-ansi "^5.0.0" through "^2.3.6" @@ -4210,10 +4519,10 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-api@^2.0.8: - version "2.1.0" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.0.tgz#37ab0c2c3e83065462f5254b94749d6157846c4e" - integrity sha512-+Ygg4t1StoiNlBGc6x0f8q/Bv26FbZqP/+jegzfNpU7Q8o+4ZRoJxJPhBkgE/UonpAjtxnE4zCZIyJX+MwLRMQ== +istanbul-api@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.1.tgz#194b773f6d9cbc99a9258446848b0f988951c4d0" + integrity sha512-kVmYrehiwyeBAk/wE71tW6emzLiHGjYIiDrc8sfyty4F8M02/lrgXSm+R1kXysmF20zArvmZXjlE/mg24TVPJw== dependencies: async "^2.6.1" compare-versions "^3.2.1" @@ -4223,7 +4532,7 @@ istanbul-api@^2.0.8: istanbul-lib-instrument "^3.1.0" istanbul-lib-report "^2.0.4" istanbul-lib-source-maps "^3.0.2" - istanbul-reports "^2.1.0" + istanbul-reports "^2.1.1" js-yaml "^3.12.0" make-dir "^1.3.0" minimatch "^3.0.4" @@ -4274,7 +4583,7 @@ istanbul-lib-source-maps@^3.0.1, istanbul-lib-source-maps@^3.0.2: rimraf "^2.6.2" source-map "^0.6.1" -istanbul-reports@^2.1.0, istanbul-reports@^2.1.1: +istanbul-reports@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.1.1.tgz#72ef16b4ecb9a4a7bd0e2001e00f95d1eec8afa9" integrity sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw== @@ -4286,334 +4595,349 @@ iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2: resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== -jest-changed-files@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.0.0.tgz#c02c09a8cc9ca93f513166bc773741bd39898ff7" - integrity sha512-nnuU510R9U+UX0WNb5XFEcsrMqriSiRLeO9KWDFgPrpToaQm60prfQYpxsXigdClpvNot5bekDY440x9dNGnsQ== +jest-changed-files@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.3.0.tgz#7050ae29aaf1d59437c80f21d5b3cd354e88a499" + integrity sha512-fTq0YAUR6644fgsqLC7Zi2gXA/bAplMRvfXQdutmkwgrCKK6upkj+sgXqsUfUZRm15CVr3YSojr/GRNn71IMvg== dependencies: + "@jest/types" "^24.3.0" execa "^1.0.0" throat "^4.0.0" -jest-cli@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.1.0.tgz#f7cc98995f36e7210cce3cbb12974cbf60940843" - integrity sha512-U/iyWPwOI0T1CIxVLtk/2uviOTJ/OiSWJSe8qt6X1VkbbgP+nrtLJlmT9lPBe4lK78VNFJtrJ7pttcNv/s7yCw== +jest-cli@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.3.1.tgz#52e4ae5f11044b41e06ca39fc7a7302fbbcb1661" + integrity sha512-HdwMgigvDQdlWX7gwM2QMkJJRqSk7tTYKq7kVplblK28RarqquJMWV/lOCN8CukuG9u3DZTeXpCDXR7kpGfB3w== dependencies: - ansi-escapes "^3.0.0" + "@jest/core" "^24.3.1" + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" chalk "^2.0.1" exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.1.15" import-local "^2.0.0" is-ci "^2.0.0" - istanbul-api "^2.0.8" - istanbul-lib-coverage "^2.0.2" - istanbul-lib-instrument "^3.0.1" - istanbul-lib-source-maps "^3.0.1" - jest-changed-files "^24.0.0" - jest-config "^24.1.0" - jest-environment-jsdom "^24.0.0" - jest-get-type "^24.0.0" - jest-haste-map "^24.0.0" - jest-message-util "^24.0.0" - jest-regex-util "^24.0.0" - jest-resolve-dependencies "^24.1.0" - jest-runner "^24.1.0" - jest-runtime "^24.1.0" - jest-snapshot "^24.1.0" - jest-util "^24.0.0" - jest-validate "^24.0.0" - jest-watcher "^24.0.0" - jest-worker "^24.0.0" - micromatch "^3.1.10" - node-notifier "^5.2.1" - p-each-series "^1.0.0" - pirates "^4.0.0" + jest-config "^24.3.1" + jest-util "^24.3.0" + jest-validate "^24.3.1" prompts "^2.0.1" - realpath-native "^1.0.0" - rimraf "^2.5.4" - slash "^2.0.0" - string-length "^2.0.0" - strip-ansi "^5.0.0" - which "^1.2.12" + realpath-native "^1.1.0" yargs "^12.0.2" -jest-config@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.1.0.tgz#6ea6881cfdd299bc86cc144ee36d937c97c3850c" - integrity sha512-FbbRzRqtFC6eGjG5VwsbW4E5dW3zqJKLWYiZWhB0/4E5fgsMw8GODLbGSrY5t17kKOtCWb/Z7nsIThRoDpuVyg== +jest-config@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.3.1.tgz#271aff2d3aeabf1ff92512024eeca3323cd31a07" + integrity sha512-ujHQywsM//vKFvJwEC02KNZgKAGOzGz1bFPezmTQtuj8XdfsAVq8p6N/dw4yodXV11gSf6TJ075i4ehM+mKatA== dependencies: "@babel/core" "^7.1.0" - babel-jest "^24.1.0" + "@jest/types" "^24.3.0" + babel-jest "^24.3.1" chalk "^2.0.1" glob "^7.1.1" - jest-environment-jsdom "^24.0.0" - jest-environment-node "^24.0.0" - jest-get-type "^24.0.0" - jest-jasmine2 "^24.1.0" - jest-regex-util "^24.0.0" - jest-resolve "^24.1.0" - jest-util "^24.0.0" - jest-validate "^24.0.0" + jest-environment-jsdom "^24.3.1" + jest-environment-node "^24.3.1" + jest-get-type "^24.3.0" + jest-jasmine2 "^24.3.1" + jest-regex-util "^24.3.0" + jest-resolve "^24.3.1" + jest-util "^24.3.0" + jest-validate "^24.3.1" micromatch "^3.1.10" - pretty-format "^24.0.0" - realpath-native "^1.0.2" + pretty-format "^24.3.1" + realpath-native "^1.1.0" -jest-diff@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.0.0.tgz#a3e5f573dbac482f7d9513ac9cfa21644d3d6b34" - integrity sha512-XY5wMpRaTsuMoU+1/B2zQSKQ9RdE9gsLkGydx3nvApeyPijLA8GtEvIcPwISRCer+VDf9W1mStTYYq6fPt8ryA== +jest-diff@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.3.1.tgz#87952e5ea1548567da91df398fa7bf7977d3f96a" + integrity sha512-YRVzDguyzShP3Pb9wP/ykBkV7Z+O4wltrMZ2P4LBtNxrHNpxwI2DECrpD9XevxWubRy5jcE8sSkxyX3bS7W+rA== dependencies: chalk "^2.0.1" - diff-sequences "^24.0.0" - jest-get-type "^24.0.0" - pretty-format "^24.0.0" + diff-sequences "^24.3.0" + jest-get-type "^24.3.0" + pretty-format "^24.3.1" -jest-docblock@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.0.0.tgz#54d77a188743e37f62181a91a01eb9222289f94e" - integrity sha512-KfAKZ4SN7CFOZpWg4i7g7MSlY0M+mq7K0aMqENaG2vHuhC9fc3vkpU/iNN9sOus7v3h3Y48uEjqz3+Gdn2iptA== +jest-docblock@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.3.0.tgz#b9c32dac70f72e4464520d2ba4aec02ab14db5dd" + integrity sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg== dependencies: detect-newline "^2.1.0" -jest-each@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.0.0.tgz#10987a06b21c7ffbfb7706c89d24c52ed864be55" - integrity sha512-gFcbY4Cu55yxExXMkjrnLXov3bWO3dbPAW7HXb31h/DNWdNc/6X8MtxGff8nh3/MjkF9DpVqnj0KsPKuPK0cpA== +jest-each@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.3.1.tgz#ed8fe8b9f92a835a6625ca8c7ee06bc904440316" + integrity sha512-GTi+nxDaWwSgOPLiiqb/p4LURy0mv3usoqsA2eoTYSmRsLgjgZ6VUyRpUBH5JY9EMBx33suNFXk0iyUm29WRpw== dependencies: + "@jest/types" "^24.3.0" chalk "^2.0.1" - jest-get-type "^24.0.0" - jest-util "^24.0.0" - pretty-format "^24.0.0" + jest-get-type "^24.3.0" + jest-util "^24.3.0" + pretty-format "^24.3.1" -jest-environment-jsdom@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.0.0.tgz#5affa0654d6e44cd798003daa1a8701dbd6e4d11" - integrity sha512-1YNp7xtxajTRaxbylDc2pWvFnfDTH5BJJGyVzyGAKNt/lEULohwEV9zFqTgG4bXRcq7xzdd+sGFws+LxThXXOw== +jest-environment-jsdom@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.3.1.tgz#49826bcf12fb3e38895f1e2aaeb52bde603cc2e4" + integrity sha512-rz2OSYJiQerDqWDwjisqRwhVNpwkqFXdtyMzEuJ47Ip9NRpRQ+qy7/+zFujPUy/Z+zjWRO5seHLB/dOD4VpEVg== dependencies: - jest-mock "^24.0.0" - jest-util "^24.0.0" + "@jest/environment" "^24.3.1" + "@jest/fake-timers" "^24.3.0" + "@jest/types" "^24.3.0" + jest-mock "^24.3.0" + jest-util "^24.3.0" jsdom "^11.5.1" -jest-environment-node@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.0.0.tgz#330948980656ed8773ce2e04eb597ed91e3c7190" - integrity sha512-62fOFcaEdU0VLaq8JL90TqwI7hLn0cOKOl8vY2n477vRkCJRojiRRtJVRzzCcgFvs6gqU97DNqX5R0BrBP6Rxg== +jest-environment-node@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.3.1.tgz#333d864c569b27658a96bb3b10e02e7172125415" + integrity sha512-Xy+/yFem/yUs9OkzbcawQT237vwDjBhAVLjac1KYAMYVjGb0Vb/Ovw4g61PunVdrEIpfcXNtRUltM4+9c7lARQ== dependencies: - jest-mock "^24.0.0" - jest-util "^24.0.0" + "@jest/environment" "^24.3.1" + "@jest/fake-timers" "^24.3.0" + "@jest/types" "^24.3.0" + jest-mock "^24.3.0" + jest-util "^24.3.0" -jest-get-type@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.0.0.tgz#36e72930b78e33da59a4f63d44d332188278940b" - integrity sha512-z6/Eyf6s9ZDGz7eOvl+fzpuJmN9i0KyTt1no37/dHu8galssxz5ZEgnc1KaV8R31q1khxyhB4ui/X5ZjjPk77w== +jest-get-type@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.3.0.tgz#582cfd1a4f91b5cdad1d43d2932f816d543c65da" + integrity sha512-HYF6pry72YUlVcvUx3sEpMRwXEWGEPlJ0bSPVnB3b3n++j4phUEoSPcS6GC0pPJ9rpyPSe4cb5muFo6D39cXow== -jest-haste-map@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0.tgz#e9ef51b2c9257384b4d6beb83bd48c65b37b5e6e" - integrity sha512-CcViJyUo41IQqttLxXVdI41YErkzBKbE6cS6dRAploCeutePYfUimWd3C9rQEWhX0YBOQzvNsC0O9nYxK2nnxQ== +jest-haste-map@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.3.1.tgz#b4a66dbe1e6bc45afb9cd19c083bff81cdd535a1" + integrity sha512-OTMQle+astr1lWKi62Ccmk2YWn6OtUoU/8JpJdg8zdsnpFIry/k0S4sQ4nWocdM07PFdvqcthWc78CkCE6sXvA== dependencies: + "@jest/types" "^24.3.0" fb-watchman "^2.0.0" graceful-fs "^4.1.15" invariant "^2.2.4" - jest-serializer "^24.0.0" - jest-util "^24.0.0" - jest-worker "^24.0.0" + jest-serializer "^24.3.0" + jest-util "^24.3.0" + jest-worker "^24.3.1" micromatch "^3.1.10" - sane "^3.0.0" + sane "^4.0.3" -jest-jasmine2@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.1.0.tgz#8377324b967037c440f0a549ee0bbd9912055db6" - integrity sha512-H+o76SdSNyCh9fM5K8upK45YTo/DiFx5w2YAzblQebSQmukDcoVBVeXynyr7DDnxh+0NTHYRCLwJVf3tC518wg== +jest-jasmine2@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.3.1.tgz#127d628d3ac0829bd3c0fccacb87193e543b420b" + integrity sha512-STo6ar1IyPlIPq9jPxDQhM7lC0dAX7KKN0LmCLMlgJeXwX+1XiVdtZDv1a4zyg6qhNdpo1arOBGY0BcovUK7ug== dependencies: "@babel/traverse" "^7.1.0" + "@jest/environment" "^24.3.1" + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" chalk "^2.0.1" co "^4.6.0" - expect "^24.1.0" + expect "^24.3.1" is-generator-fn "^2.0.0" - jest-each "^24.0.0" - jest-matcher-utils "^24.0.0" - jest-message-util "^24.0.0" - jest-snapshot "^24.1.0" - jest-util "^24.0.0" - pretty-format "^24.0.0" + jest-each "^24.3.1" + jest-matcher-utils "^24.3.1" + jest-message-util "^24.3.0" + jest-runtime "^24.3.1" + jest-snapshot "^24.3.1" + jest-util "^24.3.0" + pretty-format "^24.3.1" throat "^4.0.0" -jest-leak-detector@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.0.0.tgz#78280119fd05ee98317daee62cddb3aa537a31c6" - integrity sha512-ZYHJYFeibxfsDSKowjDP332pStuiFT2xfc5R67Rjm/l+HFJWJgNIOCOlQGeXLCtyUn3A23+VVDdiCcnB6dTTrg== +jest-leak-detector@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.3.1.tgz#ed89d05ca07e91b2b51dac1f676ab354663aa8da" + integrity sha512-GncRwEtAw/SohdSyY4bk2RE06Ac1dZrtQGZQ2j35hSuN4gAAAKSYMszJS2WDixsAEaFN+GHBHG+d8pjVGklKyw== dependencies: - pretty-format "^24.0.0" + pretty-format "^24.3.1" -jest-matcher-utils@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.0.0.tgz#fc9c41cfc49b2c3ec14e576f53d519c37729d579" - integrity sha512-LQTDmO+aWRz1Tf9HJg+HlPHhDh1E1c65kVwRFo5mwCVp5aQDzlkz4+vCvXhOKFjitV2f0kMdHxnODrXVoi+rlA== +jest-matcher-utils@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.3.1.tgz#025e1cd9c54a5fde68e74b12428775d06d123aa8" + integrity sha512-P5VIsUTJeI0FYvWVMwEHjxK1L83vEkDiKMV0XFPIrT2jzWaWPB2+dPCHkP2ID9z4eUKElaHqynZnJiOdNVHfXQ== dependencies: chalk "^2.0.1" - jest-diff "^24.0.0" - jest-get-type "^24.0.0" - pretty-format "^24.0.0" + jest-diff "^24.3.1" + jest-get-type "^24.3.0" + pretty-format "^24.3.1" -jest-message-util@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.0.0.tgz#a07a141433b2c992dbaec68d4cbfe470ba289619" - integrity sha512-J9ROJIwz/IeC+eV1XSwnRK4oAwPuhmxEyYx1+K5UI+pIYwFZDSrfZaiWTdq0d2xYFw4Xiu+0KQWsdsQpgJMf3Q== +jest-message-util@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.3.0.tgz#e8f64b63ebc75b1a9c67ee35553752596e70d4a9" + integrity sha512-lXM0YgKYGqN5/eH1NGw4Ix+Pk2I9Y77beyRas7xM24n+XTTK3TbT0VkT3L/qiyS7WkW0YwyxoXnnAaGw4hsEDA== dependencies: "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" + "@types/stack-utils" "^1.0.1" chalk "^2.0.1" micromatch "^3.1.10" slash "^2.0.0" stack-utils "^1.0.1" -jest-mock@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.0.0.tgz#9a4b53e01d66a0e780f7d857462d063e024c617d" - integrity sha512-sQp0Hu5fcf5NZEh1U9eIW2qD0BwJZjb63Yqd98PQJFvf/zzUTBoUAwv/Dc/HFeNHIw1f3hl/48vNn+j3STaI7A== - -jest-regex-util@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.0.0.tgz#4feee8ec4a358f5bee0a654e94eb26163cb9089a" - integrity sha512-Jv/uOTCuC+PY7WpJl2mpoI+WbY2ut73qwwO9ByJJNwOCwr1qWhEW2Lyi2S9ZewUdJqeVpEBisdEVZSI+Zxo58Q== - -jest-resolve-dependencies@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.1.0.tgz#78f738a2ec59ff4d00751d9da56f176e3f589f6c" - integrity sha512-2VwPsjd3kRPu7qe2cpytAgowCObk5AKeizfXuuiwgm1a9sijJDZe8Kh1sFj6FKvSaNEfCPlBVkZEJa2482m/Uw== +jest-mock@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.3.0.tgz#95a86b6ad474e3e33227e6dd7c4ff6b07e18d3cb" + integrity sha512-AhAo0qjbVWWGvcbW5nChFjR0ObQImvGtU6DodprNziDOt+pP0CBdht/sYcNIOXeim8083QUi9bC8QdKB8PTK4Q== dependencies: - jest-regex-util "^24.0.0" - jest-snapshot "^24.1.0" + "@jest/types" "^24.3.0" -jest-resolve@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.1.0.tgz#42ff0169b0ea47bfdbd0c52a0067ca7d022c7688" - integrity sha512-TPiAIVp3TG6zAxH28u/6eogbwrvZjBMWroSLBDkwkHKrqxB/RIdwkWDye4uqPlZIXWIaHtifY3L0/eO5Z0f2wg== +jest-regex-util@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36" + integrity sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg== + +jest-resolve-dependencies@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.3.1.tgz#a22839d611ba529a74594ee274ce2b77d046bea9" + integrity sha512-9JUejNImGnJjbNR/ttnod+zQIWANpsrYMPt18s2tYGK6rP191qFsyEQ2BhAQMdYDRkTmi8At+Co9tL+jTPqdpw== dependencies: + "@jest/types" "^24.3.0" + jest-regex-util "^24.3.0" + jest-snapshot "^24.3.1" + +jest-resolve@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.3.1.tgz#103dbd438b59618ea428ec4acbd65c56495ba397" + integrity sha512-N+Q3AcVuKxpn/kjQMxUVLwBk32ZE1diP4MPcHyjVwcKpCUuKrktfRR3Mqe/T2HoD25wyccstaqcPUKIudl41bg== + dependencies: + "@jest/types" "^24.3.0" browser-resolve "^1.11.3" chalk "^2.0.1" - realpath-native "^1.0.0" + realpath-native "^1.1.0" -jest-runner@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.1.0.tgz#3686a2bb89ce62800da23d7fdc3da2c32792943b" - integrity sha512-CDGOkT3AIFl16BLL/OdbtYgYvbAprwJ+ExKuLZmGSCSldwsuU2dEGauqkpvd9nphVdAnJUcP12e/EIlnTX0QXg== +jest-runner@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.3.1.tgz#5488566fa60cdb4b00a89c734ad6b54b9561415d" + integrity sha512-Etc9hQ5ruwg+q7DChm+E8qzHHdNTLeUdlo+whPQRSpNSgl0AEgc2r2mT4lxODREqmnHg9A8JHA44pIG4GE0Gzg== dependencies: + "@jest/console" "^24.3.0" + "@jest/environment" "^24.3.1" + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" chalk "^2.4.2" exit "^0.1.2" graceful-fs "^4.1.15" - jest-config "^24.1.0" - jest-docblock "^24.0.0" - jest-haste-map "^24.0.0" - jest-jasmine2 "^24.1.0" - jest-leak-detector "^24.0.0" - jest-message-util "^24.0.0" - jest-runtime "^24.1.0" - jest-util "^24.0.0" - jest-worker "^24.0.0" + jest-config "^24.3.1" + jest-docblock "^24.3.0" + jest-haste-map "^24.3.1" + jest-jasmine2 "^24.3.1" + jest-leak-detector "^24.3.1" + jest-message-util "^24.3.0" + jest-resolve "^24.3.1" + jest-runtime "^24.3.1" + jest-util "^24.3.0" + jest-worker "^24.3.1" source-map-support "^0.5.6" throat "^4.0.0" -jest-runtime@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.1.0.tgz#7c157a2e776609e8cf552f956a5a19ec9c985214" - integrity sha512-59/BY6OCuTXxGeDhEMU7+N33dpMQyXq7MLK07cNSIY/QYt2QZgJ7Tjx+rykBI0skAoigFl0A5tmT8UdwX92YuQ== +jest-runtime@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.3.1.tgz#2798230b4fbed594b375a13e395278694d4751e2" + integrity sha512-Qz/tJWbZ2naFJ2Kvy1p+RhhRgsPYh4e6wddVRy6aHBr32FTt3Ja33bfV7pkMFWXFbVuAsJMJVdengbvdhWzq4A== dependencies: - "@babel/core" "^7.1.0" - babel-plugin-istanbul "^5.1.0" + "@jest/console" "^24.3.0" + "@jest/environment" "^24.3.1" + "@jest/source-map" "^24.3.0" + "@jest/transform" "^24.3.1" + "@jest/types" "^24.3.0" + "@types/yargs" "^12.0.2" chalk "^2.0.1" - convert-source-map "^1.4.0" exit "^0.1.2" - fast-json-stable-stringify "^2.0.0" glob "^7.1.3" graceful-fs "^4.1.15" - jest-config "^24.1.0" - jest-haste-map "^24.0.0" - jest-message-util "^24.0.0" - jest-regex-util "^24.0.0" - jest-resolve "^24.1.0" - jest-snapshot "^24.1.0" - jest-util "^24.0.0" - jest-validate "^24.0.0" - micromatch "^3.1.10" - realpath-native "^1.0.0" + jest-config "^24.3.1" + jest-haste-map "^24.3.1" + jest-message-util "^24.3.0" + jest-mock "^24.3.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.3.1" + jest-snapshot "^24.3.1" + jest-util "^24.3.0" + jest-validate "^24.3.1" + realpath-native "^1.1.0" slash "^2.0.0" strip-bom "^3.0.0" - write-file-atomic "2.4.1" yargs "^12.0.2" -jest-serializer@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0.tgz#522c44a332cdd194d8c0531eb06a1ee5afb4256b" - integrity sha512-9FKxQyrFgHtx3ozU+1a8v938ILBE7S8Ko3uiAVjT8Yfi2o91j/fj81jacCQZ/Ihjiff/VsUCXVgQ+iF1XdImOw== +jest-serializer@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.3.0.tgz#074e307300d1451617cf2630d11543ee4f74a1c8" + integrity sha512-RiSpqo2OFbVLJN/PgAOwQIUeHDfss6NBUDTLhjiJM8Bb5rMrwRqHfkaqahIsOf9cXXB5UjcqDCzbQ7AIoMqWkg== -jest-snapshot@^24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.1.0.tgz#85e22f810357aa5994ab61f236617dc2205f2f5b" - integrity sha512-th6TDfFqEmXvuViacU1ikD7xFb7lQsPn2rJl7OEmnfIVpnrx3QNY2t3PE88meeg0u/mQ0nkyvmC05PBqO4USFA== +jest-snapshot@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.3.1.tgz#0f22a86c1b8c87e823f5ad095e82c19d9ed93d72" + integrity sha512-7wbNJWh0sBjmoaexTOWqS7nleTQME7o2W9XKU6CHCxG49Thjct4aVPC/QPNF5NHnvf4M/VDmudIDbwz6noJTRA== dependencies: "@babel/types" "^7.0.0" + "@jest/types" "^24.3.0" chalk "^2.0.1" - jest-diff "^24.0.0" - jest-matcher-utils "^24.0.0" - jest-message-util "^24.0.0" - jest-resolve "^24.1.0" + expect "^24.3.1" + jest-diff "^24.3.1" + jest-matcher-utils "^24.3.1" + jest-message-util "^24.3.0" + jest-resolve "^24.3.1" mkdirp "^0.5.1" natural-compare "^1.4.0" - pretty-format "^24.0.0" + pretty-format "^24.3.1" semver "^5.5.0" -jest-util@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.0.0.tgz#fd38fcafd6dedbd0af2944d7a227c0d91b68f7d6" - integrity sha512-QxsALc4wguYS7cfjdQSOr5HTkmjzkHgmZvIDkcmPfl1ib8PNV8QUWLwbKefCudWS0PRKioV+VbQ0oCUPC691fQ== +jest-util@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.3.0.tgz#a549ae9910fedbd4c5912b204bb1bcc122ea0057" + integrity sha512-eKIAC+MTKWZthUUVOwZ3Tc5a0cKMnxalQHr6qZ4kPzKn6k09sKvsmjCygqZ1SxVVfUKoa8Sfn6XDv9uTJ1iXTg== dependencies: + "@jest/console" "^24.3.0" + "@jest/fake-timers" "^24.3.0" + "@jest/source-map" "^24.3.0" + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" + "@types/node" "*" callsites "^3.0.0" chalk "^2.0.1" graceful-fs "^4.1.15" is-ci "^2.0.0" - jest-message-util "^24.0.0" mkdirp "^0.5.1" slash "^2.0.0" source-map "^0.6.0" -jest-validate@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.0.0.tgz#aa8571a46983a6538328fef20406b4a496b6c020" - integrity sha512-vMrKrTOP4BBFIeOWsjpsDgVXATxCspC9S1gqvbJ3Tnn/b9ACsJmteYeVx9830UMV28Cob1RX55x96Qq3Tfad4g== +jest-validate@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.3.1.tgz#9359eea5a767a3d20b4fa7a5764fd78330ba8312" + integrity sha512-ww3+IPNCOEMi1oKlrHdSnBXetXtdrrdSh0bqLNTVkWglduhORf94RJWd1ko9oEPU2TcEQS5QIPacYziQIUzc4A== dependencies: + "@jest/types" "^24.3.0" camelcase "^5.0.0" chalk "^2.0.1" - jest-get-type "^24.0.0" + jest-get-type "^24.3.0" leven "^2.1.0" - pretty-format "^24.0.0" + pretty-format "^24.3.1" -jest-watcher@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.0.0.tgz#20d44244d10b0b7312410aefd256c1c1eef68890" - integrity sha512-GxkW2QrZ4YxmW1GUWER05McjVDunBlKMFfExu+VsGmXJmpej1saTEKvONdx5RJBlVdpPI5x6E3+EDQSIGgl53g== +jest-watcher@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.3.0.tgz#ee51c6afbe4b35a12fcf1107556db6756d7b9290" + integrity sha512-EpJS/aUG8D3DMuy9XNA4fnkKWy3DQdoWhY92ZUdlETIeEn1xya4Np/96MBSh4II5YvxwKe6JKwbu3Bnzfwa7vA== dependencies: + "@jest/test-result" "^24.3.0" + "@jest/types" "^24.3.0" + "@types/node" "*" + "@types/yargs" "^12.0.9" ansi-escapes "^3.0.0" chalk "^2.0.1" - jest-util "^24.0.0" + jest-util "^24.3.0" string-length "^2.0.0" -jest-worker@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0.tgz#3d3483b077bf04f412f47654a27bba7e947f8b6d" - integrity sha512-s64/OThpfQvoCeHG963MiEZOAAxu8kHsaL/rCMF7lpdzo7vgF0CtPml9hfguOMgykgH/eOm4jFP4ibfHLruytg== +jest-worker@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.3.1.tgz#c1759dd2b1d5541b09a2e5e1bc3288de6c9d8632" + integrity sha512-ZCoAe/iGLzTJvWHrO8fyx3bmEQhpL16SILJmWHKe8joHhyF3z00psF1sCRT54DoHw5GJG0ZpUtGy+ylvwA4haA== dependencies: + "@types/node" "*" merge-stream "^1.0.1" supports-color "^6.1.0" -jest@~24.1.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.1.0.tgz#b1e1135caefcf2397950ecf7f90e395fde866fd2" - integrity sha512-+q91L65kypqklvlRFfXfdzUKyngQLOcwGhXQaLmVHv+d09LkNXuBuGxlofTFW42XMzu3giIcChchTsCNUjQ78A== +jest@~24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.3.1.tgz#81959de0d57b2df923510f4fafe266712d37dcca" + integrity sha512-SqZguEbYNcZ3r0KUUBN+IkKfyPS1VBbIUiK4Wrc0AiGUR52gJa0fmlWSOCL3x25908QrfoQwkVDu5jCsfXb2ig== dependencies: import-local "^2.0.0" - jest-cli "^24.1.0" + jest-cli "^24.3.1" jmespath@0.15.0: version "0.15.0" @@ -4768,7 +5092,7 @@ jsonld@^0.4.11: request "^2.61.0" xmldom "0.1.19" -jsonwebtoken@^8.2.0, jsonwebtoken@~8.5.0: +jsonwebtoken@^8.3.0, jsonwebtoken@~8.5.0: version "8.5.0" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#ebd0ca2a69797816e1c5af65b6c759787252947e" integrity sha512-IqEycp0znWHNA11TpYi77bVgyBO/pGESDh7Ajhas+u0ttkGkKYIIAjniL4Bw5+oVejVF+SYkaI7XKfwCCyeTuA== @@ -5116,11 +5440,6 @@ merge-stream@^1.0.1: dependencies: readable-stream "^2.0.1" -merge@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" - integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== - methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -5309,21 +5628,22 @@ negotiator@0.6.1: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= -neo4j-driver@^1.7.2, neo4j-driver@~1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.2.tgz#c72a6dfa6bd2106b00a42794dc52a82b227b48e0" - integrity sha512-0IvCFYhcP9hb5JveZk33epbReDKpFTn2u5vAa8zzGG344i6yFqZrBo0mtC114ciP9zFjAtfNOP72mRm8+NV0Fg== +neo4j-driver@^1.7.2, neo4j-driver@~1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/neo4j-driver/-/neo4j-driver-1.7.3.tgz#1c1108ab26b7243975f1b20045daf31d8f685207" + integrity sha512-UCNOFiQdouq14PvZGTr+psy657BJsBpO6O2cJpP+NprZnEF4APrDzAcydPZSFxE1nfooLNc50vfuZ0q54UyY2Q== dependencies: babel-runtime "^6.26.0" text-encoding "^0.6.4" uri-js "^4.2.1" -neo4j-graphql-js@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.3.1.tgz#9a5de7e312594d63481e947a0cbe4e08b05ffed3" - integrity sha512-9DExWXD2vFdDJOmqorT1ygFOUEos7KF8KyF8Wt3jYxejWUuq+a5fAFBu7+YDH8QbvA23paKPEX0Pn1nS+Q5C1A== +neo4j-graphql-js@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.4.1.tgz#a1de65340fb6f1ad0ae6aadab90a0bb78b490b32" + integrity sha512-Py6RJuMT7A03Hzoo6qfKyo6DUnHQgbZlBcgucnhgQjbeysAzvM3F02UAVn/HxEtOgowAeGWjyjJvwozoNtiiqQ== dependencies: graphql "^14.0.2" + graphql-auth-directives "^2.0.0" lodash "^4.17.11" neo4j-driver "^1.7.2" @@ -5838,27 +6158,6 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -passport-jwt@~4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" - integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg== - dependencies: - jsonwebtoken "^8.2.0" - passport-strategy "^1.0.0" - -passport-strategy@1.x.x, passport-strategy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" - integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= - -passport@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" - integrity sha1-xQlWkTR71a07XhgCOMORTRbwWBE= - dependencies: - passport-strategy "1.x.x" - pause "0.0.1" - path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" @@ -5913,11 +6212,6 @@ pathval@^1.1.0: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= -pause@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" - integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= - performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -5945,6 +6239,13 @@ pirates@^4.0.0: dependencies: node-modules-regexp "^1.0.0" +pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== + dependencies: + node-modules-regexp "^1.0.0" + pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -6003,13 +6304,15 @@ prepend-http@^1.0.1: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -pretty-format@^24.0.0: - version "24.0.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0.tgz#cb6599fd73ac088e37ed682f61291e4678f48591" - integrity sha512-LszZaKG665djUcqg5ZQq+XzezHLKrxsA86ZABTozp+oNhkdqa+tG2dX4qa6ERl5c/sRDrAa3lHmwnvKoP+OG/g== +pretty-format@^24.3.1: + version "24.3.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.3.1.tgz#ae4a98e93d73d86913a8a7dd1a7c3c900f8fda59" + integrity sha512-NZGH1NWS6o4i9pvRWLsxIK00JB9pqOUzVrO7yWT6vjI2thdxwvxefBJO6O5T24UAhI8P5dMceZ7x5wphgVI7Mg== dependencies: + "@jest/types" "^24.3.0" ansi-regex "^4.0.0" ansi-styles "^3.2.0" + react-is "^16.8.4" private@^0.1.6: version "0.1.8" @@ -6167,6 +6470,11 @@ react-dom@^16.4.2: prop-types "^15.6.2" scheduler "^0.11.2" +react-is@^16.8.4: + version "16.8.4" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.4.tgz#90f336a68c3a29a096a3d648ab80e87ec61482a2" + integrity sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA== + react@^16.4.2: version "16.6.3" resolved "https://registry.yarnpkg.com/react/-/react-16.6.3.tgz#25d77c91911d6bbdd23db41e70fb094cc1e0871c" @@ -6252,10 +6560,10 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -realpath-native@^1.0.0, realpath-native@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560" - integrity sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g== +realpath-native@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" + integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== dependencies: util.promisify "^1.0.0" @@ -6298,10 +6606,10 @@ regenerator-runtime@^0.12.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== -regenerator-transform@^0.13.3: - version "0.13.3" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb" - integrity sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA== +regenerator-transform@^0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.4.tgz#18f6763cf1382c69c36df76c6ce122cc694284fb" + integrity sha512-T0QMBjK3J0MtxjPmdIMXm72Wvj2Abb0Bd4HADdfijwMdoIsyQZ6fWC7kDFhk2YinBBEMZDL7Y7wh0J1sGx3S4A== dependencies: private "^0.1.6" @@ -6404,7 +6712,7 @@ request-promise-native@^1.0.5: stealthy-require "^1.1.0" tough-cookie ">=2.3.3" -request@^2.61.0, request@^2.87.0, request@^2.88.0: +request@^2.61.0, request@^2.87.0, request@^2.88.0, request@~2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -6497,7 +6805,7 @@ rfc5646@^2.0.0: resolved "https://registry.yarnpkg.com/rfc5646/-/rfc5646-2.0.0.tgz#ac0c67b6cd04411ef7c80751ba159d9371ce116c" integrity sha1-rAxnts0EQR73yAdRuhWdk3HOEWw= -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@~2.6.2: +rimraf@2.6.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -6521,10 +6829,10 @@ rx@^4.1.0: resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= -rxjs@^6.1.0: - version "6.3.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" - integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== +rxjs@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.4.0.tgz#f3bb0fe7bda7fb69deac0c16f17b50b0b8790504" + integrity sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw== dependencies: tslib "^1.9.0" @@ -6545,22 +6853,20 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sane@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-3.1.0.tgz#995193b7dc1445ef1fe41ddfca2faf9f111854c6" - integrity sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q== +sane@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.0.3.tgz#e878c3f19e25cc57fbb734602f48f8a97818b181" + integrity sha512-hSLkC+cPHiBQs7LSyXkotC3UUtyn8C4FMn50TNaacRyvBlI+3ebcxMpqckmTdtXVtel87YS7GXN3UIOj7NiGVQ== dependencies: + "@cnakazawa/watch" "^1.0.3" anymatch "^2.0.0" capture-exit "^1.2.0" - exec-sh "^0.2.0" + exec-sh "^0.3.2" execa "^1.0.0" fb-watchman "^2.0.0" micromatch "^3.1.4" minimist "^1.1.1" walker "~1.0.5" - watch "~0.18.0" - optionalDependencies: - fsevents "^1.2.3" sanitize-html@~1.20.0: version "1.20.0" @@ -6732,10 +7038,10 @@ slash@^2.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== -slice-ansi@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.0.0.tgz#5373bdb8559b45676e8541c66916cdd6251612e7" - integrity sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ== +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== dependencies: ansi-styles "^3.2.0" astral-regex "^1.0.0" @@ -6987,6 +7293,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.0.0.tgz#5a1690a57cc78211fffd9bf24bbe24d090604eb1" + integrity sha512-rr8CUxBbvOZDUvc5lNIJ+OC1nPVpz+Siw9VBtUjB9b6jZehZLFt0JMCZzShFHIsI8cbhm0EsNIfWJMFV3cu3Ew== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.0.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" @@ -7115,15 +7430,15 @@ synchronous-promise@^2.0.5: resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.6.tgz#de76e0ea2b3558c1e673942e47e714a930fa64aa" integrity sha512-TyOuWLwkmtPL49LHCX1caIwHjRzcVd62+GF6h8W/jHOeZUFHpnd2XJDVuUlaTaLPH1nuu2M69mfHr5XbQJnf/g== -table@^5.0.2: - version "5.1.1" - resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837" - integrity sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw== +table@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/table/-/table-5.2.3.tgz#cde0cc6eb06751c009efab27e8c820ca5b67b7f2" + integrity sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ== dependencies: - ajv "^6.6.1" + ajv "^6.9.1" lodash "^4.17.11" - slice-ansi "2.0.0" - string-width "^2.1.1" + slice-ansi "^2.1.0" + string-width "^3.0.0" tar@^4: version "4.4.8" @@ -7310,6 +7625,20 @@ trunc-text@1.0.1: resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" integrity sha1-WPh22KxZsiS3mDS7R4uGVuaWIrU= +ts-invariant@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.2.1.tgz#3d587f9d6e3bded97bf9ec17951dd9814d5a9d3f" + integrity sha512-Z/JSxzVmhTo50I+LKagEISFJW3pvPCqsMWLamCTX8Kr3N5aMrnGOqcflbe5hLUzwjvgPfnLzQtHZv0yWQ+FIHg== + dependencies: + tslib "^1.9.3" + +ts-invariant@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.3.2.tgz#89a2ffeb70879b777258df1df1c59383c35209b0" + integrity sha512-QsY8BCaRnHiB5T6iE4DPlJMAKEG3gzMiUco9FEt1jUXQf0XP6zi0idT0i0rMTu8A326JqNSDsmlkA9dRSh1TRg== + dependencies: + tslib "^1.9.3" + tslib@^1.9.0, tslib@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -7501,6 +7830,13 @@ util.promisify@^1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" @@ -7511,7 +7847,7 @@ uuid@3.1.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== -uuid@^3.1.0, uuid@^3.3.2: +uuid@^3.1.0, uuid@^3.3.2, uuid@~3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== @@ -7639,14 +7975,6 @@ walker@~1.0.5: dependencies: makeerror "1.0.x" -watch@~0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" - integrity sha1-KAlUdsbffJDJYxOJkMClQj60uYY= - dependencies: - exec-sh "^0.2.0" - minimist "^1.2.0" - webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -7692,7 +8020,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.12, which@^1.2.9, which@^1.3.0: +which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -7763,10 +8091,10 @@ write-file-atomic@^2.3.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" -write@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== dependencies: mkdirp "^0.5.1" @@ -7875,11 +8203,12 @@ yup@^0.26.10: synchronous-promise "^2.0.5" toposort "^2.0.2" -zen-observable-ts@^0.8.15: - version "0.8.15" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.15.tgz#6cf7df6aa619076e4af2f707ccf8a6290d26699b" - integrity sha512-sXKPWiw6JszNEkRv5dQ+lQCttyjHM2Iks74QU5NP8mMPS/NrzTlHDr780gf/wOBqmHkPO6NCLMlsa+fAQ8VE8w== +zen-observable-ts@^0.8.16: + version "0.8.16" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.16.tgz#969367299074fe17422fe2f46ee417e9a30cf3fa" + integrity sha512-pQl75N7qwgybKVsh6WFO+WwPRijeQ52Gn1vSf4uvPFXald9CbVQXLa5QrOPEJhdZiC+CD4quqOVqSG+Ptz5XLA== dependencies: + tslib "^1.9.3" zen-observable "^0.8.0" zen-observable@^0.8.0: From 261edef72bb6bdd002e4f6d78d8398b4cbeb4c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 8 Mar 2019 20:55:46 +0100 Subject: [PATCH 505/554] Remove duplicate mutations --- src/schema.graphql | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/schema.graphql b/src/schema.graphql index 16db72819..5d641c0b8 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -12,7 +12,6 @@ type Mutation { report(id: ID!, description: String): Report disable(id: ID!): ID! enable(id: ID!): ID! - report(resource: Resource!, description: String): Report "Shout the given Type and ID" shout(id: ID!, type: ShoutTypeEnum): Boolean! @cypher(statement: """ MATCH (n {id: $id})<-[:WROTE]-(wu:User), (u:User {id: $cypherParams.currentUserId}) @@ -42,8 +41,6 @@ type Mutation { DELETE r RETURN COUNT(r) > 0 """) - disable(resource: Resource!): Boolean! - enable(resource: Resource!): Boolean! } type Statistics { From af4cfad3a2dfeef27f62383b3a16bd7427ef8497 Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 8 Mar 2019 21:08:18 +0100 Subject: [PATCH 506/554] Added PRIVATE_KEY_PASSPHRASE to docker compose --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 1e8c9158c..30d102f96 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,7 @@ services: - JWT_SECRET=b/&&7b78BF&fv/Vd - MOCK=false - MAPBOX_TOKEN=pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ + - PRIVATE_KEY_PASSPHRASE=a7dsf78sadg87ad87sfagsadg78 neo4j: image: humanconnection/neo4j:latest From 43505906978e14a93adc0827aba3343185f6cdd7 Mon Sep 17 00:00:00 2001 From: kachulio1 Date: Sat, 9 Mar 2019 13:36:27 +0300 Subject: [PATCH 507/554] add changePasssword mutation --- src/middleware/permissionsMiddleware.js | 3 +- src/resolvers/user_management.js | 69 ++++++++++++++++++++++--- src/schema.graphql | 1 + 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index c40803e00..15c4d1a9b 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -55,7 +55,8 @@ const permissions = shield({ report: isAuthenticated, CreateBadge: isAdmin, UpdateBadge: isAdmin, - DeleteBadge: isAdmin + DeleteBadge: isAdmin, + changePassword: isAuthenticated // addFruitToBasket: isAuthenticated // CreateUser: allow, }, diff --git a/src/resolvers/user_management.js b/src/resolvers/user_management.js index ec4ae7ce2..3a7698e24 100644 --- a/src/resolvers/user_management.js +++ b/src/resolvers/user_management.js @@ -30,22 +30,75 @@ export default { // throw new Error('Already logged in.') // } const session = driver.session() - return session.run( - 'MATCH (user:User {email: $userEmail}) ' + - 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', { - userEmail: email - }) - .then(async (result) => { + return session + .run( + 'MATCH (user:User {email: $userEmail}) ' + + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', + { + userEmail: email + } + ) + .then(async result => { session.close() const [currentUser] = await result.records.map(function (record) { return record.get('user') }) - if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { + if ( + currentUser && + (await bcrypt.compareSync(password, currentUser.password)) + ) { delete currentUser.password return encode(currentUser) - } else throw new AuthenticationError('Incorrect email address or password.') + } else { + throw new AuthenticationError( + 'Incorrect email address or password.' + ) + } }) + }, + changePassword: async ( + _, + { oldPassword, newPassword }, + { driver, user } + ) => { + const session = driver.session() + let result = await session.run( + `MATCH (user:User {email: $userEmail}) + RETURN user {.id, .email, .password}`, + { + userEmail: user.email + } + ) + + const [currentUser] = result.records.map(function (record) { + return record.get('user') + }) + + if (!(await bcrypt.compareSync(oldPassword, currentUser.password))) { + throw new AuthenticationError('Old password isn\'t valid') + } + + if (await bcrypt.compareSync(newPassword, currentUser.password)) { + throw new AuthenticationError( + 'Old password and New password should not be same' + ) + } else { + const newHashedPassword = await bcrypt.hashSync(newPassword, 10) + session.run( + `MATCH (user:User {email: $userEmail}) + SET user.password = $newHashedPassword + RETURN user + `, + { + userEmail: user.email, + newHashedPassword + } + ) + session.close() + + return encode(currentUser) + } } } } diff --git a/src/schema.graphql b/src/schema.graphql index 1f9bcb477..127b9ced2 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -6,6 +6,7 @@ type Query { type Mutation { login(email: String!, password: String!): String! signup(email: String!, password: String!): Boolean! + changePassword(oldPassword:String!, newPassword: String!): String! report(resource: Resource!, description: String): Report } From 8fcefc63bc37d190b404ce93e3b6ffa615b4c43a Mon Sep 17 00:00:00 2001 From: kachulio1 Date: Sat, 9 Mar 2019 14:47:12 +0300 Subject: [PATCH 508/554] add changePassword mutation test --- src/resolvers/user_management.spec.js | 314 ++++++++++++++++---------- 1 file changed, 197 insertions(+), 117 deletions(-) diff --git a/src/resolvers/user_management.spec.js b/src/resolvers/user_management.spec.js index a3bf6fdd0..98574f0ac 100644 --- a/src/resolvers/user_management.spec.js +++ b/src/resolvers/user_management.spec.js @@ -1,9 +1,9 @@ -import Factory from '../seed/factories' -import { GraphQLClient, request } from 'graphql-request' -import jwt from 'jsonwebtoken' -import { host, login } from '../jest/helpers' +import Factory from "../seed/factories"; +import { GraphQLClient, request } from "graphql-request"; +import jwt from "jsonwebtoken"; +import { host, login } from "../jest/helpers"; -const factory = Factory() +const factory = Factory(); // here is the decoded JWT token: // { @@ -21,59 +21,71 @@ const factory = Factory() // iss: 'http://localhost:4000', // sub: 'u3' // } -const jennyRostocksHeaders = { authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoidXNlciIsImxvY2F0aW9uTmFtZSI6bnVsbCwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJhYm91dCI6bnVsbCwiYXZhdGFyIjoiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3VpZmFjZXMvZmFjZXMvdHdpdHRlci9zYXNoYV9zaGVzdGFrb3YvMTI4LmpwZyIsImlkIjoidTMiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5vcmciLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTU1MDg0NjY4MCwiZXhwIjoxNjM3MjQ2NjgwLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.eZ_mVKas4Wzoc_JrQTEWXyRn7eY64cdIg4vqQ-F_7Jc' } +const jennyRostocksHeaders = { + authorization: + "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoidXNlciIsImxvY2F0aW9uTmFtZSI6bnVsbCwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJhYm91dCI6bnVsbCwiYXZhdGFyIjoiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3VpZmFjZXMvZmFjZXMvdHdpdHRlci9zYXNoYV9zaGVzdGFrb3YvMTI4LmpwZyIsImlkIjoidTMiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5vcmciLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTU1MDg0NjY4MCwiZXhwIjoxNjM3MjQ2NjgwLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.eZ_mVKas4Wzoc_JrQTEWXyRn7eY64cdIg4vqQ-F_7Jc" +}; beforeEach(async () => { - await factory.create('User', { - avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', - id: 'acb2d923-f3af-479e-9f00-61b12e864666', - name: 'Matilde Hermiston', - slug: 'matilde-hermiston', - role: 'user', - email: 'test@example.org', - password: '1234' - }) -}) + await factory.create("User", { + avatar: + "https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg", + id: "acb2d923-f3af-479e-9f00-61b12e864666", + name: "Matilde Hermiston", + slug: "matilde-hermiston", + role: "user", + email: "test@example.org", + password: "1234" + }); +}); afterEach(async () => { - await factory.cleanDatabase() -}) + await factory.cleanDatabase(); +}); -describe('isLoggedIn', () => { - const query = '{ isLoggedIn }' - describe('unauthenticated', () => { - it('returns false', async () => { - await expect(request(host, query)).resolves.toEqual({ isLoggedIn: false }) - }) - }) +describe("isLoggedIn", () => { + const query = "{ isLoggedIn }"; + describe("unauthenticated", () => { + it("returns false", async () => { + await expect(request(host, query)).resolves.toEqual({ + isLoggedIn: false + }); + }); + }); - describe('with malformed JWT Bearer token', () => { - const headers = { authorization: 'blah' } - const client = new GraphQLClient(host, { headers }) + describe("with malformed JWT Bearer token", () => { + const headers = { authorization: "blah" }; + const client = new GraphQLClient(host, { headers }); - it('returns false', async () => { - await expect(client.request(query)).resolves.toEqual({ isLoggedIn: false }) - }) - }) + it("returns false", async () => { + await expect(client.request(query)).resolves.toEqual({ + isLoggedIn: false + }); + }); + }); - describe('with valid JWT Bearer token', () => { - const client = new GraphQLClient(host, { headers: jennyRostocksHeaders }) + describe("with valid JWT Bearer token", () => { + const client = new GraphQLClient(host, { headers: jennyRostocksHeaders }); - it('returns false', async () => { - await expect(client.request(query)).resolves.toEqual({ isLoggedIn: false }) - }) + it("returns false", async () => { + await expect(client.request(query)).resolves.toEqual({ + isLoggedIn: false + }); + }); - describe('and a corresponding user in the database', () => { - it('returns true', async () => { + describe("and a corresponding user in the database", () => { + it("returns true", async () => { // see the decoded token above - await factory.create('User', { id: 'u3' }) - await expect(client.request(query)).resolves.toEqual({ isLoggedIn: true }) - }) - }) - }) -}) + await factory.create("User", { id: "u3" }); + await expect(client.request(query)).resolves.toEqual({ + isLoggedIn: true + }); + }); + }); + }); +}); -describe('currentUser', () => { +describe("currentUser", () => { const query = `{ currentUser { id @@ -83,97 +95,165 @@ describe('currentUser', () => { email role } - }` + }`; - describe('unauthenticated', () => { - it('returns null', async () => { - const expected = { currentUser: null } - await expect(request(host, query)).resolves.toEqual(expected) - }) - }) + describe("unauthenticated", () => { + it("returns null", async () => { + const expected = { currentUser: null }; + await expect(request(host, query)).resolves.toEqual(expected); + }); + }); - describe('with valid JWT Bearer Token', () => { - let client - let headers + describe("with valid JWT Bearer Token", () => { + let client; + let headers; - describe('but no corresponding user in the database', () => { + describe("but no corresponding user in the database", () => { beforeEach(async () => { - client = new GraphQLClient(host, { headers: jennyRostocksHeaders }) - }) + client = new GraphQLClient(host, { headers: jennyRostocksHeaders }); + }); - it('returns null', async () => { - const expected = { currentUser: null } - await expect(client.request(query)).resolves.toEqual(expected) - }) - }) + it("returns null", async () => { + const expected = { currentUser: null }; + await expect(client.request(query)).resolves.toEqual(expected); + }); + }); - describe('and corresponding user in the database', () => { + describe("and corresponding user in the database", () => { beforeEach(async () => { - headers = await login({ email: 'test@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - }) + headers = await login({ email: "test@example.org", password: "1234" }); + client = new GraphQLClient(host, { headers }); + }); - it('returns the whole user object', async () => { + it("returns the whole user object", async () => { const expected = { currentUser: { - avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', - email: 'test@example.org', - id: 'acb2d923-f3af-479e-9f00-61b12e864666', - name: 'Matilde Hermiston', - slug: 'matilde-hermiston', - role: 'user' + avatar: + "https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg", + email: "test@example.org", + id: "acb2d923-f3af-479e-9f00-61b12e864666", + name: "Matilde Hermiston", + slug: "matilde-hermiston", + role: "user" } - } - await expect(client.request(query)).resolves.toEqual(expected) - }) - }) - }) -}) + }; + await expect(client.request(query)).resolves.toEqual(expected); + }); + }); + }); +}); -describe('login', () => { - const mutation = (params) => { - const { email, password } = params +describe("login", () => { + const mutation = params => { + const { email, password } = params; return ` mutation { login(email:"${email}", password:"${password}") - }` - } + }`; + }; - describe('ask for a `token`', () => { - describe('with valid email/password combination', () => { - it('responds with a JWT token', async () => { - const data = await request(host, mutation({ - email: 'test@example.org', - password: '1234' - })) - const token = data.login + describe("ask for a `token`", () => { + describe("with valid email/password combination", () => { + it("responds with a JWT token", async () => { + const data = await request( + host, + mutation({ + email: "test@example.org", + password: "1234" + }) + ); + const token = data.login; jwt.verify(token, process.env.JWT_SECRET, (err, data) => { - expect(data.email).toEqual('test@example.org') - expect(err).toBeNull() - }) - }) - }) + expect(data.email).toEqual("test@example.org"); + expect(err).toBeNull(); + }); + }); + }); - describe('with a valid email but incorrect password', () => { + describe("with a valid email but incorrect password", () => { it('responds with "Incorrect email address or password."', async () => { await expect( - request(host, mutation({ - email: 'test@example.org', - password: 'wrong' - })) - ).rejects.toThrow('Incorrect email address or password.') - }) - }) + request( + host, + mutation({ + email: "test@example.org", + password: "wrong" + }) + ) + ).rejects.toThrow("Incorrect email address or password."); + }); + }); - describe('with a non-existing email', () => { + describe("with a non-existing email", () => { it('responds with "Incorrect email address or password."', async () => { await expect( - request(host, mutation({ - email: 'non-existent@example.org', - password: 'wrong' - })) - ).rejects.toThrow('Incorrect email address or password.') - }) - }) - }) -}) + request( + host, + mutation({ + email: "non-existent@example.org", + password: "wrong" + }) + ) + ).rejects.toThrow("Incorrect email address or password."); + }); + }); + }); +}); + +describe("change password", () => { + let headers; + let client; + + beforeEach(async () => { + headers = await login({ email: "test@example.org", password: "1234" }); + client = new GraphQLClient(host, { headers }); + }); + + const mutation = params => { + const { oldPassword, newPassword } = params; + return ` + mutation { + changePassword(oldPassword:"${oldPassword}", newPassword:"${newPassword}") + }`; + }; + + describe("should be authenticated before changing password", () => { + it('should throw not "Not Authorised!', async () => { + await expect( + request( + host, + mutation({ + oldPassword: "1234", + newPassword: "1234" + }) + ) + ).rejects.toThrow("Not Authorised!"); + }); + }); + + describe("old and new password should not match", () => { + it('responds with "Old password and New password should not be same"', async () => { + await expect( + client.request( + mutation({ + oldPassword: "1234", + newPassword: "1234" + }) + ) + ).rejects.toThrow("Old password and New password should not be same"); + }); + }); + + describe("incorrect old password", () => { + it('responds with "Old password isn\'t valid"', async () => { + await expect( + client.request( + mutation({ + oldPassword: "notOldPassword", + newPassword: "12345" + }) + ) + ).rejects.toThrow("Old password isn't valid"); + }); + }); +}); From 82ae81d8fe24f3c88c238d7f9a458145e9fe0ec6 Mon Sep 17 00:00:00 2001 From: kachulio1 Date: Sat, 9 Mar 2019 13:36:27 +0300 Subject: [PATCH 509/554] add changePasssword mutation --- src/middleware/permissionsMiddleware.js | 4 +- src/resolvers/user_management.js | 69 ++++++++++++++++++++++--- src/schema.graphql | 1 + 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 7fb6e75b8..434b97200 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -56,9 +56,9 @@ const permissions = shield({ CreateBadge: isAdmin, UpdateBadge: isAdmin, DeleteBadge: isAdmin, - enable: isModerator, - disable: isModerator + disable: isModerator, + changePassword: isAuthenticated // addFruitToBasket: isAuthenticated // CreateUser: allow, }, diff --git a/src/resolvers/user_management.js b/src/resolvers/user_management.js index ec4ae7ce2..3a7698e24 100644 --- a/src/resolvers/user_management.js +++ b/src/resolvers/user_management.js @@ -30,22 +30,75 @@ export default { // throw new Error('Already logged in.') // } const session = driver.session() - return session.run( - 'MATCH (user:User {email: $userEmail}) ' + - 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', { - userEmail: email - }) - .then(async (result) => { + return session + .run( + 'MATCH (user:User {email: $userEmail}) ' + + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', + { + userEmail: email + } + ) + .then(async result => { session.close() const [currentUser] = await result.records.map(function (record) { return record.get('user') }) - if (currentUser && await bcrypt.compareSync(password, currentUser.password)) { + if ( + currentUser && + (await bcrypt.compareSync(password, currentUser.password)) + ) { delete currentUser.password return encode(currentUser) - } else throw new AuthenticationError('Incorrect email address or password.') + } else { + throw new AuthenticationError( + 'Incorrect email address or password.' + ) + } }) + }, + changePassword: async ( + _, + { oldPassword, newPassword }, + { driver, user } + ) => { + const session = driver.session() + let result = await session.run( + `MATCH (user:User {email: $userEmail}) + RETURN user {.id, .email, .password}`, + { + userEmail: user.email + } + ) + + const [currentUser] = result.records.map(function (record) { + return record.get('user') + }) + + if (!(await bcrypt.compareSync(oldPassword, currentUser.password))) { + throw new AuthenticationError('Old password isn\'t valid') + } + + if (await bcrypt.compareSync(newPassword, currentUser.password)) { + throw new AuthenticationError( + 'Old password and New password should not be same' + ) + } else { + const newHashedPassword = await bcrypt.hashSync(newPassword, 10) + session.run( + `MATCH (user:User {email: $userEmail}) + SET user.password = $newHashedPassword + RETURN user + `, + { + userEmail: user.email, + newHashedPassword + } + ) + session.close() + + return encode(currentUser) + } } } } diff --git a/src/schema.graphql b/src/schema.graphql index 0cf099411..b6abd8f81 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -9,6 +9,7 @@ type Mutation { "Get a JWT Token for the given Email and password" login(email: String!, password: String!): String! signup(email: String!, password: String!): Boolean! + changePassword(oldPassword:String!, newPassword: String!): String! report(resource: Resource!, description: String): Report "Shout the given Type and ID" shout(id: ID!, type: ShoutTypeEnum): Boolean! @cypher(statement: """ From 35339b4674ec46b483f16174554d94d2cd2e4187 Mon Sep 17 00:00:00 2001 From: kachulio1 Date: Sat, 9 Mar 2019 14:47:12 +0300 Subject: [PATCH 510/554] add changePassword mutation test --- src/resolvers/user_management.spec.js | 314 ++++++++++++++++---------- 1 file changed, 197 insertions(+), 117 deletions(-) diff --git a/src/resolvers/user_management.spec.js b/src/resolvers/user_management.spec.js index a3bf6fdd0..98574f0ac 100644 --- a/src/resolvers/user_management.spec.js +++ b/src/resolvers/user_management.spec.js @@ -1,9 +1,9 @@ -import Factory from '../seed/factories' -import { GraphQLClient, request } from 'graphql-request' -import jwt from 'jsonwebtoken' -import { host, login } from '../jest/helpers' +import Factory from "../seed/factories"; +import { GraphQLClient, request } from "graphql-request"; +import jwt from "jsonwebtoken"; +import { host, login } from "../jest/helpers"; -const factory = Factory() +const factory = Factory(); // here is the decoded JWT token: // { @@ -21,59 +21,71 @@ const factory = Factory() // iss: 'http://localhost:4000', // sub: 'u3' // } -const jennyRostocksHeaders = { authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoidXNlciIsImxvY2F0aW9uTmFtZSI6bnVsbCwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJhYm91dCI6bnVsbCwiYXZhdGFyIjoiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3VpZmFjZXMvZmFjZXMvdHdpdHRlci9zYXNoYV9zaGVzdGFrb3YvMTI4LmpwZyIsImlkIjoidTMiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5vcmciLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTU1MDg0NjY4MCwiZXhwIjoxNjM3MjQ2NjgwLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.eZ_mVKas4Wzoc_JrQTEWXyRn7eY64cdIg4vqQ-F_7Jc' } +const jennyRostocksHeaders = { + authorization: + "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoidXNlciIsImxvY2F0aW9uTmFtZSI6bnVsbCwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJhYm91dCI6bnVsbCwiYXZhdGFyIjoiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3VpZmFjZXMvZmFjZXMvdHdpdHRlci9zYXNoYV9zaGVzdGFrb3YvMTI4LmpwZyIsImlkIjoidTMiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5vcmciLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTU1MDg0NjY4MCwiZXhwIjoxNjM3MjQ2NjgwLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.eZ_mVKas4Wzoc_JrQTEWXyRn7eY64cdIg4vqQ-F_7Jc" +}; beforeEach(async () => { - await factory.create('User', { - avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', - id: 'acb2d923-f3af-479e-9f00-61b12e864666', - name: 'Matilde Hermiston', - slug: 'matilde-hermiston', - role: 'user', - email: 'test@example.org', - password: '1234' - }) -}) + await factory.create("User", { + avatar: + "https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg", + id: "acb2d923-f3af-479e-9f00-61b12e864666", + name: "Matilde Hermiston", + slug: "matilde-hermiston", + role: "user", + email: "test@example.org", + password: "1234" + }); +}); afterEach(async () => { - await factory.cleanDatabase() -}) + await factory.cleanDatabase(); +}); -describe('isLoggedIn', () => { - const query = '{ isLoggedIn }' - describe('unauthenticated', () => { - it('returns false', async () => { - await expect(request(host, query)).resolves.toEqual({ isLoggedIn: false }) - }) - }) +describe("isLoggedIn", () => { + const query = "{ isLoggedIn }"; + describe("unauthenticated", () => { + it("returns false", async () => { + await expect(request(host, query)).resolves.toEqual({ + isLoggedIn: false + }); + }); + }); - describe('with malformed JWT Bearer token', () => { - const headers = { authorization: 'blah' } - const client = new GraphQLClient(host, { headers }) + describe("with malformed JWT Bearer token", () => { + const headers = { authorization: "blah" }; + const client = new GraphQLClient(host, { headers }); - it('returns false', async () => { - await expect(client.request(query)).resolves.toEqual({ isLoggedIn: false }) - }) - }) + it("returns false", async () => { + await expect(client.request(query)).resolves.toEqual({ + isLoggedIn: false + }); + }); + }); - describe('with valid JWT Bearer token', () => { - const client = new GraphQLClient(host, { headers: jennyRostocksHeaders }) + describe("with valid JWT Bearer token", () => { + const client = new GraphQLClient(host, { headers: jennyRostocksHeaders }); - it('returns false', async () => { - await expect(client.request(query)).resolves.toEqual({ isLoggedIn: false }) - }) + it("returns false", async () => { + await expect(client.request(query)).resolves.toEqual({ + isLoggedIn: false + }); + }); - describe('and a corresponding user in the database', () => { - it('returns true', async () => { + describe("and a corresponding user in the database", () => { + it("returns true", async () => { // see the decoded token above - await factory.create('User', { id: 'u3' }) - await expect(client.request(query)).resolves.toEqual({ isLoggedIn: true }) - }) - }) - }) -}) + await factory.create("User", { id: "u3" }); + await expect(client.request(query)).resolves.toEqual({ + isLoggedIn: true + }); + }); + }); + }); +}); -describe('currentUser', () => { +describe("currentUser", () => { const query = `{ currentUser { id @@ -83,97 +95,165 @@ describe('currentUser', () => { email role } - }` + }`; - describe('unauthenticated', () => { - it('returns null', async () => { - const expected = { currentUser: null } - await expect(request(host, query)).resolves.toEqual(expected) - }) - }) + describe("unauthenticated", () => { + it("returns null", async () => { + const expected = { currentUser: null }; + await expect(request(host, query)).resolves.toEqual(expected); + }); + }); - describe('with valid JWT Bearer Token', () => { - let client - let headers + describe("with valid JWT Bearer Token", () => { + let client; + let headers; - describe('but no corresponding user in the database', () => { + describe("but no corresponding user in the database", () => { beforeEach(async () => { - client = new GraphQLClient(host, { headers: jennyRostocksHeaders }) - }) + client = new GraphQLClient(host, { headers: jennyRostocksHeaders }); + }); - it('returns null', async () => { - const expected = { currentUser: null } - await expect(client.request(query)).resolves.toEqual(expected) - }) - }) + it("returns null", async () => { + const expected = { currentUser: null }; + await expect(client.request(query)).resolves.toEqual(expected); + }); + }); - describe('and corresponding user in the database', () => { + describe("and corresponding user in the database", () => { beforeEach(async () => { - headers = await login({ email: 'test@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - }) + headers = await login({ email: "test@example.org", password: "1234" }); + client = new GraphQLClient(host, { headers }); + }); - it('returns the whole user object', async () => { + it("returns the whole user object", async () => { const expected = { currentUser: { - avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', - email: 'test@example.org', - id: 'acb2d923-f3af-479e-9f00-61b12e864666', - name: 'Matilde Hermiston', - slug: 'matilde-hermiston', - role: 'user' + avatar: + "https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg", + email: "test@example.org", + id: "acb2d923-f3af-479e-9f00-61b12e864666", + name: "Matilde Hermiston", + slug: "matilde-hermiston", + role: "user" } - } - await expect(client.request(query)).resolves.toEqual(expected) - }) - }) - }) -}) + }; + await expect(client.request(query)).resolves.toEqual(expected); + }); + }); + }); +}); -describe('login', () => { - const mutation = (params) => { - const { email, password } = params +describe("login", () => { + const mutation = params => { + const { email, password } = params; return ` mutation { login(email:"${email}", password:"${password}") - }` - } + }`; + }; - describe('ask for a `token`', () => { - describe('with valid email/password combination', () => { - it('responds with a JWT token', async () => { - const data = await request(host, mutation({ - email: 'test@example.org', - password: '1234' - })) - const token = data.login + describe("ask for a `token`", () => { + describe("with valid email/password combination", () => { + it("responds with a JWT token", async () => { + const data = await request( + host, + mutation({ + email: "test@example.org", + password: "1234" + }) + ); + const token = data.login; jwt.verify(token, process.env.JWT_SECRET, (err, data) => { - expect(data.email).toEqual('test@example.org') - expect(err).toBeNull() - }) - }) - }) + expect(data.email).toEqual("test@example.org"); + expect(err).toBeNull(); + }); + }); + }); - describe('with a valid email but incorrect password', () => { + describe("with a valid email but incorrect password", () => { it('responds with "Incorrect email address or password."', async () => { await expect( - request(host, mutation({ - email: 'test@example.org', - password: 'wrong' - })) - ).rejects.toThrow('Incorrect email address or password.') - }) - }) + request( + host, + mutation({ + email: "test@example.org", + password: "wrong" + }) + ) + ).rejects.toThrow("Incorrect email address or password."); + }); + }); - describe('with a non-existing email', () => { + describe("with a non-existing email", () => { it('responds with "Incorrect email address or password."', async () => { await expect( - request(host, mutation({ - email: 'non-existent@example.org', - password: 'wrong' - })) - ).rejects.toThrow('Incorrect email address or password.') - }) - }) - }) -}) + request( + host, + mutation({ + email: "non-existent@example.org", + password: "wrong" + }) + ) + ).rejects.toThrow("Incorrect email address or password."); + }); + }); + }); +}); + +describe("change password", () => { + let headers; + let client; + + beforeEach(async () => { + headers = await login({ email: "test@example.org", password: "1234" }); + client = new GraphQLClient(host, { headers }); + }); + + const mutation = params => { + const { oldPassword, newPassword } = params; + return ` + mutation { + changePassword(oldPassword:"${oldPassword}", newPassword:"${newPassword}") + }`; + }; + + describe("should be authenticated before changing password", () => { + it('should throw not "Not Authorised!', async () => { + await expect( + request( + host, + mutation({ + oldPassword: "1234", + newPassword: "1234" + }) + ) + ).rejects.toThrow("Not Authorised!"); + }); + }); + + describe("old and new password should not match", () => { + it('responds with "Old password and New password should not be same"', async () => { + await expect( + client.request( + mutation({ + oldPassword: "1234", + newPassword: "1234" + }) + ) + ).rejects.toThrow("Old password and New password should not be same"); + }); + }); + + describe("incorrect old password", () => { + it('responds with "Old password isn\'t valid"', async () => { + await expect( + client.request( + mutation({ + oldPassword: "notOldPassword", + newPassword: "12345" + }) + ) + ).rejects.toThrow("Old password isn't valid"); + }); + }); +}); From 3fbe4cb2e6e32555adb00daf08b2ed0177c800f0 Mon Sep 17 00:00:00 2001 From: kachulio1 Date: Sun, 10 Mar 2019 00:48:16 +0300 Subject: [PATCH 511/554] add use single quotes --- src/resolvers/user_management.spec.js | 280 +++++++++++++------------- 1 file changed, 140 insertions(+), 140 deletions(-) diff --git a/src/resolvers/user_management.spec.js b/src/resolvers/user_management.spec.js index 98574f0ac..5aaadfeed 100644 --- a/src/resolvers/user_management.spec.js +++ b/src/resolvers/user_management.spec.js @@ -1,9 +1,9 @@ -import Factory from "../seed/factories"; -import { GraphQLClient, request } from "graphql-request"; -import jwt from "jsonwebtoken"; -import { host, login } from "../jest/helpers"; +import Factory from '../seed/factories' +import { GraphQLClient, request } from 'graphql-request' +import jwt from 'jsonwebtoken' +import { host, login } from '../jest/helpers' -const factory = Factory(); +const factory = Factory() // here is the decoded JWT token: // { @@ -23,69 +23,69 @@ const factory = Factory(); // } const jennyRostocksHeaders = { authorization: - "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoidXNlciIsImxvY2F0aW9uTmFtZSI6bnVsbCwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJhYm91dCI6bnVsbCwiYXZhdGFyIjoiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3VpZmFjZXMvZmFjZXMvdHdpdHRlci9zYXNoYV9zaGVzdGFrb3YvMTI4LmpwZyIsImlkIjoidTMiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5vcmciLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTU1MDg0NjY4MCwiZXhwIjoxNjM3MjQ2NjgwLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.eZ_mVKas4Wzoc_JrQTEWXyRn7eY64cdIg4vqQ-F_7Jc" -}; + 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoidXNlciIsImxvY2F0aW9uTmFtZSI6bnVsbCwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJhYm91dCI6bnVsbCwiYXZhdGFyIjoiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3VpZmFjZXMvZmFjZXMvdHdpdHRlci9zYXNoYV9zaGVzdGFrb3YvMTI4LmpwZyIsImlkIjoidTMiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5vcmciLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTU1MDg0NjY4MCwiZXhwIjoxNjM3MjQ2NjgwLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.eZ_mVKas4Wzoc_JrQTEWXyRn7eY64cdIg4vqQ-F_7Jc' +} beforeEach(async () => { - await factory.create("User", { + await factory.create('User', { avatar: - "https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg", - id: "acb2d923-f3af-479e-9f00-61b12e864666", - name: "Matilde Hermiston", - slug: "matilde-hermiston", - role: "user", - email: "test@example.org", - password: "1234" - }); -}); + 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', + id: 'acb2d923-f3af-479e-9f00-61b12e864666', + name: 'Matilde Hermiston', + slug: 'matilde-hermiston', + role: 'user', + email: 'test@example.org', + password: '1234' + }) +}) afterEach(async () => { - await factory.cleanDatabase(); -}); + await factory.cleanDatabase() +}) -describe("isLoggedIn", () => { - const query = "{ isLoggedIn }"; - describe("unauthenticated", () => { - it("returns false", async () => { +describe('isLoggedIn', () => { + const query = '{ isLoggedIn }' + describe('unauthenticated', () => { + it('returns false', async () => { await expect(request(host, query)).resolves.toEqual({ isLoggedIn: false - }); - }); - }); + }) + }) + }) - describe("with malformed JWT Bearer token", () => { - const headers = { authorization: "blah" }; - const client = new GraphQLClient(host, { headers }); + describe('with malformed JWT Bearer token', () => { + const headers = { authorization: 'blah' } + const client = new GraphQLClient(host, { headers }) - it("returns false", async () => { + it('returns false', async () => { await expect(client.request(query)).resolves.toEqual({ isLoggedIn: false - }); - }); - }); + }) + }) + }) - describe("with valid JWT Bearer token", () => { - const client = new GraphQLClient(host, { headers: jennyRostocksHeaders }); + describe('with valid JWT Bearer token', () => { + const client = new GraphQLClient(host, { headers: jennyRostocksHeaders }) - it("returns false", async () => { + it('returns false', async () => { await expect(client.request(query)).resolves.toEqual({ isLoggedIn: false - }); - }); + }) + }) - describe("and a corresponding user in the database", () => { - it("returns true", async () => { + describe('and a corresponding user in the database', () => { + it('returns true', async () => { // see the decoded token above - await factory.create("User", { id: "u3" }); + await factory.create('User', { id: 'u3' }) await expect(client.request(query)).resolves.toEqual({ isLoggedIn: true - }); - }); - }); - }); -}); + }) + }) + }) + }) +}) -describe("currentUser", () => { +describe('currentUser', () => { const query = `{ currentUser { id @@ -95,165 +95,165 @@ describe("currentUser", () => { email role } - }`; + }` - describe("unauthenticated", () => { - it("returns null", async () => { - const expected = { currentUser: null }; - await expect(request(host, query)).resolves.toEqual(expected); - }); - }); + describe('unauthenticated', () => { + it('returns null', async () => { + const expected = { currentUser: null } + await expect(request(host, query)).resolves.toEqual(expected) + }) + }) - describe("with valid JWT Bearer Token", () => { - let client; - let headers; + describe('with valid JWT Bearer Token', () => { + let client + let headers - describe("but no corresponding user in the database", () => { + describe('but no corresponding user in the database', () => { beforeEach(async () => { - client = new GraphQLClient(host, { headers: jennyRostocksHeaders }); - }); + client = new GraphQLClient(host, { headers: jennyRostocksHeaders }) + }) - it("returns null", async () => { - const expected = { currentUser: null }; - await expect(client.request(query)).resolves.toEqual(expected); - }); - }); + it('returns null', async () => { + const expected = { currentUser: null } + await expect(client.request(query)).resolves.toEqual(expected) + }) + }) - describe("and corresponding user in the database", () => { + describe('and corresponding user in the database', () => { beforeEach(async () => { - headers = await login({ email: "test@example.org", password: "1234" }); - client = new GraphQLClient(host, { headers }); - }); + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) - it("returns the whole user object", async () => { + it('returns the whole user object', async () => { const expected = { currentUser: { avatar: - "https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg", - email: "test@example.org", - id: "acb2d923-f3af-479e-9f00-61b12e864666", - name: "Matilde Hermiston", - slug: "matilde-hermiston", - role: "user" + 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', + email: 'test@example.org', + id: 'acb2d923-f3af-479e-9f00-61b12e864666', + name: 'Matilde Hermiston', + slug: 'matilde-hermiston', + role: 'user' } - }; - await expect(client.request(query)).resolves.toEqual(expected); - }); - }); - }); -}); + } + await expect(client.request(query)).resolves.toEqual(expected) + }) + }) + }) +}) -describe("login", () => { +describe('login', () => { const mutation = params => { - const { email, password } = params; + const { email, password } = params return ` mutation { login(email:"${email}", password:"${password}") - }`; - }; + }` + } - describe("ask for a `token`", () => { - describe("with valid email/password combination", () => { - it("responds with a JWT token", async () => { + describe('ask for a `token`', () => { + describe('with valid email/password combination', () => { + it('responds with a JWT token', async () => { const data = await request( host, mutation({ - email: "test@example.org", - password: "1234" + email: 'test@example.org', + password: '1234' }) - ); - const token = data.login; + ) + const token = data.login jwt.verify(token, process.env.JWT_SECRET, (err, data) => { - expect(data.email).toEqual("test@example.org"); - expect(err).toBeNull(); - }); - }); - }); + expect(data.email).toEqual('test@example.org') + expect(err).toBeNull() + }) + }) + }) - describe("with a valid email but incorrect password", () => { + describe('with a valid email but incorrect password', () => { it('responds with "Incorrect email address or password."', async () => { await expect( request( host, mutation({ - email: "test@example.org", - password: "wrong" + email: 'test@example.org', + password: 'wrong' }) ) - ).rejects.toThrow("Incorrect email address or password."); - }); - }); + ).rejects.toThrow('Incorrect email address or password.') + }) + }) - describe("with a non-existing email", () => { + describe('with a non-existing email', () => { it('responds with "Incorrect email address or password."', async () => { await expect( request( host, mutation({ - email: "non-existent@example.org", - password: "wrong" + email: 'non-existent@example.org', + password: 'wrong' }) ) - ).rejects.toThrow("Incorrect email address or password."); - }); - }); - }); -}); + ).rejects.toThrow('Incorrect email address or password.') + }) + }) + }) +}) -describe("change password", () => { - let headers; - let client; +describe('change password', () => { + let headers + let client beforeEach(async () => { - headers = await login({ email: "test@example.org", password: "1234" }); - client = new GraphQLClient(host, { headers }); - }); + headers = await login({ email: 'test@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) const mutation = params => { - const { oldPassword, newPassword } = params; + const { oldPassword, newPassword } = params return ` mutation { changePassword(oldPassword:"${oldPassword}", newPassword:"${newPassword}") - }`; - }; + }` + } - describe("should be authenticated before changing password", () => { + describe('should be authenticated before changing password', () => { it('should throw not "Not Authorised!', async () => { await expect( request( host, mutation({ - oldPassword: "1234", - newPassword: "1234" + oldPassword: '1234', + newPassword: '1234' }) ) - ).rejects.toThrow("Not Authorised!"); - }); - }); + ).rejects.toThrow('Not Authorised!') + }) + }) - describe("old and new password should not match", () => { + describe('old and new password should not match', () => { it('responds with "Old password and New password should not be same"', async () => { await expect( client.request( mutation({ - oldPassword: "1234", - newPassword: "1234" + oldPassword: '1234', + newPassword: '1234' }) ) - ).rejects.toThrow("Old password and New password should not be same"); - }); - }); + ).rejects.toThrow('Old password and New password should not be same') + }) + }) - describe("incorrect old password", () => { + describe('incorrect old password', () => { it('responds with "Old password isn\'t valid"', async () => { await expect( client.request( mutation({ - oldPassword: "notOldPassword", - newPassword: "12345" + oldPassword: 'notOldPassword', + newPassword: '12345' }) ) - ).rejects.toThrow("Old password isn't valid"); - }); - }); -}); + ).rejects.toThrow('Old password isn\'t valid') + }) + }) +}) From 6cba9f1fd8f584b5b53ecaf32f3feac276f99b99 Mon Sep 17 00:00:00 2001 From: kachulio1 Date: Sun, 10 Mar 2019 00:50:16 +0300 Subject: [PATCH 512/554] remove image url --- src/resolvers/user_management.spec.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/resolvers/user_management.spec.js b/src/resolvers/user_management.spec.js index 5aaadfeed..8007737f0 100644 --- a/src/resolvers/user_management.spec.js +++ b/src/resolvers/user_management.spec.js @@ -28,8 +28,6 @@ const jennyRostocksHeaders = { beforeEach(async () => { await factory.create('User', { - avatar: - 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', id: 'acb2d923-f3af-479e-9f00-61b12e864666', name: 'Matilde Hermiston', slug: 'matilde-hermiston', From 0a31e5278c35911691bac5d24a500178027f262f Mon Sep 17 00:00:00 2001 From: kachulio1 Date: Sun, 10 Mar 2019 01:44:41 +0300 Subject: [PATCH 513/554] add test for correct credentials --- src/resolvers/user_management.js | 50 ++++++++++++--------------- src/resolvers/user_management.spec.js | 28 +++++++++++---- 2 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/resolvers/user_management.js b/src/resolvers/user_management.js index 3a7698e24..36865646f 100644 --- a/src/resolvers/user_management.js +++ b/src/resolvers/user_management.js @@ -30,32 +30,28 @@ export default { // throw new Error('Already logged in.') // } const session = driver.session() - return session - .run( - 'MATCH (user:User {email: $userEmail}) ' + - 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', - { - userEmail: email - } - ) - .then(async result => { - session.close() - const [currentUser] = await result.records.map(function (record) { - return record.get('user') - }) + const result = await session.run( + 'MATCH (user:User {email: $userEmail}) ' + + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', + { + userEmail: email + } + ) - if ( - currentUser && - (await bcrypt.compareSync(password, currentUser.password)) - ) { - delete currentUser.password - return encode(currentUser) - } else { - throw new AuthenticationError( - 'Incorrect email address or password.' - ) - } - }) + session.close() + const [currentUser] = await result.records.map(function (record) { + return record.get('user') + }) + + if ( + currentUser && + (await bcrypt.compareSync(password, currentUser.password)) + ) { + delete currentUser.password + return encode(currentUser) + } else { + throw new AuthenticationError('Incorrect email address or password.') + } }, changePassword: async ( _, @@ -76,12 +72,12 @@ export default { }) if (!(await bcrypt.compareSync(oldPassword, currentUser.password))) { - throw new AuthenticationError('Old password isn\'t valid') + throw new AuthenticationError('Old password is not correct') } if (await bcrypt.compareSync(newPassword, currentUser.password)) { throw new AuthenticationError( - 'Old password and New password should not be same' + 'Old password and new password should be different' ) } else { const newHashedPassword = await bcrypt.hashSync(newPassword, 10) diff --git a/src/resolvers/user_management.spec.js b/src/resolvers/user_management.spec.js index 8007737f0..c4b09df37 100644 --- a/src/resolvers/user_management.spec.js +++ b/src/resolvers/user_management.spec.js @@ -28,6 +28,7 @@ const jennyRostocksHeaders = { beforeEach(async () => { await factory.create('User', { + avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/jimmuirhead/128.jpg', id: 'acb2d923-f3af-479e-9f00-61b12e864666', name: 'Matilde Hermiston', slug: 'matilde-hermiston', @@ -126,8 +127,7 @@ describe('currentUser', () => { it('returns the whole user object', async () => { const expected = { currentUser: { - avatar: - 'https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg', + avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/jimmuirhead/128.jpg', email: 'test@example.org', id: 'acb2d923-f3af-479e-9f00-61b12e864666', name: 'Matilde Hermiston', @@ -216,7 +216,7 @@ describe('change password', () => { } describe('should be authenticated before changing password', () => { - it('should throw not "Not Authorised!', async () => { + it('throws not "Not Authorised!', async () => { await expect( request( host, @@ -230,7 +230,7 @@ describe('change password', () => { }) describe('old and new password should not match', () => { - it('responds with "Old password and New password should not be same"', async () => { + it('responds with "Old password and new password should be different"', async () => { await expect( client.request( mutation({ @@ -238,7 +238,7 @@ describe('change password', () => { newPassword: '1234' }) ) - ).rejects.toThrow('Old password and New password should not be same') + ).rejects.toThrow('Old password and new password should be different') }) }) @@ -251,7 +251,23 @@ describe('change password', () => { newPassword: '12345' }) ) - ).rejects.toThrow('Old password isn\'t valid') + ).rejects.toThrow('Old password is not correct') + }) + }) + + describe('correct password', () => { + it('changes the password if given correct credentials "', async () => { + let response = await client.request( + mutation({ + oldPassword: '1234', + newPassword: '12345' + }) + ) + await expect( + response + ).toEqual(expect.objectContaining({ + changePassword: expect.any(String) + })) }) }) }) From cae33301052e37461b099a423836d02958ad4d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sun, 10 Mar 2019 18:29:25 +0100 Subject: [PATCH 514/554] Fix deprecation: async function passed to describe --- src/middleware/permissionsMiddleware.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 78766aad2..89904a7bf 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -34,7 +34,7 @@ describe('authorization', () => { return graphQLClient.request('{User(name: "Owner") { email } }') } - describe('not logged in', async () => { + describe('not logged in', () => { it('rejects', async () => { await expect(action()).rejects.toThrow('Not Authorised!') }) From f14c903d2a406a7a1038e0084b1d7fd3f4cc6a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sun, 10 Mar 2019 18:33:51 +0100 Subject: [PATCH 515/554] Refactor: we don't need a setup object --- src/resolvers/moderation.spec.js | 69 ++++++++++++++++---------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/src/resolvers/moderation.spec.js b/src/resolvers/moderation.spec.js index 3b2ace1cc..4791fd0ee 100644 --- a/src/resolvers/moderation.spec.js +++ b/src/resolvers/moderation.spec.js @@ -14,22 +14,21 @@ const setupAuthenticateClient = (params) => { return authenticateClient } -let setup -const runSetup = async () => { - await setup.createResource() - await setup.authenticateClient() -} +let createResource +let authenticateClient beforeEach(() => { - setup = { - createResource: () => { - }, - authenticateClient: () => { - client = new GraphQLClient(host) - } + createResource = () => {} + authenticateClient = () => { + client = new GraphQLClient(host) } }) +const setup = async () => { + await createResource() + await authenticateClient() +} + afterEach(async () => { await factory.cleanDatabase() }) @@ -54,26 +53,26 @@ describe('disable', () => { } it('throws authorization error', async () => { - await runSetup() + await setup() await expect(action()).rejects.toThrow('Not Authorised') }) describe('authenticated', () => { beforeEach(() => { - setup.authenticateClient = setupAuthenticateClient({ + authenticateClient = setupAuthenticateClient({ email: 'user@example.org', password: '1234' }) }) it('throws authorization error', async () => { - await runSetup() + await setup() await expect(action()).rejects.toThrow('Not Authorised') }) describe('as moderator', () => { beforeEach(() => { - setup.authenticateClient = setupAuthenticateClient({ + authenticateClient = setupAuthenticateClient({ id: 'u7', email: 'moderator@example.org', password: '1234', @@ -87,7 +86,7 @@ describe('disable', () => { id: 'c47' } - setup.createResource = async () => { + createResource = async () => { await factory.create('User', { id: 'u45', email: 'commenter@example.org', password: '1234' }) await factory.authenticateAs({ email: 'commenter@example.org', password: '1234' }) await Promise.all([ @@ -103,7 +102,7 @@ describe('disable', () => { it('returns disabled resource id', async () => { const expected = { disable: 'c47' } - await runSetup() + await setup() await expect(action()).resolves.toEqual(expected) }) @@ -111,7 +110,7 @@ describe('disable', () => { const before = { Comment: [{ id: 'c47', disabledBy: null }] } const expected = { Comment: [{ id: 'c47', disabledBy: { id: 'u7' } }] } - await runSetup() + await setup() await expect(client.request( '{ Comment { id, disabledBy { id } } }' )).resolves.toEqual(before) @@ -125,7 +124,7 @@ describe('disable', () => { const before = { Comment: [ { id: 'c47', disabled: false } ] } const expected = { Comment: [ { id: 'c47', disabled: true } ] } - await runSetup() + await setup() await expect(client.request( '{ Comment { id disabled } }' )).resolves.toEqual(before) @@ -142,7 +141,7 @@ describe('disable', () => { id: 'p9' } - setup.createResource = async () => { + createResource = async () => { await factory.create('User', { email: 'author@example.org', password: '1234' }) await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) await factory.create('Post', { @@ -153,7 +152,7 @@ describe('disable', () => { it('returns disabled resource id', async () => { const expected = { disable: 'p9' } - await runSetup() + await setup() await expect(action()).resolves.toEqual(expected) }) @@ -161,7 +160,7 @@ describe('disable', () => { const before = { Post: [{ id: 'p9', disabledBy: null }] } const expected = { Post: [{ id: 'p9', disabledBy: { id: 'u7' } }] } - await runSetup() + await setup() await expect(client.request( '{ Post { id, disabledBy { id } } }' )).resolves.toEqual(before) @@ -175,7 +174,7 @@ describe('disable', () => { const before = { Post: [ { id: 'p9', disabled: false } ] } const expected = { Post: [ { id: 'p9', disabled: true } ] } - await runSetup() + await setup() await expect(client.request( '{ Post { id disabled } }' )).resolves.toEqual(before) @@ -209,26 +208,26 @@ describe('enable', () => { }) it('throws authorization error', async () => { - await runSetup() + await setup() await expect(action()).rejects.toThrow('Not Authorised') }) describe('authenticated', () => { beforeEach(() => { - setup.authenticateClient = setupAuthenticateClient({ + authenticateClient = setupAuthenticateClient({ email: 'user@example.org', password: '1234' }) }) it('throws authorization error', async () => { - await runSetup() + await setup() await expect(action()).rejects.toThrow('Not Authorised') }) describe('as moderator', () => { beforeEach(async () => { - setup.authenticateClient = setupAuthenticateClient({ + authenticateClient = setupAuthenticateClient({ role: 'moderator', email: 'someUser@example.org', password: '1234' @@ -241,7 +240,7 @@ describe('enable', () => { id: 'c456' } - setup.createResource = async () => { + createResource = async () => { await factory.create('User', { id: 'u123', email: 'author@example.org', password: '1234' }) await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) await Promise.all([ @@ -264,7 +263,7 @@ describe('enable', () => { it('returns disabled resource id', async () => { const expected = { enable: 'c456' } - await runSetup() + await setup() await expect(action()).resolves.toEqual(expected) }) @@ -272,7 +271,7 @@ describe('enable', () => { const before = { Comment: [{ id: 'c456', disabledBy: { id: 'u123' } }] } const expected = { Comment: [{ id: 'c456', disabledBy: null }] } - await runSetup() + await setup() await expect(client.request( '{ Comment(disabled: true) { id, disabledBy { id } } }' )).resolves.toEqual(before) @@ -286,7 +285,7 @@ describe('enable', () => { const before = { Comment: [ { id: 'c456', disabled: true } ] } const expected = { Comment: [ { id: 'c456', disabled: false } ] } - await runSetup() + await setup() await expect(client.request( '{ Comment(disabled: true) { id disabled } }' )).resolves.toEqual(before) @@ -303,7 +302,7 @@ describe('enable', () => { id: 'p9' } - setup.createResource = async () => { + createResource = async () => { await factory.create('User', { id: 'u123', email: 'author@example.org', password: '1234' }) await factory.authenticateAs({ email: 'author@example.org', password: '1234' }) await factory.create('Post', { @@ -321,7 +320,7 @@ describe('enable', () => { it('returns disabled resource id', async () => { const expected = { enable: 'p9' } - await runSetup() + await setup() await expect(action()).resolves.toEqual(expected) }) @@ -329,7 +328,7 @@ describe('enable', () => { const before = { Post: [{ id: 'p9', disabledBy: { id: 'u123' } }] } const expected = { Post: [{ id: 'p9', disabledBy: null }] } - await runSetup() + await setup() await expect(client.request( '{ Post(disabled: true) { id, disabledBy { id } } }' )).resolves.toEqual(before) @@ -343,7 +342,7 @@ describe('enable', () => { const before = { Post: [ { id: 'p9', disabled: true } ] } const expected = { Post: [ { id: 'p9', disabled: false } ] } - await runSetup() + await setup() await expect(client.request( '{ Post(disabled: true) { id disabled } }' )).resolves.toEqual(before) From ee5c4127e6eb50bf605432db77d35b896548b17d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sun, 10 Mar 2019 18:49:04 +0100 Subject: [PATCH 516/554] Prevent disabling any type Resource must have a label Post|Comment|User --- src/resolvers/moderation.js | 7 ++++-- src/resolvers/moderation.spec.js | 39 ++++++++++++++++++++++++++++++++ src/schema.graphql | 4 ++-- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/resolvers/moderation.js b/src/resolvers/moderation.js index 33af83bb6..97fe22e9a 100644 --- a/src/resolvers/moderation.js +++ b/src/resolvers/moderation.js @@ -6,16 +6,18 @@ export default { const cypher = ` MATCH (u:User {id: $userId}) MATCH (resource {id: $id}) + WHERE resource:User OR resource:Comment OR resource:Post SET resource.disabled = true MERGE (resource)<-[:DISABLED]-(u) RETURN resource {.id} ` const session = driver.session() const res = await session.run(cypher, { id, userId }) + session.close() const [resource] = res.records.map((record) => { return record.get('resource') }) - session.close() + if(!resource) return null return resource.id }, enable: async (object, params, { user, driver }) => { @@ -28,10 +30,11 @@ export default { ` const session = driver.session() const res = await session.run(cypher, { id }) + session.close() const [resource] = res.records.map((record) => { return record.get('resource') }) - session.close() + if(!resource) return null return resource.id } } diff --git a/src/resolvers/moderation.spec.js b/src/resolvers/moderation.spec.js index 4791fd0ee..0b74287b4 100644 --- a/src/resolvers/moderation.spec.js +++ b/src/resolvers/moderation.spec.js @@ -80,6 +80,25 @@ describe('disable', () => { }) }) + describe('on something that is not a (Comment|Post|User) ', () => { + beforeEach(async () => { + variables = { + id: 't23' + } + createResource = () => { + return Promise.all([ + factory.create('Tag', { id: 't23' }), + ]) + } + }) + + it('returns null', async () => { + const expected = { disable: null } + await setup() + await expect(action()).resolves.toEqual(expected) + }) + }) + describe('on a comment', () => { beforeEach(async () => { variables = { @@ -234,6 +253,26 @@ describe('enable', () => { }) }) + describe('on something that is not a (Comment|Post|User) ', () => { + beforeEach(async () => { + variables = { + id: 't23' + } + createResource = () => { + // we cannot create a :DISABLED relationship here + return Promise.all([ + factory.create('Tag', { id: 't23' }), + ]) + } + }) + + it('returns null', async () => { + const expected = { enable: null } + await setup() + await expect(action()).resolves.toEqual(expected) + }) + }) + describe('on a comment', () => { beforeEach(async () => { variables = { diff --git a/src/schema.graphql b/src/schema.graphql index 5d641c0b8..a542e1229 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -10,8 +10,8 @@ type Mutation { login(email: String!, password: String!): String! signup(email: String!, password: String!): Boolean! report(id: ID!, description: String): Report - disable(id: ID!): ID! - enable(id: ID!): ID! + disable(id: ID!): ID + enable(id: ID!): ID "Shout the given Type and ID" shout(id: ID!, type: ShoutTypeEnum): Boolean! @cypher(statement: """ MATCH (n {id: $id})<-[:WROTE]-(wu:User), (u:User {id: $cypherParams.currentUserId}) From 60d711bb0a6544fd4460b458396a9c56e53d8784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Sun, 10 Mar 2019 18:57:45 +0100 Subject: [PATCH 517/554] Prevent to report any type Resouce must have a label (Post|Comment|User) --- src/resolvers/moderation.js | 4 ++-- src/resolvers/moderation.spec.js | 5 ++--- src/resolvers/reports.js | 1 + src/resolvers/reports.spec.js | 16 ++++++++++++++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/resolvers/moderation.js b/src/resolvers/moderation.js index 97fe22e9a..7bc1227ff 100644 --- a/src/resolvers/moderation.js +++ b/src/resolvers/moderation.js @@ -17,7 +17,7 @@ export default { const [resource] = res.records.map((record) => { return record.get('resource') }) - if(!resource) return null + if (!resource) return null return resource.id }, enable: async (object, params, { user, driver }) => { @@ -34,7 +34,7 @@ export default { const [resource] = res.records.map((record) => { return record.get('resource') }) - if(!resource) return null + if (!resource) return null return resource.id } } diff --git a/src/resolvers/moderation.spec.js b/src/resolvers/moderation.spec.js index 0b74287b4..dfbcac80f 100644 --- a/src/resolvers/moderation.spec.js +++ b/src/resolvers/moderation.spec.js @@ -14,7 +14,6 @@ const setupAuthenticateClient = (params) => { return authenticateClient } - let createResource let authenticateClient beforeEach(() => { @@ -87,7 +86,7 @@ describe('disable', () => { } createResource = () => { return Promise.all([ - factory.create('Tag', { id: 't23' }), + factory.create('Tag', { id: 't23' }) ]) } }) @@ -261,7 +260,7 @@ describe('enable', () => { createResource = () => { // we cannot create a :DISABLED relationship here return Promise.all([ - factory.create('Tag', { id: 't23' }), + factory.create('Tag', { id: 't23' }) ]) } }) diff --git a/src/resolvers/reports.js b/src/resolvers/reports.js index acac516e0..fb912a557 100644 --- a/src/resolvers/reports.js +++ b/src/resolvers/reports.js @@ -14,6 +14,7 @@ export default { const res = await session.run(` MATCH (submitter:User {id: $userId}) MATCH (resource {id: $resourceId}) + WHERE resource:User OR resource:Comment OR resource:Post CREATE (report:Report $reportData) MERGE (resource)<-[:REPORTED]-(report) MERGE (report)<-[:REPORTED]-(submitter) diff --git a/src/resolvers/reports.spec.js b/src/resolvers/reports.spec.js index ac45235ac..ae8894572 100644 --- a/src/resolvers/reports.spec.js +++ b/src/resolvers/reports.spec.js @@ -11,6 +11,8 @@ describe('report', () => { let variables beforeEach(async () => { + returnedObject = '{ description }' + variables = { id: 'whatever' } headers = {} await factory.create('User', { id: 'u1', @@ -36,10 +38,9 @@ describe('report', () => { report( id: $id, description: "Violates code of conduct" - ) ${returnedObject || '{ description }'} + ) ${returnedObject} } ` - variables = variables || { id: 'whatever' } client = new GraphQLClient(host, { headers }) return client.request(mutation, variables) } @@ -146,6 +147,17 @@ describe('report', () => { }) }) }) + + describe('reported resource is a tag', () => { + beforeEach(async () => { + await factory.create('Tag', { id: 't23' }) + variables = { id: 't23' } + }) + + it('returns null', async () => { + await expect(action()).resolves.toEqual({ report: null }) + }) + }) }) }) }) From 211693606284f727871d79624278dcc7ca5fecdc Mon Sep 17 00:00:00 2001 From: Grzegorz Leoniec Date: Fri, 8 Mar 2019 16:49:43 +0100 Subject: [PATCH 518/554] Fixed shout and follow seeding --- src/seed/seed-db.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index 860ff6707..e8c757db8 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -146,6 +146,26 @@ import Factory from './factories' f.relate('Post', 'Tags', { from: 'p15', to: 't3' }) ]) + await Promise.all([ + asAdmin + .shout({ id: 'p2', type: 'Post' }), + asAdmin + .shout({ id: 'p6', type: 'Post' }), + asModerator + .shout({ id: 'p0', type: 'Post' }), + asModerator + .shout({ id: 'p6', type: 'Post' }), + asUser + .shout({ id: 'p6', type: 'Post' }), + asUser + .shout({ id: 'p7', type: 'Post' }), + asTick + .shout({ id: 'p8', type: 'Post' }), + asTick + .shout({ id: 'p9', type: 'Post' }), + asTrack + .shout({ id: 'p10', type: 'Post' }) + ]) await Promise.all([ asAdmin .shout({ id: 'p2', type: 'Post' }), From a1b9f770cec631daa2dc3a3884406ec2230904e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Sun, 10 Mar 2019 19:41:58 +0000 Subject: [PATCH 519/554] Bump date-fns from 2.0.0-alpha.26 to 2.0.0-alpha.27 Bumps [date-fns](https://github.com/date-fns/date-fns) from 2.0.0-alpha.26 to 2.0.0-alpha.27. - [Release notes](https://github.com/date-fns/date-fns/releases) - [Changelog](https://github.com/date-fns/date-fns/blob/master/CHANGELOG.md) - [Commits](https://github.com/date-fns/date-fns/compare/v2.0.0-alpha.26...v2.0.0-alpha.27) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 8d426c6ae..fc789e20d 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", "cross-env": "~5.2.0", - "date-fns": "2.0.0-alpha.26", + "date-fns": "2.0.0-alpha.27", "dotenv": "~6.2.0", "faker": "~4.1.0", "graphql": "~14.1.1", diff --git a/yarn.lock b/yarn.lock index f8babfaf6..6a9739214 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2368,10 +2368,10 @@ data-urls@^1.0.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" -date-fns@2.0.0-alpha.26: - version "2.0.0-alpha.26" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.26.tgz#e46afd73a2b50e0359446309ee7cb631d7467227" - integrity sha512-UAptCZ53MVimUFR8MXTyHED51AVGIqFlBfWgiS/KIoSYiJGrWScx4PYQVNSWfK2Js+43OlokCW1ttnexBTJ5Bg== +date-fns@2.0.0-alpha.27: + version "2.0.0-alpha.27" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-alpha.27.tgz#5ecd4204ef0e7064264039570f6e8afbc014481c" + integrity sha512-cqfVLS+346P/Mpj2RpDrBv0P4p2zZhWWvfY5fuWrXNR/K38HaAGEkeOwb47hIpQP9Jr/TIxjZ2/sNMQwdXuGMg== debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" From 77b7ed58d3d500cd7e6ad2f08b926e922209aa69 Mon Sep 17 00:00:00 2001 From: Armin Date: Mon, 11 Mar 2019 00:58:19 +0100 Subject: [PATCH 520/554] Add HTTP Signature Test (Problems with crypto lib till now) --- .../security/httpSignature.spec.js | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/activitypub/security/httpSignature.spec.js diff --git a/src/activitypub/security/httpSignature.spec.js b/src/activitypub/security/httpSignature.spec.js new file mode 100644 index 000000000..8fd8ab480 --- /dev/null +++ b/src/activitypub/security/httpSignature.spec.js @@ -0,0 +1,72 @@ +import { createSignature, verifySignature, generateRsaKeyPair } from '.' +import Factory from '../../seed/factories' +import { host, login } from '../../jest/helpers' +import { GraphQLClient } from 'graphql-request' +import crypto from 'crypto' +import { expect } from 'chai' +const factory = Factory() + +describe('Signature creation and verification', () => { + process.env.PRIVATE_KEY_PASSPHRASE = 'test-password' + let user = null + let client = null + const headers = { + 'Date': '2019-03-08T14:35:45.759Z', + 'Host': 'democracy-app.de', + 'Content-Type': 'application/json' + } + + beforeEach(async () => { + await factory.create('User', { + 'slug': 'test-user', + 'name': 'Test User', + 'email': 'user@example.org', + 'password': 'swordfish' + }) + const headers = await login({ email: 'user@example.org', password: 'swordfish' }) + client = new GraphQLClient(host, { headers }) + const result = await client.request(`query { + User(slug: "test-user") { + privateKey + publicKey + } + }`) + user = result.User[0] + }) + + afterEach(async () => { + await factory.cleanDatabase() + }) + + describe('Signature creation', () => { + let signatureB64 = '' + beforeEach(() => { + const signer = crypto.createSign('rsa-sha256') + signer.update('(request-target): post /activitypub/users/max/inbox\ndate: 2019-03-08T14:35:45.759Z\nhost: democracy-app.de\ncontent-type: application/json') + console.log(JSON.stringify(user, null, 2)) + signatureB64 = signer.sign({ key: user.privateKey, passphrase: 'test-password' }, 'base64') + }) + it('creates a Signature with given privateKey, keyId, url and headers (default algorithm: "rsa-sha256")', () => { + const httpSignature = createSignature(user.privateKey, 'https://human-connection.org/activitypub/users/lea#main-key', 'https://democracy-app.de/activitypub/users/max/inbox', headers) + + expect(httpSignature).to.contain('keyId="https://human-connection.org/activitypub/users/lea#main-key"') + expect(httpSignature).to.contain('algorithm="rsa-sha256"') + expect(httpSignature).to.contain('headers="(request-target) date host content-type"') + expect(httpSignature).to.contain('signature="' + signatureB64 + '"') + }) + }) + + describe('Signature verification', () => { + let httpSignature = '' + beforeEach(() => { + httpSignature = createSignature(user.privateKey, 'http://localhost:4001/activitypub/users/test-user#main-key', 'https://democracy-app.de/activitypub/users/max/inbox', headers) + }) + + it('verifies a Signature by ', async () => { + headers['Signature'] = httpSignature + const isVerified = await verifySignature('https://democracy-app.de/activitypub/users/max/inbox', headers) + console.log(JSON.stringify(isVerified, null, 2)) + expect(isVerified).to.equal(true) + }) + }) +}) From ff9840b844a58a3e38d2a96c01860784627e1190 Mon Sep 17 00:00:00 2001 From: Armin Date: Mon, 11 Mar 2019 02:21:16 +0100 Subject: [PATCH 521/554] Signature Test lint fix --- src/activitypub/security/httpSignature.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/activitypub/security/httpSignature.spec.js b/src/activitypub/security/httpSignature.spec.js index 8fd8ab480..17ab3b91a 100644 --- a/src/activitypub/security/httpSignature.spec.js +++ b/src/activitypub/security/httpSignature.spec.js @@ -1,4 +1,4 @@ -import { createSignature, verifySignature, generateRsaKeyPair } from '.' +import { createSignature, verifySignature } from '.' import Factory from '../../seed/factories' import { host, login } from '../../jest/helpers' import { GraphQLClient } from 'graphql-request' From 22b521b93db3d20a190e2715688887f6228a93cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 11 Mar 2019 17:02:31 +0100 Subject: [PATCH 522/554] Deleted a line in graphql.schema --- src/schema.graphql | 1 - 1 file changed, 1 deletion(-) diff --git a/src/schema.graphql b/src/schema.graphql index a542e1229..06a53afba 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -26,7 +26,6 @@ type Mutation { DELETE r RETURN COUNT(r) > 0 """) - "Follow the given Type and ID" follow(id: ID!, type: FollowTypeEnum): Boolean! @cypher(statement: """ MATCH (n {id: $id}), (u:User {id: $cypherParams.currentUserId}) From 48ed75b6e409ec14f81f6a956ae57ec8f369a88d Mon Sep 17 00:00:00 2001 From: Armin Date: Tue, 12 Mar 2019 19:07:58 +0100 Subject: [PATCH 523/554] Use GRAPHQL_URI env var instead establishing ACTIVITYPUB env vars + http Signature test fix --- src/activitypub/ActivityPub.js | 13 ++++++------- src/activitypub/NitroDataSource.js | 10 +++------- src/activitypub/security/httpSignature.spec.js | 5 +---- src/activitypub/security/index.js | 2 +- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/activitypub/ActivityPub.js b/src/activitypub/ActivityPub.js index 9cbf5b52e..ade2362bc 100644 --- a/src/activitypub/ActivityPub.js +++ b/src/activitypub/ActivityPub.js @@ -13,7 +13,6 @@ import as from 'activitystrea.ms' import NitroDataSource from './NitroDataSource' import router from './routes' import dotenv from 'dotenv' -import { resolve } from 'path' import Collections from './Collections' const debug = require('debug')('ea') @@ -22,19 +21,19 @@ let activityPub = null export { activityPub } export default class ActivityPub { - constructor (domain, port) { + constructor (domain, port, uri) { if (domain === 'localhost') { this.domain = `${domain}:${port}` } else { this.domain = domain } this.port = port - this.dataSource = new NitroDataSource(this.domain) + this.dataSource = new NitroDataSource(uri) this.collections = new Collections(this.dataSource) } static init (server) { if (!activityPub) { - dotenv.config({ path: resolve('src', 'activitypub', '.env') }) - const port = process.env.ACTIVITYPUB_PORT - activityPub = new ActivityPub(process.env.ACTIVITYPUB_DOMAIN || 'localhost', port || 4100) + dotenv.config() + const url = new URL(process.env.GRAPHQL_URI) + activityPub = new ActivityPub(url.hostname || 'localhost', url.port || 4000, url.origin) - // integrated into "server" express framework + // integrated into "server's" express framework server.express.set('ap', activityPub) server.express.use(router) debug('ActivityPub middleware added to the express service') diff --git a/src/activitypub/NitroDataSource.js b/src/activitypub/NitroDataSource.js index a8b65b27e..c5d520dce 100644 --- a/src/activitypub/NitroDataSource.js +++ b/src/activitypub/NitroDataSource.js @@ -19,25 +19,21 @@ import { setContext } from 'apollo-link-context' import { InMemoryCache } from 'apollo-cache-inmemory' import fetch from 'node-fetch' import { ApolloClient } from 'apollo-client' -import dotenv from 'dotenv' import uuid from 'uuid' import encode from '../jwt/encode' -import { resolve } from 'path' import trunc from 'trunc-html' const debug = require('debug')('ea:nitro-datasource') -dotenv.config({ path: resolve('src', 'activitypub', '.env') }) - export default class NitroDataSource { - constructor (domain) { - this.domain = domain + constructor (uri) { + this.uri = uri const defaultOptions = { query: { fetchPolicy: 'network-only', errorPolicy: 'all' } } - const link = createHttpLink({ uri: process.env.GRAPHQL_URI, fetch: fetch }) // eslint-disable-line + const link = createHttpLink({ uri: this.uri, fetch: fetch }) // eslint-disable-line const cache = new InMemoryCache() const authLink = setContext((_, { headers }) => { // generate the authentication token (maybe from env? Which user?) diff --git a/src/activitypub/security/httpSignature.spec.js b/src/activitypub/security/httpSignature.spec.js index 17ab3b91a..bf1162219 100644 --- a/src/activitypub/security/httpSignature.spec.js +++ b/src/activitypub/security/httpSignature.spec.js @@ -7,7 +7,6 @@ import { expect } from 'chai' const factory = Factory() describe('Signature creation and verification', () => { - process.env.PRIVATE_KEY_PASSPHRASE = 'test-password' let user = null let client = null const headers = { @@ -43,8 +42,7 @@ describe('Signature creation and verification', () => { beforeEach(() => { const signer = crypto.createSign('rsa-sha256') signer.update('(request-target): post /activitypub/users/max/inbox\ndate: 2019-03-08T14:35:45.759Z\nhost: democracy-app.de\ncontent-type: application/json') - console.log(JSON.stringify(user, null, 2)) - signatureB64 = signer.sign({ key: user.privateKey, passphrase: 'test-password' }, 'base64') + signatureB64 = signer.sign({ key: user.privateKey, passphrase: 'a7dsf78sadg87ad87sfagsadg78' }, 'base64') }) it('creates a Signature with given privateKey, keyId, url and headers (default algorithm: "rsa-sha256")', () => { const httpSignature = createSignature(user.privateKey, 'https://human-connection.org/activitypub/users/lea#main-key', 'https://democracy-app.de/activitypub/users/max/inbox', headers) @@ -65,7 +63,6 @@ describe('Signature creation and verification', () => { it('verifies a Signature by ', async () => { headers['Signature'] = httpSignature const isVerified = await verifySignature('https://democracy-app.de/activitypub/users/max/inbox', headers) - console.log(JSON.stringify(isVerified, null, 2)) expect(isVerified).to.equal(true) }) }) diff --git a/src/activitypub/security/index.js b/src/activitypub/security/index.js index 583535bcc..412084022 100644 --- a/src/activitypub/security/index.js +++ b/src/activitypub/security/index.js @@ -24,7 +24,7 @@ export function generateRsaKeyPair () { // signing export function createSignature (privKey, keyId, url, headers = {}, algorithm = 'rsa-sha256') { - if (!SUPPORTED_HASH_ALGORITHMS.includes(algorithm)) { return throw Error(`SIGNING: Unsupported hashing algorithm = ${algorithm}`) } + if (!SUPPORTED_HASH_ALGORITHMS.includes(algorithm)) { throw Error(`SIGNING: Unsupported hashing algorithm = ${algorithm}`) } const signer = crypto.createSign(algorithm) const signingString = constructSigningString(url, headers) signer.update(signingString) From 5aeb2845dbcd983061a6a9e841633275be22fc89 Mon Sep 17 00:00:00 2001 From: Armin Date: Tue, 12 Mar 2019 19:14:13 +0100 Subject: [PATCH 524/554] Change test port in some feature files --- test/features/activity-delete.feature | 8 ++++---- test/features/activity-like.feature | 16 ++++++++-------- test/features/object-article.feature | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/test/features/activity-delete.feature b/test/features/activity-delete.feature index ad33f1e4c..9bdcbe9ab 100644 --- a/test/features/activity-delete.feature +++ b/test/features/activity-delete.feature @@ -2,7 +2,7 @@ Feature: Delete an object I want to delete objects Background: - Given our own server runs at "http://localhost:4100" + Given our own server runs at "http://localhost:4123" And we have the following users in our database: | Slug | | bernd-das-brot| @@ -29,7 +29,7 @@ Feature: Delete an object """ { "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://localhost:4100/users/karl-heinz/status/a4DJ2afdg323v32641vna42lkj685kasd2", + "id": "https://localhost:4123/users/karl-heinz/status/a4DJ2afdg323v32641vna42lkj685kasd2", "type": "Delete", "object": { "id": "https://aronda.org/users/bernd-das-brot/status/kljsdfg9843jknsdf", @@ -37,7 +37,7 @@ Feature: Delete an object "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/users/bernd-das-brot", "content": "Hi Max, how are you?", - "to": "https://localhost:4100/activitypub/users/moritz" + "to": "https://localhost:4123/activitypub/users/moritz" } } """ @@ -50,6 +50,6 @@ Feature: Delete an object "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/users/bernd-das-brot", "content": "Hi Max, how are you?", - "to": "https://localhost:4100/activitypub/users/moritz" + "to": "https://localhost:4123/activitypub/users/moritz" } """ diff --git a/test/features/activity-like.feature b/test/features/activity-like.feature index d71a0396f..35d32c842 100644 --- a/test/features/activity-like.feature +++ b/test/features/activity-like.feature @@ -4,7 +4,7 @@ Feature: Like an object like an article or note I want to undo the follow. Background: - Given our own server runs at "http://localhost:4100" + Given our own server runs at "http://localhost:4123" And we have the following users in our database: | Slug | | karl-heinz | @@ -13,14 +13,14 @@ Feature: Like an object like an article or note """ { "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://localhost:4100/activitypub/users/karl-heinz/status/faslkasa7dasfzkjn2398hsfd", + "id": "https://localhost:4123/activitypub/users/karl-heinz/status/faslkasa7dasfzkjn2398hsfd", "type": "Create", - "actor": "https://localhost:4100/activitypub/users/karl-heinz", + "actor": "https://localhost:4123/activitypub/users/karl-heinz", "object": { - "id": "https://localhost:4100/activitypub/users/karl-heinz/status/dkasfljsdfaafg9843jknsdf", + "id": "https://localhost:4123/activitypub/users/karl-heinz/status/dkasfljsdfaafg9843jknsdf", "type": "Article", "published": "2019-02-07T19:37:55.002Z", - "attributedTo": "https://localhost:4100/activitypub/users/karl-heinz", + "attributedTo": "https://localhost:4123/activitypub/users/karl-heinz", "content": "Hi Max, how are you?", "to": "https://www.w3.org/ns/activitystreams#Public" } @@ -32,10 +32,10 @@ Feature: Like an object like an article or note """ { "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://localhost:4100/activitypub/users/peter-lustiger/status/83J23549sda1k72fsa4567na42312455kad83", + "id": "https://localhost:4123/activitypub/users/peter-lustiger/status/83J23549sda1k72fsa4567na42312455kad83", "type": "Like", - "actor": "http://localhost:4100/activitypub/users/peter-lustiger", - "object": "http://localhost:4100/activitypub/users/karl-heinz/status/dkasfljsdfaafg9843jknsdf" + "actor": "http://localhost:4123/activitypub/users/peter-lustiger", + "object": "http://localhost:4123/activitypub/users/karl-heinz/status/dkasfljsdfaafg9843jknsdf" } """ Then I expect the status code to be 200 diff --git a/test/features/object-article.feature b/test/features/object-article.feature index 0a8af2606..5358f2925 100644 --- a/test/features/object-article.feature +++ b/test/features/object-article.feature @@ -2,7 +2,7 @@ Feature: Send and receive Articles I want to send and receive article's via ActivityPub Background: - Given our own server runs at "http://localhost:4100" + Given our own server runs at "http://localhost:4123" And we have the following users in our database: | Slug | | marvin | @@ -22,7 +22,7 @@ Feature: Send and receive Articles "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/users/marvin", "content": "Hi Max, how are you?", - "to": "https://localhost:4100/activitypub/users/max" + "to": "https://localhost:4123/activitypub/users/max" } } """ From 00ba891cbf9ddd67438842942950e6c5fa37652e Mon Sep 17 00:00:00 2001 From: Armin Date: Tue, 12 Mar 2019 22:50:25 +0100 Subject: [PATCH 525/554] Some refactoring + add timeout functions to some step definitions + add objectId to Post and schema --- src/activitypub/ActivityPub.js | 29 ++++++++++++++++++--------- src/activitypub/NitroDataSource.js | 26 +++++++++++++++++------- src/activitypub/routes/inbox.js | 26 ++++++++++++------------ src/activitypub/utils/activity.js | 6 ++++++ src/middleware/userMiddleware.js | 5 ++--- src/resolvers/posts.js | 11 +++++----- src/schema.graphql | 1 + test/features/activity-delete.feature | 12 +++++------ test/features/support/steps.js | 15 +++++++++----- 9 files changed, 82 insertions(+), 49 deletions(-) diff --git a/src/activitypub/ActivityPub.js b/src/activitypub/ActivityPub.js index ade2362bc..ed64816b9 100644 --- a/src/activitypub/ActivityPub.js +++ b/src/activitypub/ActivityPub.js @@ -14,6 +14,7 @@ import NitroDataSource from './NitroDataSource' import router from './routes' import dotenv from 'dotenv' import Collections from './Collections' +import uuid from 'uuid/v4' const debug = require('debug')('ea') let activityPub = null @@ -27,6 +28,7 @@ export default class ActivityPub { this.dataSource = new NitroDataSource(uri) this.collections = new Collections(this.dataSource) } + static init (server) { if (!activityPub) { dotenv.config() @@ -179,30 +181,37 @@ export default class ActivityPub { }) } + generateStatusId (slug) { + return `http://${this.domain}/activitypub/users/${slug}/status/${uuid()}` + } + async sendActivity (activity) { delete activity.send const fromName = extractNameFromId(activity.actor) if (Array.isArray(activity.to) && isPublicAddressed(activity)) { + debug('is public addressed') const sharedInboxEndpoints = await this.dataSource.getSharedInboxEndpoints() // serve shared inbox endpoints - sharedInboxEndpoints.map((el) => { - return this.trySend(activity, fromName, new URL(el).host, el) + sharedInboxEndpoints.map((sharedInbox) => { + return this.trySend(activity, fromName, new URL(sharedInbox).host, sharedInbox) }) - activity.to = activity.to.filter((el) => { - return !(isPublicAddressed({ to: el })) + activity.to = activity.to.filter((recipient) => { + return !(isPublicAddressed({ to: recipient })) }) // serve the rest - activity.to.map(async (el) => { - const actorObject = await this.getActorObject(el) - return this.trySend(activity, fromName, new URL(el).host, actorObject.inbox) + activity.to.map(async (recipient) => { + debug('serve rest') + const actorObject = await this.getActorObject(recipient) + return this.trySend(activity, fromName, new URL(recipient).host, actorObject.inbox) }) } else if (typeof activity.to === 'string') { + debug('is string') const actorObject = await this.getActorObject(activity.to) return this.trySend(activity, fromName, new URL(activity.to).host, actorObject.inbox) } else if (Array.isArray(activity.to)) { - activity.to.map(async (el) => { - const actorObject = await this.getActorObject(el) - return this.trySend(activity, fromName, new URL(el).host, actorObject.inbox) + activity.to.map(async (recipient) => { + const actorObject = await this.getActorObject(recipient) + return this.trySend(activity, fromName, new URL(recipient).host, actorObject.inbox) }) } } diff --git a/src/activitypub/NitroDataSource.js b/src/activitypub/NitroDataSource.js index c5d520dce..4225e02ea 100644 --- a/src/activitypub/NitroDataSource.js +++ b/src/activitypub/NitroDataSource.js @@ -19,8 +19,6 @@ import { setContext } from 'apollo-link-context' import { InMemoryCache } from 'apollo-cache-inmemory' import fetch from 'node-fetch' import { ApolloClient } from 'apollo-client' -import uuid from 'uuid' -import encode from '../jwt/encode' import trunc from 'trunc-html' const debug = require('debug')('ea:nitro-datasource') @@ -37,12 +35,12 @@ export default class NitroDataSource { const cache = new InMemoryCache() const authLink = setContext((_, { headers }) => { // generate the authentication token (maybe from env? Which user?) - const token = encode({ name: 'ActivityPub', id: uuid() }) + const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYWRtaW4iLCJuYW1lIjoiUGV0ZXIgTHVzdGlnIiwiYXZhdGFyIjoiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3VpZmFjZXMvZmFjZXMvdHdpdHRlci9qb2huY2FmYXp6YS8xMjguanBnIiwiaWQiOiJ1MSIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5vcmciLCJzbHVnIjoicGV0ZXItbHVzdGlnIiwiaWF0IjoxNTUyNDIwMTExLCJleHAiOjE2Mzg4MjAxMTEsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCIsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDAwMCIsInN1YiI6InUxIn0.G7An1yeQUViJs-0Qj-Tc-zm0WrLCMB3M02pfPnm6xzw' // return the headers to the context so httpLink can read them return { headers: { ...headers, - authorization: token ? `Bearer ${token}` : '' + Authorization: token ? `Bearer ${token}` : '' } } }) @@ -213,6 +211,7 @@ export default class NitroDataSource { async getOutboxCollectionPage (actorId) { const slug = extractNameFromId(actorId) + debug(`inside getting outbox collection page => ${slug}`) const result = await this.client.query({ query: gql` query { @@ -220,11 +219,16 @@ export default class NitroDataSource { actorId contributions { id + activityId + objectId title slug content contentExcerpt createdAt + author { + name + } } } } @@ -240,7 +244,7 @@ export default class NitroDataSource { outboxCollection.totalItems = posts.length await Promise.all( posts.map(async (post) => { - outboxCollection.orderedItems.push(await createArticleObject(post.activityId, post.objectId, post.content, extractNameFromId(post.id), post.id, post.createdAt)) + outboxCollection.orderedItems.push(await createArticleObject(post.activityId, post.objectId, post.content, post.author.name, post.id, post.createdAt)) }) ) @@ -332,6 +336,7 @@ export default class NitroDataSource { } const title = postObject.summary ? postObject.summary : postObject.content.split(' ').slice(0, 5).join(' ') const postId = extractIdFromActivityId(postObject.id) + debug('inside create post') let result = await this.client.mutate({ mutation: gql` mutation { @@ -346,10 +351,16 @@ export default class NitroDataSource { // ensure user and add author to post const userId = await this.ensureUser(postObject.attributedTo) + debug(`userId = ${userId}`) + debug(`postId = ${postId}`) result = await this.client.mutate({ mutation: gql` mutation { - AddPostAuthor(from: {id: "${userId}"}, to: {id: "${postId}"}) + AddPostAuthor(from: {id: "${userId}"}, to: {id: "${postId}"}) { + from { + name + } + } } ` }) @@ -523,10 +534,11 @@ export default class NitroDataSource { debug('ensureUser: user not exists.. createUser') // user does not exist.. create it const pw = crypto.randomBytes(16).toString('hex') + const slug = name.toLowerCase().split(' ').join('-') const result = await this.client.mutate({ mutation: gql` mutation { - CreateUser(password: "${pw}", slug:"${name}", actorId: "${actorId}", name: "${name}") { + CreateUser(password: "${pw}", slug:"${slug}", actorId: "${actorId}", name: "${name}", email: "${slug}@test.org") { id } } diff --git a/src/activitypub/routes/inbox.js b/src/activitypub/routes/inbox.js index 062f4b916..f9cfb3794 100644 --- a/src/activitypub/routes/inbox.js +++ b/src/activitypub/routes/inbox.js @@ -13,36 +13,36 @@ router.post('/', async function (req, res, next) { debug(`Request headers = ${JSON.stringify(req.headers, null, 2)}`) switch (req.body.type) { case 'Create': - if (req.body.send) { - await activityPub.sendActivity(req.body).catch(next) - break - } await activityPub.handleCreateActivity(req.body).catch(next) break case 'Undo': await activityPub.handleUndoActivity(req.body).catch(next) break case 'Follow': - debug('handleFollow') - await activityPub.handleFollowActivity(req.body) - debug('handledFollow') + await activityPub.handleFollowActivity(req.body).catch(next) break case 'Delete': await activityPub.handleDeleteActivity(req.body).catch(next) break - /* eslint-disable */ + /* eslint-disable */ case 'Update': - + await activityPub.handleUpdateActivity(req.body).catch(next) + break case 'Accept': await activityPub.handleAcceptActivity(req.body).catch(next) case 'Reject': - + // Do nothing + break case 'Add': - + break case 'Remove': - + break case 'Like': - + await activityPub.handleLikeActivity(req.body).catch(next) + break + case 'Dislike': + await activityPub.handleDislikeActivity(req.body).catch(next) + break case 'Announce': debug('else!!') debug(JSON.stringify(req.body, null, 2)) diff --git a/src/activitypub/utils/activity.js b/src/activitypub/utils/activity.js index 00a91813d..53bcd37ea 100644 --- a/src/activitypub/utils/activity.js +++ b/src/activitypub/utils/activity.js @@ -96,6 +96,12 @@ export function isPublicAddressed (postObject) { if (typeof postObject.to === 'string') { postObject.to = [postObject.to] } + if (typeof postObject === 'string') { + postObject.to = [postObject] + } + if (Array.isArray(postObject)) { + postObject.to = postObject + } return postObject.to.includes('Public') || postObject.to.includes('as:Public') || postObject.to.includes('https://www.w3.org/ns/activitystreams#Public') diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 9f3864dfe..a85bd1244 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -1,16 +1,15 @@ import createOrUpdateLocations from './nodes/locations' import { generateRsaKeyPair } from '../activitypub/security' import dotenv from 'dotenv' -import { resolve } from 'path' -dotenv.config({ path: resolve('src', 'activitypub', '.env') }) +dotenv.config() export default { Mutation: { CreateUser: async (resolve, root, args, context, info) => { const keys = generateRsaKeyPair() Object.assign(args, keys) - args.actorId = `${process.env.ACTIVITYPUB_URI}/activitypub/users/${args.slug}` + args.actorId = `${process.env.GRAPHQL_URI}/activitypub/users/${args.slug}` const result = await resolve(root, args, context, info) await createOrUpdateLocations(args.id, args.locationName, context.driver) return result diff --git a/src/resolvers/posts.js b/src/resolvers/posts.js index d895b29a3..b7a6d8a2a 100644 --- a/src/resolvers/posts.js +++ b/src/resolvers/posts.js @@ -1,22 +1,23 @@ import { neo4jgraphql } from 'neo4j-graphql-js' import { activityPub } from '../activitypub/ActivityPub' -import uuid from 'uuid/v4' import as from 'activitystrea.ms' +import dotenv from 'dotenv' /* import as from 'activitystrea.ms' import request from 'request' */ const debug = require('debug')('backend:schema') +dotenv.config() export default { Mutation: { CreatePost: async (object, params, context, resolveInfo) => { - params.activityId = uuid() + params.activityId = activityPub.generateStatusId(context.user.slug) + params.objectId = activityPub.generateStatusId(context.user.slug) const result = await neo4jgraphql(object, params, context, resolveInfo, false) const session = context.driver.session() - const author = await session.run( 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + 'MERGE (post)<-[:WROTE]-(author) ' + @@ -25,6 +26,7 @@ export default { postId: result.id } ) + session.close() debug(`actorId = ${author.records[0]._fields[0].properties.actorId}`) if (Array.isArray(author.records) && author.records.length > 0) { @@ -54,10 +56,9 @@ export default { try { await activityPub.sendActivity(createActivity) } catch (e) { - debug(`error sending post activity = ${JSON.stringify(e, null, 2)}`) + debug(`error sending post activity\n${e}`) } } - session.close() return result } diff --git a/src/schema.graphql b/src/schema.graphql index cd6573e83..a57e43373 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -158,6 +158,7 @@ type User { type Post { id: ID! activityId: String + objectId: String author: User @relation(name: "WROTE", direction: "IN") title: String! slug: String diff --git a/test/features/activity-delete.feature b/test/features/activity-delete.feature index 9bdcbe9ab..b5ef7158a 100644 --- a/test/features/activity-delete.feature +++ b/test/features/activity-delete.feature @@ -14,7 +14,7 @@ Feature: Delete an object "type": "Create", "actor": "https://aronda.org/users/bernd-das-brot", "object": { - "id": "https://aronda.org/users/bernd-das-brot/status/kljsdfg9843jknsdf", + "id": "https://aronda.org/users/bernd-das-brot/status/kljsdfg9843jknsdf234", "type": "Article", "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/users/bernd-das-brot", @@ -29,13 +29,13 @@ Feature: Delete an object """ { "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://localhost:4123/users/karl-heinz/status/a4DJ2afdg323v32641vna42lkj685kasd2", + "id": "https://localhost:4123/activitypub/users/karl-heinz/status/a4DJ2afdg323v32641vna42lkj685kasd2", "type": "Delete", "object": { - "id": "https://aronda.org/users/bernd-das-brot/status/kljsdfg9843jknsdf", + "id": "https://aronda.org/activitypub/users/bernd-das-brot/status/kljsdfg9843jknsdf234", "type": "Article", "published": "2019-02-07T19:37:55.002Z", - "attributedTo": "https://aronda.org/users/bernd-das-brot", + "attributedTo": "https://aronda.org/activitypub/users/bernd-das-brot", "content": "Hi Max, how are you?", "to": "https://localhost:4123/activitypub/users/moritz" } @@ -45,10 +45,10 @@ Feature: Delete an object And the object is removed from the outbox collection of "bernd-das-brot" """ { - "id": "https://aronda.org/users/bernd-das-brot/status/kljsdfg9843jknsdf", + "id": "https://aronda.org/activitypub/users/bernd-das-brot/status/kljsdfg9843jknsdf234", "type": "Article", "published": "2019-02-07T19:37:55.002Z", - "attributedTo": "https://aronda.org/users/bernd-das-brot", + "attributedTo": "https://aronda.org/activitypub/users/bernd-das-brot", "content": "Hi Max, how are you?", "to": "https://localhost:4123/activitypub/users/moritz" } diff --git a/test/features/support/steps.js b/test/features/support/steps.js index f2aaf6ffd..d7581f549 100644 --- a/test/features/support/steps.js +++ b/test/features/support/steps.js @@ -105,14 +105,17 @@ Then('the activity is added to the users inbox collection', async function () { }) Then('the post with id {string} to be created', async function (id) { - const result = await client.request(` + setTimeout(async () => { + const result = await client.request(` query { Post(id: "${id}") { title } } `) - expect(result.data.Post).to.be.an('array').that.is.not.empty // eslint-disable-line + + expect(result.data.Post).to.be.an('array').that.is.not.empty // eslint-disable-line + }, 2000) }) Then('the object is removed from the outbox collection of {string}', async function (name, object) { @@ -126,7 +129,8 @@ Then('I send a GET request to {string} and expect a ordered collection', () => { }) Then('the post with id {string} has been liked by {string}', async function (id, slug) { - const result = await client.request(` + setTimeout(async () => { + const result = await client.request(` query { Post(id: "${id}") { shoutedBy { @@ -135,6 +139,7 @@ Then('the post with id {string} has been liked by {string}', async function (id, } } `) - expect(result.data.Post[0].shoutedBy).to.be.an('array').that.is.not.empty // eslint-disable-line - expect(result.data.Post[0].shoutedBy[0].slug).to.equal(slug) + expect(result.data.Post[0].shoutedBy).to.be.an('array').that.is.not.empty // eslint-disable-line + expect(result.data.Post[0].shoutedBy[0].slug).to.equal(slug) + }, 2000) }) From 5ea3ef99e1edd609912b2176ad059227be496d2c Mon Sep 17 00:00:00 2001 From: Armin Date: Wed, 13 Mar 2019 00:25:32 +0100 Subject: [PATCH 526/554] Fixed follow feature + clean database after tests run + wait for user to be created before proceed --- package.json | 2 +- src/activitypub/ActivityPub.js | 10 ++-- src/activitypub/routes/verify.js | 2 +- .../security/httpSignature.spec.js | 2 +- test/features/activity-delete.feature | 4 +- test/features/activity-follow.feature | 33 +++++++------ test/features/object-article.feature | 2 +- test/features/support/steps.js | 48 +++++++++++++------ test/features/world.js | 4 +- 9 files changed, 63 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index fc0d5a751..db42c1135 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "test:cucumber:cmd": "wait-on tcp:4001 tcp:4123 && cucumber-js --require-module @babel/register --exit test/", "test:jest:cmd:debug": "wait-on tcp:4001 tcp:4123 && node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand", "test:jest": "run-p --race test:before:* 'test:jest:cmd {@}' --", - "test:cucumber": "ACTIVITYPUB_PORT=4123 run-p --race test:before:* 'test:cucumber:cmd {@}' --", + "test:cucumber": "run-p --race test:before:* 'test:cucumber:cmd {@}' --", "test:jest:debug": "run-p --race test:before:* 'test:jest:cmd:debug {@}' --", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", diff --git a/src/activitypub/ActivityPub.js b/src/activitypub/ActivityPub.js index ed64816b9..bcebf4d49 100644 --- a/src/activitypub/ActivityPub.js +++ b/src/activitypub/ActivityPub.js @@ -35,12 +35,13 @@ export default class ActivityPub { const url = new URL(process.env.GRAPHQL_URI) activityPub = new ActivityPub(url.hostname || 'localhost', url.port || 4000, url.origin) - // integrated into "server's" express framework + // integrate into running graphql express server server.express.set('ap', activityPub) + server.express.set('port', url.port) server.express.use(router) - debug('ActivityPub middleware added to the express service') + console.log('-> ActivityPub middleware added to the graphql express server') } else { - debug('ActivityPub middleware already added to the express service') + console.log('-> ActivityPub middleware already added to the graphql express server') } } @@ -60,6 +61,7 @@ export default class ActivityPub { if (err) return reject(err) debug(`name = ${toActorName}@${this.domain}`) // save shared inbox + toActorObject = JSON.parse(toActorObject) await this.dataSource.addSharedInboxEndpoint(toActorObject.endpoints.sharedInbox) let followersCollectionPage = await this.dataSource.getFollowersCollectionPage(activity.object) @@ -159,7 +161,7 @@ export default class ActivityPub { switch (activity.object.type) { case 'Follow': const followObject = activity.object - const followingCollectionPage = await this.getFollowingCollectionPage(followObject.actor) + const followingCollectionPage = await this.collections.getFollowingCollectionPage(followObject.actor) followingCollectionPage.orderedItems.push(followObject.object) await this.dataSource.saveFollowingCollectionPage(followingCollectionPage) } diff --git a/src/activitypub/routes/verify.js b/src/activitypub/routes/verify.js index 34676b44f..bb5850b3e 100644 --- a/src/activitypub/routes/verify.js +++ b/src/activitypub/routes/verify.js @@ -4,7 +4,7 @@ const debug = require('debug')('ea:verify') export default async (req, res, next) => { debug(`actorId = ${req.body.actor}`) // TODO stop if signature validation fails - if (await verifySignature(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)) { + if (await verifySignature(`${req.protocol}://${req.hostname}:${req.app.get('port')}${req.originalUrl}`, req.headers)) { debug('verify = true') next() } else { diff --git a/src/activitypub/security/httpSignature.spec.js b/src/activitypub/security/httpSignature.spec.js index bf1162219..fe09eda8a 100644 --- a/src/activitypub/security/httpSignature.spec.js +++ b/src/activitypub/security/httpSignature.spec.js @@ -60,7 +60,7 @@ describe('Signature creation and verification', () => { httpSignature = createSignature(user.privateKey, 'http://localhost:4001/activitypub/users/test-user#main-key', 'https://democracy-app.de/activitypub/users/max/inbox', headers) }) - it('verifies a Signature by ', async () => { + it('verifies a Signature correct', async () => { headers['Signature'] = httpSignature const isVerified = await verifySignature('https://democracy-app.de/activitypub/users/max/inbox', headers) expect(isVerified).to.equal(true) diff --git a/test/features/activity-delete.feature b/test/features/activity-delete.feature index b5ef7158a..f5e269cce 100644 --- a/test/features/activity-delete.feature +++ b/test/features/activity-delete.feature @@ -37,7 +37,7 @@ Feature: Delete an object "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/activitypub/users/bernd-das-brot", "content": "Hi Max, how are you?", - "to": "https://localhost:4123/activitypub/users/moritz" + "to": "https://www.w3.org/ns/activitystreams#Public" } } """ @@ -50,6 +50,6 @@ Feature: Delete an object "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/activitypub/users/bernd-das-brot", "content": "Hi Max, how are you?", - "to": "https://localhost:4123/activitypub/users/moritz" + "to": "https://www.w3.org/ns/activitystreams#Public" } """ diff --git a/test/features/activity-follow.feature b/test/features/activity-follow.feature index a6974309c..6634a342b 100644 --- a/test/features/activity-follow.feature +++ b/test/features/activity-follow.feature @@ -7,45 +7,44 @@ Feature: Follow a user Given our own server runs at "http://localhost:4123" And we have the following users in our database: | Slug | - | peter-lustiger | - | bob-der-baumeister | - | karl-heinz | + | stuart-little | + | tero-vota | Scenario: Send a follow to a user inbox and make sure it's added to the right followers collection - When I send a POST request with the following activity to "/activitypub/users/peter-lustiger/inbox": + When I send a POST request with the following activity to "/activitypub/users/tero-vota/inbox": """ { "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://localhost:4123/activitypub/users/bob-der-baumeister/status/83J23549sda1k72fsa4567na42312455kad83", + "id": "https://localhost:4123/activitypub/users/stuart-little/status/83J23549sda1k72fsa4567na42312455kad83", "type": "Follow", - "actor": "http://localhost:4123/activitypub/users/bob-der-baumeister", - "object": "http://localhost:4123/activitypub/users/peter-lustiger" + "actor": "http://localhost:4123/activitypub/users/stuart-little", + "object": "http://localhost:4123/activitypub/users/tero-vota" } """ Then I expect the status code to be 200 - And the follower is added to the followers collection of "peter-lustiger" + And the follower is added to the followers collection of "tero-vota" """ - https://localhost:4123/activitypub/users/bob-der-baumeister + http://localhost:4123/activitypub/users/stuart-little """ Scenario: Send an undo activity to revert the previous follow activity - When I send a POST request with the following activity to "/activitypub/users/bob-der-baumeister/inbox": + When I send a POST request with the following activity to "/activitypub/users/stuart-little/inbox": """ { "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://localhost:4123/activitypub/users/peter-lustiger/status/a4DJ2afdg323v32641vna42lkj685kasd2", + "id": "https://localhost:4123/activitypub/users/tero-vota/status/a4DJ2afdg323v32641vna42lkj685kasd2", "type": "Undo", - "actor": "http://localhost:4123/activitypub/users/peter-lustiger", + "actor": "http://localhost:4123/activitypub/users/tero-vota", "object": { - "id": "https://localhost:4123/activitypub/users/bob-der-baumeister/status/83J23549sda1k72fsa4567na42312455kad83", + "id": "https://localhost:4123/activitypub/users/stuart-little/status/83J23549sda1k72fsa4567na42312455kad83", "type": "Follow", - "actor": "http://localhost:4123/activitypub/users/bob-der-baumeister", - "object": "http://localhost:4123/activitypub/users/peter-lustiger" + "actor": "http://localhost:4123/activitypub/users/stuart-little", + "object": "http://localhost:4123/activitypub/users/tero-vota" } } """ Then I expect the status code to be 200 - And the follower is removed from the followers collection of "peter-lustiger" + And the follower is removed from the followers collection of "tero-vota" """ - https://localhost:4123/activitypub/users/bob-der-baumeister + http://localhost:4123/activitypub/users/stuart-little """ diff --git a/test/features/object-article.feature b/test/features/object-article.feature index 5358f2925..030e408e9 100644 --- a/test/features/object-article.feature +++ b/test/features/object-article.feature @@ -22,7 +22,7 @@ Feature: Send and receive Articles "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/users/marvin", "content": "Hi Max, how are you?", - "to": "https://localhost:4123/activitypub/users/max" + "to": "as:Public" } } """ diff --git a/test/features/support/steps.js b/test/features/support/steps.js index d7581f549..a535a523e 100644 --- a/test/features/support/steps.js +++ b/test/features/support/steps.js @@ -22,14 +22,15 @@ function createUser (slug) { AfterAll('Clean up the test data', function () { debug('All the tests are done! Deleting test data') + return factory.cleanDatabase() }) Given('our own server runs at {string}', function (string) { // just documenation }) -Given('we have the following users in our database:', async function (dataTable) { - await Promise.all(dataTable.hashes().map((user) => { +Given('we have the following users in our database:', function (dataTable) { + return Promise.all(dataTable.hashes().map((user) => { return createUser(user.Slug) })) }) @@ -45,6 +46,20 @@ When('I send a GET request to {string}', async function (pathname) { When('I send a POST request with the following activity to {string}:', async function (inboxUrl, activity) { debug(`inboxUrl = ${inboxUrl}`) debug(`activity = ${activity}`) + const splitted = inboxUrl.split('/') + const slug = splitted[splitted.indexOf('users') + 1] + let result + do { + result = await client.request(` + query { + User(slug: "${slug}") { + id + slug + actorId + } + } + `) + } while (result.User.length === 0) this.lastInboxUrl = inboxUrl this.lastActivity = activity const response = await this.post(inboxUrl, activity) @@ -100,22 +115,19 @@ Then('the follower is removed from the followers collection of {string}', async expect(responseObject.orderedItems).to.not.include(follower) }) -Then('the activity is added to the users inbox collection', async function () { - -}) - Then('the post with id {string} to be created', async function (id) { - setTimeout(async () => { - const result = await client.request(` + let result + do { + result = await client.request(` query { Post(id: "${id}") { title } } `) + } while (result.Post.length === 0) - expect(result.data.Post).to.be.an('array').that.is.not.empty // eslint-disable-line - }, 2000) + expect(result.Post).to.be.an('array').that.is.not.empty // eslint-disable-line }) Then('the object is removed from the outbox collection of {string}', async function (name, object) { @@ -128,9 +140,14 @@ Then('I send a GET request to {string} and expect a ordered collection', () => { }) +Then('the activity is added to the users inbox collection', async function () { + +}) + Then('the post with id {string} has been liked by {string}', async function (id, slug) { - setTimeout(async () => { - const result = await client.request(` + let result + do { + result = await client.request(` query { Post(id: "${id}") { shoutedBy { @@ -139,7 +156,8 @@ Then('the post with id {string} has been liked by {string}', async function (id, } } `) - expect(result.data.Post[0].shoutedBy).to.be.an('array').that.is.not.empty // eslint-disable-line - expect(result.data.Post[0].shoutedBy[0].slug).to.equal(slug) - }, 2000) + } while (result.Post.length === 0) + + expect(result.Post[0].shoutedBy).to.be.an('array').that.is.not.empty // eslint-disable-line + expect(result.Post[0].shoutedBy[0].slug).to.equal(slug) }) diff --git a/test/features/world.js b/test/features/world.js index 1b96e0761..be436b536 100644 --- a/test/features/world.js +++ b/test/features/world.js @@ -20,8 +20,8 @@ class CustomWorld { 'Accept': 'application/activity+json' }}, function (error, response, body) { if (!error) { - debug(`get response = ${response.headers['content-type']}`) - debug(`body = ${body}`) + debug(`get content-type = ${response.headers['content-type']}`) + debug(`get body = ${JSON.stringify(typeof body === 'string' ? JSON.parse(body) : body, null, 2)}`) resolve({ lastResponse: body, lastContentType: response.headers['content-type'], statusCode: response.statusCode }) } else { reject(error) From 3d56875be516d3b7353aa514eb4435a7de5eca9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 13 Mar 2019 13:51:51 +0100 Subject: [PATCH 527/554] Typo --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 01063f573..c91f3e9be 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ import createServer from './server' -import ActiviyPub from './activitypub/ActivityPub' +import ActivityPub from './activitypub/ActivityPub' const serverConfig = { port: process.env.GRAPHQL_PORT || 4000 @@ -13,5 +13,5 @@ const server = createServer() server.start(serverConfig, options => { /* eslint-disable-next-line no-console */ console.log(`Server ready at ${process.env.GRAPHQL_URI} 🚀`) - ActiviyPub.init(server) + ActivityPub.init(server) }) From ac155b7f1751bca253331654d6eb3b3e59c32618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 13 Mar 2019 13:57:46 +0100 Subject: [PATCH 528/554] Small refactoring `let client` in the upmost scope cc @Tirokk --- src/resolvers/badges.spec.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/resolvers/badges.spec.js b/src/resolvers/badges.spec.js index e38f54381..dfcf1c5b6 100644 --- a/src/resolvers/badges.spec.js +++ b/src/resolvers/badges.spec.js @@ -3,6 +3,7 @@ import { GraphQLClient } from 'graphql-request' import { host, login } from '../jest/helpers' const factory = Factory() +let client describe('badges', () => { beforeEach(async () => { @@ -55,7 +56,6 @@ describe('badges', () => { ` describe('unauthenticated', () => { - let client it('throws authorization error', async () => { client = new GraphQLClient(host) @@ -66,7 +66,6 @@ describe('badges', () => { }) describe('authenticated admin', () => { - let client beforeEach(async () => { const headers = await login({ email: 'admin@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) @@ -86,7 +85,6 @@ describe('badges', () => { }) describe('authenticated moderator', () => { - let client beforeEach(async () => { const headers = await login({ email: 'moderator@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) @@ -120,7 +118,6 @@ describe('badges', () => { ` describe('unauthenticated', () => { - let client it('throws authorization error', async () => { client = new GraphQLClient(host) @@ -131,7 +128,6 @@ describe('badges', () => { }) describe('authenticated moderator', () => { - let client beforeEach(async () => { const headers = await login({ email: 'moderator@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) @@ -145,7 +141,6 @@ describe('badges', () => { }) describe('authenticated admin', () => { - let client beforeEach(async () => { const headers = await login({ email: 'admin@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) @@ -180,7 +175,6 @@ describe('badges', () => { ` describe('unauthenticated', () => { - let client it('throws authorization error', async () => { client = new GraphQLClient(host) @@ -191,7 +185,6 @@ describe('badges', () => { }) describe('authenticated moderator', () => { - let client beforeEach(async () => { const headers = await login({ email: 'moderator@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) @@ -205,7 +198,6 @@ describe('badges', () => { }) describe('authenticated admin', () => { - let client beforeEach(async () => { const headers = await login({ email: 'admin@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) From 460f94ea3f37929e27398abe9c65487a75851b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Wed, 13 Mar 2019 14:32:15 +0100 Subject: [PATCH 529/554] Add unauthenticated test to follow and shout close #234 --- src/middleware/permissionsMiddleware.js | 5 +- src/resolvers/follow.spec.js | 86 +++++++++++------ src/resolvers/shout.spec.js | 121 ++++++++++++++---------- 3 files changed, 132 insertions(+), 80 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 7fb6e75b8..08feb1e5e 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -56,10 +56,13 @@ const permissions = shield({ CreateBadge: isAdmin, UpdateBadge: isAdmin, DeleteBadge: isAdmin, + follow: isAuthenticated, + unfollow: isAuthenticated, + shout: isAuthenticated, + unshout: isAuthenticated, enable: isModerator, disable: isModerator - // addFruitToBasket: isAuthenticated // CreateUser: allow, }, User: { diff --git a/src/resolvers/follow.spec.js b/src/resolvers/follow.spec.js index 3c16560e5..081e49081 100644 --- a/src/resolvers/follow.spec.js +++ b/src/resolvers/follow.spec.js @@ -4,6 +4,7 @@ import { host, login } from '../jest/helpers' const factory = Factory() let clientUser1 +let headersUser1 const mutationFollowUser = (id) => ` mutation { @@ -27,18 +28,25 @@ beforeEach(async () => { email: 'test2@example.org', password: '1234' }) + + headersUser1 = await login({ email: 'test@example.org', password: '1234' }) + clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) }) afterEach(async () => { await factory.cleanDatabase() }) -describe('follow ', () => { - describe('(un)follow user', () => { - let headersUser1 - beforeEach(async () => { - headersUser1 = await login({ email: 'test@example.org', password: '1234' }) - clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) +describe('follow', () => { + describe('follow user', () => { + describe('unauthenticated follow', () => { + it('throws authorization error', async () => { + let client + client = new GraphQLClient(host) + await expect( + client.request(mutationFollowUser('u2')) + ).rejects.toThrow('Not Authorised') + }) }) it('I can follow another user', async () => { @@ -65,31 +73,6 @@ describe('follow ', () => { expect(User[0]).toMatchObject(expected2) }) - it('I can unfollow a user', async () => { - // follow - await clientUser1.request( - mutationFollowUser('u2') - ) - const expected = { - unfollow: true - } - // unfollow - const res = await clientUser1.request(mutationUnfollowUser('u2')) - expect(res).toMatchObject(expected) - - const { User } = await clientUser1.request(`{ - User(id: "u2") { - followedBy { id } - followedByCurrentUser - } - }`) - const expected2 = { - followedBy: [], - followedByCurrentUser: false - } - expect(User[0]).toMatchObject(expected2) - }) - it('I can`t follow myself', async () => { const res = await clientUser1.request( mutationFollowUser('u1') @@ -112,4 +95,45 @@ describe('follow ', () => { expect(User[0]).toMatchObject(expected2) }) }) + describe('unfollow user', () => { + describe('unauthenticated follow', () => { + it('throws authorization error', async () => { + // follow + await clientUser1.request( + mutationFollowUser('u2') + ) + // unfollow + let client + client = new GraphQLClient(host) + await expect( + client.request(mutationUnfollowUser('u2')) + ).rejects.toThrow('Not Authorised') + }) + }) + + it('I can unfollow a user', async () => { + // follow + await clientUser1.request( + mutationFollowUser('u2') + ) + // unfollow + const expected = { + unfollow: true + } + const res = await clientUser1.request(mutationUnfollowUser('u2')) + expect(res).toMatchObject(expected) + + const { User } = await clientUser1.request(`{ + User(id: "u2") { + followedBy { id } + followedByCurrentUser + } + }`) + const expected2 = { + followedBy: [], + followedByCurrentUser: false + } + expect(User[0]).toMatchObject(expected2) + }) + }) }) diff --git a/src/resolvers/shout.spec.js b/src/resolvers/shout.spec.js index 490191c7a..88866a74f 100644 --- a/src/resolvers/shout.spec.js +++ b/src/resolvers/shout.spec.js @@ -4,6 +4,7 @@ import { host, login } from '../jest/helpers' const factory = Factory() let clientUser1, clientUser2 +let headersUser1, headersUser2 const mutationShoutPost = (id) => ` mutation { @@ -27,37 +28,44 @@ beforeEach(async () => { email: 'test2@example.org', password: '1234' }) + + headersUser1 = await login({ email: 'test@example.org', password: '1234' }) + headersUser2 = await login({ email: 'test2@example.org', password: '1234' }) + clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) + clientUser2 = new GraphQLClient(host, { headers: headersUser2 }) + + await clientUser1.request(` + mutation { + CreatePost(id: "p1", title: "Post Title 1", content: "Some Post Content 1") { + id + title + } + } + `) + await clientUser2.request(` + mutation { + CreatePost(id: "p2", title: "Post Title 2", content: "Some Post Content 2") { + id + title + } + } + `) }) afterEach(async () => { await factory.cleanDatabase() }) -describe('shout ', () => { - describe('(un)shout foreign post', () => { - let headersUser1, headersUser2 - beforeEach(async () => { - headersUser1 = await login({ email: 'test@example.org', password: '1234' }) - headersUser2 = await login({ email: 'test2@example.org', password: '1234' }) - clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) - clientUser2 = new GraphQLClient(host, { headers: headersUser2 }) - - await clientUser1.request(` - mutation { - CreatePost(id: "p1", title: "Post Title 1", content: "Some Post Content 1") { - id - title - } - } - `) - await clientUser2.request(` - mutation { - CreatePost(id: "p2", title: "Post Title 2", content: "Some Post Content 2") { - id - title - } - } - `) +describe('shout', () => { + describe('shout foreign post', () => { + describe('unauthenticated shout', () => { + it('throws authorization error', async () => { + let client + client = new GraphQLClient(host) + await expect( + client.request(mutationShoutPost('p1')) + ).rejects.toThrow('Not Authorised') + }) }) it('I shout a post of another user', async () => { @@ -80,29 +88,6 @@ describe('shout ', () => { expect(Post[0]).toMatchObject(expected2) }) - it('I unshout a post of another user', async () => { - // shout - await clientUser1.request( - mutationShoutPost('p2') - ) - const expected = { - unshout: true - } - // unshout - const res = await clientUser1.request(mutationUnshoutPost('p2')) - expect(res).toMatchObject(expected) - - const { Post } = await clientUser1.request(`{ - Post(id: "p2") { - shoutedByCurrentUser - } - }`) - const expected2 = { - shoutedByCurrentUser: false - } - expect(Post[0]).toMatchObject(expected2) - }) - it('I can`t shout my own post', async () => { const res = await clientUser1.request( mutationShoutPost('p1') @@ -123,4 +108,44 @@ describe('shout ', () => { expect(Post[0]).toMatchObject(expected2) }) }) + + describe('unshout foreign post', () => { + describe('unauthenticated shout', () => { + it('throws authorization error', async () => { + // shout + await clientUser1.request( + mutationShoutPost('p2') + ) + // unshout + let client + client = new GraphQLClient(host) + await expect( + client.request(mutationUnshoutPost('p2')) + ).rejects.toThrow('Not Authorised') + }) + }) + + it('I unshout a post of another user', async () => { + // shout + await clientUser1.request( + mutationShoutPost('p2') + ) + const expected = { + unshout: true + } + // unshout + const res = await clientUser1.request(mutationUnshoutPost('p2')) + expect(res).toMatchObject(expected) + + const { Post } = await clientUser1.request(`{ + Post(id: "p2") { + shoutedByCurrentUser + } + }`) + const expected2 = { + shoutedByCurrentUser: false + } + expect(Post[0]).toMatchObject(expected2) + }) + }) }) From 9dffb69162a85017d6167bef52708e3ccb66ba52 Mon Sep 17 00:00:00 2001 From: Armin Date: Wed, 13 Mar 2019 14:39:00 +0100 Subject: [PATCH 530/554] Fix blank lines in test --- src/resolvers/badges.spec.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/resolvers/badges.spec.js b/src/resolvers/badges.spec.js index dfcf1c5b6..1966ce241 100644 --- a/src/resolvers/badges.spec.js +++ b/src/resolvers/badges.spec.js @@ -56,7 +56,6 @@ describe('badges', () => { ` describe('unauthenticated', () => { - it('throws authorization error', async () => { client = new GraphQLClient(host) await expect( @@ -118,7 +117,6 @@ describe('badges', () => { ` describe('unauthenticated', () => { - it('throws authorization error', async () => { client = new GraphQLClient(host) await expect( @@ -175,7 +173,6 @@ describe('badges', () => { ` describe('unauthenticated', () => { - it('throws authorization error', async () => { client = new GraphQLClient(host) await expect( From e9e0c84cb2776f60aa8ad068ae38e537ee559f72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 13 Mar 2019 16:48:56 +0100 Subject: [PATCH 531/554] Fixed merge error CC @Lulalaby --- src/schema.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schema.graphql b/src/schema.graphql index 752532d8b..4e0347cc7 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -10,7 +10,7 @@ type Mutation { login(email: String!, password: String!): String! signup(email: String!, password: String!): Boolean! changePassword(oldPassword:String!, newPassword: String!): String! - report(resource: Resource!, description: String): Report + report(id: ID!, description: String): Report disable(id: ID!): ID enable(id: ID!): ID "Shout the given Type and ID" From 57fc99fc3f5b76be6c9531025f83c4a2059d2030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 13 Mar 2019 17:01:49 +0100 Subject: [PATCH 532/554] Fix merge error again cc @Lulaby pay attention when merging `master` --- src/middleware/permissionsMiddleware.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index 9e1bc6fbe..62999c235 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -56,8 +56,6 @@ const permissions = shield({ CreateBadge: isAdmin, UpdateBadge: isAdmin, DeleteBadge: isAdmin, - enable: isModerator, - disable: isModerator, // addFruitToBasket: isAuthenticated follow: isAuthenticated, unfollow: isAuthenticated, From e6d51d04bc4ba41d905c8346112b44e3e8ce167c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 13 Mar 2019 16:27:59 +0000 Subject: [PATCH 533/554] Bump babel-jest from 24.3.1 to 24.5.0 Bumps [babel-jest](https://github.com/facebook/jest/tree/HEAD/packages/babel-jest) from 24.3.1 to 24.5.0. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/commits/v24.5.0/packages/babel-jest) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 122 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 106 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index fc789e20d..c785fe5ce 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "apollo-server-testing": "~2.4.8", "babel-core": "~7.0.0-0", "babel-eslint": "~10.0.1", - "babel-jest": "~24.3.1", + "babel-jest": "~24.5.0", "chai": "~4.2.0", "eslint": "~5.15.1", "eslint-config-standard": "~12.0.0", diff --git a/yarn.lock b/yarn.lock index 6a9739214..47dc152cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -802,6 +802,16 @@ jest-message-util "^24.3.0" jest-mock "^24.3.0" +"@jest/fake-timers@^24.5.0": + version "24.5.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.5.0.tgz#4a29678b91fd0876144a58f8d46e6c62de0266f0" + integrity sha512-i59KVt3QBz9d+4Qr4QxsKgsIg+NjfuCjSOWj3RQhjF5JNy+eVJDhANQ4WzulzNCHd72srMAykwtRn5NYDGVraw== + dependencies: + "@jest/types" "^24.5.0" + "@types/node" "*" + jest-message-util "^24.5.0" + jest-mock "^24.5.0" + "@jest/reporters@^24.3.1": version "24.3.1" resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.3.1.tgz#68e4abc8d4233acd0dd87287f3bd270d81066248" @@ -846,31 +856,40 @@ "@jest/types" "^24.3.0" "@types/istanbul-lib-coverage" "^1.1.0" -"@jest/transform@^24.3.1": - version "24.3.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.3.1.tgz#ce9e1329eb5e640f493bcd5c8eb9970770959bfc" - integrity sha512-PpjylI5goT4Si69+qUjEeHuKjex0LjjrqJzrMYzlOZn/+SCumGKuGC0UQFeEPThyGsFvWH1Q4gj0R66eOHnIpw== +"@jest/test-result@^24.5.0": + version "24.5.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.5.0.tgz#ab66fb7741a04af3363443084e72ea84861a53f2" + integrity sha512-u66j2vBfa8Bli1+o3rCaVnVYa9O8CAFZeqiqLVhnarXtreSXG33YQ6vNYBogT7+nYiFNOohTU21BKiHlgmxD5A== + dependencies: + "@jest/console" "^24.3.0" + "@jest/types" "^24.5.0" + "@types/istanbul-lib-coverage" "^1.1.0" + +"@jest/transform@^24.3.1", "@jest/transform@^24.5.0": + version "24.5.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.5.0.tgz#6709fc26db918e6af63a985f2cc3c464b4cf99d9" + integrity sha512-XSsDz1gdR/QMmB8UCKlweAReQsZrD/DK7FuDlNo/pE8EcKMrfi2kqLRk8h8Gy/PDzgqJj64jNEzOce9pR8oj1w== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^24.3.0" + "@jest/types" "^24.5.0" babel-plugin-istanbul "^5.1.0" chalk "^2.0.1" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.1.15" - jest-haste-map "^24.3.1" + jest-haste-map "^24.5.0" jest-regex-util "^24.3.0" - jest-util "^24.3.0" + jest-util "^24.5.0" micromatch "^3.1.10" realpath-native "^1.1.0" slash "^2.0.0" source-map "^0.6.1" write-file-atomic "2.4.1" -"@jest/types@^24.3.0": - version "24.3.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.3.0.tgz#3f6e117e47248a9a6b5f1357ec645bd364f7ad23" - integrity sha512-VoO1F5tU2n/93QN/zaZ7Q8SeV/Rj+9JJOgbvKbBwy4lenvmdj1iDaQEPXGTKrO6OSvDeb2drTFipZJYxgo6kIQ== +"@jest/types@^24.3.0", "@jest/types@^24.5.0": + version "24.5.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.5.0.tgz#feee214a4d0167b0ca447284e95a57aa10b3ee95" + integrity sha512-kN7RFzNMf2R8UDadPOl6ReyI+MT8xfqRuAnuVL+i4gwjv/zubdDK+EDeLHYwq1j0CSSR2W/MmgaRlMZJzXdmVA== dependencies: "@types/istanbul-lib-coverage" "^1.1.0" "@types/yargs" "^12.0.9" @@ -1702,13 +1721,13 @@ babel-eslint@~10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-jest@^24.3.1, babel-jest@~24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.3.1.tgz#168468a37e90426520c5293da4f55e1a512063b0" - integrity sha512-6KaXyUevY0KAxD5Ba+EBhyfwvc+R2f7JV7BpBZ5T8yJGgj0M1hYDfRhDq35oD5MzprMf/ggT81nEuLtMyxfDIg== +babel-jest@^24.3.1, babel-jest@~24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.5.0.tgz#0ea042789810c2bec9065f7c8ab4dc18e1d28559" + integrity sha512-0fKCXyRwxFTJL0UXDJiT2xYxO9Lu2vBd9n+cC+eDjESzcVG3s2DRGAxbzJX21fceB1WYoBjAh8pQ83dKcl003g== dependencies: - "@jest/transform" "^24.3.1" - "@jest/types" "^24.3.0" + "@jest/transform" "^24.5.0" + "@jest/types" "^24.5.0" "@types/babel__core" "^7.1.0" babel-plugin-istanbul "^5.1.0" babel-preset-jest "^24.3.0" @@ -4325,6 +4344,21 @@ jest-haste-map@^24.3.1: micromatch "^3.1.10" sane "^4.0.3" +jest-haste-map@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.5.0.tgz#3f17d0c548b99c0c96ed2893f9c0ccecb2eb9066" + integrity sha512-mb4Yrcjw9vBgSvobDwH8QUovxApdimGcOkp+V1ucGGw4Uvr3VzZQBJhNm1UY3dXYm4XXyTW2G7IBEZ9pM2ggRQ== + dependencies: + "@jest/types" "^24.5.0" + fb-watchman "^2.0.0" + graceful-fs "^4.1.15" + invariant "^2.2.4" + jest-serializer "^24.4.0" + jest-util "^24.5.0" + jest-worker "^24.4.0" + micromatch "^3.1.10" + sane "^4.0.3" + jest-jasmine2@^24.3.1: version "24.3.1" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.3.1.tgz#127d628d3ac0829bd3c0fccacb87193e543b420b" @@ -4378,6 +4412,20 @@ jest-message-util@^24.3.0: slash "^2.0.0" stack-utils "^1.0.1" +jest-message-util@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.5.0.tgz#181420a65a7ef2e8b5c2f8e14882c453c6d41d07" + integrity sha512-6ZYgdOojowCGiV0D8WdgctZEAe+EcFU+KrVds+0ZjvpZurUW2/oKJGltJ6FWY2joZwYXN5VL36GPV6pNVRqRnQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.5.0" + "@jest/types" "^24.5.0" + "@types/stack-utils" "^1.0.1" + chalk "^2.0.1" + micromatch "^3.1.10" + slash "^2.0.0" + stack-utils "^1.0.1" + jest-mock@^24.3.0: version "24.3.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.3.0.tgz#95a86b6ad474e3e33227e6dd7c4ff6b07e18d3cb" @@ -4385,6 +4433,13 @@ jest-mock@^24.3.0: dependencies: "@jest/types" "^24.3.0" +jest-mock@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.5.0.tgz#976912c99a93f2a1c67497a9414aa4d9da4c7b76" + integrity sha512-ZnAtkWrKf48eERgAOiUxVoFavVBziO2pAi2MfZ1+bGXVkDfxWLxU0//oJBkgwbsv6OAmuLBz4XFFqvCFMqnGUw== + dependencies: + "@jest/types" "^24.5.0" + jest-regex-util@^24.3.0: version "24.3.0" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36" @@ -4468,6 +4523,11 @@ jest-serializer@^24.3.0: resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.3.0.tgz#074e307300d1451617cf2630d11543ee4f74a1c8" integrity sha512-RiSpqo2OFbVLJN/PgAOwQIUeHDfss6NBUDTLhjiJM8Bb5rMrwRqHfkaqahIsOf9cXXB5UjcqDCzbQ7AIoMqWkg== +jest-serializer@^24.4.0: + version "24.4.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3" + integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q== + jest-snapshot@^24.3.1: version "24.3.1" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.3.1.tgz#0f22a86c1b8c87e823f5ad095e82c19d9ed93d72" @@ -4505,6 +4565,25 @@ jest-util@^24.3.0: slash "^2.0.0" source-map "^0.6.0" +jest-util@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.5.0.tgz#9d9cb06d9dcccc8e7cc76df91b1635025d7baa84" + integrity sha512-Xy8JsD0jvBz85K7VsTIQDuY44s+hYJyppAhcsHsOsGisVtdhar6fajf2UOf2mEVEgh15ZSdA0zkCuheN8cbr1Q== + dependencies: + "@jest/console" "^24.3.0" + "@jest/fake-timers" "^24.5.0" + "@jest/source-map" "^24.3.0" + "@jest/test-result" "^24.5.0" + "@jest/types" "^24.5.0" + "@types/node" "*" + callsites "^3.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.15" + is-ci "^2.0.0" + mkdirp "^0.5.1" + slash "^2.0.0" + source-map "^0.6.0" + jest-validate@^24.3.1: version "24.3.1" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.3.1.tgz#9359eea5a767a3d20b4fa7a5764fd78330ba8312" @@ -4540,6 +4619,15 @@ jest-worker@^24.3.1: merge-stream "^1.0.1" supports-color "^6.1.0" +jest-worker@^24.4.0: + version "24.4.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.4.0.tgz#fbc452b0120bb5c2a70cdc88fa132b48eeb11dd0" + integrity sha512-BH9X/klG9vxwoO99ZBUbZFfV8qO0XNZ5SIiCyYK2zOuJBl6YJVAeNIQjcoOVNu4HGEHeYEKsUWws8kSlSbZ9YQ== + dependencies: + "@types/node" "*" + merge-stream "^1.0.1" + supports-color "^6.1.0" + jest@~24.3.1: version "24.3.1" resolved "https://registry.yarnpkg.com/jest/-/jest-24.3.1.tgz#81959de0d57b2df923510f4fafe266712d37dcca" From 412f220dba4a838acf6c7e6a2b323ffc765d1272 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 13 Mar 2019 16:28:31 +0000 Subject: [PATCH 534/554] Bump eslint-plugin-jest from 22.3.0 to 22.3.2 Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 22.3.0 to 22.3.2. - [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases) - [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v22.3.0...v22.3.2) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index fc789e20d..03ee9af5f 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "eslint": "~5.15.1", "eslint-config-standard": "~12.0.0", "eslint-plugin-import": "~2.16.0", - "eslint-plugin-jest": "~22.3.0", + "eslint-plugin-jest": "~22.3.2", "eslint-plugin-node": "~8.0.1", "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", diff --git a/yarn.lock b/yarn.lock index 6a9739214..f9e75ab16 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2748,10 +2748,10 @@ eslint-plugin-import@~2.16.0: read-pkg-up "^2.0.0" resolve "^1.9.0" -eslint-plugin-jest@~22.3.0: - version "22.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.3.0.tgz#a10f10dedfc92def774ec9bb5bfbd2fb8e1c96d2" - integrity sha512-P1mYVRNlOEoO5T9yTqOfucjOYf1ktmJ26NjwjH8sxpCFQa6IhBGr5TpKl3hcAAT29hOsRJVuMWmTsHoUVo9FoA== +eslint-plugin-jest@~22.3.2: + version "22.3.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.3.2.tgz#702ac04b06223c9241d92b986165318db474ca81" + integrity sha512-K1i3qORvcX2VuGLI4N+slreGpeObAWkT5gi1ya8olZ6YXwnxzBrMlif3uEUHgXwPIStpO26vAlRX0SgFy8SkZA== eslint-plugin-node@~8.0.1: version "8.0.1" From f36c91a2a1776932957288eeffa072dc2615498c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 13 Mar 2019 18:26:11 +0000 Subject: [PATCH 535/554] Bump supertest from 3.4.2 to 4.0.0 Bumps [supertest](https://github.com/visionmedia/supertest) from 3.4.2 to 4.0.0. - [Release notes](https://github.com/visionmedia/supertest/releases) - [Commits](https://github.com/visionmedia/supertest/compare/v3.4.2...v4.0.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 49 ++++++++++++++++++++++++------------------------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 9778d6cef..1da1f35c6 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,6 @@ "jest": "~24.3.1", "nodemon": "~1.18.10", "nyc": "~13.3.0", - "supertest": "~3.4.2" + "supertest": "~4.0.0" } } diff --git a/yarn.lock b/yarn.lock index ea1076fec..afbc08dae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2246,7 +2246,7 @@ 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: +cookiejar@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== @@ -3032,7 +3032,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== @@ -3216,7 +3216,7 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@^2.3.1, form-data@~2.3.2: +form-data@^2.3.3, form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== @@ -5129,10 +5129,10 @@ mime@1.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== -mime@^1.4.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6" + integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w== mimic-fn@^1.0.0: version "1.2.0" @@ -6005,7 +6005,7 @@ qs@6.5.2, qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -qs@^6.5.1: +qs@^6.6.0: version "6.6.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.6.0.tgz#a99c0f69a8d26bf7ef012f871cdabb0aee4424c2" integrity sha512-KIJqT9jQJDQx5h5uAVPimw6yVg2SekOKu959OCtktD3FjzbpvaPr8i4zzg07DOMz+igA4W/aNM7OV8H37pFYfA== @@ -6109,7 +6109,7 @@ readable-stream@1.1.x: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.3.5: +readable-stream@^2.0.1, 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== @@ -6881,29 +6881,28 @@ subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.8: symbol-observable "^1.0.4" ws "^5.2.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== +superagent@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-4.1.0.tgz#c465c2de41df2b8d05c165cbe403e280790cdfd5" + integrity sha512-FT3QLMasz0YyCd4uIi5HNe+3t/onxMyEho7C3PSqmti3Twgy2rXT4fmkTz6wRL6bTF4uzPcfkUCa8u4JWHw8Ag== dependencies: component-emitter "^1.2.0" - cookiejar "^2.1.0" - debug "^3.1.0" - extend "^3.0.0" - form-data "^2.3.1" + cookiejar "^2.1.2" + debug "^4.1.0" + form-data "^2.3.3" formidable "^1.2.0" methods "^1.1.1" - mime "^1.4.1" - qs "^6.5.1" - readable-stream "^2.3.5" + mime "^2.4.0" + qs "^6.6.0" + readable-stream "^3.0.6" -supertest@~3.4.2: - version "3.4.2" - resolved "https://registry.yarnpkg.com/supertest/-/supertest-3.4.2.tgz#bad7de2e43d60d27c8caeb8ab34a67c8a5f71aad" - integrity sha512-WZWbwceHUo2P36RoEIdXvmqfs47idNNZjCuJOqDz6rvtkk8ym56aU5oglORCpPeXGxT7l9rkJ41+O1lffQXYSA== +supertest@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-4.0.0.tgz#1fda3a5faf331b20ad5fb836ddf789e80b365db6" + integrity sha512-e3UaSMkmVaPQ10MHqb5T9G1mb3L6MVUtLTxkVhKWndHfXyZylwtkjWXD9FzyHqlZ1/EPfeTJ+QDtmax5fb02cw== dependencies: methods "^1.1.2" - superagent "^3.8.3" + superagent "^4.1.0" supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" From 7d82b27aaa53a422954a9e18bd7e203147fbf59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 12 Mar 2019 12:59:45 +0100 Subject: [PATCH 536/554] Hide disabled comments and posts by default I had to trick neo4j-graphql-js to return disabled and deleted fields by default on any neo4j node. If disabled is not queried, then we don't have it in our middleware and we're not able to filter it. --- src/middleware/idMiddleware.js | 28 -------- src/middleware/includedFieldsMiddleware.js | 29 ++++++++ src/middleware/index.js | 4 +- src/middleware/softDeleteMiddleware.js | 45 +++++++++---- src/middleware/softDeleteMiddleware.spec.js | 73 +++++++++++++++++++-- src/schema.graphql | 4 +- src/seed/seed-db.js | 9 ++- 7 files changed, 136 insertions(+), 56 deletions(-) delete mode 100644 src/middleware/idMiddleware.js create mode 100644 src/middleware/includedFieldsMiddleware.js diff --git a/src/middleware/idMiddleware.js b/src/middleware/idMiddleware.js deleted file mode 100644 index 2f1854fa6..000000000 --- a/src/middleware/idMiddleware.js +++ /dev/null @@ -1,28 +0,0 @@ -import cloneDeep from 'lodash/cloneDeep' - -const includeId = async (resolve, root, args, context, resolveInfo) => { - // Keeping the graphql resolveInfo untouched ensures that we don't add the - // following attributes to the result set returned to the graphQL client. - // We only want to pass these attributes to our resolver for internal - // purposes e.g. authorization. - const copy = cloneDeep(resolveInfo) - - copy.fieldNodes[0].selectionSet.selections.unshift({ - kind: 'Field', - name: { kind: 'Name', value: 'id' } - }) - return resolve(root, args, context, copy) -} - -export default { - Query: { - User: (resolve, root, args, context, info) => { - return includeId(resolve, root, args, context, info) - } - }, - Mutation: { - CreatePost: (resolve, root, args, context, info) => { - return includeId(resolve, root, args, context, info) - } - } -} diff --git a/src/middleware/includedFieldsMiddleware.js b/src/middleware/includedFieldsMiddleware.js new file mode 100644 index 000000000..6d8ccf8f1 --- /dev/null +++ b/src/middleware/includedFieldsMiddleware.js @@ -0,0 +1,29 @@ +import cloneDeep from 'lodash/cloneDeep' + +const _includeFieldsRecursively = (selectionSet, includedFields) => { + if (!selectionSet) return + includedFields.forEach((includedField) => { + selectionSet.selections.unshift({ + kind: 'Field', + name: { kind: 'Name', value: includedField } + }) + }) + selectionSet.selections.forEach((selection) => { + _includeFieldsRecursively(selection.selectionSet, includedFields) + }) +} + +const includeFieldsRecursively = (includedFields) => { + return (resolve, root, args, context, resolveInfo) => { + const copy = cloneDeep(resolveInfo) + copy.fieldNodes.forEach((fieldNode) => { + _includeFieldsRecursively(fieldNode.selectionSet, includedFields) + }) + return resolve(root, args, context, copy) + } +} + +export default { + Query: includeFieldsRecursively(['id', 'disabled', 'deleted']), + Mutation: includeFieldsRecursively(['id', 'disabled', 'deleted']) +} diff --git a/src/middleware/index.js b/src/middleware/index.js index 5cc20f969..6f95c7451 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -7,7 +7,7 @@ import dateTimeMiddleware from './dateTimeMiddleware' import xssMiddleware from './xssMiddleware' import permissionsMiddleware from './permissionsMiddleware' import userMiddleware from './userMiddleware' -import idMiddleware from './idMiddleware' +import includedFieldsMiddleware from './includedFieldsMiddleware' export default schema => { let middleware = [ @@ -19,7 +19,7 @@ export default schema => { fixImageUrlsMiddleware, softDeleteMiddleware, userMiddleware, - idMiddleware + includedFieldsMiddleware ] // add permisions middleware at the first position (unless we're seeding) diff --git a/src/middleware/softDeleteMiddleware.js b/src/middleware/softDeleteMiddleware.js index 0c12e7a72..042219916 100644 --- a/src/middleware/softDeleteMiddleware.js +++ b/src/middleware/softDeleteMiddleware.js @@ -1,26 +1,43 @@ -const setDefaults = (args) => { +const isModerator = ({ user }) => { + return user && (user.role === 'moderator' || user.role === 'admin') +} + +const setDefaultFilters = (resolve, root, args, context, info) => { if (typeof args.deleted !== 'boolean') { args.deleted = false } - if (typeof args.disabled !== 'boolean') { + + if (!isModerator(context)) { args.disabled = false } - return args + return resolve(root, args, context, info) +} + +const hideDisabledComments = async (resolve, root, args, context, info) => { + const { comments } = root + if (!Array.isArray(comments)) return resolve(root, args, context, info) + if (!isModerator(context)) { + root.comments = comments.filter((comment) => { + return !comment.disabled + }) + } + return resolve(root, args, context, info) } export default { Query: { - Post: (resolve, root, args, context, info) => { - return resolve(root, setDefaults(args), context, info) - }, - Comment: async (resolve, root, args, context, info) => { - return resolve(root, setDefaults(args), context, info) - }, - User: async (resolve, root, args, context, info) => { - return resolve(root, setDefaults(args), context, info) - } + Post: setDefaultFilters, + Comment: setDefaultFilters, + User: setDefaultFilters }, Mutation: async (resolve, root, args, context, info) => { - return resolve(root, setDefaults(args), context, info) - } + args.disabled = false + // TODO: remove as soon as our factories don't need this anymore + if (typeof args.deleted !== 'boolean') { + args.deleted = false + } + return resolve(root, args, context, info) + }, + Post: hideDisabledComments, + User: hideDisabledComments } diff --git a/src/middleware/softDeleteMiddleware.spec.js b/src/middleware/softDeleteMiddleware.spec.js index ed132104e..f478feb7c 100644 --- a/src/middleware/softDeleteMiddleware.spec.js +++ b/src/middleware/softDeleteMiddleware.spec.js @@ -9,14 +9,14 @@ let action beforeEach(async () => { await Promise.all([ - factory.create('User', { role: 'user', email: 'user@example.org', password: '1234' }), + factory.create('User', { id: 'u1', role: 'user', email: 'user@example.org', password: '1234' }), factory.create('User', { id: 'm1', role: 'moderator', email: 'moderator@example.org', password: '1234' }) ]) await factory.authenticateAs({ email: 'user@example.org', password: '1234' }) await Promise.all([ - factory.create('Post', { title: 'Deleted post', deleted: true }), - factory.create('Post', { id: 'p2', title: 'Disabled post', deleted: false }), - factory.create('Post', { title: 'Publicly visible post', deleted: false }) + await factory.create('Post', { id: 'p1', title: 'Deleted post', deleted: true }), + await factory.create('Post', { id: 'p2', title: 'Disabled post', deleted: false }), + await factory.create('Post', { id: 'p3', title: 'Publicly visible post', deleted: false }) ]) const moderatorFactory = Factory() await moderatorFactory.authenticateAs({ email: 'moderator@example.org', password: '1234' }) @@ -62,9 +62,68 @@ describe('softDeleteMiddleware', () => { client = new GraphQLClient(host, { headers }) }) - it('hides deleted or disabled posts', async () => { - const expected = { Post: [{ title: 'Publicly visible post' }] } - await expect(action()).resolves.toEqual(expected) + it('shows disabled but hides deleted posts', async () => { + const expected = [ + { title: 'Disabled post' }, + { title: 'Publicly visible post' } + ] + const { Post } = await action() + await expect(Post).toEqual(expect.arrayContaining(expected)) + }) + }) + + describe('.comments', () => { + beforeEach(async () => { + query = '{ Post(id: "p3") { title comments { content } } }' + + const asModerator = Factory() + await asModerator.authenticateAs({ email: 'moderator@example.org', password: '1234' }) + await Promise.all([ + asModerator.create('Comment', { id: 'c1', content: 'Disabled comment' }), + asModerator.create('Comment', { id: 'c2', content: 'Enabled comment on public post' }) + ]) + await Promise.all([ + asModerator.relate('Comment', 'Author', { from: 'u1', to: 'c1' }), + asModerator.relate('Comment', 'Post', { from: 'c1', to: 'p3' }), + asModerator.relate('Comment', 'Author', { from: 'u1', to: 'c2' }), + asModerator.relate('Comment', 'Post', { from: 'c2', to: 'p3' }) + ]) + await asModerator.mutate('mutation { disable( id: "c1") }') + }) + + describe('as user', () => { + beforeEach(async () => { + const headers = await login({ email: 'user@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('hides disabled comments', async () => { + const expected = { Post: [ { + title: 'Publicly visible post', + comments: [ + { content: 'Enabled comment on public post' } + ] + } + ] } + await expect(action()).resolves.toEqual(expected) + }) + }) + + describe('as moderator', () => { + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('shows disabled comments', async () => { + const expected = [ + { content: 'Enabled comment on public post' }, + { content: 'Disabled comment' } + ] + const { Post: [{ comments }] } = await action() + + await expect(comments).toEqual(expect.arrayContaining(expected)) + }) }) }) diff --git a/src/schema.graphql b/src/schema.graphql index 152301715..801eb4502 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -148,7 +148,7 @@ type User { ) comments: [Comment]! @relation(name: "WROTE", direction: "OUT") - commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) WHERE NOT r.deleted = true RETURN COUNT(r)") + commentsCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)") shouted: [Post]! @relation(name: "SHOUTED", direction: "OUT") shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)") @@ -189,7 +189,7 @@ type Post { categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT") comments: [Comment]! @relation(name: "COMMENTS", direction: "IN") - commentsCount: Int! @cypher(statement: "MATCH (this)<-[:COMMENTS]-(r:Comment) RETURN COUNT(r)") + commentsCount: Int! @cypher(statement: "MATCH (this)<-[:COMMENTS]-(r:Comment) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(r)") shoutedBy: [User]! @relation(name: "SHOUTED", direction: "IN") shoutedCount: Int! @cypher(statement: "MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)") diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index e8c757db8..d526518b9 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -107,9 +107,6 @@ import Factory from './factories' asTick.create('Post', { id: 'p15' }) ]) - const disableMutation = 'mutation { disable( id: "p11") }' - await asModerator.mutate(disableMutation) - await Promise.all([ f.relate('Post', 'Categories', { from: 'p0', to: 'cat16' }), f.relate('Post', 'Categories', { from: 'p1', to: 'cat1' }), @@ -214,6 +211,12 @@ import Factory from './factories' f.relate('Comment', 'Post', { from: 'c7', to: 'p2' }) ]) + const disableMutation = 'mutation($id: ID!) { disable(id: $id) }' + await Promise.all([ + asModerator.mutate(disableMutation, { id: 'p11' }), + asModerator.mutate(disableMutation, { id: 'c5' }) + ]) + await Promise.all([ asTick.create('Report', { description: 'I don\'t like this comment', id: 'c1' }), asTrick.create('Report', { description: 'I don\'t like this post', id: 'p1' }), From d71cb16a01e98f7d5c069fac2142e762be58dbff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 13 Mar 2019 20:57:50 +0100 Subject: [PATCH 537/554] Spec a new behaviour of softDisable If we have nested content, the content should be obfuscated instead of being filtered. cc @datenbrei --- src/middleware/softDeleteMiddleware.spec.js | 297 +++++++++++++------- src/seed/factories/users.js | 2 + 2 files changed, 192 insertions(+), 107 deletions(-) diff --git a/src/middleware/softDeleteMiddleware.spec.js b/src/middleware/softDeleteMiddleware.spec.js index f478feb7c..6b8b4bc49 100644 --- a/src/middleware/softDeleteMiddleware.spec.js +++ b/src/middleware/softDeleteMiddleware.spec.js @@ -7,41 +7,103 @@ let client let query let action -beforeEach(async () => { +beforeAll(async () => { + // For performance reasons we do this only once await Promise.all([ factory.create('User', { id: 'u1', role: 'user', email: 'user@example.org', password: '1234' }), - factory.create('User', { id: 'm1', role: 'moderator', email: 'moderator@example.org', password: '1234' }) + factory.create('User', { id: 'm1', role: 'moderator', email: 'moderator@example.org', password: '1234' }), + factory.create('User', { id: 'u2', role: 'user', avatar: '/some/offensive/avatar.jpg', about: 'This self description is very offensive', email: 'troll@example.org', password: '1234' }) ]) + await factory.authenticateAs({ email: 'user@example.org', password: '1234' }) await Promise.all([ - await factory.create('Post', { id: 'p1', title: 'Deleted post', deleted: true }), - await factory.create('Post', { id: 'p2', title: 'Disabled post', deleted: false }), - await factory.create('Post', { id: 'p3', title: 'Publicly visible post', deleted: false }) + factory.follow({ id: 'u2', type: 'User' }), + factory.create('Post', { id: 'p1', title: 'Deleted post', deleted: true }), + factory.create('Post', { id: 'p3', title: 'Publicly visible post', deleted: false }) ]) - const moderatorFactory = Factory() - await moderatorFactory.authenticateAs({ email: 'moderator@example.org', password: '1234' }) - const disableMutation = ` - mutation { - disable( - id: "p2" - ) - } - ` - await moderatorFactory.mutate(disableMutation) + + await Promise.all([ + factory.create('Comment', { id: 'c2', content: 'Enabled comment on public post' }) + ]) + + await Promise.all([ + factory.relate('Comment', 'Author', { from: 'u1', to: 'c2' }), + factory.relate('Comment', 'Post', { from: 'c2', to: 'p3' }) + ]) + + const asTroll = Factory() + await asTroll.authenticateAs({ email: 'troll@example.org', password: '1234' }) + await asTroll.create('Post', { id: 'p2', title: 'Disabled post', content: 'This is an offensive post content', image: '/some/offensive/image.jpg', deleted: false }) + await asTroll.create('Comment', { id: 'c1', content: 'Disabled comment' }) + await Promise.all([ + asTroll.relate('Comment', 'Author', { from: 'u2', to: 'c1' }), + asTroll.relate('Comment', 'Post', { from: 'c1', to: 'p3' }) + ]) + + const asModerator = Factory() + await asModerator.authenticateAs({ email: 'moderator@example.org', password: '1234' }) + await asModerator.mutate('mutation { disable( id: "p2") }') + await asModerator.mutate('mutation { disable( id: "c1") }') + await asModerator.mutate('mutation { disable( id: "u2") }') }) -afterEach(async () => { +afterAll(async () => { await factory.cleanDatabase() }) describe('softDeleteMiddleware', () => { - describe('Post', () => { + describe('read disabled content', () => { + let user + let post + let comment + const beforeComment = async () => { + query = '{ User(id: "u1") { following { comments { content contentExcerpt } } } }' + const response = await action() + comment = response.User[0].following[0].comments[0] + } + const beforeUser = async () => { + query = '{ User(id: "u1") { following { about avatar } } }' + const response = await action() + user = response.User[0].following[0] + } + const beforePost = async () => { + query = '{ User(id: "u1") { following { contributions { title image content contentExcerpt } } } }' + const response = await action() + post = response.User[0].following[0].contributions[0] + } + action = () => { return client.request(query) } - beforeEach(() => { - query = '{ Post { title } }' + describe('as moderator', () => { + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + describe('User', () => { + beforeEach(beforeUser) + + it('displays about', () => expect(user.about).toEqual('This self description is very offensive')) + it('displays avatar', () => expect(user.avatar).toEqual('/some/offensive/avatar.jpg')) + }) + + describe('Post', () => { + beforeEach(beforePost) + + it('displays title', () => expect(post.title).toEqual('Disabled post')) + it('displays content', () => expect(post.content).toEqual('This is an offensive post content')) + it('displays contentExcerpt', () => expect(post.contentExcerpt).toEqual('This is an offensive post content')) + it('displays image', () => expect(post.image).toEqual('/some/offensive/image.jpg')) + }) + + describe('Comment', () => { + beforeEach(beforeComment) + + it('displays content', () => expect(comment.content).toEqual('Disabled comment')) + it('displays contentExcerpt', () => expect(comment.contentExcerpt).toEqual('Disabled comment')) + }) }) describe('as user', () => { @@ -50,45 +112,35 @@ describe('softDeleteMiddleware', () => { client = new GraphQLClient(host, { headers }) }) - it('hides deleted or disabled posts', async () => { - const expected = { Post: [{ title: 'Publicly visible post' }] } - await expect(action()).resolves.toEqual(expected) + describe('User', () => { + beforeEach(beforeUser) + + it('obfuscates about', () => expect(user.about).toEqual('DELETED')) + it('obfuscates avatar', () => expect(user.avatar).toEqual('DELETED')) + }) + + describe('Post', () => { + beforeEach(beforePost) + + it('obfuscates title', () => expect(post.title).toEqual('DELETED')) + it('obfuscates content', () => expect(post.content).toEqual('DELETED')) + it('obfuscates contentExcerpt', () => expect(post.contentExcerpt).toEqual('DELETED')) + it('obfuscates image', () => expect(post.image).toEqual('DELETED')) + }) + + describe('Comment', () => { + beforeEach(beforeComment) + + it('obfuscates content', () => expect(comment.content).toEqual('DELETED')) + it('obfuscates contentExcerpt', () => expect(comment.contentExcerpt).toEqual('DELETED')) }) }) + }) - describe('as moderator', () => { + describe('Query', () => { + describe('Post', () => { beforeEach(async () => { - const headers = await login({ email: 'moderator@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) - }) - - it('shows disabled but hides deleted posts', async () => { - const expected = [ - { title: 'Disabled post' }, - { title: 'Publicly visible post' } - ] - const { Post } = await action() - await expect(Post).toEqual(expect.arrayContaining(expected)) - }) - }) - - describe('.comments', () => { - beforeEach(async () => { - query = '{ Post(id: "p3") { title comments { content } } }' - - const asModerator = Factory() - await asModerator.authenticateAs({ email: 'moderator@example.org', password: '1234' }) - await Promise.all([ - asModerator.create('Comment', { id: 'c1', content: 'Disabled comment' }), - asModerator.create('Comment', { id: 'c2', content: 'Enabled comment on public post' }) - ]) - await Promise.all([ - asModerator.relate('Comment', 'Author', { from: 'u1', to: 'c1' }), - asModerator.relate('Comment', 'Post', { from: 'c1', to: 'p3' }), - asModerator.relate('Comment', 'Author', { from: 'u1', to: 'c2' }), - asModerator.relate('Comment', 'Post', { from: 'c2', to: 'p3' }) - ]) - await asModerator.mutate('mutation { disable( id: "c1") }') + query = '{ Post { title } }' }) describe('as user', () => { @@ -97,14 +149,8 @@ describe('softDeleteMiddleware', () => { client = new GraphQLClient(host, { headers }) }) - it('hides disabled comments', async () => { - const expected = { Post: [ { - title: 'Publicly visible post', - comments: [ - { content: 'Enabled comment on public post' } - ] - } - ] } + it('hides deleted or disabled posts', async () => { + const expected = { Post: [{ title: 'Publicly visible post' }] } await expect(action()).resolves.toEqual(expected) }) }) @@ -115,72 +161,109 @@ describe('softDeleteMiddleware', () => { client = new GraphQLClient(host, { headers }) }) - it('shows disabled comments', async () => { + it('shows disabled but hides deleted posts', async () => { const expected = [ - { content: 'Enabled comment on public post' }, - { content: 'Disabled comment' } + { title: 'Disabled post' }, + { title: 'Publicly visible post' } ] - const { Post: [{ comments }] } = await action() - - await expect(comments).toEqual(expect.arrayContaining(expected)) + const { Post } = await action() + await expect(Post).toEqual(expect.arrayContaining(expected)) }) }) - }) - describe('filter (deleted: true)', () => { - beforeEach(() => { - query = '{ Post(deleted: true) { title } }' - }) - - describe('as user', () => { + describe('.comments', () => { beforeEach(async () => { - const headers = await login({ email: 'user@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) + query = '{ Post(id: "p3") { title comments { content } } }' }) - it('throws authorisation error', async () => { - await expect(action()).rejects.toThrow('Not Authorised!') + describe('as user', () => { + beforeEach(async () => { + const headers = await login({ email: 'user@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('conceals disabled comments', async () => { + const expected = [ + { content: 'Enabled comment on public post' }, + { content: 'DELETED' } + ] + const { Post: [{ comments }] } = await action() + await expect(comments).toEqual(expect.arrayContaining(expected)) + }) + }) + + describe('as moderator', () => { + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('shows disabled comments', async () => { + const expected = [ + { content: 'Enabled comment on public post' }, + { content: 'Disabled comment' } + ] + const { Post: [{ comments }] } = await action() + await expect(comments).toEqual(expect.arrayContaining(expected)) + }) }) }) - describe('as moderator', () => { - beforeEach(async () => { - const headers = await login({ email: 'moderator@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) + describe('filter (deleted: true)', () => { + beforeEach(() => { + query = '{ Post(deleted: true) { title } }' }) - it('shows deleted posts', async () => { - const expected = { Post: [{ title: 'Deleted post' }] } - await expect(action()).resolves.toEqual(expected) - }) - }) - }) + describe('as user', () => { + beforeEach(async () => { + const headers = await login({ email: 'user@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) - describe('filter (disabled: true)', () => { - beforeEach(() => { - query = '{ Post(disabled: true) { title } }' - }) - - describe('as user', () => { - beforeEach(async () => { - const headers = await login({ email: 'user@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) + it('throws authorisation error', async () => { + await expect(action()).rejects.toThrow('Not Authorised!') + }) }) - it('throws authorisation error', async () => { - await expect(action()).rejects.toThrow('Not Authorised!') + describe('as moderator', () => { + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('shows deleted posts', async () => { + const expected = { Post: [{ title: 'Deleted post' }] } + await expect(action()).resolves.toEqual(expected) + }) }) }) - describe('as moderator', () => { - beforeEach(async () => { - const headers = await login({ email: 'moderator@example.org', password: '1234' }) - client = new GraphQLClient(host, { headers }) + describe('filter (disabled: true)', () => { + beforeEach(() => { + query = '{ Post(disabled: true) { title } }' }) - it('shows disabled posts', async () => { - const expected = { Post: [{ title: 'Disabled post' }] } - await expect(action()).resolves.toEqual(expected) + describe('as user', () => { + beforeEach(async () => { + const headers = await login({ email: 'user@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('throws authorisation error', async () => { + await expect(action()).rejects.toThrow('Not Authorised!') + }) + }) + + describe('as moderator', () => { + beforeEach(async () => { + const headers = await login({ email: 'moderator@example.org', password: '1234' }) + client = new GraphQLClient(host, { headers }) + }) + + it('shows disabled posts', async () => { + const expected = { Post: [{ title: 'Disabled post' }] } + await expect(action()).resolves.toEqual(expected) + }) }) }) }) diff --git a/src/seed/factories/users.js b/src/seed/factories/users.js index c27b2b1ce..491b3f9e1 100644 --- a/src/seed/factories/users.js +++ b/src/seed/factories/users.js @@ -9,6 +9,7 @@ export default function create (params) { password = '1234', role = 'user', avatar = faker.internet.avatar(), + about = faker.lorem.paragraph(), disabled = false, deleted = false } = params @@ -21,6 +22,7 @@ export default function create (params) { password: "${password}", email: "${email}", avatar: "${avatar}", + about: "${about}", role: ${role}, disabled: ${disabled}, deleted: ${deleted} From a252879964d1a715de8692e3b56d25ad75a910e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 13 Mar 2019 21:03:40 +0100 Subject: [PATCH 538/554] Implement obfuscation behaviour --- src/middleware/softDeleteMiddleware.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/middleware/softDeleteMiddleware.js b/src/middleware/softDeleteMiddleware.js index 042219916..24105c435 100644 --- a/src/middleware/softDeleteMiddleware.js +++ b/src/middleware/softDeleteMiddleware.js @@ -13,13 +13,14 @@ const setDefaultFilters = (resolve, root, args, context, info) => { return resolve(root, args, context, info) } -const hideDisabledComments = async (resolve, root, args, context, info) => { - const { comments } = root - if (!Array.isArray(comments)) return resolve(root, args, context, info) - if (!isModerator(context)) { - root.comments = comments.filter((comment) => { - return !comment.disabled - }) +const obfuscateDisabled = async (resolve, root, args, context, info) => { + if (!isModerator(context) && root.disabled) { + root.content = 'DELETED' + root.contentExcerpt = 'DELETED' + root.title = 'DELETED' + root.image = 'DELETED' + root.avatar = 'DELETED' + root.about = 'DELETED' } return resolve(root, args, context, info) } @@ -38,6 +39,7 @@ export default { } return resolve(root, args, context, info) }, - Post: hideDisabledComments, - User: hideDisabledComments + Post: obfuscateDisabled, + User: obfuscateDisabled, + Comment: obfuscateDisabled } From dc9706caf35a42de84bded5ef411d3656fdaaf7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 12 Mar 2019 04:31:18 +0000 Subject: [PATCH 539/554] Bump jest from 24.3.1 to 24.4.0 Bumps [jest](https://github.com/facebook/jest) from 24.3.1 to 24.4.0. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/compare/v24.3.1...v24.4.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 514 ++++++++++++++++++++++----------------------------- 2 files changed, 217 insertions(+), 299 deletions(-) diff --git a/package.json b/package.json index 1da1f35c6..254b55e5d 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", "graphql-request": "~1.8.2", - "jest": "~24.3.1", + "jest": "~24.4.0", "nodemon": "~1.18.10", "nyc": "~13.3.0", "supertest": "~4.0.0" diff --git a/yarn.lock b/yarn.lock index afbc08dae..24b54ead3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -748,32 +748,32 @@ chalk "^2.0.1" slash "^2.0.0" -"@jest/core@^24.3.1": - version "24.3.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.3.1.tgz#9811596d9fcc6dbb3d4062c67e4c4867bc061585" - integrity sha512-orucOIBKfXgm1IJirtPT0ToprqDVGYKUNJKNc9a6v1Lww6qLPq+xj5OfxyhpJb2rWOgzEkATW1bfZzg3oqV70w== +"@jest/core@^24.5.0": + version "24.5.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.5.0.tgz#2cefc6a69e9ebcae1da8f7c75f8a257152ba1ec0" + integrity sha512-RDZArRzAs51YS7dXG1pbXbWGxK53rvUu8mCDYsgqqqQ6uSOaTjcVyBl2Jce0exT2rSLk38ca7az7t2f3b0/oYQ== dependencies: "@jest/console" "^24.3.0" - "@jest/reporters" "^24.3.1" - "@jest/test-result" "^24.3.0" - "@jest/transform" "^24.3.1" - "@jest/types" "^24.3.0" + "@jest/reporters" "^24.5.0" + "@jest/test-result" "^24.5.0" + "@jest/transform" "^24.5.0" + "@jest/types" "^24.5.0" ansi-escapes "^3.0.0" chalk "^2.0.1" exit "^0.1.2" graceful-fs "^4.1.15" - jest-changed-files "^24.3.0" - jest-config "^24.3.1" - jest-haste-map "^24.3.1" - jest-message-util "^24.3.0" + jest-changed-files "^24.5.0" + jest-config "^24.5.0" + jest-haste-map "^24.5.0" + jest-message-util "^24.5.0" jest-regex-util "^24.3.0" - jest-resolve-dependencies "^24.3.1" - jest-runner "^24.3.1" - jest-runtime "^24.3.1" - jest-snapshot "^24.3.1" - jest-util "^24.3.0" - jest-validate "^24.3.1" - jest-watcher "^24.3.0" + jest-resolve-dependencies "^24.5.0" + jest-runner "^24.5.0" + jest-runtime "^24.5.0" + jest-snapshot "^24.5.0" + jest-util "^24.5.0" + jest-validate "^24.5.0" + jest-watcher "^24.5.0" micromatch "^3.1.10" p-each-series "^1.0.0" pirates "^4.0.1" @@ -781,26 +781,16 @@ rimraf "^2.5.4" strip-ansi "^5.0.0" -"@jest/environment@^24.3.1": - version "24.3.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.3.1.tgz#1fbda3ec8fb8ffbaee665d314da91d662227e11e" - integrity sha512-M8bqEkQqPwZVhMMFMqqCnzqIZtuM5vDMfFQ9ZvnEfRT+2T1zTA4UAOH/V4HagEi6S3BCd/mdxFdYmPgXf7GKCA== +"@jest/environment@^24.5.0": + version "24.5.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.5.0.tgz#a2557f7808767abea3f9e4cc43a172122a63aca8" + integrity sha512-tzUHR9SHjMXwM8QmfHb/EJNbF0fjbH4ieefJBvtwO8YErLTrecc1ROj0uo2VnIT6SlpEGZnvdCK6VgKYBo8LsA== dependencies: - "@jest/fake-timers" "^24.3.0" - "@jest/transform" "^24.3.1" - "@jest/types" "^24.3.0" + "@jest/fake-timers" "^24.5.0" + "@jest/transform" "^24.5.0" + "@jest/types" "^24.5.0" "@types/node" "*" - jest-mock "^24.3.0" - -"@jest/fake-timers@^24.3.0": - version "24.3.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.3.0.tgz#0a7f8b877b78780c3fa5c3f8683cc0aaf9488331" - integrity sha512-rHwVI17dGMHxHzfAhnZ04+wFznjFfZ246QugeBnbiYr7/bDosPD2P1qeNjWnJUUcfl0HpS6kkr+OB/mqSJxQFg== - dependencies: - "@jest/types" "^24.3.0" - "@types/node" "*" - jest-message-util "^24.3.0" - jest-mock "^24.3.0" + jest-mock "^24.5.0" "@jest/fake-timers@^24.5.0": version "24.5.0" @@ -812,15 +802,15 @@ jest-message-util "^24.5.0" jest-mock "^24.5.0" -"@jest/reporters@^24.3.1": - version "24.3.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.3.1.tgz#68e4abc8d4233acd0dd87287f3bd270d81066248" - integrity sha512-jEIDJcvk20ReUW1Iqb+prlAcFV+kfFhQ/01poCq8X9As7/l/2y1GqVwJ3+6SaPTZuCXh0d0LVDy86zDAa8zlVA== +"@jest/reporters@^24.5.0": + version "24.5.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.5.0.tgz#9363a210d0daa74696886d9cb294eb8b3ad9b4d9" + integrity sha512-vfpceiaKtGgnuC3ss5czWOihKOUSyjJA4M4udm6nH8xgqsuQYcyDCi4nMMcBKsHXWgz9/V5G7iisnZGfOh1w6Q== dependencies: - "@jest/environment" "^24.3.1" - "@jest/test-result" "^24.3.0" - "@jest/transform" "^24.3.1" - "@jest/types" "^24.3.0" + "@jest/environment" "^24.5.0" + "@jest/test-result" "^24.5.0" + "@jest/transform" "^24.5.0" + "@jest/types" "^24.5.0" chalk "^2.0.1" exit "^0.1.2" glob "^7.1.2" @@ -828,11 +818,11 @@ istanbul-lib-coverage "^2.0.2" istanbul-lib-instrument "^3.0.1" istanbul-lib-source-maps "^3.0.1" - jest-haste-map "^24.3.1" - jest-resolve "^24.3.1" - jest-runtime "^24.3.1" - jest-util "^24.3.0" - jest-worker "^24.3.1" + jest-haste-map "^24.5.0" + jest-resolve "^24.5.0" + jest-runtime "^24.5.0" + jest-util "^24.5.0" + jest-worker "^24.4.0" node-notifier "^5.2.1" slash "^2.0.0" source-map "^0.6.0" @@ -847,15 +837,6 @@ graceful-fs "^4.1.15" source-map "^0.6.0" -"@jest/test-result@^24.3.0": - version "24.3.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.3.0.tgz#4c0b1c9716212111920f7cf8c4329c69bc81924a" - integrity sha512-j7UZ49T8C4CVipEY99nLttnczVTtLyVzFfN20OiBVn7awOs0U3endXSTq7ouPrLR5y4YjI5GDcbcvDUjgeamzg== - dependencies: - "@jest/console" "^24.3.0" - "@jest/types" "^24.3.0" - "@types/istanbul-lib-coverage" "^1.1.0" - "@jest/test-result@^24.5.0": version "24.5.0" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.5.0.tgz#ab66fb7741a04af3363443084e72ea84861a53f2" @@ -865,7 +846,7 @@ "@jest/types" "^24.5.0" "@types/istanbul-lib-coverage" "^1.1.0" -"@jest/transform@^24.3.1", "@jest/transform@^24.5.0": +"@jest/transform@^24.5.0": version "24.5.0" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.5.0.tgz#6709fc26db918e6af63a985f2cc3c464b4cf99d9" integrity sha512-XSsDz1gdR/QMmB8UCKlweAReQsZrD/DK7FuDlNo/pE8EcKMrfi2kqLRk8h8Gy/PDzgqJj64jNEzOce9pR8oj1w== @@ -886,7 +867,7 @@ source-map "^0.6.1" write-file-atomic "2.4.1" -"@jest/types@^24.3.0", "@jest/types@^24.5.0": +"@jest/types@^24.5.0": version "24.5.0" resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.5.0.tgz#feee214a4d0167b0ca447284e95a57aa10b3ee95" integrity sha512-kN7RFzNMf2R8UDadPOl6ReyI+MT8xfqRuAnuVL+i4gwjv/zubdDK+EDeLHYwq1j0CSSR2W/MmgaRlMZJzXdmVA== @@ -1721,7 +1702,7 @@ babel-eslint@~10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-jest@^24.3.1, babel-jest@~24.5.0: +babel-jest@^24.5.0, babel-jest@~24.5.0: version "24.5.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.5.0.tgz#0ea042789810c2bec9065f7c8ab4dc18e1d28559" integrity sha512-0fKCXyRwxFTJL0UXDJiT2xYxO9Lu2vBd9n+cC+eDjESzcVG3s2DRGAxbzJX21fceB1WYoBjAh8pQ83dKcl003g== @@ -2969,16 +2950,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.3.1.tgz#7c42507da231a91a8099d065bc8dc9322dc85fc0" - integrity sha512-xnmobSlaqhg4FKqjb5REk4AobQzFMJoctDdREKfSGqrtzRfCWYbfqt3WmikAvQz/J8mCNQhORgYdEjPMJbMQPQ== +expect@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.5.0.tgz#492fb0df8378d8474cc84b827776b069f46294ed" + integrity sha512-p2Gmc0CLxOgkyA93ySWmHFYHUPFIHG6XZ06l7WArWAsrqYVaVEkOU5NtT5i68KUyGKbkQgDCkiT65bWmdoL6Bw== dependencies: - "@jest/types" "^24.3.0" + "@jest/types" "^24.5.0" ansi-styles "^3.2.0" jest-get-type "^24.3.0" - jest-matcher-utils "^24.3.1" - jest-message-util "^24.3.0" + jest-matcher-utils "^24.5.0" + jest-message-util "^24.5.0" jest-regex-util "^24.3.0" express@^4.0.0, express@^4.16.3: @@ -4223,65 +4204,65 @@ iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2: resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== -jest-changed-files@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.3.0.tgz#7050ae29aaf1d59437c80f21d5b3cd354e88a499" - integrity sha512-fTq0YAUR6644fgsqLC7Zi2gXA/bAplMRvfXQdutmkwgrCKK6upkj+sgXqsUfUZRm15CVr3YSojr/GRNn71IMvg== +jest-changed-files@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.5.0.tgz#4075269ee115d87194fd5822e642af22133cf705" + integrity sha512-Ikl29dosYnTsH9pYa1Tv9POkILBhN/TLZ37xbzgNsZ1D2+2n+8oEZS2yP1BrHn/T4Rs4Ggwwbp/x8CKOS5YJOg== dependencies: - "@jest/types" "^24.3.0" + "@jest/types" "^24.5.0" execa "^1.0.0" throat "^4.0.0" -jest-cli@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.3.1.tgz#52e4ae5f11044b41e06ca39fc7a7302fbbcb1661" - integrity sha512-HdwMgigvDQdlWX7gwM2QMkJJRqSk7tTYKq7kVplblK28RarqquJMWV/lOCN8CukuG9u3DZTeXpCDXR7kpGfB3w== +jest-cli@^24.4.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.5.0.tgz#598139d3446d1942fb7dc93944b9ba766d756d4b" + integrity sha512-P+Jp0SLO4KWN0cGlNtC7JV0dW1eSFR7eRpoOucP2UM0sqlzp/bVHeo71Omonvigrj9AvCKy7NtQANtqJ7FXz8g== dependencies: - "@jest/core" "^24.3.1" - "@jest/test-result" "^24.3.0" - "@jest/types" "^24.3.0" + "@jest/core" "^24.5.0" + "@jest/test-result" "^24.5.0" + "@jest/types" "^24.5.0" chalk "^2.0.1" exit "^0.1.2" import-local "^2.0.0" is-ci "^2.0.0" - jest-config "^24.3.1" - jest-util "^24.3.0" - jest-validate "^24.3.1" + jest-config "^24.5.0" + jest-util "^24.5.0" + jest-validate "^24.5.0" prompts "^2.0.1" realpath-native "^1.1.0" yargs "^12.0.2" -jest-config@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.3.1.tgz#271aff2d3aeabf1ff92512024eeca3323cd31a07" - integrity sha512-ujHQywsM//vKFvJwEC02KNZgKAGOzGz1bFPezmTQtuj8XdfsAVq8p6N/dw4yodXV11gSf6TJ075i4ehM+mKatA== +jest-config@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.5.0.tgz#404d1bc6bb81aed6bd1890d07e2dca9fbba2e121" + integrity sha512-t2UTh0Z2uZhGBNVseF8wA2DS2SuBiLOL6qpLq18+OZGfFUxTM7BzUVKyHFN/vuN+s/aslY1COW95j1Rw81huOQ== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^24.3.0" - babel-jest "^24.3.1" + "@jest/types" "^24.5.0" + babel-jest "^24.5.0" chalk "^2.0.1" glob "^7.1.1" - jest-environment-jsdom "^24.3.1" - jest-environment-node "^24.3.1" + jest-environment-jsdom "^24.5.0" + jest-environment-node "^24.5.0" jest-get-type "^24.3.0" - jest-jasmine2 "^24.3.1" + jest-jasmine2 "^24.5.0" jest-regex-util "^24.3.0" - jest-resolve "^24.3.1" - jest-util "^24.3.0" - jest-validate "^24.3.1" + jest-resolve "^24.5.0" + jest-util "^24.5.0" + jest-validate "^24.5.0" micromatch "^3.1.10" - pretty-format "^24.3.1" + pretty-format "^24.5.0" realpath-native "^1.1.0" -jest-diff@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.3.1.tgz#87952e5ea1548567da91df398fa7bf7977d3f96a" - integrity sha512-YRVzDguyzShP3Pb9wP/ykBkV7Z+O4wltrMZ2P4LBtNxrHNpxwI2DECrpD9XevxWubRy5jcE8sSkxyX3bS7W+rA== +jest-diff@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.5.0.tgz#a2d8627964bb06a91893c0fbcb28ab228c257652" + integrity sha512-mCILZd9r7zqL9Uh6yNoXjwGQx0/J43OD2vvWVKwOEOLZliQOsojXwqboubAQ+Tszrb6DHGmNU7m4whGeB9YOqw== dependencies: chalk "^2.0.1" diff-sequences "^24.3.0" jest-get-type "^24.3.0" - pretty-format "^24.3.1" + pretty-format "^24.5.0" jest-docblock@^24.3.0: version "24.3.0" @@ -4290,60 +4271,45 @@ jest-docblock@^24.3.0: dependencies: detect-newline "^2.1.0" -jest-each@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.3.1.tgz#ed8fe8b9f92a835a6625ca8c7ee06bc904440316" - integrity sha512-GTi+nxDaWwSgOPLiiqb/p4LURy0mv3usoqsA2eoTYSmRsLgjgZ6VUyRpUBH5JY9EMBx33suNFXk0iyUm29WRpw== +jest-each@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.5.0.tgz#da14d017a1b7d0f01fb458d338314cafe7f72318" + integrity sha512-6gy3Kh37PwIT5sNvNY2VchtIFOOBh8UCYnBlxXMb5sr5wpJUDPTUATX2Axq1Vfk+HWTMpsYPeVYp4TXx5uqUBw== dependencies: - "@jest/types" "^24.3.0" + "@jest/types" "^24.5.0" chalk "^2.0.1" jest-get-type "^24.3.0" - jest-util "^24.3.0" - pretty-format "^24.3.1" + jest-util "^24.5.0" + pretty-format "^24.5.0" -jest-environment-jsdom@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.3.1.tgz#49826bcf12fb3e38895f1e2aaeb52bde603cc2e4" - integrity sha512-rz2OSYJiQerDqWDwjisqRwhVNpwkqFXdtyMzEuJ47Ip9NRpRQ+qy7/+zFujPUy/Z+zjWRO5seHLB/dOD4VpEVg== +jest-environment-jsdom@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.5.0.tgz#1c3143063e1374100f8c2723a8b6aad23b6db7eb" + integrity sha512-62Ih5HbdAWcsqBx2ktUnor/mABBo1U111AvZWcLKeWN/n/gc5ZvDBKe4Og44fQdHKiXClrNGC6G0mBo6wrPeGQ== dependencies: - "@jest/environment" "^24.3.1" - "@jest/fake-timers" "^24.3.0" - "@jest/types" "^24.3.0" - jest-mock "^24.3.0" - jest-util "^24.3.0" + "@jest/environment" "^24.5.0" + "@jest/fake-timers" "^24.5.0" + "@jest/types" "^24.5.0" + jest-mock "^24.5.0" + jest-util "^24.5.0" jsdom "^11.5.1" -jest-environment-node@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.3.1.tgz#333d864c569b27658a96bb3b10e02e7172125415" - integrity sha512-Xy+/yFem/yUs9OkzbcawQT237vwDjBhAVLjac1KYAMYVjGb0Vb/Ovw4g61PunVdrEIpfcXNtRUltM4+9c7lARQ== +jest-environment-node@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.5.0.tgz#763eebdf529f75b60aa600c6cf8cb09873caa6ab" + integrity sha512-du6FuyWr/GbKLsmAbzNF9mpr2Iu2zWSaq/BNHzX+vgOcts9f2ayXBweS7RAhr+6bLp6qRpMB6utAMF5Ygktxnw== dependencies: - "@jest/environment" "^24.3.1" - "@jest/fake-timers" "^24.3.0" - "@jest/types" "^24.3.0" - jest-mock "^24.3.0" - jest-util "^24.3.0" + "@jest/environment" "^24.5.0" + "@jest/fake-timers" "^24.5.0" + "@jest/types" "^24.5.0" + jest-mock "^24.5.0" + jest-util "^24.5.0" jest-get-type@^24.3.0: version "24.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.3.0.tgz#582cfd1a4f91b5cdad1d43d2932f816d543c65da" integrity sha512-HYF6pry72YUlVcvUx3sEpMRwXEWGEPlJ0bSPVnB3b3n++j4phUEoSPcS6GC0pPJ9rpyPSe4cb5muFo6D39cXow== -jest-haste-map@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.3.1.tgz#b4a66dbe1e6bc45afb9cd19c083bff81cdd535a1" - integrity sha512-OTMQle+astr1lWKi62Ccmk2YWn6OtUoU/8JpJdg8zdsnpFIry/k0S4sQ4nWocdM07PFdvqcthWc78CkCE6sXvA== - dependencies: - "@jest/types" "^24.3.0" - fb-watchman "^2.0.0" - graceful-fs "^4.1.15" - invariant "^2.2.4" - jest-serializer "^24.3.0" - jest-util "^24.3.0" - jest-worker "^24.3.1" - micromatch "^3.1.10" - sane "^4.0.3" - jest-haste-map@^24.5.0: version "24.5.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.5.0.tgz#3f17d0c548b99c0c96ed2893f9c0ccecb2eb9066" @@ -4359,58 +4325,44 @@ jest-haste-map@^24.5.0: micromatch "^3.1.10" sane "^4.0.3" -jest-jasmine2@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.3.1.tgz#127d628d3ac0829bd3c0fccacb87193e543b420b" - integrity sha512-STo6ar1IyPlIPq9jPxDQhM7lC0dAX7KKN0LmCLMlgJeXwX+1XiVdtZDv1a4zyg6qhNdpo1arOBGY0BcovUK7ug== +jest-jasmine2@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.5.0.tgz#e6af4d7f73dc527d007cca5a5b177c0bcc29d111" + integrity sha512-sfVrxVcx1rNUbBeyIyhkqZ4q+seNKyAG6iM0S2TYBdQsXjoFDdqWFfsUxb6uXSsbimbXX/NMkJIwUZ1uT9+/Aw== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.3.1" - "@jest/test-result" "^24.3.0" - "@jest/types" "^24.3.0" + "@jest/environment" "^24.5.0" + "@jest/test-result" "^24.5.0" + "@jest/types" "^24.5.0" chalk "^2.0.1" co "^4.6.0" - expect "^24.3.1" + expect "^24.5.0" is-generator-fn "^2.0.0" - jest-each "^24.3.1" - jest-matcher-utils "^24.3.1" - jest-message-util "^24.3.0" - jest-runtime "^24.3.1" - jest-snapshot "^24.3.1" - jest-util "^24.3.0" - pretty-format "^24.3.1" + jest-each "^24.5.0" + jest-matcher-utils "^24.5.0" + jest-message-util "^24.5.0" + jest-runtime "^24.5.0" + jest-snapshot "^24.5.0" + jest-util "^24.5.0" + pretty-format "^24.5.0" throat "^4.0.0" -jest-leak-detector@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.3.1.tgz#ed89d05ca07e91b2b51dac1f676ab354663aa8da" - integrity sha512-GncRwEtAw/SohdSyY4bk2RE06Ac1dZrtQGZQ2j35hSuN4gAAAKSYMszJS2WDixsAEaFN+GHBHG+d8pjVGklKyw== +jest-leak-detector@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.5.0.tgz#21ae2b3b0da252c1171cd494f75696d65fb6fa89" + integrity sha512-LZKBjGovFRx3cRBkqmIg+BZnxbrLqhQl09IziMk3oeh1OV81Hg30RUIx885mq8qBv1PA0comB9bjKcuyNO1bCQ== dependencies: - pretty-format "^24.3.1" + pretty-format "^24.5.0" -jest-matcher-utils@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.3.1.tgz#025e1cd9c54a5fde68e74b12428775d06d123aa8" - integrity sha512-P5VIsUTJeI0FYvWVMwEHjxK1L83vEkDiKMV0XFPIrT2jzWaWPB2+dPCHkP2ID9z4eUKElaHqynZnJiOdNVHfXQ== +jest-matcher-utils@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.5.0.tgz#5995549dcf09fa94406e89526e877b094dad8770" + integrity sha512-QM1nmLROjLj8GMGzg5VBra3I9hLpjMPtF1YqzQS3rvWn2ltGZLrGAO1KQ9zUCVi5aCvrkbS5Ndm2evIP9yZg1Q== dependencies: chalk "^2.0.1" - jest-diff "^24.3.1" + jest-diff "^24.5.0" jest-get-type "^24.3.0" - pretty-format "^24.3.1" - -jest-message-util@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.3.0.tgz#e8f64b63ebc75b1a9c67ee35553752596e70d4a9" - integrity sha512-lXM0YgKYGqN5/eH1NGw4Ix+Pk2I9Y77beyRas7xM24n+XTTK3TbT0VkT3L/qiyS7WkW0YwyxoXnnAaGw4hsEDA== - dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.3.0" - "@jest/types" "^24.3.0" - "@types/stack-utils" "^1.0.1" - chalk "^2.0.1" - micromatch "^3.1.10" - slash "^2.0.0" - stack-utils "^1.0.1" + pretty-format "^24.5.0" jest-message-util@^24.5.0: version "24.5.0" @@ -4426,13 +4378,6 @@ jest-message-util@^24.5.0: slash "^2.0.0" stack-utils "^1.0.1" -jest-mock@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.3.0.tgz#95a86b6ad474e3e33227e6dd7c4ff6b07e18d3cb" - integrity sha512-AhAo0qjbVWWGvcbW5nChFjR0ObQImvGtU6DodprNziDOt+pP0CBdht/sYcNIOXeim8083QUi9bC8QdKB8PTK4Q== - dependencies: - "@jest/types" "^24.3.0" - jest-mock@^24.5.0: version "24.5.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.5.0.tgz#976912c99a93f2a1c67497a9414aa4d9da4c7b76" @@ -4440,131 +4385,113 @@ jest-mock@^24.5.0: dependencies: "@jest/types" "^24.5.0" +jest-pnp-resolver@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" + integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== + jest-regex-util@^24.3.0: version "24.3.0" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36" integrity sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg== -jest-resolve-dependencies@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.3.1.tgz#a22839d611ba529a74594ee274ce2b77d046bea9" - integrity sha512-9JUejNImGnJjbNR/ttnod+zQIWANpsrYMPt18s2tYGK6rP191qFsyEQ2BhAQMdYDRkTmi8At+Co9tL+jTPqdpw== +jest-resolve-dependencies@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.5.0.tgz#1a0dae9cdd41349ca4a84148b3e78da2ba33fd4b" + integrity sha512-dRVM1D+gWrFfrq2vlL5P9P/i8kB4BOYqYf3S7xczZ+A6PC3SgXYSErX/ScW/469pWMboM1uAhgLF+39nXlirCQ== dependencies: - "@jest/types" "^24.3.0" + "@jest/types" "^24.5.0" jest-regex-util "^24.3.0" - jest-snapshot "^24.3.1" + jest-snapshot "^24.5.0" -jest-resolve@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.3.1.tgz#103dbd438b59618ea428ec4acbd65c56495ba397" - integrity sha512-N+Q3AcVuKxpn/kjQMxUVLwBk32ZE1diP4MPcHyjVwcKpCUuKrktfRR3Mqe/T2HoD25wyccstaqcPUKIudl41bg== +jest-resolve@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.5.0.tgz#8c16ba08f60a1616c3b1cd7afb24574f50a24d04" + integrity sha512-ZIfGqLX1Rg8xJpQqNjdoO8MuxHV1q/i2OO1hLXjgCWFWs5bsedS8UrOdgjUqqNae6DXA+pCyRmdcB7lQEEbXew== dependencies: - "@jest/types" "^24.3.0" + "@jest/types" "^24.5.0" browser-resolve "^1.11.3" chalk "^2.0.1" + jest-pnp-resolver "^1.2.1" realpath-native "^1.1.0" -jest-runner@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.3.1.tgz#5488566fa60cdb4b00a89c734ad6b54b9561415d" - integrity sha512-Etc9hQ5ruwg+q7DChm+E8qzHHdNTLeUdlo+whPQRSpNSgl0AEgc2r2mT4lxODREqmnHg9A8JHA44pIG4GE0Gzg== +jest-runner@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.5.0.tgz#9be26ece4fd4ab3dfb528b887523144b7c5ffca8" + integrity sha512-oqsiS9TkIZV5dVkD+GmbNfWBRPIvxqmlTQ+AQUJUQ07n+4xTSDc40r+aKBynHw9/tLzafC00DIbJjB2cOZdvMA== dependencies: "@jest/console" "^24.3.0" - "@jest/environment" "^24.3.1" - "@jest/test-result" "^24.3.0" - "@jest/types" "^24.3.0" + "@jest/environment" "^24.5.0" + "@jest/test-result" "^24.5.0" + "@jest/types" "^24.5.0" chalk "^2.4.2" exit "^0.1.2" graceful-fs "^4.1.15" - jest-config "^24.3.1" + jest-config "^24.5.0" jest-docblock "^24.3.0" - jest-haste-map "^24.3.1" - jest-jasmine2 "^24.3.1" - jest-leak-detector "^24.3.1" - jest-message-util "^24.3.0" - jest-resolve "^24.3.1" - jest-runtime "^24.3.1" - jest-util "^24.3.0" - jest-worker "^24.3.1" + jest-haste-map "^24.5.0" + jest-jasmine2 "^24.5.0" + jest-leak-detector "^24.5.0" + jest-message-util "^24.5.0" + jest-resolve "^24.5.0" + jest-runtime "^24.5.0" + jest-util "^24.5.0" + jest-worker "^24.4.0" source-map-support "^0.5.6" throat "^4.0.0" -jest-runtime@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.3.1.tgz#2798230b4fbed594b375a13e395278694d4751e2" - integrity sha512-Qz/tJWbZ2naFJ2Kvy1p+RhhRgsPYh4e6wddVRy6aHBr32FTt3Ja33bfV7pkMFWXFbVuAsJMJVdengbvdhWzq4A== +jest-runtime@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.5.0.tgz#3a76e0bfef4db3896d5116e9e518be47ba771aa2" + integrity sha512-GTFHzfLdwpaeoDPilNpBrorlPoNZuZrwKKzKJs09vWwHo+9TOsIIuszK8cWOuKC7ss07aN1922Ge8fsGdsqCuw== dependencies: "@jest/console" "^24.3.0" - "@jest/environment" "^24.3.1" + "@jest/environment" "^24.5.0" "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.3.1" - "@jest/types" "^24.3.0" + "@jest/transform" "^24.5.0" + "@jest/types" "^24.5.0" "@types/yargs" "^12.0.2" chalk "^2.0.1" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.1.15" - jest-config "^24.3.1" - jest-haste-map "^24.3.1" - jest-message-util "^24.3.0" - jest-mock "^24.3.0" + jest-config "^24.5.0" + jest-haste-map "^24.5.0" + jest-message-util "^24.5.0" + jest-mock "^24.5.0" jest-regex-util "^24.3.0" - jest-resolve "^24.3.1" - jest-snapshot "^24.3.1" - jest-util "^24.3.0" - jest-validate "^24.3.1" + jest-resolve "^24.5.0" + jest-snapshot "^24.5.0" + jest-util "^24.5.0" + jest-validate "^24.5.0" realpath-native "^1.1.0" slash "^2.0.0" strip-bom "^3.0.0" yargs "^12.0.2" -jest-serializer@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.3.0.tgz#074e307300d1451617cf2630d11543ee4f74a1c8" - integrity sha512-RiSpqo2OFbVLJN/PgAOwQIUeHDfss6NBUDTLhjiJM8Bb5rMrwRqHfkaqahIsOf9cXXB5UjcqDCzbQ7AIoMqWkg== - jest-serializer@^24.4.0: version "24.4.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3" integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q== -jest-snapshot@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.3.1.tgz#0f22a86c1b8c87e823f5ad095e82c19d9ed93d72" - integrity sha512-7wbNJWh0sBjmoaexTOWqS7nleTQME7o2W9XKU6CHCxG49Thjct4aVPC/QPNF5NHnvf4M/VDmudIDbwz6noJTRA== +jest-snapshot@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.5.0.tgz#e5d224468a759fd19e36f01217aac912f500f779" + integrity sha512-eBEeJb5ROk0NcpodmSKnCVgMOo+Qsu5z9EDl3tGffwPzK1yV37mjGWF2YeIz1NkntgTzP+fUL4s09a0+0dpVWA== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^24.3.0" + "@jest/types" "^24.5.0" chalk "^2.0.1" - expect "^24.3.1" - jest-diff "^24.3.1" - jest-matcher-utils "^24.3.1" - jest-message-util "^24.3.0" - jest-resolve "^24.3.1" + expect "^24.5.0" + jest-diff "^24.5.0" + jest-matcher-utils "^24.5.0" + jest-message-util "^24.5.0" + jest-resolve "^24.5.0" mkdirp "^0.5.1" natural-compare "^1.4.0" - pretty-format "^24.3.1" + pretty-format "^24.5.0" semver "^5.5.0" -jest-util@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.3.0.tgz#a549ae9910fedbd4c5912b204bb1bcc122ea0057" - integrity sha512-eKIAC+MTKWZthUUVOwZ3Tc5a0cKMnxalQHr6qZ4kPzKn6k09sKvsmjCygqZ1SxVVfUKoa8Sfn6XDv9uTJ1iXTg== - dependencies: - "@jest/console" "^24.3.0" - "@jest/fake-timers" "^24.3.0" - "@jest/source-map" "^24.3.0" - "@jest/test-result" "^24.3.0" - "@jest/types" "^24.3.0" - "@types/node" "*" - callsites "^3.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.15" - is-ci "^2.0.0" - mkdirp "^0.5.1" - slash "^2.0.0" - source-map "^0.6.0" - jest-util@^24.5.0: version "24.5.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.5.0.tgz#9d9cb06d9dcccc8e7cc76df91b1635025d7baa84" @@ -4584,41 +4511,32 @@ jest-util@^24.5.0: slash "^2.0.0" source-map "^0.6.0" -jest-validate@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.3.1.tgz#9359eea5a767a3d20b4fa7a5764fd78330ba8312" - integrity sha512-ww3+IPNCOEMi1oKlrHdSnBXetXtdrrdSh0bqLNTVkWglduhORf94RJWd1ko9oEPU2TcEQS5QIPacYziQIUzc4A== +jest-validate@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.5.0.tgz#62fd93d81214c070bb2d7a55f329a79d8057c7de" + integrity sha512-gg0dYszxjgK2o11unSIJhkOFZqNRQbWOAB2/LOUdsd2LfD9oXiMeuee8XsT0iRy5EvSccBgB4h/9HRbIo3MHgQ== dependencies: - "@jest/types" "^24.3.0" + "@jest/types" "^24.5.0" camelcase "^5.0.0" chalk "^2.0.1" jest-get-type "^24.3.0" leven "^2.1.0" - pretty-format "^24.3.1" + pretty-format "^24.5.0" -jest-watcher@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.3.0.tgz#ee51c6afbe4b35a12fcf1107556db6756d7b9290" - integrity sha512-EpJS/aUG8D3DMuy9XNA4fnkKWy3DQdoWhY92ZUdlETIeEn1xya4Np/96MBSh4II5YvxwKe6JKwbu3Bnzfwa7vA== +jest-watcher@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.5.0.tgz#da7bd9cb5967e274889b42078c8f501ae1c47761" + integrity sha512-/hCpgR6bg0nKvD3nv4KasdTxuhwfViVMHUATJlnGCD0r1QrmIssimPbmc5KfAQblAVxkD8xrzuij9vfPUk1/rA== dependencies: - "@jest/test-result" "^24.3.0" - "@jest/types" "^24.3.0" + "@jest/test-result" "^24.5.0" + "@jest/types" "^24.5.0" "@types/node" "*" "@types/yargs" "^12.0.9" ansi-escapes "^3.0.0" chalk "^2.0.1" - jest-util "^24.3.0" + jest-util "^24.5.0" string-length "^2.0.0" -jest-worker@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.3.1.tgz#c1759dd2b1d5541b09a2e5e1bc3288de6c9d8632" - integrity sha512-ZCoAe/iGLzTJvWHrO8fyx3bmEQhpL16SILJmWHKe8joHhyF3z00psF1sCRT54DoHw5GJG0ZpUtGy+ylvwA4haA== - dependencies: - "@types/node" "*" - merge-stream "^1.0.1" - supports-color "^6.1.0" - jest-worker@^24.4.0: version "24.4.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.4.0.tgz#fbc452b0120bb5c2a70cdc88fa132b48eeb11dd0" @@ -4628,13 +4546,13 @@ jest-worker@^24.4.0: merge-stream "^1.0.1" supports-color "^6.1.0" -jest@~24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.3.1.tgz#81959de0d57b2df923510f4fafe266712d37dcca" - integrity sha512-SqZguEbYNcZ3r0KUUBN+IkKfyPS1VBbIUiK4Wrc0AiGUR52gJa0fmlWSOCL3x25908QrfoQwkVDu5jCsfXb2ig== +jest@~24.4.0: + version "24.4.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.4.0.tgz#688b71a2dadd41e26d0cfc04e1ddcacf30a1efbb" + integrity sha512-gAGfjvu8hHN0N6/aDyCBpncWWBcpY6wq69Msq/I6Xd763q/ZYBEMh0SKUomrViFoJ/dyistA6b4aJh8e+5QMyw== dependencies: import-local "^2.0.0" - jest-cli "^24.3.1" + jest-cli "^24.4.0" jmespath@0.15.0: version "0.15.0" @@ -5884,12 +5802,12 @@ prepend-http@^1.0.1: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -pretty-format@^24.3.1: - version "24.3.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.3.1.tgz#ae4a98e93d73d86913a8a7dd1a7c3c900f8fda59" - integrity sha512-NZGH1NWS6o4i9pvRWLsxIK00JB9pqOUzVrO7yWT6vjI2thdxwvxefBJO6O5T24UAhI8P5dMceZ7x5wphgVI7Mg== +pretty-format@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.5.0.tgz#cc69a0281a62cd7242633fc135d6930cd889822d" + integrity sha512-/3RuSghukCf8Riu5Ncve0iI+BzVkbRU5EeUoArKARZobREycuH5O4waxvaNIloEXdb0qwgmEAed5vTpX1HNROQ== dependencies: - "@jest/types" "^24.3.0" + "@jest/types" "^24.5.0" ansi-regex "^4.0.0" ansi-styles "^3.2.0" react-is "^16.8.4" From 41ee83a9a873360bf659d0b5fbe0d29d329772fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 14 Mar 2019 04:16:57 +0000 Subject: [PATCH 540/554] Bump apollo-link-http from 1.5.12 to 1.5.13 Bumps [apollo-link-http](https://github.com/apollographql/apollo-link) from 1.5.12 to 1.5.13. - [Release notes](https://github.com/apollographql/apollo-link/releases) - [Changelog](https://github.com/apollographql/apollo-link/blob/master/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-link/compare/apollo-link-http@1.5.12...apollo-link-http@1.5.13) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 40 ++++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 254b55e5d..140fdc616 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "dependencies": { "apollo-cache-inmemory": "~1.5.1", "apollo-client": "~2.5.1", - "apollo-link-http": "~1.5.12", + "apollo-link-http": "~1.5.13", "apollo-server": "~2.4.8", "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.2", diff --git a/yarn.lock b/yarn.lock index 24b54ead3..c978f7a5e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1307,33 +1307,33 @@ apollo-link-dedup@^1.0.0: dependencies: apollo-link "^1.2.4" -apollo-link-http-common@^0.2.11: - version "0.2.11" - resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.11.tgz#d4e494ed1e45ea0e0c0ed60f3df64541d0de682d" - integrity sha512-FjtzEDiG6blH/2MR4fpVNoxdZUFmddP0sez34qnoLaYz6ABFbTDlmRE/dVN79nPExM4Spfs/DtW7KRqyjJ3tOg== +apollo-link-http-common@^0.2.12: + version "0.2.12" + resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.12.tgz#30cb42b6417076872d3e9e7699dbf79a9c9d7bee" + integrity sha512-jMgvp8ZURiaSivKLsB7J0uVKLNit5nPeFaxr85r6CsdS0HQB0tH+aqzblPQeMQ0zpR/EqX8YrogXFZ08y9kjYQ== dependencies: - apollo-link "^1.2.9" + apollo-link "^1.2.10" ts-invariant "^0.3.2" tslib "^1.9.3" -apollo-link-http@~1.5.12: - version "1.5.12" - resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.12.tgz#878d48bf9d8ae091752710529a222c4a5548118e" - integrity sha512-2tS36RIU6OdxzoWYTPrjvDTF2sCrnlaJ6SL7j0ILPn1Lmw4y6YLwKDsv/SWLwtodtVe9v1dLCGKIGMRMM/SdyA== +apollo-link-http@~1.5.13: + version "1.5.13" + resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.13.tgz#f7d6e1fda0009e0b623df1cbd83902fd71d34f67" + integrity sha512-e8pU/omWPy3pI3v+UKktFuG5YcjbA4jT0jUHo59U51vKszqw5xsYjCOQhw7IPoixYN651vkn122CQEFgL6MuvA== dependencies: - apollo-link "^1.2.9" - apollo-link-http-common "^0.2.11" + apollo-link "^1.2.10" + apollo-link-http-common "^0.2.12" tslib "^1.9.3" -apollo-link@^1.0.0, apollo-link@^1.2.3, apollo-link@^1.2.4, apollo-link@^1.2.9: - version "1.2.9" - resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.9.tgz#40a8f0b90716ce3fd6beb27b7eae1108b92e0054" - integrity sha512-ZLUwthOFZq4lxchQ2jeBfVqS/UDdcVmmh8aUw6Ar9awZH4r+RgkcDeu2ooFLUfodWE3mZr7wIZuYsBas/MaNVA== +apollo-link@^1.0.0, apollo-link@^1.2.10, apollo-link@^1.2.3, apollo-link@^1.2.4: + version "1.2.10" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.10.tgz#98cf24c46c0d75cb878804143e39dcf9813f0c20" + integrity sha512-vQ5u+jEHyLJaV+eUoVKFYYiJcCY9dBNSNhf7Ve9YxeFf84ZDt5NNOPXQEygF39qdoqFRYJb7OkAOJptydteOvw== dependencies: apollo-utilities "^1.2.1" ts-invariant "^0.3.2" tslib "^1.9.3" - zen-observable-ts "^0.8.16" + zen-observable-ts "^0.8.17" apollo-server-caching@0.3.1: version "0.3.1" @@ -7513,10 +7513,10 @@ yup@^0.26.10: synchronous-promise "^2.0.5" toposort "^2.0.2" -zen-observable-ts@^0.8.16: - version "0.8.16" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.16.tgz#969367299074fe17422fe2f46ee417e9a30cf3fa" - integrity sha512-pQl75N7qwgybKVsh6WFO+WwPRijeQ52Gn1vSf4uvPFXald9CbVQXLa5QrOPEJhdZiC+CD4quqOVqSG+Ptz5XLA== +zen-observable-ts@^0.8.17: + version "0.8.17" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.17.tgz#b3183625fa55d3960c829e3a90061f82ec2d7863" + integrity sha512-eVQH3UG5h4lMlD9HMMIsiMk3vsCW66QVOPJQMCSJhP4THswDW7r/BPHO6oCZbA/LZzntv2t8W/bv3vYO9NYh/g== dependencies: tslib "^1.9.3" zen-observable "^0.8.0" From 6b5afe0520878154cde7ab2c25d0ab04f2aba5fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 14 Mar 2019 04:17:11 +0000 Subject: [PATCH 541/554] Bump jest from 24.4.0 to 24.5.0 Bumps [jest](https://github.com/facebook/jest) from 24.4.0 to 24.5.0. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/compare/v24.4.0...v24.5.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 254b55e5d..45d0737bd 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "eslint-plugin-promise": "~4.0.1", "eslint-plugin-standard": "~4.0.0", "graphql-request": "~1.8.2", - "jest": "~24.4.0", + "jest": "~24.5.0", "nodemon": "~1.18.10", "nyc": "~13.3.0", "supertest": "~4.0.0" diff --git a/yarn.lock b/yarn.lock index 24b54ead3..cad225d99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4213,7 +4213,7 @@ jest-changed-files@^24.5.0: execa "^1.0.0" throat "^4.0.0" -jest-cli@^24.4.0: +jest-cli@^24.5.0: version "24.5.0" resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.5.0.tgz#598139d3446d1942fb7dc93944b9ba766d756d4b" integrity sha512-P+Jp0SLO4KWN0cGlNtC7JV0dW1eSFR7eRpoOucP2UM0sqlzp/bVHeo71Omonvigrj9AvCKy7NtQANtqJ7FXz8g== @@ -4546,13 +4546,13 @@ jest-worker@^24.4.0: merge-stream "^1.0.1" supports-color "^6.1.0" -jest@~24.4.0: - version "24.4.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.4.0.tgz#688b71a2dadd41e26d0cfc04e1ddcacf30a1efbb" - integrity sha512-gAGfjvu8hHN0N6/aDyCBpncWWBcpY6wq69Msq/I6Xd763q/ZYBEMh0SKUomrViFoJ/dyistA6b4aJh8e+5QMyw== +jest@~24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.5.0.tgz#38f11ae2c2baa2f86c2bc4d8a91d2b51612cd19a" + integrity sha512-lxL+Fq5/RH7inxxmfS2aZLCf8MsS+YCUBfeiNO6BWz/MmjhDGaIEA/2bzEf9q4Q0X+mtFHiinHFvQ0u+RvW/qQ== dependencies: import-local "^2.0.0" - jest-cli "^24.4.0" + jest-cli "^24.5.0" jmespath@0.15.0: version "0.15.0" From 582d2e5c4ea42aba396e46e0711fdc89275cad23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 14 Mar 2019 11:57:44 +0000 Subject: [PATCH 542/554] Bump dotenv from 6.2.0 to 7.0.0 Bumps [dotenv](https://github.com/motdotla/dotenv) from 6.2.0 to 7.0.0. - [Release notes](https://github.com/motdotla/dotenv/releases) - [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md) - [Commits](https://github.com/motdotla/dotenv/compare/v6.2.0...v7.0.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 343251848..5c596b910 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "cheerio": "~1.0.0-rc.2", "cross-env": "~5.2.0", "date-fns": "2.0.0-alpha.27", - "dotenv": "~6.2.0", + "dotenv": "~7.0.0", "faker": "~4.1.0", "graphql": "~14.1.1", "graphql-custom-directives": "~0.2.14", diff --git a/yarn.lock b/yarn.lock index 15d79aede..591428412 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2580,10 +2580,10 @@ dotenv@^0.4.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" integrity sha1-9vs1E2PC2SIHJFxzeALJq1rhSVo= -dotenv@~6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" - integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w== +dotenv@~7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-7.0.0.tgz#a2be3cd52736673206e8a85fb5210eea29628e7c" + integrity sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g== duplexer3@^0.1.4: version "0.1.4" From b04e922afc0ad2ce64c260d05bb166bbe8b5e53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 14 Mar 2019 16:24:16 +0100 Subject: [PATCH 543/554] Disabled users are unauthenticated --- src/jwt/decode.js | 3 ++- src/resolvers/user_management.spec.js | 29 ++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/jwt/decode.js b/src/jwt/decode.js index 0ab1e4529..6abc06dc1 100644 --- a/src/jwt/decode.js +++ b/src/jwt/decode.js @@ -13,7 +13,7 @@ export default async (driver, authorizationHeader) => { const session = driver.session() const query = ` MATCH (user:User {id: {id} }) - RETURN user {.id, .slug, .name, .avatar, .email, .role} as user + RETURN user {.id, .slug, .name, .avatar, .email, .role, .disabled} LIMIT 1 ` const result = await session.run(query, { id }) @@ -22,6 +22,7 @@ export default async (driver, authorizationHeader) => { return record.get('user') }) if (!currentUser) return null + if (currentUser.disabled) return null return { token, ...currentUser diff --git a/src/resolvers/user_management.spec.js b/src/resolvers/user_management.spec.js index c4b09df37..6df1b1626 100644 --- a/src/resolvers/user_management.spec.js +++ b/src/resolvers/user_management.spec.js @@ -73,11 +73,30 @@ describe('isLoggedIn', () => { }) describe('and a corresponding user in the database', () => { - it('returns true', async () => { - // see the decoded token above - await factory.create('User', { id: 'u3' }) - await expect(client.request(query)).resolves.toEqual({ - isLoggedIn: true + describe('user is enabled', () => { + it('returns true', async () => { + // see the decoded token above + await factory.create('User', { id: 'u3' }) + await expect(client.request(query)).resolves.toEqual({ + isLoggedIn: true + }) + }) + }) + + describe('user is disabled', () => { + beforeEach(async () => { + const moderatorParams = { email: 'moderator@example.org', role: 'moderator', password: '1234' } + const asModerator = Factory() + await asModerator.create('User', moderatorParams) + await asModerator.authenticateAs(moderatorParams) + await factory.create('User', { id: 'u3' }) + await asModerator.mutate('mutation($id: ID!) { disable(id: $id) }', { id: 'u3' }) + }) + + it('returns false', async () => { + await expect(client.request(query)).resolves.toEqual({ + isLoggedIn: false + }) }) }) }) From b0ce023f49eb5c7c17d323ab7cec2c16a5e2d2c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 14 Mar 2019 16:44:22 +0100 Subject: [PATCH 544/554] Create failing test @abdellani your turn :muscle: --- src/resolvers/user_management.spec.js | 29 ++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/resolvers/user_management.spec.js b/src/resolvers/user_management.spec.js index 6df1b1626..1c21adac1 100644 --- a/src/resolvers/user_management.spec.js +++ b/src/resolvers/user_management.spec.js @@ -26,6 +26,14 @@ const jennyRostocksHeaders = { 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoidXNlciIsImxvY2F0aW9uTmFtZSI6bnVsbCwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJhYm91dCI6bnVsbCwiYXZhdGFyIjoiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3VpZmFjZXMvZmFjZXMvdHdpdHRlci9zYXNoYV9zaGVzdGFrb3YvMTI4LmpwZyIsImlkIjoidTMiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5vcmciLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTU1MDg0NjY4MCwiZXhwIjoxNjM3MjQ2NjgwLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.eZ_mVKas4Wzoc_JrQTEWXyRn7eY64cdIg4vqQ-F_7Jc' } +const disable = async (id) => { + const moderatorParams = { email: 'moderator@example.org', role: 'moderator', password: '1234' } + const asModerator = Factory() + await asModerator.create('User', moderatorParams) + await asModerator.authenticateAs(moderatorParams) + await asModerator.mutate('mutation($id: ID!) { disable(id: $id) }', { id }) +} + beforeEach(async () => { await factory.create('User', { avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/jimmuirhead/128.jpg', @@ -85,12 +93,8 @@ describe('isLoggedIn', () => { describe('user is disabled', () => { beforeEach(async () => { - const moderatorParams = { email: 'moderator@example.org', role: 'moderator', password: '1234' } - const asModerator = Factory() - await asModerator.create('User', moderatorParams) - await asModerator.authenticateAs(moderatorParams) await factory.create('User', { id: 'u3' }) - await asModerator.mutate('mutation($id: ID!) { disable(id: $id) }', { id: 'u3' }) + await disable('u3') }) it('returns false', async () => { @@ -187,6 +191,21 @@ describe('login', () => { }) }) + describe('valid email/password but user is disabled', () => { + it('responds with "Your account has been disabled."', async () => { + await disable('acb2d923-f3af-479e-9f00-61b12e864666') + await expect( + request( + host, + mutation({ + email: 'test@example.org', + password: '1234' + }) + ) + ).rejects.toThrow('Your account has been disabled.') + }) + }) + describe('with a valid email but incorrect password', () => { it('responds with "Incorrect email address or password."', async () => { await expect( From b4372dff36562c61b8c49da9751b809e9bd7ddbb Mon Sep 17 00:00:00 2001 From: abdellani Date: Fri, 15 Mar 2019 14:59:36 +0100 Subject: [PATCH 545/554] Show error message when a disabled user tries to authenticate --- src/resolvers/user_management.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/resolvers/user_management.js b/src/resolvers/user_management.js index 36865646f..ebb50f0b1 100644 --- a/src/resolvers/user_management.js +++ b/src/resolvers/user_management.js @@ -32,7 +32,7 @@ export default { const session = driver.session() const result = await session.run( 'MATCH (user:User {email: $userEmail}) ' + - 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role} as user LIMIT 1', + 'RETURN user {.id, .slug, .name, .avatar, .email, .password, .role, .disabled} as user LIMIT 1', { userEmail: email } @@ -45,11 +45,18 @@ export default { if ( currentUser && - (await bcrypt.compareSync(password, currentUser.password)) + (await bcrypt.compareSync(password, currentUser.password)) && + currentUser.disabled == false ) { delete currentUser.password return encode(currentUser) - } else { + } + else if (currentUser && + currentUser.disabled + ){ + throw new AuthenticationError('Your account has been disabled.') + } + else { throw new AuthenticationError('Incorrect email address or password.') } }, From b7cc18ee98e568cdf31ba41d3eafd21344a421db Mon Sep 17 00:00:00 2001 From: abdellani Date: Fri, 15 Mar 2019 18:33:07 +0100 Subject: [PATCH 546/554] Show error message when a disabled user tries to authenticate --- src/resolvers/user_management.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/resolvers/user_management.js b/src/resolvers/user_management.js index ebb50f0b1..c81d12c37 100644 --- a/src/resolvers/user_management.js +++ b/src/resolvers/user_management.js @@ -46,17 +46,15 @@ export default { if ( currentUser && (await bcrypt.compareSync(password, currentUser.password)) && - currentUser.disabled == false + !currentUser.disabled ) { delete currentUser.password return encode(currentUser) - } - else if (currentUser && + } else if (currentUser && currentUser.disabled - ){ + ) { throw new AuthenticationError('Your account has been disabled.') - } - else { + } else { throw new AuthenticationError('Incorrect email address or password.') } }, From eacb0a452e8fd6bc7f44e056a5373189376d6e84 Mon Sep 17 00:00:00 2001 From: abdellani Date: Fri, 15 Mar 2019 18:33:07 +0100 Subject: [PATCH 547/554] Show error message when a disabled user tries to authenticate --- src/resolvers/user_management.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/resolvers/user_management.js b/src/resolvers/user_management.js index ebb50f0b1..26dfb81db 100644 --- a/src/resolvers/user_management.js +++ b/src/resolvers/user_management.js @@ -46,17 +46,15 @@ export default { if ( currentUser && (await bcrypt.compareSync(password, currentUser.password)) && - currentUser.disabled == false + !currentUser.disabled ) { delete currentUser.password return encode(currentUser) - } - else if (currentUser && + } else if (currentUser && currentUser.disabled - ){ + ) { throw new AuthenticationError('Your account has been disabled.') - } - else { + } else { throw new AuthenticationError('Incorrect email address or password.') } }, From d0fd20e790efdf6805ed74f3997e98f519a51e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Mar 2019 20:36:18 +0100 Subject: [PATCH 548/554] Obfuscate user name and use a neutral replacement --- src/middleware/softDeleteMiddleware.js | 13 +++++------ src/middleware/softDeleteMiddleware.spec.js | 24 +++++++++++---------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/middleware/softDeleteMiddleware.js b/src/middleware/softDeleteMiddleware.js index 24105c435..53beca219 100644 --- a/src/middleware/softDeleteMiddleware.js +++ b/src/middleware/softDeleteMiddleware.js @@ -15,12 +15,13 @@ const setDefaultFilters = (resolve, root, args, context, info) => { const obfuscateDisabled = async (resolve, root, args, context, info) => { if (!isModerator(context) && root.disabled) { - root.content = 'DELETED' - root.contentExcerpt = 'DELETED' - root.title = 'DELETED' - root.image = 'DELETED' - root.avatar = 'DELETED' - root.about = 'DELETED' + root.content = 'UNAVAILABLE' + root.contentExcerpt = 'UNAVAILABLE' + root.title = 'UNAVAILABLE' + root.image = 'UNAVAILABLE' + root.avatar = 'UNAVAILABLE' + root.about = 'UNAVAILABLE' + root.name = 'UNAVAILABLE' } return resolve(root, args, context, info) } diff --git a/src/middleware/softDeleteMiddleware.spec.js b/src/middleware/softDeleteMiddleware.spec.js index 6b8b4bc49..46005a4ff 100644 --- a/src/middleware/softDeleteMiddleware.spec.js +++ b/src/middleware/softDeleteMiddleware.spec.js @@ -12,7 +12,7 @@ beforeAll(async () => { await Promise.all([ factory.create('User', { id: 'u1', role: 'user', email: 'user@example.org', password: '1234' }), factory.create('User', { id: 'm1', role: 'moderator', email: 'moderator@example.org', password: '1234' }), - factory.create('User', { id: 'u2', role: 'user', avatar: '/some/offensive/avatar.jpg', about: 'This self description is very offensive', email: 'troll@example.org', password: '1234' }) + factory.create('User', { id: 'u2', role: 'user', name: 'Offensive Name', avatar: '/some/offensive/avatar.jpg', about: 'This self description is very offensive', email: 'troll@example.org', password: '1234' }) ]) await factory.authenticateAs({ email: 'user@example.org', password: '1234' }) @@ -62,7 +62,7 @@ describe('softDeleteMiddleware', () => { comment = response.User[0].following[0].comments[0] } const beforeUser = async () => { - query = '{ User(id: "u1") { following { about avatar } } }' + query = '{ User(id: "u1") { following { name about avatar } } }' const response = await action() user = response.User[0].following[0] } @@ -85,6 +85,7 @@ describe('softDeleteMiddleware', () => { describe('User', () => { beforeEach(beforeUser) + it('displays name', () => expect(user.name).toEqual('Offensive Name')) it('displays about', () => expect(user.about).toEqual('This self description is very offensive')) it('displays avatar', () => expect(user.avatar).toEqual('/some/offensive/avatar.jpg')) }) @@ -115,24 +116,25 @@ describe('softDeleteMiddleware', () => { describe('User', () => { beforeEach(beforeUser) - it('obfuscates about', () => expect(user.about).toEqual('DELETED')) - it('obfuscates avatar', () => expect(user.avatar).toEqual('DELETED')) + it('displays name', () => expect(user.name).toEqual('UNAVAILABLE')) + it('obfuscates about', () => expect(user.about).toEqual('UNAVAILABLE')) + it('obfuscates avatar', () => expect(user.avatar).toEqual('UNAVAILABLE')) }) describe('Post', () => { beforeEach(beforePost) - it('obfuscates title', () => expect(post.title).toEqual('DELETED')) - it('obfuscates content', () => expect(post.content).toEqual('DELETED')) - it('obfuscates contentExcerpt', () => expect(post.contentExcerpt).toEqual('DELETED')) - it('obfuscates image', () => expect(post.image).toEqual('DELETED')) + it('obfuscates title', () => expect(post.title).toEqual('UNAVAILABLE')) + it('obfuscates content', () => expect(post.content).toEqual('UNAVAILABLE')) + it('obfuscates contentExcerpt', () => expect(post.contentExcerpt).toEqual('UNAVAILABLE')) + it('obfuscates image', () => expect(post.image).toEqual('UNAVAILABLE')) }) describe('Comment', () => { beforeEach(beforeComment) - it('obfuscates content', () => expect(comment.content).toEqual('DELETED')) - it('obfuscates contentExcerpt', () => expect(comment.contentExcerpt).toEqual('DELETED')) + it('obfuscates content', () => expect(comment.content).toEqual('UNAVAILABLE')) + it('obfuscates contentExcerpt', () => expect(comment.contentExcerpt).toEqual('UNAVAILABLE')) }) }) }) @@ -185,7 +187,7 @@ describe('softDeleteMiddleware', () => { it('conceals disabled comments', async () => { const expected = [ { content: 'Enabled comment on public post' }, - { content: 'DELETED' } + { content: 'UNAVAILABLE' } ] const { Post: [{ comments }] } = await action() await expect(comments).toEqual(expect.arrayContaining(expected)) From 71ed58de3aca7440e65216f5f9873ef3d5190fd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 15 Mar 2019 20:47:33 +0100 Subject: [PATCH 549/554] Create a nice discussion on the most recent post --- src/seed/seed-db.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/seed/seed-db.js b/src/seed/seed-db.js index d526518b9..3de70e643 100644 --- a/src/seed/seed-db.js +++ b/src/seed/seed-db.js @@ -191,7 +191,12 @@ import Factory from './factories' f.create('Comment', { id: 'c4' }), f.create('Comment', { id: 'c5' }), f.create('Comment', { id: 'c6' }), - f.create('Comment', { id: 'c7' }) + f.create('Comment', { id: 'c7' }), + f.create('Comment', { id: 'c8' }), + f.create('Comment', { id: 'c9' }), + f.create('Comment', { id: 'c10' }), + f.create('Comment', { id: 'c11' }), + f.create('Comment', { id: 'c12' }) ]) await Promise.all([ @@ -208,7 +213,17 @@ import Factory from './factories' f.relate('Comment', 'Author', { from: 'u3', to: 'c6' }), f.relate('Comment', 'Post', { from: 'c6', to: 'p4' }), f.relate('Comment', 'Author', { from: 'u2', to: 'c7' }), - f.relate('Comment', 'Post', { from: 'c7', to: 'p2' }) + f.relate('Comment', 'Post', { from: 'c7', to: 'p2' }), + f.relate('Comment', 'Author', { from: 'u5', to: 'c8' }), + f.relate('Comment', 'Post', { from: 'c8', to: 'p15' }), + f.relate('Comment', 'Author', { from: 'u6', to: 'c9' }), + f.relate('Comment', 'Post', { from: 'c9', to: 'p15' }), + f.relate('Comment', 'Author', { from: 'u7', to: 'c10' }), + f.relate('Comment', 'Post', { from: 'c10', to: 'p15' }), + f.relate('Comment', 'Author', { from: 'u5', to: 'c11' }), + f.relate('Comment', 'Post', { from: 'c11', to: 'p15' }), + f.relate('Comment', 'Author', { from: 'u6', to: 'c12' }), + f.relate('Comment', 'Post', { from: 'c12', to: 'p15' }) ]) const disableMutation = 'mutation($id: ID!) { disable(id: $id) }' From 7a4f10395cd48e4bb38edfae897770010819b8d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 19 Mar 2019 04:38:09 +0000 Subject: [PATCH 550/554] Bump jsonwebtoken from 8.5.0 to 8.5.1 Bumps [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) from 8.5.0 to 8.5.1. - [Release notes](https://github.com/auth0/node-jsonwebtoken/releases) - [Changelog](https://github.com/auth0/node-jsonwebtoken/blob/master/CHANGELOG.md) - [Commits](https://github.com/auth0/node-jsonwebtoken/compare/v8.5.0...v8.5.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 5c596b910..bc5b1a1df 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "graphql-shield": "~5.3.0", "graphql-tag": "~2.10.1", "graphql-yoga": "~1.17.4", - "jsonwebtoken": "~8.5.0", + "jsonwebtoken": "~8.5.1", "linkifyjs": "~2.1.8", "lodash": "~4.17.11", "ms": "~2.1.1", diff --git a/yarn.lock b/yarn.lock index 591428412..d88dc494e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4675,12 +4675,12 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= -jsonwebtoken@^8.3.0, jsonwebtoken@~8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#ebd0ca2a69797816e1c5af65b6c759787252947e" - integrity sha512-IqEycp0znWHNA11TpYi77bVgyBO/pGESDh7Ajhas+u0ttkGkKYIIAjniL4Bw5+oVejVF+SYkaI7XKfwCCyeTuA== +jsonwebtoken@^8.3.0, jsonwebtoken@~8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== dependencies: - jws "^3.2.1" + jws "^3.2.2" lodash.includes "^4.3.0" lodash.isboolean "^3.0.3" lodash.isinteger "^4.0.4" @@ -4701,21 +4701,21 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jwa@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.3.0.tgz#061a7c3bb8ab2b3434bb2f432005a8bb7fca0efa" - integrity sha512-SxObIyzv9a6MYuZYaSN6DhSm9j3+qkokwvCB0/OTSV5ylPq1wUQiygZQcHT5Qlux0I5kmISx3J86TxKhuefItg== +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== dependencies: buffer-equal-constant-time "1.0.1" ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" -jws@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.1.tgz#d79d4216a62c9afa0a3d5e8b5356d75abdeb2be5" - integrity sha512-bGA2omSrFUkd72dhh05bIAN832znP4wOU3lfuXtRBuGTbsmNmDXMQg28f0Vsxaxgk4myF5YkKQpz6qeRpMgX9g== +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== dependencies: - jwa "^1.2.0" + jwa "^1.4.1" safe-buffer "^5.0.1" kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: From a9963fb1a9c4a948a77dedc261bb266b808f54f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 19 Mar 2019 21:24:11 +0100 Subject: [PATCH 551/554] Bundle all activityPub in middleware This way we can disable it for the seeder server which does not need to create RSA keys for all created users --- src/middleware/activityPubMiddleware.js | 18 ++++++++++++++++++ src/middleware/index.js | 2 ++ src/middleware/userMiddleware.js | 4 ---- src/resolvers/posts.js | 3 --- 4 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 src/middleware/activityPubMiddleware.js diff --git a/src/middleware/activityPubMiddleware.js b/src/middleware/activityPubMiddleware.js new file mode 100644 index 000000000..2fcd04729 --- /dev/null +++ b/src/middleware/activityPubMiddleware.js @@ -0,0 +1,18 @@ +import { generateRsaKeyPair } from '../activitypub/security' +import { activityPub } from '../activitypub/ActivityPub' + +export default { + Mutation: { + CreatePost: async (resolve, root, args, context, info) => { + args.activityId = activityPub.generateStatusId(context.user.slug) + args.objectId = activityPub.generateStatusId(context.user.slug) + return resolve(root, args, context, info) + }, + CreateUser: async (resolve, root, args, context, info) => { + const keys = generateRsaKeyPair() + Object.assign(args, keys) + args.actorId = `${process.env.GRAPHQL_URI}/activitypub/users/${args.slug}` + return resolve(root, args, context, info) + } + } +} diff --git a/src/middleware/index.js b/src/middleware/index.js index 6f95c7451..6ed0955e8 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -1,3 +1,4 @@ +import activityPubMiddleware from './activityPubMiddleware' import passwordMiddleware from './passwordMiddleware' import softDeleteMiddleware from './softDeleteMiddleware' import sluggifyMiddleware from './sluggifyMiddleware' @@ -25,6 +26,7 @@ export default schema => { // add permisions middleware at the first position (unless we're seeding) // NOTE: DO NOT SET THE PERMISSION FLAT YOUR SELF if (process.env.PERMISSIONS !== 'disabled' && process.env.NODE_ENV !== 'production') { + middleware.unshift(activityPubMiddleware) middleware.unshift(permissionsMiddleware.generate(schema)) } return middleware diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index a85bd1244..2979fdadf 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -1,5 +1,4 @@ import createOrUpdateLocations from './nodes/locations' -import { generateRsaKeyPair } from '../activitypub/security' import dotenv from 'dotenv' dotenv.config() @@ -7,9 +6,6 @@ dotenv.config() export default { Mutation: { CreateUser: async (resolve, root, args, context, info) => { - const keys = generateRsaKeyPair() - Object.assign(args, keys) - args.actorId = `${process.env.GRAPHQL_URI}/activitypub/users/${args.slug}` const result = await resolve(root, args, context, info) await createOrUpdateLocations(args.id, args.locationName, context.driver) return result diff --git a/src/resolvers/posts.js b/src/resolvers/posts.js index b7a6d8a2a..de5cd8282 100644 --- a/src/resolvers/posts.js +++ b/src/resolvers/posts.js @@ -1,5 +1,4 @@ import { neo4jgraphql } from 'neo4j-graphql-js' -import { activityPub } from '../activitypub/ActivityPub' import as from 'activitystrea.ms' import dotenv from 'dotenv' /* @@ -13,8 +12,6 @@ dotenv.config() export default { Mutation: { CreatePost: async (object, params, context, resolveInfo) => { - params.activityId = activityPub.generateStatusId(context.user.slug) - params.objectId = activityPub.generateStatusId(context.user.slug) const result = await neo4jgraphql(object, params, context, resolveInfo, false) const session = context.driver.session() From c2c9e98787b55f02b7a0c004193bac4492483c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Mar 2019 12:33:10 +0100 Subject: [PATCH 552/554] Fix http signature unit test --- .../security/httpSignature.spec.js | 131 ++++++++++-------- src/activitypub/security/index.js | 15 +- src/activitypub/utils/index.js | 7 +- 3 files changed, 88 insertions(+), 65 deletions(-) diff --git a/src/activitypub/security/httpSignature.spec.js b/src/activitypub/security/httpSignature.spec.js index fe09eda8a..bddb05ea9 100644 --- a/src/activitypub/security/httpSignature.spec.js +++ b/src/activitypub/security/httpSignature.spec.js @@ -1,69 +1,84 @@ -import { createSignature, verifySignature } from '.' -import Factory from '../../seed/factories' -import { host, login } from '../../jest/helpers' -import { GraphQLClient } from 'graphql-request' +import { generateRsaKeyPair, createSignature, verifySignature } from '.' import crypto from 'crypto' -import { expect } from 'chai' -const factory = Factory() +jest.mock('request') +import request from 'request' -describe('Signature creation and verification', () => { - let user = null - let client = null - const headers = { - 'Date': '2019-03-08T14:35:45.759Z', - 'Host': 'democracy-app.de', - 'Content-Type': 'application/json' - } +let privateKey +let publicKey +let headers +const passphrase = "a7dsf78sadg87ad87sfagsadg78" - beforeEach(async () => { - await factory.create('User', { - 'slug': 'test-user', - 'name': 'Test User', - 'email': 'user@example.org', - 'password': 'swordfish' +describe('activityPub/security', () => { + beforeEach(() => { + const pair = generateRsaKeyPair({passphrase}) + privateKey = pair.privateKey + publicKey = pair.publicKey + headers = { + 'Date': '2019-03-08T14:35:45.759Z', + 'Host': 'democracy-app.de', + 'Content-Type': 'application/json' + } + }) + + describe('createSignature', () => { + describe('returned http signature', () => { + let signatureB64 + let httpSignature + + beforeEach(() => { + const signer = crypto.createSign('rsa-sha256') + signer.update('(request-target): post /activitypub/users/max/inbox\ndate: 2019-03-08T14:35:45.759Z\nhost: democracy-app.de\ncontent-type: application/json') + signatureB64 = signer.sign({ key: privateKey, passphrase: 'a7dsf78sadg87ad87sfagsadg78' }, 'base64') + httpSignature = createSignature({privateKey, keyId: 'https://human-connection.org/activitypub/users/lea#main-key', url: 'https://democracy-app.de/activitypub/users/max/inbox', headers, passphrase}) + }) + + it('contains keyId', () => { + expect(httpSignature).toContain('keyId="https://human-connection.org/activitypub/users/lea#main-key"') + }) + + it('contains default algorithm "rsa-sha256"', () => { + expect(httpSignature).toContain('algorithm="rsa-sha256"') + }) + + it('contains headers', () => { + expect(httpSignature).toContain('headers="(request-target) date host content-type"') + }) + + it('contains signature', () => { + expect(httpSignature).toContain('signature="' + signatureB64 + '"') + }) }) - const headers = await login({ email: 'user@example.org', password: 'swordfish' }) - client = new GraphQLClient(host, { headers }) - const result = await client.request(`query { - User(slug: "test-user") { - privateKey - publicKey + }) + + describe('verifySignature', () => { + let httpSignature + + beforeEach(() => { + httpSignature = createSignature({privateKey, keyId: 'http://localhost:4001/activitypub/users/test-user#main-key', url: 'https://democracy-app.de/activitypub/users/max/inbox', headers, passphrase}) + const body = { + "publicKey":{ + "id":"https://localhost:4001/activitypub/users/test-user#main-key", + "owner":"https://localhost:4001/activitypub/users/test-user", + "publicKeyPem": publicKey + } } - }`) - user = result.User[0] - }) - afterEach(async () => { - await factory.cleanDatabase() - }) - - describe('Signature creation', () => { - let signatureB64 = '' - beforeEach(() => { - const signer = crypto.createSign('rsa-sha256') - signer.update('(request-target): post /activitypub/users/max/inbox\ndate: 2019-03-08T14:35:45.759Z\nhost: democracy-app.de\ncontent-type: application/json') - signatureB64 = signer.sign({ key: user.privateKey, passphrase: 'a7dsf78sadg87ad87sfagsadg78' }, 'base64') - }) - it('creates a Signature with given privateKey, keyId, url and headers (default algorithm: "rsa-sha256")', () => { - const httpSignature = createSignature(user.privateKey, 'https://human-connection.org/activitypub/users/lea#main-key', 'https://democracy-app.de/activitypub/users/max/inbox', headers) - - expect(httpSignature).to.contain('keyId="https://human-connection.org/activitypub/users/lea#main-key"') - expect(httpSignature).to.contain('algorithm="rsa-sha256"') - expect(httpSignature).to.contain('headers="(request-target) date host content-type"') - expect(httpSignature).to.contain('signature="' + signatureB64 + '"') - }) - }) - - describe('Signature verification', () => { - let httpSignature = '' - beforeEach(() => { - httpSignature = createSignature(user.privateKey, 'http://localhost:4001/activitypub/users/test-user#main-key', 'https://democracy-app.de/activitypub/users/max/inbox', headers) + const mockedRequest = jest.fn((_, callback) => callback(null, null, JSON.stringify(body))) + request.mockImplementation(mockedRequest) }) - it('verifies a Signature correct', async () => { - headers['Signature'] = httpSignature - const isVerified = await verifySignature('https://democracy-app.de/activitypub/users/max/inbox', headers) - expect(isVerified).to.equal(true) + it('resolves false', async () => { + await expect(verifySignature('https://democracy-app.de/activitypub/users/max/inbox', headers)).resolves.toEqual(false) + }) + + describe('valid signature', () => { + beforeEach(() => { + headers.Signature = httpSignature + }) + + it('resolves true', async () => { + await expect(verifySignature('https://democracy-app.de/activitypub/users/max/inbox', headers)).resolves.toEqual(true) + }) }) }) }) diff --git a/src/activitypub/security/index.js b/src/activitypub/security/index.js index 412084022..fdb1e27c6 100644 --- a/src/activitypub/security/index.js +++ b/src/activitypub/security/index.js @@ -6,7 +6,8 @@ const debug = require('debug')('ea:security') dotenv.config({ path: resolve('src', 'activitypub', '.env') }) -export function generateRsaKeyPair () { +export function generateRsaKeyPair (options = {}) { + const { passphrase = process.env.PRIVATE_KEY_PASSPHRASE } = options return crypto.generateKeyPairSync('rsa', { modulusLength: 4096, publicKeyEncoding: { @@ -17,18 +18,24 @@ export function generateRsaKeyPair () { type: 'pkcs8', format: 'pem', cipher: 'aes-256-cbc', - passphrase: process.env.PRIVATE_KEY_PASSPHRASE + passphrase } }) } // signing -export function createSignature (privKey, keyId, url, headers = {}, algorithm = 'rsa-sha256') { +export function createSignature (options) { + const { + privateKey, keyId, url, + headers = {}, + algorithm = 'rsa-sha256', + passphrase = process.env.PRIVATE_KEY_PASSPHRASE + } = options if (!SUPPORTED_HASH_ALGORITHMS.includes(algorithm)) { throw Error(`SIGNING: Unsupported hashing algorithm = ${algorithm}`) } const signer = crypto.createSign(algorithm) const signingString = constructSigningString(url, headers) signer.update(signingString) - const signatureB64 = signer.sign({ key: privKey, passphrase: process.env.PRIVATE_KEY_PASSPHRASE }, 'base64') + const signatureB64 = signer.sign({ key: privateKey, passphrase }, 'base64') const headersString = Object.keys(headers).reduce((result, key) => { return result + ' ' + key.toLowerCase() }, '') return `keyId="${keyId}",algorithm="${algorithm}",headers="(request-target)${headersString}",signature="${signatureB64}"` } diff --git a/src/activitypub/utils/index.js b/src/activitypub/utils/index.js index 0cb4b7d0d..6940ca082 100644 --- a/src/activitypub/utils/index.js +++ b/src/activitypub/utils/index.js @@ -75,12 +75,13 @@ export function signAndSend (activity, fromName, targetDomain, url) { headers: { 'Host': targetDomain, 'Date': date, - 'Signature': createSignature(privateKey, `http://${activityPub.domain}/activitypub/users/${fromName}#main-key`, url, - { + 'Signature': createSignature({privateKey, keyId: `http://${activityPub.domain}/activitypub/users/${fromName}#main-key`, url, + headers: { 'Host': targetDomain, 'Date': date, 'Content-Type': 'application/activity+json' - }), + } + }), 'Content-Type': 'application/activity+json' }, method: 'POST', From 27e8b70412487c6812369d80e331764d90c97500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Mar 2019 15:09:38 +0100 Subject: [PATCH 553/554] Fix lint and refactor cc @Mastercuber Send out an activity should be the responsibility of the middleware. --- .../security/httpSignature.spec.js | 20 ++++----- src/activitypub/utils/index.js | 4 +- src/jwt/decode.js | 2 +- src/middleware/activityPubMiddleware.js | 40 ++++++++++++++++- src/resolvers/posts.js | 43 +------------------ 5 files changed, 54 insertions(+), 55 deletions(-) diff --git a/src/activitypub/security/httpSignature.spec.js b/src/activitypub/security/httpSignature.spec.js index bddb05ea9..fc7e69479 100644 --- a/src/activitypub/security/httpSignature.spec.js +++ b/src/activitypub/security/httpSignature.spec.js @@ -1,16 +1,16 @@ import { generateRsaKeyPair, createSignature, verifySignature } from '.' import crypto from 'crypto' -jest.mock('request') import request from 'request' +jest.mock('request') let privateKey let publicKey let headers -const passphrase = "a7dsf78sadg87ad87sfagsadg78" +const passphrase = 'a7dsf78sadg87ad87sfagsadg78' describe('activityPub/security', () => { beforeEach(() => { - const pair = generateRsaKeyPair({passphrase}) + const pair = generateRsaKeyPair({ passphrase }) privateKey = pair.privateKey publicKey = pair.publicKey headers = { @@ -29,7 +29,7 @@ describe('activityPub/security', () => { const signer = crypto.createSign('rsa-sha256') signer.update('(request-target): post /activitypub/users/max/inbox\ndate: 2019-03-08T14:35:45.759Z\nhost: democracy-app.de\ncontent-type: application/json') signatureB64 = signer.sign({ key: privateKey, passphrase: 'a7dsf78sadg87ad87sfagsadg78' }, 'base64') - httpSignature = createSignature({privateKey, keyId: 'https://human-connection.org/activitypub/users/lea#main-key', url: 'https://democracy-app.de/activitypub/users/max/inbox', headers, passphrase}) + httpSignature = createSignature({ privateKey, keyId: 'https://human-connection.org/activitypub/users/lea#main-key', url: 'https://democracy-app.de/activitypub/users/max/inbox', headers, passphrase }) }) it('contains keyId', () => { @@ -54,12 +54,12 @@ describe('activityPub/security', () => { let httpSignature beforeEach(() => { - httpSignature = createSignature({privateKey, keyId: 'http://localhost:4001/activitypub/users/test-user#main-key', url: 'https://democracy-app.de/activitypub/users/max/inbox', headers, passphrase}) - const body = { - "publicKey":{ - "id":"https://localhost:4001/activitypub/users/test-user#main-key", - "owner":"https://localhost:4001/activitypub/users/test-user", - "publicKeyPem": publicKey + httpSignature = createSignature({ privateKey, keyId: 'http://localhost:4001/activitypub/users/test-user#main-key', url: 'https://democracy-app.de/activitypub/users/max/inbox', headers, passphrase }) + const body = { + 'publicKey': { + 'id': 'https://localhost:4001/activitypub/users/test-user#main-key', + 'owner': 'https://localhost:4001/activitypub/users/test-user', + 'publicKeyPem': publicKey } } diff --git a/src/activitypub/utils/index.js b/src/activitypub/utils/index.js index 6940ca082..c48e15e3d 100644 --- a/src/activitypub/utils/index.js +++ b/src/activitypub/utils/index.js @@ -75,7 +75,9 @@ export function signAndSend (activity, fromName, targetDomain, url) { headers: { 'Host': targetDomain, 'Date': date, - 'Signature': createSignature({privateKey, keyId: `http://${activityPub.domain}/activitypub/users/${fromName}#main-key`, url, + 'Signature': createSignature({ privateKey, + keyId: `http://${activityPub.domain}/activitypub/users/${fromName}#main-key`, + url, headers: { 'Host': targetDomain, 'Date': date, diff --git a/src/jwt/decode.js b/src/jwt/decode.js index 6abc06dc1..e8305a83b 100644 --- a/src/jwt/decode.js +++ b/src/jwt/decode.js @@ -13,7 +13,7 @@ export default async (driver, authorizationHeader) => { const session = driver.session() const query = ` MATCH (user:User {id: {id} }) - RETURN user {.id, .slug, .name, .avatar, .email, .role, .disabled} + RETURN user {.id, .slug, .name, .avatar, .email, .role, .disabled, .actorId} LIMIT 1 ` const result = await session.run(query, { id }) diff --git a/src/middleware/activityPubMiddleware.js b/src/middleware/activityPubMiddleware.js index 2fcd04729..6c737faff 100644 --- a/src/middleware/activityPubMiddleware.js +++ b/src/middleware/activityPubMiddleware.js @@ -1,12 +1,50 @@ import { generateRsaKeyPair } from '../activitypub/security' import { activityPub } from '../activitypub/ActivityPub' +import as from 'activitystrea.ms' +import dotenv from 'dotenv' + +const debug = require('debug')('backend:schema') +dotenv.config() export default { Mutation: { CreatePost: async (resolve, root, args, context, info) => { args.activityId = activityPub.generateStatusId(context.user.slug) args.objectId = activityPub.generateStatusId(context.user.slug) - return resolve(root, args, context, info) + + const post = await resolve(root, args, context, info) + + const { user: author } = context + const actorId = author.actorId + debug(`actorId = ${actorId}`) + const createActivity = await new Promise((resolve, reject) => { + as.create() + .id(`${actorId}/status/${args.activityId}`) + .actor(`${actorId}`) + .object( + as.article() + .id(`${actorId}/status/${post.id}`) + .content(post.content) + .to('https://www.w3.org/ns/activitystreams#Public') + .publishedNow() + .attributedTo(`${actorId}`) + ).prettyWrite((err, doc) => { + if (err) { + reject(err) + } else { + debug(doc) + const parsedDoc = JSON.parse(doc) + parsedDoc.send = true + resolve(JSON.stringify(parsedDoc)) + } + }) + }) + try { + await activityPub.sendActivity(createActivity) + } catch (e) { + debug(`error sending post activity\n${e}`) + } + return post }, CreateUser: async (resolve, root, args, context, info) => { const keys = generateRsaKeyPair() diff --git a/src/resolvers/posts.js b/src/resolvers/posts.js index de5cd8282..5b06c38fa 100644 --- a/src/resolvers/posts.js +++ b/src/resolvers/posts.js @@ -1,13 +1,4 @@ import { neo4jgraphql } from 'neo4j-graphql-js' -import as from 'activitystrea.ms' -import dotenv from 'dotenv' -/* -import as from 'activitystrea.ms' -import request from 'request' -*/ - -const debug = require('debug')('backend:schema') -dotenv.config() export default { Mutation: { @@ -15,7 +6,7 @@ export default { const result = await neo4jgraphql(object, params, context, resolveInfo, false) const session = context.driver.session() - const author = await session.run( + await session.run( 'MATCH (author:User {id: $userId}), (post:Post {id: $postId}) ' + 'MERGE (post)<-[:WROTE]-(author) ' + 'RETURN author', { @@ -25,38 +16,6 @@ export default { ) session.close() - debug(`actorId = ${author.records[0]._fields[0].properties.actorId}`) - if (Array.isArray(author.records) && author.records.length > 0) { - const actorId = author.records[0]._fields[0].properties.actorId - const createActivity = await new Promise((resolve, reject) => { - as.create() - .id(`${actorId}/status/${params.activityId}`) - .actor(`${actorId}`) - .object( - as.article() - .id(`${actorId}/status/${result.id}`) - .content(result.content) - .to('https://www.w3.org/ns/activitystreams#Public') - .publishedNow() - .attributedTo(`${actorId}`) - ).prettyWrite((err, doc) => { - if (err) { - reject(err) - } else { - debug(doc) - const parsedDoc = JSON.parse(doc) - parsedDoc.send = true - resolve(JSON.stringify(parsedDoc)) - } - }) - }) - try { - await activityPub.sendActivity(createActivity) - } catch (e) { - debug(`error sending post activity\n${e}`) - } - } - return result } } From 431030f05b75c57bf4c7e797696cad802e8c7ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 20 Mar 2019 19:24:22 +0100 Subject: [PATCH 554/554] Follow review of @Mastercuber --- src/activitypub/security/httpSignature.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/activitypub/security/httpSignature.spec.js b/src/activitypub/security/httpSignature.spec.js index fc7e69479..d40c38242 100644 --- a/src/activitypub/security/httpSignature.spec.js +++ b/src/activitypub/security/httpSignature.spec.js @@ -28,7 +28,7 @@ describe('activityPub/security', () => { beforeEach(() => { const signer = crypto.createSign('rsa-sha256') signer.update('(request-target): post /activitypub/users/max/inbox\ndate: 2019-03-08T14:35:45.759Z\nhost: democracy-app.de\ncontent-type: application/json') - signatureB64 = signer.sign({ key: privateKey, passphrase: 'a7dsf78sadg87ad87sfagsadg78' }, 'base64') + signatureB64 = signer.sign({ key: privateKey, passphrase }, 'base64') httpSignature = createSignature({ privateKey, keyId: 'https://human-connection.org/activitypub/users/lea#main-key', url: 'https://democracy-app.de/activitypub/users/max/inbox', headers, passphrase }) })

Z{l%nn|4pFwrJ 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 hJF@nQZz2<(p4>3d{S|>j_yqV Date: Tue, 9 Oct 2018 15:22:28 +0200 Subject: [PATCH 009/554] made screenshot smaller --- graphql-playground.png | Bin 318421 -> 75776 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/graphql-playground.png b/graphql-playground.png index 87f04d242265f84ca99dddf21c8337e19bd310d0..32396a5773a0aabb05623ee7671cd0079b8eb349 100644 GIT binary patch literal 75776 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%0Da0rc+? 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�ksg{J%oZtXc^soyB(qE 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