This project is a GraphQL-based application implemented using TypeScript and NestJS. It provides a set of APIs to manage various entities such as posts, users, tags, sliders, FAQs, menu positions, menu items, categories, and their relationships.
The project consists of the following entities and their corresponding attributes:
- Posts (id, title, slug, content, fullcontent, createdAt, updatedAt, author)
- Users (id, username, hashedPassword, email, firstName, lastName, name, role_id)
- User Permissions (user_id, key, value=0 or 1)
- post-edit
- post-insert
- post-delete
- tag-edit
- tag-insert
- tag-delete
- faq-insert
- faq-delete
- faq-edit
- menu_positions-insert
- menu_positions-delete
- menu_positions-edit
- menu_items-insert
- menu_items-delete
- menu_items-edit
- slider-insert
- slider-delete
- slider-edit
- Slider Positions (id, name, slug)
- Slider Slides (id, slider_position_id, image, title, description, link)
- Tags (id, text)
- Post Tags (id, post_id, tag_id)
- Contact Us (id, firstName, lastName, email, tel, text)
- FAQs (id, question, answer)
- Menu Positions (id, name, slug)
- Menu Items (id, menu_position_id, name, link, parent_id=null)
- Categories (id, name, slug, parent_id=null)
- Post Categories (id, post_id, category_id)
To run this GraphQL project locally, follow the instructions below:
Clone the repository:
git clone https://github.com/BaseMax/GeneralCMSGraphQLTS.git
Navigate to the project directory:
cd GeneralCMSGraphQLTS
Install the dependencies:
npm install
Set up the environment variables:
Create a .env file in the project root. Define the required environment variables (e.g., database connection details, API keys, etc.) in the .env file.
mv .env.example .env
Start the application:
npm run start:dev
If you want to have a better experience, use the document and postman json .
The application should now be running locally on the specified port.
Once the application is running, you can interact with the GraphQL API using a GraphQL client or a tool like GraphiQL or GraphQL Playground. The GraphQL endpoint will be available at https://localhost:<port>/graphql
.
The API provides various queries and mutations to perform CRUD operations on the entities mentioned above. You can explore the available queries and mutations by accessing the GraphQL endpoint and referring to the provided documentation or schema.
getAllPosts
: Retrieves a list of all posts.getPostById(id: ID!)
: Retrieves a specific post by its ID.getAllUsers
: Retrieves a list of all users.getUserById(id: ID!)
: Retrieves a specific user by their ID.getAllTags
: Retrieves a list of all tags.getTagById(id: ID!)
: Retrieves a specific tag by its ID.getAllSliderPositions
: Retrieves a list of all slider positions.getSliderPositionById(id: ID!)
: Retrieves a specific slider position by its ID.getAllSliderSlides
: Retrieves a list of all slider slides.getSliderSlideById(id: ID!)
: Retrieves a specific slider slide by its ID.getAllFAQs
: Retrieves a list of all FAQs.getFAQById(id: ID!)
: Retrieves a specific FAQ by its ID.getAllMenuPositions
: Retrieves a list of all menu positions.getMenuPositionById(id: ID!)
: Retrieves a specific menu position by its ID.getAllMenuItems
: Retrieves a list of all menu items.getMenuItemById(id: ID!)
: Retrieves a specific menu item by its ID.getAllCategories
: Retrieves a list of all categories.getCategoryById(id: ID!)
: Retrieves a specific category by its ID.
createPost(input: CreatePostInput!):
Post: Creates a new post.updatePost(id: ID!, input: UpdatePostInput!):
Post: Updates an existing post.deletePost(id: ID!):
ID: Deletes a post by its ID.createUser(input: CreateUserInput!):
User: Creates a new user.updateUser(id: ID!, input: UpdateUserInput!):
User: Updates an existing user.deleteUser(id: ID!):
ID: Deletes a user by their ID.createTag(input: CreateTagInput!):
Tag: Creates a new tag.updateTag(id: ID!, input: UpdateTagInput!):
Tag: Updates an existing tag.deleteTag(id: ID!):
ID: Deletes a tag by its ID.createSliderPosition(input: CreateSliderPositionInput!):
SliderPosition: Creates a new slider position.updateSliderPosition(id: ID!, input: UpdateSliderPositionInput!):
SliderPosition: Updates an existing slider position.deleteSliderPosition(id: ID!):
ID: Deletes a slider position by its ID.createSliderSlide(input: CreateSliderSlideInput!):
SliderSlide: Creates a new slider slide.updateSliderSlide(id: ID!, input: UpdateSliderSlideInput!):
SliderSlide: Updates an existing slider slide.deleteSliderSlide(id: ID!):
ID: Deletes a slider slide by its ID.createFAQ(input: CreateFAQInput!):
FAQ: Creates a new FAQ.updateFAQ(id: ID!, input: UpdateFAQInput!):
FAQ: Updates an existing FAQ.deleteFAQ(id: ID!):
ID: Deletes an FAQ by its ID.createMenuPosition(input: CreateMenuPositionInput!):
MenuPosition: Creates a new menu position.updateMenuPosition(id: ID!, input: UpdateMenuPositionInput!):
MenuPosition: Updates an existing menu position.deleteMenuPosition(id: ID!):
ID: Deletes a menu position by its ID.- `createMenuItem(input: CreateMenuItemInput!): MenuItem: Creates a new menu item.
updateMenuItem(id: ID!, input: UpdateMenuItemInput!):
MenuItem: Updates an existing menu item.deleteMenuItem(id: ID!):
ID: Deletes a menu item by its ID.createCategory(input: CreateCategoryInput!):
Category: Creates a new category.updateCategory(id: ID!, input: UpdateCategoryInput!):
Category: Updates an existing category.deleteCategory(id: ID!):
ID: Deletes a category by its ID.
Note: The input and output types mentioned in the above queries and mutations are placeholders and may vary based on your specific implementation. Please refer to the project's GraphQL schema for accurate types and field definitions.
Note : Users are created and have the normal user role by default , But the person who enters first has an admin flag , Roles are written in enum type and column role is set in this way
roles: ["Admin" , "User"]
If you want to contribute to this project, you can follow the steps below:
- Fork the repository.
- Create a new branch for your feature or bug fix.
- Make the necessary changes.
- Commit and push your changes to the branch.
- Submit a pull request, explaining the changes you made and their purpose.
- Please make sure to follow the existing coding style and include appropriate tests for your changes.
type Post {
id: ID!
title: String!
slug: String!
content: String!
fullContent: String!
createdAt: String!
updatedAt: String!
author: User!
tags: [Tag!]!
categories: [Category!]!
}
type User {
id: ID!
username: String!
hashedPassword: String!
email: String!
firstName: String!
lastName: String!
name: String!
role: Role!
}
type SliderPosition {
id: ID!
name: String!
slug: String!
slides: [SliderSlide!]!
}
type SliderSlide {
id: ID!
sliderPosition: SliderPosition!
image: String!
title: String!
description: String!
link: String!
}
type Tag {
id: ID!
text: String!
posts: [Post!]!
}
type ContactUs {
id: ID!
firstName: String!
lastName: String!
email: String!
tel: String!
text: String!
}
type FAQ {
id: ID!
question: String!
answer: String!
}
type MenuPosition {
id: ID!
name: String!
slug: String!
menuItems: [MenuItem!]!
}
type MenuItem {
id: ID!
menuPosition: MenuPosition!
name: String!
link: String!
parent: MenuItem
}
type Category {
id: ID!
name: String!
slug: String!
parent: Category
posts: [Post!]!
}
input CreatePostInput {
title: String!
slug: String!
content: String!
fullContent: String!
authorId: ID!
tagIds: [ID!]!
categoryIds: [ID!]!
}
input UpdatePostInput {
title: String
slug: String
content: String
fullContent: String
authorId: ID
tagIds: [ID!]
categoryIds: [ID!]
}
input CreateUserInput {
username: String!
hashedPassword: String!
email: String!
firstName: String!
lastName: String!
roleId: ID!
}
input UpdateUserInput {
username: String
hashedPassword: String
email: String
firstName: String
lastName: String
roleId: ID
}
input CreateTagInput {
text: String!
}
input UpdateTagInput {
text: String
}
input CreateSliderPositionInput {
name: String!
slug: String!
}
input UpdateSliderPositionInput {
name: String
slug: String
}
input CreateSliderSlideInput {
sliderPositionId: ID!
image: String!
title: String!
description: String!
link: String!
}
input UpdateSliderSlideInput {
sliderPositionId: ID
image: String
title: String
description: String
link: String
}
input CreateFAQInput {
question: String!
answer: String!
}
input UpdateFAQInput {
question: String
answer: String
}
input CreateMenuPositionInput {
name: String!
slug: String!
}
input UpdateMenuPositionInput {
name: String
slug: String
}
input CreateMenuItemInput {
menuPositionId: ID!
name: String!
link: String!
parentId: ID
}
input UpdateMenuItemInput {
menuPositionId: ID
name: String
link: String
parentId: ID
}
input CreateCategoryInput {
name: String!
slug: String!
parentId: ID
}
input UpdateCategoryInput {
name: String
slug: String
parentId: ID
}
type Query {
getAllPosts: [Post!]!
getPostById(id: ID!): Post
getAllUsers: [User!]!
getUserById(id: ID!): User
getAllTags: [Tag!]!
getTagById(id: ID!): Tag
getAllSliderPositions: [SliderPosition!]!
getSliderPositionById(id: ID!): SliderPosition
getAllSliderSlides: [SliderSlide!]!
getSliderSlideById(id: ID!): SliderSlide
getAllFAQs: [FAQ!]!
getFAQById(id: ID!): FAQ
getAllMenuPositions: [MenuPosition!]!
getMenuPositionById(id: ID!): MenuPosition
getAllMenuItems: [MenuItem!]!
getMenuItemById(id: ID!): MenuItem
getAllCategories: [Category!]!
getCategoryById(id: ID!): Category
}
type Mutation {
createPost(input: CreatePostInput!): Post
updatePost(id: ID!, input: UpdatePostInput!): Post
deletePost(id: ID!): ID
createUser(input: CreateUserInput!): User
updateUser(id: ID!, input: UpdateUserInput!): User
deleteUser(id: ID!): ID
createTag(input: CreateTagInput!): Tag
updateTag(id: ID!, input: UpdateTagInput!): Tag
deleteTag(id: ID!): ID
createSliderPosition(input: CreateSliderPositionInput!): SliderPosition
updateSliderPosition(id: ID!, input: UpdateSliderPositionInput!): SliderPosition
deleteSliderPosition(id: ID!): ID
createSliderSlide(input: CreateSliderSlideInput!): SliderSlide
updateSliderSlide(id: ID!, input: UpdateSliderSlideInput!): SliderSlide
deleteSliderSlide(id: ID!): ID
createFAQ(input: CreateFAQInput!): FAQ
updateFAQ(id: ID!, input: UpdateFAQInput!): FAQ
deleteFAQ(id: ID!): ID
createMenuPosition(input: CreateMenuPositionInput!): MenuPosition
updateMenuPosition(id: ID!, input: UpdateMenuPositionInput!): MenuPosition
deleteMenuPosition(id: ID!): ID
createMenuItem(input: CreateMenuItemInput!): MenuItem
updateMenuItem(id: ID!, input: UpdateMenuItemInput!): MenuItem
deleteMenuItem(id: ID!): ID
createCategory(input: CreateCategoryInput!): Category
updateCategory(id: ID!, input: UpdateCategoryInput!): Category
deleteCategory(id: ID!): ID
}
Retrieves a list of all posts.
query {
getAllPosts {
id
title
slug
content
fullContent
createdAt
updatedAt
author {
id
username
email
}
tags {
id
text
}
categories {
id
name
slug
}
}
}
Retrieves a specific post by its ID.
- id: ID! (required) - The ID of the post.
query {
getPostById(id: "123") {
id
title
slug
content
fullContent
createdAt
updatedAt
author {
id
username
email
}
tags {
id
text
}
categories {
id
name
slug
}
}
}
Retrieves a list of all users.
query {
getAllUsers {
id
username
email
firstName
lastName
name
role {
id
name
}
}
}
Retrieves a specific user by their ID.
- id: ID! (required) - The ID of the user.
query {
getUserById(id: "456") {
id
username
email
firstName
lastName
name
role {
id
name
}
}
}
Retrieves a list of all tags.
query {
getAllTags {
id
text
}
}
Retrieves a specific tag by its ID.
- id: ID! (required) - The ID of the tag.
query {
getTagById(id: "789") {
id
text
}
}
Retrieves a list of all slider positions.
query {
getAllSliderPositions {
id
name
slug
slides {
id
image
title
description
link
}
}
}
Retrieves a specific slider position by its ID.
- id: ID! (required) - The ID of the slider position.
query {
getSliderPositionById(id: "987") {
id
name
slug
slides {
id
image
title
description
link
}
}
}
Retrieves a list of all slider slides.
query {
getAllSliderSlides {
id
sliderPosition {
id
name
}
image
title
description
link
}
}
Retrieves a specific slider slide by its ID.
- id: ID! (required) - The ID of the slider slide.
query {
getSliderSlideById(id: "654") {
id
sliderPosition {
id
name
}
image
title
description
link
}
}
Retrieves a list of all FAQs.
query {
getAllFAQs {
id
question
answer
}
}
Retrieves a specific FAQ by its ID.
- id: ID! (required) - The ID of the FAQ.
query {
getFAQById(id: "321") {
id
question
answer
}
}
Retrieves a list of all menu positions.
query {
getAllMenuPositions {
id
name
slug
menuItems {
id
name
link
parent {
id
name
}
}
}
}
Retrieves a specific menu position by its ID.
- id: ID! (required) - The ID of the menu position.
query {
getMenuPositionById(id: "456") {
id
name
slug
menuItems {
id
name
link
parent {
id
name
}
}
}
}
Retrieves a list of all menu items.
query {
getAllMenuItems {
id
menuPosition {
id
name
}
name
link
parent {
id
name
}
}
}
Retrieves a specific menu item by its ID.
- id: ID! (required) - The ID of the menu item.
query {
getMenuItemById(id: "789") {
id
menuPosition {
id
name
}
name
link
parent {
id
name
}
}
}
Retrieves a list of all categories.
query {
getAllCategories {
id
name
slug
parent {
id
name
}
posts {
id
title
slug
}
}
}
Retrieves a specific category by its ID.
- id: ID! (required) - The ID of the category.
query {
getCategoryById(id: "987") {
id
name
slug
parent {
id
name
}
posts {
id
title
slug
}
}
}
Creates a new post.
- input: CreatePostInput! (required) - The input data for creating a post.
mutation {
createPost(input: {
title: "New Post",
slug: "new-post",
content: "Lorem ipsum dolor sit amet",
fullContent: "Lorem ipsum dolor sit amet,consectetur adipiscing elit. Sed ut enim at quam elementum blandit",
authorId: "123",
tagIds: ["tag1", "tag2"],
categoryIds: ["category1", "category2"]
}) {
id
title
slug
content
fullContent
createdAt
updatedAt
author {
id
username
email
}
tags {
id
text
}
categories {
id
name
slug
}
}
}
Updates an existing post.
- id: ID! (required) - The ID of the post to update.
- input: UpdatePostInput! (required) - The updated data for the post.
mutation {
updatePost(id: "post1", input: {
title: "Updated Post",
slug: "updated-post",
content: "Lorem ipsum dolor sit amet",
fullContent: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ut enim at quam elementum blandit",
authorId: "123",
tagIds: ["tag1", "tag2"],
categoryIds: ["category1", "category2"]
}) {
id
title
slug
content
fullContent
createdAt
updatedAt
author {
id
username
email
}
tags {
id
text
}
categories {
id
name
slug
}
}
}
Deletes a post by its ID.
- id: ID! (required) - The ID of the post to delete.
mutation {
deletePost(id: "post1")
}
Creates a new user.
- input: CreateUserInput! (required) - The input data for creating a user.
mutation {
createUser(input: {
username: "john_doe",
hashedPassword: "hashedpassword123",
email: "[email protected]",
firstName: "John",
lastName: "Doe",
roleId: "role1"
}) {
id
username
email
firstName
lastName
name
role {
id
name
}
}
}
Updates an existing user.
- id: ID! (required) - The ID of the user to update.
- input: UpdateUserInput! (required) - The updated data for the user.
mutation {
updateUser(id: "user1", input: {
username: "johndoe",
hashedPassword: "updatedhashedpassword123",
email: "[email protected]",
firstName: "John",
lastName: "Doe",
roleId: "role1"
}) {
id
username
email
firstName
lastName
name
role {
id
name
}
}
}
Deletes a user by their ID.
- id: ID! (required) - The ID of the user to delete.
mutation {
deleteUser(id: "user1")
}
Creates a new tag.
- input: CreateTagInput! (required) - The input data for creating a tag.
mutation {
createTag(input: {
text: "New Tag"
}) {
id
text
}
}
Updates an existing tag.
- id: ID! (required) - The ID of the tag to update.
- input: UpdateTagInput! (required) - The updated data for the tag.
mutation {
updateTag(id: "tag1", input: {
text: "Updated Tag"
}) {
id
text
}
}
Deletes a tag by its ID.
- id: ID! (required) - The ID of the tag to delete.
mutation {
deleteTag(id: "tag1")
}
Creates a new slider position.
- input: CreateSliderPositionInput! (required) - The input data for creating a slider position.
mutation {
createSliderPosition(input: {
name: "New Position",
slug: "new-position"
}) {
id
name
slug
}
}
Updates an existing slider position.
- id: ID! (required) - The ID of the slider position to update.
- input: UpdateSliderPositionInput! (required) - The updated data for the slider position.
mutation {
updateSliderPosition(id: "position1", input: {
name: "Updated Position",
slug: "updated-position"
}) {
id
name
slug
}
}
Deletes a slider position by its ID.
- id: ID! (required) - The ID of the slider position to delete.
mutation {
deleteSliderPosition(id: "position1")
}
Creates a new slider slide.
- input: CreateSliderSlideInput! (required) - The input data for creating a slider slide.
mutation {
createSliderSlide(input: {
sliderPositionId: "position1",
image: "slide-image.jpg",
title: "New Slide",
description: "Lorem ipsum dolor sit amet",
link: "https://example.com"
}) {
id
sliderPosition {
id
name
}
image
title
description
link
}
}
Updates an existing slider slide.
- id: ID! (required) - The ID of the slider slide to update.
- input: UpdateSliderSlideInput! (required) - The updated data for the slider slide.
mutation {
updateSliderSlide(id: "slide1", input: {
sliderPositionId: "position1",
image: "updated-slide-image.jpg",
title: "Updated Slide",
description: "Lorem ipsum dolor sit amet",
link: "https://example.com"
}) {
id
sliderPosition {
id
name
}
image
title
description
link
}
}
Deletes a slider slide by its ID.
- id: ID! (required) - The ID of the slider slide to delete.
mutation {
deleteSliderSlide(id: "slide1")
}
Creates a new FAQ.
- input: CreateFAQInput! (required) - The input data for creating an FAQ.
mutation {
createFAQ(input: {
question: "New FAQ",
answer: "Lorem ipsum dolor sit amet"
}) {
id
question
answer
}
}
Updates an existing FAQ.
- id: ID! (required) - The ID of the FAQ to update.
- input: UpdateFAQInput! (required) - The updated data for the FAQ.
mutation {
updateFAQ(id: "faq1", input: {
question: "Updated FAQ",
answer: "Lorem ipsum dolor sit amet"
}) {
id
question
answer
}
}
Deletes an FAQ by its ID.
- id: ID! (required) - The ID of the FAQ to delete.
mutation {
deleteFAQ(id: "faq1")
}
Creates a new menu position.
- input: CreateMenuPositionInput! (required) - The input data for creating a menu position.
mutation {
createMenuPosition(input: {
name: "New Position",
slug: "new-position"
}) {
id
name
slug
}
}
Updates an existing menu position.
- id: ID! (required) - The ID of the menu position to update.
- input: UpdateMenuPositionInput! (required) - The updated data for the menu position.
mutation {
updateMenuPosition(id: "position1", input: {
name: "Updated Position",
slug: "updated-position"
}) {
id
name
slug
}
}
Deletes a menu position by its ID.
- id: ID! (required) - The ID of the menu position to delete.
mutation {
deleteMenuPosition(id: "position1")
}
Creates a new menu item.
- input: CreateMenuItemInput! (required) - The input data for creating a menu item.
mutation {
createMenuItem(input: {
menuPositionId: "position1",
name: "New Menu Item",
link: "/new"
}) {
id
menuPosition {
id
name
}
name
link
parent {
id
name
}
}
}
Updates an existing menu item.
- id: ID! (required) - The ID of the menu item to update.
- input: UpdateMenuItemInput! (required) - The updated data for the menu item.
mutation {
updateMenuItem(id: "item1", input: {
menuPositionId: "position1",
name: "Updated Menu Item",
link: "/updated",
parentId: "parent1"
}) {
id
menuPosition {
id
name
}
name
link
parent {
id
name
}
}
}
Deletes a menu item by its ID.
- id: ID! (required) - The ID of the menu item to delete.
mutation {
deleteMenuItem(id: "item1")
}
Creates a new category.
- input: CreateCategoryInput! (required) - The input data for creating a category.
mutation {
createCategory(input: {
name: "New Category",
slug: "new-category"
}) {
id
name
slug
parent {
id
name
}
}
}
Updates an existing category.
- id: ID! (required) - The ID of the category to update.
- input: UpdateCategoryInput! (required) - The updated data for the category.
mutation {
updateCategory(id: "category1", input: {
name: "Updated Category",
slug: "updated-category"
}) {
id
name
slug
parent {
id
name
}
}
}
Deletes a category by its ID.
- id: ID! (required) - The ID of the category to delete.
mutation {
deleteCategory(id: "category1")
}
This project is licensed under the GPL-3.0 License. Feel free to modify and distribute it as needed.
Copyright 2023, Max Base