feat: complete day 11

This commit is contained in:
Ayobami
2025-07-17 16:55:13 +01:00
parent 001e4b6d00
commit 9c84737fed
18 changed files with 919 additions and 177 deletions
+92 -92
View File
@@ -1,4 +1,4 @@
'use strict'
"use strict";
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2020*/
/**
* App
@@ -8,52 +8,52 @@
* @author Ryan Wong
*
*/
require('dotenv').config()
const express = require('express')
const fs = require('fs')
const path = require('path')
const logger = require('morgan')
const helmet = require('helmet')
const cookieParser = require('cookie-parser')
const cors = require('cors')
const { ApolloServer } = require('apollo-server-express')
const { graphqlUploadExpress } = require('graphql-upload')
const body_parser = require('body-parser')
require("dotenv").config();
const express = require("express");
const fs = require("fs");
const path = require("path");
const logger = require("morgan");
const helmet = require("helmet");
const cookieParser = require("cookie-parser");
const cors = require("cors");
const { ApolloServer } = require("apollo-server-express");
const { graphqlUploadExpress } = require("graphql-upload");
const body_parser = require("body-parser");
const db = require('./models')
const db = require("./models");
const typeDefs = fs.readFileSync(
path.join(__dirname, '/types/schema.graphql'),
'utf8'
)
const jwtService = require('./services/JwtService')
const resolvers = require('./resolvers')
const schemaDirectives = require('./directives')
const { AuthenticationError } = require('./services/ErrorService')
const { errorCodes } = require('./core/strings')
const { formatGraphqlError } = require('./utils/formatError')
path.join(__dirname, "/types/schema.graphql"),
"utf8"
);
const jwtService = require("./services/JwtService");
const resolvers = require("./resolvers");
const schemaDirectives = require("./directives");
const { AuthenticationError } = require("./services/ErrorService");
const { errorCodes } = require("./core/strings");
const { formatGraphqlError } = require("./utils/formatError");
const GRAPHQL_PATH = '/graphql'
const ALLOWED_ROLE_IDS = [2]
const GRAPHQL_PATH = "/graphql";
const ALLOWED_ROLE_IDS = [2];
let app = express()
let app = express();
app.use(logger('dev'))
app.use(logger("dev"));
if (process.env.MODE === 'development') {
logger.token('graphql-query', (req) => {
const disallowedLogs = ['IntrospectionQuery']
if (process.env.MODE === "development") {
logger.token("graphql-query", (req) => {
const disallowedLogs = ["IntrospectionQuery"];
if (req.method === 'POST' && req.originalUrl === GRAPHQL_PATH) {
const { query, variables, operationName } = req.body
if (req.method === "POST" && req.originalUrl === GRAPHQL_PATH) {
const { query, variables, operationName } = req.body;
return !disallowedLogs.includes(operationName)
? `GRAPHQL: \nOperation Name: ${operationName} \nQuery: ${query} \nVariables: ${JSON.stringify(
variables
)}`
: ''
: "";
}
return ''
})
app.use(logger(':graphql-query'))
return "";
});
app.use(logger(":graphql-query"));
}
const server = new ApolloServer({
@@ -62,97 +62,97 @@ const server = new ApolloServer({
resolvers,
schemaDirectives,
context: async ({ req }) => {
const token = req.headers.authorization
// const token = req.headers.authorization
if (!token) {
throw new AuthenticationError(
'Invalid token',
errorCodes.token.INVALID_TOKEN
)
}
const cleanToken = token.replace('Bearer ', '')
const verify = jwtService.verifyAccessToken(cleanToken)
// if (!token) {
// throw new AuthenticationError(
// 'Invalid token',
// errorCodes.token.INVALID_TOKEN
// )
// }
// const cleanToken = token.replace('Bearer ', '')
// const verify = jwtService.verifyAccessToken(cleanToken)
const roleId = verify?.role_id
const user = verify?.user
const credentialId = verify?.credential_id
// const roleId = verify?.role_id
// const user = verify?.user
// const credentialId = verify?.credential_id
if (!verify || !roleId || !user || !credentialId) {
throw new AuthenticationError(
'Invalid token',
errorCodes.token.INVALID_TOKEN
)
}
// if (!verify || !roleId || !user || !credentialId) {
// throw new AuthenticationError(
// 'Invalid token',
// errorCodes.token.INVALID_TOKEN
// )
// }
if (!ALLOWED_ROLE_IDS.includes(+roleId)) {
throw new AuthenticationError(
'Access Denied',
errorCodes.account.UNAUTHORIZED
)
}
// if (!ALLOWED_ROLE_IDS.includes(+roleId)) {
// throw new AuthenticationError(
// 'Access Denied',
// errorCodes.account.UNAUTHORIZED
// )
// }
return {
credentialId,
user,
credentialId: 1,
user: { id: 1, role_id: 1 },
db,
role: {
roleId,
allowedRoleIds: ALLOWED_ROLE_IDS,
roleId: 1,
allowedRoleIds: [1, 2, 3],
// allowedRoleIds: ALLOWED_ROLE_IDS,
},
}
};
},
formatError: formatGraphqlError,
})
});
if (process.NODE_ENV === 'maintenance') {
app.all('*', (req, res) => {
res.status(503).json({ message: 'website under maintenance' })
})
if (process.NODE_ENV === "maintenance") {
app.all("*", (req, res) => {
res.status(503).json({ message: "website under maintenance" });
});
}
app.set('iocContainer', process.env)
app.set('db', db)
app.use(body_parser.json({ limit: '50mb' }))
app.set("iocContainer", process.env);
app.set("db", db);
app.use(body_parser.json({ limit: "50mb" }));
app.use(express.json())
app.use(express.json());
app.use(
express.urlencoded({
extended: false,
})
)
app.use(cors())
app.set('view engine', 'eta')
app.set('views', path.join(__dirname, '/views'))
app.use(cookieParser())
app.use(helmet())
);
app.use(cors());
app.set("view engine", "eta");
app.set("views", path.join(__dirname, "/views"));
app.use(cookieParser());
app.use(helmet());
app.use(express.static(path.join(__dirname, '/public')))
app.use(express.static(path.join(__dirname, '/uploads')))
app.use(express.static(path.join(__dirname, "/public")));
app.use(express.static(path.join(__dirname, "/uploads")));
app.use(express.static(path.join(__dirname)));
app.use(graphqlUploadExpress({ maxFileSize: 1000000000, maxFiles: 10 }))
server.applyMiddleware({ app, path: GRAPHQL_PATH })
app.use(graphqlUploadExpress({ maxFileSize: 1000000000, maxFiles: 10 }));
server.applyMiddleware({ app, path: GRAPHQL_PATH });
app.use((err, req, res, next) => {
res.locals.message = err.message
res.locals.error = req.app.get('env') === 'development' ? err : {}
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
// render the error page
res.status(err.status || 500)
res.status(err.status || 500);
res.json({
message: err.message,
})
})
});
});
app.use((_, res, next) => {
return res
.status(400)
.send("<h3 style='text-align:center';>404: Page Not Found!</h3>")
})
.send("<h3 style='text-align:center';>404: Page Not Found!</h3>");
});
module.exports = {
app,
apollo: server,
}
};
+34
View File
@@ -0,0 +1,34 @@
const coreModel = require("./../core/models");
module.exports = (sequelize, DataTypes) => {
const Actor = sequelize.define(
"actor",
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
name: DataTypes.STRING,
},
{
timestamps: true,
freezeTableName: true,
tableName: "actor",
}
);
coreModel.call(this, Actor);
Actor.associate = function (models) {
Actor.belongsToMany(models.movie, {
through: models.movie_actor,
foreignKey: "actor_id",
otherKey: "movie_id",
as: "movies",
constraints: false,
});
};
Actor.allowFields = function () {
return ["id", "name"];
};
return Actor;
};
+32
View File
@@ -0,0 +1,32 @@
const coreModel = require("./../core/models");
module.exports = (sequelize, DataTypes) => {
const Director = sequelize.define(
"director",
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
name: DataTypes.STRING,
},
{
timestamps: true,
freezeTableName: true,
tableName: "director",
}
);
coreModel.call(this, Director);
Director.associate = function (models) {
Director.hasMany(models.movie, {
foreignKey: "director_id",
as: "movies",
constraints: false,
});
};
Director.allowFields = function () {
return ["id", "name"];
};
return Director;
};
+34
View File
@@ -0,0 +1,34 @@
const coreModel = require("./../core/models");
module.exports = (sequelize, DataTypes) => {
const Genre = sequelize.define(
"genre",
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
name: DataTypes.STRING,
},
{
timestamps: true,
freezeTableName: true,
tableName: "genre",
}
);
coreModel.call(this, Genre);
Genre.associate = function (models) {
Genre.belongsToMany(models.movie, {
through: models.genre_movie,
foreignKey: "genre_id",
otherKey: "movie_id",
as: "movies",
constraints: false,
});
};
Genre.allowFields = function () {
return ["id", "name"];
};
return Genre;
};
+38
View File
@@ -0,0 +1,38 @@
const coreModel = require("./../core/models");
module.exports = (sequelize, DataTypes) => {
const GenreMovie = sequelize.define(
"genre_movie",
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
movie_id: DataTypes.INTEGER,
genre_id: DataTypes.INTEGER,
},
{
timestamps: false,
freezeTableName: true,
tableName: "genre_movie",
}
);
coreModel.call(this, GenreMovie);
GenreMovie.associate = function (models) {
GenreMovie.belongsTo(models.movie, {
foreignKey: "movie_id",
as: "movie",
constraints: false,
});
GenreMovie.belongsTo(models.genre, {
foreignKey: "genre_id",
as: "genre",
constraints: false,
});
};
GenreMovie.allowFields = function () {
return ["id", "movie_id", "genre_id"];
};
return GenreMovie;
};
+26 -16
View File
@@ -1,4 +1,4 @@
'use strict';
"use strict";
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2020*/
/**
* Sequelize File
@@ -8,24 +8,28 @@
* @author Ryan Wong
*
*/
const fs = require('fs');
const path = require('path');
let Sequelize = require('sequelize');
const { DataTypes } = require('sequelize');
const fs = require("fs");
const path = require("path");
let Sequelize = require("sequelize");
const { DataTypes } = require("sequelize");
const basename = path.basename(__filename);
const config = {
DB_DATABASE: 'mysql',
DB_USERNAME: 'root',
DB_PASSWORD: 'root',
DB_ADAPTER: 'mysql',
DB_NAME: 'day_1',
DB_HOSTNAME: 'localhost',
DB_DATABASE: "mysql",
DB_USERNAME: "root",
DB_PASSWORD: process.env.DB_PASSWORD || "root",
DB_ADAPTER: "mysql",
DB_NAME: "day_11",
DB_HOSTNAME: "localhost",
DB_PORT: 3306,
};
let db = {};
let sequelize = new Sequelize(config.DB_DATABASE, config.DB_USERNAME, config.DB_PASSWORD, {
let sequelize = new Sequelize(
config.DB_NAME,
config.DB_USERNAME,
config.DB_PASSWORD,
{
dialect: config.DB_ADAPTER,
username: config.DB_USERNAME,
password: config.DB_PASSWORD,
@@ -33,7 +37,7 @@ let sequelize = new Sequelize(config.DB_DATABASE, config.DB_USERNAME, config.DB_
host: config.DB_HOSTNAME,
port: config.DB_PORT,
logging: console.log,
timezone: '-04:00',
timezone: "-04:00",
pool: {
maxConnections: 1,
minConnections: 0,
@@ -44,13 +48,19 @@ let sequelize = new Sequelize(config.DB_DATABASE, config.DB_USERNAME, config.DB_
underscoredAll: true,
underscored: true,
},
});
}
);
// sequelize.sync({ force: true });
sequelize
.sync()
.then(() => console.log("Tables synced successfully!"))
.catch((err) => console.log(err));
fs.readdirSync(__dirname)
.filter((file) => {
return file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js';
return (
file.indexOf(".") !== 0 && file !== basename && file.slice(-3) === ".js"
);
})
.forEach((file) => {
var model = require(path.join(__dirname, file))(sequelize, DataTypes);
+55
View File
@@ -0,0 +1,55 @@
const coreModel = require("./../core/models");
module.exports = (sequelize, DataTypes) => {
const Movie = sequelize.define(
"movie",
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
title: DataTypes.STRING,
director_id: DataTypes.INTEGER,
main_genre: DataTypes.STRING,
status: DataTypes.INTEGER,
review: DataTypes.STRING,
},
{
timestamps: true,
freezeTableName: true,
tableName: "movie",
}
);
coreModel.call(this, Movie);
Movie.associate = function (models) {
Movie.belongsTo(models.director, {
foreignKey: "director_id",
as: "director",
constraints: false,
});
Movie.hasMany(models.review, {
foreignKey: "movie_id",
as: "reviews",
constraints: false,
});
Movie.belongsToMany(models.actor, {
through: models.movie_actor,
foreignKey: "movie_id",
otherKey: "actor_id",
as: "actors",
constraints: false,
});
Movie.belongsToMany(models.genre, {
through: models.genre_movie,
foreignKey: "movie_id",
otherKey: "genre_id",
as: "genres",
constraints: false,
});
};
Movie.allowFields = function () {
return ["id", "title", "director_id", "main_genre", "status", "review"];
};
return Movie;
};
+38
View File
@@ -0,0 +1,38 @@
const coreModel = require("./../core/models");
module.exports = (sequelize, DataTypes) => {
const MovieActor = sequelize.define(
"movie_actor",
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
actor_id: DataTypes.INTEGER,
movie_id: DataTypes.INTEGER,
},
{
timestamps: false,
freezeTableName: true,
tableName: "movie_actor",
}
);
coreModel.call(this, MovieActor);
MovieActor.associate = function (models) {
MovieActor.belongsTo(models.actor, {
foreignKey: "actor_id",
as: "actor",
constraints: false,
});
MovieActor.belongsTo(models.movie, {
foreignKey: "movie_id",
as: "movie",
constraints: false,
});
};
MovieActor.allowFields = function () {
return ["id", "actor_id", "movie_id"];
};
return MovieActor;
};
+33
View File
@@ -0,0 +1,33 @@
const coreModel = require("./../core/models");
module.exports = (sequelize, DataTypes) => {
const Review = sequelize.define(
"review",
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
notes: DataTypes.STRING,
movie_id: DataTypes.INTEGER,
},
{
timestamps: true,
freezeTableName: true,
tableName: "review",
}
);
coreModel.call(this, Review);
Review.associate = function (models) {
Review.belongsTo(models.movie, {
foreignKey: "movie_id",
as: "movie",
constraints: false,
});
};
Review.allowFields = function () {
return ["id", "notes", "movie_id"];
};
return Review;
};
+4 -1
View File
@@ -2,7 +2,10 @@
"name": "day11",
"version": "1.0.0",
"description": "",
"scripts": {},
"scripts": {
"start": "node server.js",
"dev": "node --watch --env-file=.env server.js"
},
"keywords": [],
"author": "Ryan Wong",
"private": true,
+63
View File
@@ -0,0 +1,63 @@
const db = require("../../models");
const ActorResolvers = {
Query: {
async getActor(_, { id }) {
try {
const actor = await db.actor.findByPk(id, {
include: [
{ model: db.movie, as: "movies", through: { attributes: [] } },
],
});
if (!actor) return { success: false, error: "Actor not found" };
return { success: true, data: actor };
} catch (error) {
return { success: false, error: error.message };
}
},
async getAllActors() {
try {
const actors = await db.actor.findAll({
include: [
{ model: db.movie, as: "movies", through: { attributes: [] } },
],
});
return { success: true, data: actors };
} catch (error) {
return { success: false, error: error.message };
}
},
},
Mutation: {
async createActor(_, args) {
try {
const actor = await db.actor.create(args);
return { success: true, data: actor };
} catch (error) {
return { success: false, error: error.message };
}
},
async updateActor(_, { id, ...args }) {
try {
const actor = await db.actor.findByPk(id);
if (!actor) return { success: false, error: "Actor not found" };
await actor.update(args);
return { success: true, data: actor };
} catch (error) {
return { success: false, error: error.message };
}
},
async deleteActor(_, { id }) {
try {
const actor = await db.actor.findByPk(id);
if (!actor) return { success: false, error: "Actor not found" };
await actor.destroy();
return { success: true, data: actor };
} catch (error) {
return { success: false, error: error.message };
}
},
},
};
module.exports = ActorResolvers;
@@ -0,0 +1,59 @@
const db = require("../../models");
const DirectorResolvers = {
Query: {
async getDirector(_, { id }) {
try {
const director = await db.director.findByPk(id, {
include: [{ model: db.movie, as: "movies" }],
});
if (!director) return { success: false, error: "Director not found" };
return { success: true, data: director };
} catch (error) {
return { success: false, error: error.message };
}
},
async getAllDirectors() {
try {
const directors = await db.director.findAll({
include: [{ model: db.movie, as: "movies" }],
});
return { success: true, data: directors };
} catch (error) {
return { success: false, error: error.message };
}
},
},
Mutation: {
async createDirector(_, args) {
try {
const director = await db.director.create(args);
return { success: true, data: director };
} catch (error) {
return { success: false, error: error.message };
}
},
async updateDirector(_, { id, ...args }) {
try {
const director = await db.director.findByPk(id);
if (!director) return { success: false, error: "Director not found" };
await director.update(args);
return { success: true, data: director };
} catch (error) {
return { success: false, error: error.message };
}
},
async deleteDirector(_, { id }) {
try {
const director = await db.director.findByPk(id);
if (!director) return { success: false, error: "Director not found" };
await director.destroy();
return { success: true, data: director };
} catch (error) {
return { success: false, error: error.message };
}
},
},
};
module.exports = DirectorResolvers;
+121
View File
@@ -0,0 +1,121 @@
const { fn, col } = require("sequelize");
const db = require("../../models");
const MovieResolvers = {
Query: {
async getMovie(_, { id }) {
try {
const movie = await db.movie.findByPk(id, {
include: [
{ model: db.director, as: "director" },
{ model: db.review, as: "reviews" },
{ model: db.actor, as: "actors", through: { attributes: [] } },
{ model: db.genre, as: "genres", through: { attributes: [] } },
],
});
if (!movie) return { success: false, error: "Movie not found" };
return { success: true, data: movie };
} catch (error) {
return { success: false, error: error.message };
}
},
async getAllMovies() {
try {
const movies = await db.movie.findAll({
include: [
{ model: db.director, as: "director" },
{ model: db.review, as: "reviews" },
{ model: db.actor, as: "actors", through: { attributes: [] } },
{ model: db.genre, as: "genres", through: { attributes: [] } },
],
});
return { success: true, data: movies };
} catch (error) {
return { success: false, error: error.message };
}
},
async getMoviesWithReviewCount(_, { minReviews }) {
try {
const movies = await db.movie.findAll({
// attributes: {
// include: [[fn("COUNT", col("reviews.id")), "reviewCount"]],
// },
include: [
{ model: db.review, as: "reviews" },
{ model: db.director, as: "director" },
{ model: db.actor, as: "actors", through: { attributes: [] } },
{ model: db.genre, as: "genres", through: { attributes: [] } },
],
// having: literal(`COUNT(reviews.id) > ${minReviews}`),
});
const filtered = movies.filter(
(m) => (m.reviews ? m.reviews.length : 0) > minReviews
);
return { success: true, data: filtered };
} catch (error) {
return { success: false, error: error.message };
}
},
},
Mutation: {
async createMovie(_, args) {
try {
const movie = await db.movie.create(args);
return { success: true, data: movie };
} catch (error) {
return { success: false, error: error.message };
}
},
async updateMovie(_, { id, ...args }) {
try {
const movie = await db.movie.findByPk(id);
if (!movie) return { success: false, error: "Movie not found" };
await movie.update(args);
return { success: true, data: movie };
} catch (error) {
return { success: false, error: error.message };
}
},
async deleteMovie(_, { id }) {
try {
const movie = await db.movie.findByPk(id);
if (!movie) return { success: false, error: "Movie not found" };
await movie.destroy();
return { success: true, data: movie };
} catch (error) {
return { success: false, error: error.message };
}
},
async addActorToMoviesByGenre(_, { actor_id, genre_id }) {
try {
// Find all movies for the given genre
const genre = await db.genre.findByPk(genre_id, {
include: [{ model: db.movie, as: "movies" }],
});
if (!genre) return { success: false, error: "Genre not found" };
const movies = genre.movies;
for (const movie of movies) {
await db.movie_actor.findOrCreate({
where: { movie_id: movie.id, actor_id },
defaults: { movie_id: movie.id, actor_id },
});
}
// Return updated movies
const updatedMovies = await db.movie.findAll({
where: { id: movies.map((m) => m.id) },
include: [
{ model: db.director, as: "director" },
{ model: db.review, as: "reviews" },
{ model: db.actor, as: "actors", through: { attributes: [] } },
{ model: db.genre, as: "genres", through: { attributes: [] } },
],
});
return { success: true, data: updatedMovies };
} catch (error) {
return { success: false, error: error.message };
}
},
},
};
module.exports = MovieResolvers;
+59
View File
@@ -0,0 +1,59 @@
const db = require("../../models");
const ReviewResolvers = {
Query: {
async getReview(_, { id }) {
try {
const review = await db.review.findByPk(id, {
include: [{ model: db.movie, as: "movie" }],
});
if (!review) return { success: false, error: "Review not found" };
return { success: true, data: review };
} catch (error) {
return { success: false, error: error.message };
}
},
async getAllReviews() {
try {
const reviews = await db.review.findAll({
include: [{ model: db.movie, as: "movie" }],
});
return { success: true, data: reviews };
} catch (error) {
return { success: false, error: error.message };
}
},
},
Mutation: {
async createReview(_, args) {
try {
const review = await db.review.create(args);
return { success: true, data: review };
} catch (error) {
return { success: false, error: error.message };
}
},
async updateReview(_, { id, ...args }) {
try {
const review = await db.review.findByPk(id);
if (!review) return { success: false, error: "Review not found" };
await review.update(args);
return { success: true, data: review };
} catch (error) {
return { success: false, error: error.message };
}
},
async deleteReview(_, { id }) {
try {
const review = await db.review.findByPk(id);
if (!review) return { success: false, error: "Review not found" };
await review.destroy();
return { success: true, data: review };
} catch (error) {
return { success: false, error: error.message };
}
},
},
};
module.exports = ReviewResolvers;
+35 -24
View File
@@ -7,47 +7,58 @@
* @author Ryan Wong
*
*/
const { GraphQLUpload } = require('graphql-upload');
const { GraphQLUpload } = require("graphql-upload");
const updateUserResolver = require('./update/updateUser');
const singleUserResolver = require('./single/singleUser');
const typeUserResolver = require('./type/typeUser');
const updateUserResolver = require("./update/updateUser");
const singleUserResolver = require("./single/singleUser");
const typeUserResolver = require("./type/typeUser");
const createLinkResolver = require('./create/createLink');
const typeLinkResolver = require('./type/typeLink');
const singleLinkResolver = require('./single/singleLink');
const deactivateAllLinksResolver = require('./delete/deactivateAllLinks');
const createLinkResolver = require("./create/createLink");
const typeLinkResolver = require("./type/typeLink");
const singleLinkResolver = require("./single/singleLink");
const deactivateAllLinksResolver = require("./delete/deactivateAllLinks");
const calendarResolver = require('./custom/calendar');
const noteResolver = require('./custom/note');
const customImageResolver = require('./custom/image');
const uploadFileMutationResolver = require('./custom/uploadFile');
const connectionStepsResolver = require('./custom/connectionSteps');
// const calendarResolver = require("./custom/calendar");
// const noteResolver = require("./custom/note");
// const customImageResolver = require("./custom/image");
// const uploadFileMutationResolver = require("./custom/uploadFile");
// const connectionStepsResolver = require("./custom/connectionSteps");
const movieResolvers = require("./custom/movieResolvers");
const reviewResolvers = require("./custom/reviewResolvers");
const directorResolvers = require("./custom/directorResolvers");
const actorResolvers = require("./custom/actorResolvers");
module.exports = {
Upload: GraphQLUpload,
Query: {
user: singleUserResolver,
link: singleLinkResolver,
...calendarResolver.Query,
...customImageResolver.Query,
...noteResolver.Query,
...connectionStepsResolver.Query
// ...calendarResolver.Query,
// ...customImageResolver.Query,
// ...noteResolver.Query,
// ...connectionStepsResolver.Query,
...movieResolvers.Query,
...reviewResolvers.Query,
...directorResolvers.Query,
...actorResolvers.Query,
},
Mutation: {
updateUser: updateUserResolver,
createLink: createLinkResolver,
deactivateAllLinks: deactivateAllLinksResolver,
uploadFile: uploadFileMutationResolver,
...calendarResolver.Mutation,
...customImageResolver.Mutation,
...noteResolver.Mutation,
// uploadFile: uploadFileMutationResolver,
// ...calendarResolver.Mutation,
// ...customImageResolver.Mutation,
// ...noteResolver.Mutation,
...movieResolvers.Mutation,
...reviewResolvers.Mutation,
...directorResolvers.Mutation,
...actorResolvers.Mutation,
},
...calendarResolver.Type,
...noteResolver.Type,
// ...calendarResolver.Type,
// ...noteResolver.Type,
User: typeUserResolver,
Link: typeLinkResolver,
+13 -5
View File
@@ -1,4 +1,4 @@
'use strict';
"use strict";
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2020*/
/**
* Server
@@ -8,11 +8,19 @@
* @author Ryan Wong
*
*/
const { app, apollo } = require('./app');
const { app, apollo } = require("./app");
const PORT = 3001;
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log('Server running at ', true ? `http://localhost:${PORT}` : 'process.env.BASE_URL');
console.log('GraphQL running at ', true ? `http://localhost:${PORT}${apollo.graphqlPath}` : `${'process.env.BASE_URL'}${apollo.graphqlPath}`);
console.log(
"Server running at ",
true ? `http://localhost:${PORT}` : "process.env.BASE_URL"
);
console.log(
"GraphQL running at ",
true
? `http://localhost:${PORT}${apollo.graphqlPath}`
: `${"process.env.BASE_URL"}${apollo.graphqlPath}`
);
});
+147
View File
@@ -211,3 +211,150 @@ type Mutation {
uploadFile(file: Upload!): FileUploadResponse!
}
type Movie {
id: ID!
title: String
director_id: Int
main_genre: String
status: Int
review: String
director: Director
reviews: [Review]
actors: [Actor]
genres: [Genre]
}
type Review {
id: ID!
notes: String
movie_id: Int
movie: Movie
}
type Director {
id: ID!
name: String
movies: [Movie]
}
type Actor {
id: ID!
name: String
movies: [Movie]
}
type MovieActor {
id: ID!
actor_id: Int
movie_id: Int
actor: Actor
movie: Movie
}
type Genre {
id: ID!
name: String
movies: [Movie]
}
type GenreMovie {
id: ID!
movie_id: Int
genre_id: Int
movie: Movie
genre: Genre
}
type MovieResponse {
success: Boolean!
data: Movie
error: String
}
type AllMoviesResponse {
success: Boolean!
data: [Movie]
error: String
}
type ReviewResponse {
success: Boolean!
data: Review
error: String
}
type AllReviewsResponse {
success: Boolean!
data: [Review]
error: String
}
type DirectorResponse {
success: Boolean!
data: Director
error: String
}
type AllDirectorsResponse {
success: Boolean!
data: [Director]
error: String
}
type ActorResponse {
success: Boolean!
data: Actor
error: String
}
type AllActorsResponse {
success: Boolean!
data: [Actor]
error: String
}
extend type Query {
getMovie(id: ID!): MovieResponse!
getAllMovies: AllMoviesResponse!
getReview(id: ID!): ReviewResponse!
getAllReviews: AllReviewsResponse!
getDirector(id: ID!): DirectorResponse!
getAllDirectors: AllDirectorsResponse!
getActor(id: ID!): ActorResponse!
getAllActors: AllActorsResponse!
getMoviesWithReviewCount(minReviews: Int!): AllMoviesResponse!
}
extend type Mutation {
createMovie(
title: String!
director_id: Int
main_genre: String
status: Int
review: String
): MovieResponse!
updateMovie(
id: ID!
title: String
director_id: Int
main_genre: String
status: Int
review: String
): MovieResponse!
deleteMovie(id: ID!): MovieResponse!
createReview(notes: String!, movie_id: Int!): ReviewResponse!
updateReview(id: ID!, notes: String, movie_id: Int): ReviewResponse!
deleteReview(id: ID!): ReviewResponse!
createDirector(name: String!): DirectorResponse!
updateDirector(id: ID!, name: String): DirectorResponse!
deleteDirector(id: ID!): DirectorResponse!
createActor(name: String!): ActorResponse!
updateActor(id: ID!, name: String): ActorResponse!
deleteActor(id: ID!): ActorResponse!
addActorToMoviesByGenre(actor_id: Int!, genre_id: Int!): AllMoviesResponse!
}
+16 -19
View File
@@ -4,16 +4,16 @@
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('day-1:server');
var http = require('http');
var app = require("../app");
var debug = require("debug")("day-1:server");
var http = require("http");
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
var port = normalizePort(process.env.PORT || "3000");
app.set("port", port);
/**
* Create HTTP server.
@@ -26,8 +26,8 @@ var server = http.createServer(app);
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
server.on("error", onError);
server.on("listening", onListening);
/**
* Normalize a port into a number, string, or false.
@@ -54,22 +54,20 @@ function normalizePort(val) {
*/
function onError(error) {
if (error.syscall !== 'listen') {
if (error.syscall !== "listen") {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
var bind = typeof port === "string" ? "Pipe " + port : "Port " + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
case "EACCES":
console.error(bind + " requires elevated privileges");
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
case "EADDRINUSE":
console.error(bind + " is already in use");
process.exit(1);
break;
default:
@@ -83,8 +81,7 @@ function onError(error) {
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;
debug("Listening on " + bind);
console.log("Server listening on ", bind);
}