[
  {
    "path": ".babelrc",
    "content": "{\n  \"presets\": [\"env\", \"react\"]\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n.DS_STORE\n"
  },
  {
    "path": "README.md",
    "content": "# Lyrical-GraphQL\n\nStarter project from a GraphQL course on Udemy.com\n\n### Setup\n\n- Run `npm install --legacy-peer-deps` in the root of the project to install dependencies\n- Access the application at `localhost:4000` in your browser\n"
  },
  {
    "path": "client/index.html",
    "content": "<head>\n  <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css\">\n  <link href=\"http://fonts.googleapis.com/icon?family=Material+Icons\" rel=\"stylesheet\">\n</head>\n<body>\n  <div id=\"root\" />\n</body>\n"
  },
  {
    "path": "client/index.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\n\nconst Root = () => {\n  return <div>Lyrical</div>\n};\n\nReactDOM.render(\n  <Root />,\n  document.querySelector('#root')\n);\n"
  },
  {
    "path": "client/style/style.css",
    "content": ""
  },
  {
    "path": "index.js",
    "content": "const app = require('./server/server');\n\napp.listen(4000, () => {\n  console.log('Listening');\n});\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"lyrical\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Starter point for a graphQL course\",\n  \"main\": \"index.js\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/StephenGrider/Lyrical-GraphQL\"\n  },\n  \"scripts\": {\n    \"dev\": \"nodemon index.js --ignore client\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"apollo-client\": \"^0.8.1\",\n    \"axios\": \"^0.15.3\",\n    \"babel-core\": \"^6.22.1\",\n    \"babel-loader\": \"^6.2.10\",\n    \"babel-preset-env\": \"^1.1.8\",\n    \"babel-preset-react\": \"^6.22.0\",\n    \"body-parser\": \"^1.16.0\",\n    \"connect-mongo\": \"^1.3.2\",\n    \"css-loader\": \"^0.26.1\",\n    \"express\": \"^4.14.0\",\n    \"express-graphql\": \"0.6.1\",\n    \"express-session\": \"^1.15.0\",\n    \"graphql\": \"^0.8.2\",\n    \"html-webpack-plugin\": \"^2.26.0\",\n    \"lodash\": \"^4.17.4\",\n    \"mongoose\": \"^7.3.1\",\n    \"nodemon\": \"^2.0.22\",\n    \"passport\": \"^0.3.2\",\n    \"passport-local\": \"^1.0.0\",\n    \"react\": \"^15.4.2\",\n    \"react-apollo\": \"^0.9.0\",\n    \"react-dom\": \"^15.4.2\",\n    \"react-router\": \"^3.0.2\",\n    \"style-loader\": \"^0.13.1\",\n    \"webpack\": \"^2.2.0\",\n    \"webpack-dev-middleware\": \"^1.9.0\"\n  }\n}\n"
  },
  {
    "path": "server/models/index.js",
    "content": "require('./song');\nrequire('./lyric');\n"
  },
  {
    "path": "server/models/lyric.js",
    "content": "const mongoose = require('mongoose');\nconst Schema = mongoose.Schema;\n\nconst LyricSchema = new Schema({\n  song: {\n    type: Schema.Types.ObjectId,\n    ref: 'song'\n  },\n  likes: { type: Number, default: 0 },\n  content: { type: String }\n});\n\nLyricSchema.statics.like = function(id) {\n  const Lyric = mongoose.model('lyric');\n\n  return Lyric.findById(id)\n    .then(lyric => {\n      ++lyric.likes;\n      return lyric.save();\n    })\n}\n\nmongoose.model('lyric', LyricSchema);\n"
  },
  {
    "path": "server/models/song.js",
    "content": "const mongoose = require('mongoose');\nconst Schema = mongoose.Schema;\n\nconst SongSchema = new Schema({\n  title: { type: String },\n  user: {\n    type: Schema.Types.ObjectId,\n    ref: 'user'\n  },\n  lyrics: [{\n    type: Schema.Types.ObjectId,\n    ref: 'lyric'\n  }]\n});\n\nSongSchema.statics.addLyric = function(id, content) {\n  const Lyric = mongoose.model('lyric');\n\n  return this.findById(id)\n    .then(song => {\n      const lyric = new Lyric({ content, song })\n      song.lyrics.push(lyric)\n      return Promise.all([lyric.save(), song.save()])\n        .then(([lyric, song]) => song);\n    });\n}\n\nSongSchema.statics.findLyrics = function(id) {\n  return this.findById(id)\n    .populate('lyrics')\n    .then(song => song.lyrics);\n}\n\nmongoose.model('song', SongSchema);\n"
  },
  {
    "path": "server/schema/lyric_type.js",
    "content": "const mongoose = require('mongoose');\nconst graphql = require('graphql');\nconst {\n  GraphQLObjectType,\n  GraphQLList,\n  GraphQLID,\n  GraphQLInt,\n  GraphQLString\n} = graphql;\nconst Lyric = mongoose.model('lyric');\n\nconst LyricType = new GraphQLObjectType({\n  name:  'LyricType',\n  fields: () => ({\n    id: { type: GraphQLID },\n    likes: { type: GraphQLInt },\n    content: { type: GraphQLString },\n    song: {\n      type: require('./song_type'),\n      resolve(parentValue) {\n        return Lyric.findById(parentValue).populate('song')\n          .then(lyric => {\n            console.log(lyric)\n            return lyric.song\n          });\n      }\n    }\n  })\n});\n\nmodule.exports = LyricType;\n"
  },
  {
    "path": "server/schema/mutations.js",
    "content": "const graphql = require('graphql');\nconst { GraphQLObjectType, GraphQLString, GraphQLID } = graphql;\nconst mongoose = require('mongoose');\nconst Song = mongoose.model('song');\nconst Lyric = mongoose.model('lyric');\nconst SongType = require('./song_type');\nconst LyricType = require('./lyric_type');\n\nconst mutation = new GraphQLObjectType({\n  name: 'Mutation',\n  fields: {\n    addSong: {\n      type: SongType,\n      args: {\n        title: { type: GraphQLString }\n      },\n      resolve(parentValue, { title }) {\n        return new Song({ title }).save();\n      }\n    },\n    addLyricToSong: {\n      type: SongType,\n      args: {\n        content: { type: GraphQLString },\n        songId: { type: GraphQLID }\n      },\n      resolve(parentValue, { content, songId }) {\n        return Song.addLyric(songId, content);\n      }\n    },\n    likeLyric: {\n      type: LyricType,\n      args: { id: { type: GraphQLID } },\n      resolve(parentValue, { id }) {\n        return Lyric.like(id);\n      }\n    },\n    deleteSong: {\n      type: SongType,\n      args: { id: { type: GraphQLID } },\n      resolve(parentValue, { id }) {\n        return Song.findByIdAndRemove(id);\n      }\n    }\n  }\n});\n\nmodule.exports = mutation;\n"
  },
  {
    "path": "server/schema/root_query_type.js",
    "content": "const mongoose = require('mongoose');\nconst graphql = require('graphql');\nconst { GraphQLObjectType, GraphQLList, GraphQLID, GraphQLNonNull } = graphql;\nconst SongType = require('./song_type');\nconst LyricType = require('./lyric_type');\nconst Lyric = mongoose.model('lyric');\nconst Song = mongoose.model('song');\n\nconst RootQuery = new GraphQLObjectType({\n  name: 'RootQueryType',\n  fields: () => ({\n    songs: {\n      type: new GraphQLList(SongType),\n      resolve() {\n        return Song.find({});\n      }\n    },\n    song: {\n      type: SongType,\n      args: { id: { type: new GraphQLNonNull(GraphQLID) } },\n      resolve(parentValue, { id }) {\n        return Song.findById(id);\n      }\n    },\n    lyric: {\n      type: LyricType,\n      args: { id: { type: new GraphQLNonNull(GraphQLID) } },\n      resolve(parnetValue, { id }) {\n        return Lyric.findById(id);\n      }\n    }\n  })\n});\n\nmodule.exports = RootQuery;\n"
  },
  {
    "path": "server/schema/schema.js",
    "content": "const _ = require('lodash');\nconst graphql = require('graphql');\nconst { GraphQLSchema } = graphql;\n\nconst RootQueryType = require('./root_query_type');\nconst mutations = require('./mutations');\n\nmodule.exports = new GraphQLSchema({\n  query: RootQueryType,\n  mutation: mutations\n});\n"
  },
  {
    "path": "server/schema/song_type.js",
    "content": "const mongoose = require('mongoose');\nconst graphql = require('graphql');\nconst { GraphQLObjectType, GraphQLString, GraphQLID, GraphQLList } = graphql;\nconst LyricType = require('./lyric_type');\nconst Song = mongoose.model('song');\n\nconst SongType = new GraphQLObjectType({\n  name:  'SongType',\n  fields: () => ({\n    id: { type: GraphQLID },\n    title: { type: GraphQLString },\n    lyrics: {\n      type: new GraphQLList(LyricType),\n      resolve(parentValue) {\n        return Song.findLyrics(parentValue.id);\n      }\n    }\n  })\n});\n\nmodule.exports = SongType;\n"
  },
  {
    "path": "server/server.js",
    "content": "const express = require('express');\nconst models = require('./models');\nconst expressGraphQL = require('express-graphql');\nconst mongoose = require('mongoose');\nconst bodyParser = require('body-parser');\nconst schema = require('./schema/schema');\n\nconst app = express();\n\n// Replace with your Mongo Atlas URI\nconst MONGO_URI = '';\nif (!MONGO_URI) {\n  throw new Error('You must provide a Mongo Atlas URI');\n}\n\nmongoose.Promise = global.Promise;\nmongoose.connect(MONGO_URI);\nmongoose.connection\n  .once('open', () => console.log('Connected to Mongo Atlas instance.'))\n  .on('error', (error) =>\n    console.log('Error connecting to Mongo Atlas:', error)\n  );\n\napp.use(bodyParser.json());\napp.use(\n  '/graphql',\n  expressGraphQL({\n    schema,\n    graphiql: true\n  })\n);\n\nconst webpackMiddleware = require('webpack-dev-middleware');\nconst webpack = require('webpack');\nconst webpackConfig = require('../webpack.config.js');\napp.use(webpackMiddleware(webpack(webpackConfig)));\n\nmodule.exports = app;\n"
  },
  {
    "path": "webpack.config.js",
    "content": "const webpack = require('webpack');\nconst HtmlWebpackPlugin = require('html-webpack-plugin');\n\nmodule.exports = {\n  entry: './client/index.js',\n  output: {\n    path: '/',\n    filename: 'bundle.js'\n  },\n  module: {\n    rules: [\n      {\n        use: 'babel-loader',\n        test: /\\.js$/,\n        exclude: /node_modules/\n      },\n      {\n        use: ['style-loader', 'css-loader'],\n        test: /\\.css$/\n      }\n    ]\n  },\n  plugins: [\n    new HtmlWebpackPlugin({\n      template: 'client/index.html'\n    })\n  ]\n};\n"
  }
]