mirror of
https://github.com/Such-Software/medusa-plugin-blog.git
synced 2026-10-17 05:32:06 +02:00
add tagging posts with products, collections, and custom tags
This commit is contained in:
+21
-18
@@ -13,7 +13,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
|
||||
const router = Router()
|
||||
|
||||
// BLOG - GET ALL BLOG POSTS
|
||||
// GET ALL BLOG POSTS
|
||||
router.get("/store/blog", cors(storeCorsOptions), async (req, res) => {
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
blogService.getBlogPosts().then((blog_posts) => {
|
||||
@@ -21,7 +21,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - GET A SINGLE BLOG POST BY HANDLE
|
||||
// GET A SINGLE BLOG POST BY HANDLE
|
||||
router.get("/store/blog/:handle", cors(storeCorsOptions), async (req, res) => {
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
blogService.getBlogPostByHandle(req.params.handle).then((blog_post) => {
|
||||
@@ -29,7 +29,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - GET ALL BLOG CATEGORIES
|
||||
// GET ALL BLOG CATEGORIES
|
||||
router.get("/store/blog/categories", cors(storeCorsOptions), async (req, res) => {
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
blogService.getBlogCategories().then((blog_categories) => {
|
||||
@@ -37,7 +37,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - GET A SINGLE BLOG CATEGORY BY HANDLE
|
||||
// GET A SINGLE BLOG CATEGORY BY HANDLE
|
||||
router.get("/store/blog/categories/:handle", cors(storeCorsOptions), async (req, res) => {
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
blogService.getBlogCategoryByHandle(req.params.handle).then((blog_category) => {
|
||||
@@ -45,7 +45,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - GET ALL BLOG TAGS
|
||||
// GET ALL BLOG TAGS
|
||||
router.get("/store/blog/tags", cors(storeCorsOptions), async (req, res) => {
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
blogService.getBlogTags().then((blog_tags) => {
|
||||
@@ -53,7 +53,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - GET ALL BLOG POSTS TAGGED WITH A TAG OR AN ARRAY OF TAGS
|
||||
// GET ALL BLOG POSTS TAGGED WITH A TAG OR AN ARRAY OF TAGS
|
||||
router.get("/store/blog/tags", cors(storeCorsOptions), async (req, res) => {
|
||||
const tags = req.query.tags
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
@@ -68,7 +68,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
}
|
||||
})
|
||||
|
||||
// BLOG - GET ALL BLOG POSTS TAGGED WITH A PRODUCT
|
||||
// GET ALL BLOG POSTS TAGGED WITH A PRODUCT
|
||||
router.get("/store/blog/products/:id", cors(storeCorsOptions), async (req, res) => {
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
blogService.getBlogPostsByProduct(req.params.id).then((blog_posts) => {
|
||||
@@ -76,7 +76,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - GET ALL BLOG POSTS TAGGED WITH A COLLECTION
|
||||
// GET ALL BLOG POSTS TAGGED WITH A COLLECTION
|
||||
router.get("/store/blog/collections/:id", cors(storeCorsOptions), async (req, res) => {
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
blogService.getBlogPostsByCollection(req.params.id).then((blog_posts) => {
|
||||
@@ -84,7 +84,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - ADD A BLOG CATEGORY
|
||||
// ADD A BLOG CATEGORY
|
||||
router.use("/admin/blog/categories", bodyParser.json())
|
||||
router.post("/admin/blog/categories", cors(adminCorsOptions), async (req, res) => {
|
||||
const schema = z.object({
|
||||
@@ -100,12 +100,12 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
throw new MedusaError(MedusaError.Types.INVALID_DATA, error)
|
||||
}
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
blogService.createBlogCategory(data).then((blog_category) => {
|
||||
blogService.addBlogCategory(data).then((blog_category) => {
|
||||
return res.json({blog_category})
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - UPDATE A BLOG CATEGORY
|
||||
// UPDATE A BLOG CATEGORY
|
||||
router.use("/admin/blog/categories/:id", bodyParser.json())
|
||||
router.post("/admin/blog/categories/:id", cors(adminCorsOptions), async (req, res) => {
|
||||
const schema = z.object({
|
||||
@@ -126,7 +126,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - DELETE A BLOG CATEGORY
|
||||
// DELETE A BLOG CATEGORY
|
||||
router.delete("/admin/blog/categories/:id", cors(adminCorsOptions), async (req, res) => {
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
blogService.deleteBlogCategory(req.params.id).then(() => {
|
||||
@@ -134,7 +134,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - ADD A BLOG POST
|
||||
// ADD A BLOG POST
|
||||
router.use("/admin/blog/posts", bodyParser.json())
|
||||
router.post("/admin/blog/posts", cors(adminCorsOptions), async (req, res) => {
|
||||
const schema = z.object({
|
||||
@@ -146,6 +146,9 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
description: z.string().optional(),
|
||||
keywords: z.string().array().optional(),
|
||||
category_id: z.string().optional(),
|
||||
tag_ids: z.string().array().optional(),
|
||||
product_ids: z.string().array().optional(),
|
||||
collection_ids: z.string().array().optional(),
|
||||
metadata: z.object({}).passthrough() as z.ZodObject<{}>
|
||||
})
|
||||
/* @ts-ignore */
|
||||
@@ -159,7 +162,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - UPDATE A BLOG POST
|
||||
// UPDATE A BLOG POST
|
||||
router.use("/admin/blog/posts/:id", bodyParser.json())
|
||||
router.post("/admin/blog/posts/:id", cors(adminCorsOptions), async (req, res) => {
|
||||
const schema = z.object({
|
||||
@@ -184,7 +187,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - DELETE A BLOG POST
|
||||
// DELETE A BLOG POST
|
||||
router.delete("/admin/blog/posts/:id", cors(adminCorsOptions), async (req, res) => {
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
blogService.deleteBlogPost(req.params.id).then(() => {
|
||||
@@ -192,7 +195,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - ADD A BLOG TAG
|
||||
// ADD A BLOG TAG
|
||||
router.use("/admin/blog/tags", bodyParser.json())
|
||||
router.post("/admin/blog/tags", cors(adminCorsOptions), async (req, res) => {
|
||||
const schema = z.object({
|
||||
@@ -209,7 +212,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - UPDATE A BLOG TAG
|
||||
// UPDATE A BLOG TAG
|
||||
router.use("/admin/blog/tags/:id", bodyParser.json())
|
||||
router.post("/admin/blog/tags/:id", cors(adminCorsOptions), async (req, res) => {
|
||||
const schema = z.object({
|
||||
@@ -226,7 +229,7 @@ export default (rootDirectory: string): Router | Router[] => {
|
||||
})
|
||||
})
|
||||
|
||||
// BLOG - DELETE A BLOG TAG
|
||||
// DELETE A BLOG TAG
|
||||
router.delete("/admin/blog/tags/:id", cors(adminCorsOptions), async (req, res) => {
|
||||
const blogService = req.scope.resolve("blogService")
|
||||
blogService.deleteBlogTag(req.params.id).then(() => {
|
||||
|
||||
@@ -9,7 +9,9 @@ export class Blog1684173263726 implements MigrationInterface {
|
||||
"title" character varying NOT NULL,
|
||||
"description" character varying,
|
||||
"keywords" varchar array,
|
||||
"metadata" jsonb)`
|
||||
"metadata" jsonb,
|
||||
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
||||
"updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now())`
|
||||
)
|
||||
await queryRunner.createPrimaryKey("blog_category", ["id"])
|
||||
|
||||
@@ -38,7 +40,9 @@ export class Blog1684173263726 implements MigrationInterface {
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE IF NOT EXISTS "blog_tag" ("id" character varying NOT NULL,
|
||||
"value" character varying NOT NULL)`
|
||||
"value" character varying NOT NULL,
|
||||
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
||||
"updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now())`
|
||||
)
|
||||
await queryRunner.createPrimaryKey("blog_tag", ["id"])
|
||||
|
||||
|
||||
@@ -26,6 +26,6 @@ export class BlogCategory extends BaseEntity {
|
||||
|
||||
@BeforeInsert()
|
||||
private beforeInsert(): void {
|
||||
this.id = generateEntityId(this.id, "post")
|
||||
this.id = generateEntityId(this.id, "bcat")
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,6 @@ export class BlogTag extends BaseEntity {
|
||||
|
||||
@BeforeInsert()
|
||||
private beforeInsert(): void {
|
||||
this.id = generateEntityId(this.id, "post")
|
||||
this.id = generateEntityId(this.id, "btag")
|
||||
}
|
||||
}
|
||||
+77
-5
@@ -1,16 +1,22 @@
|
||||
import { TransactionBaseService } from '@medusajs/utils'
|
||||
import { ProductRepository } from '@medusajs/medusa/dist/repositories/product'
|
||||
import { ProductCollectionRepository } from '@medusajs/medusa/dist/repositories/product-collection'
|
||||
import { BlogCategoryRepository } from '../repositories/blog-category'
|
||||
import { BlogPostRepository } from '../repositories/blog-post'
|
||||
import { BlogTagRepository } from '../repositories/blog-tag'
|
||||
import { ArrayContains, ArrayOverlap } from 'typeorm'
|
||||
|
||||
export default class BlogService extends TransactionBaseService {
|
||||
protected readonly productRepository_: typeof ProductRepository
|
||||
protected readonly productCollectionRepository_: typeof ProductCollectionRepository
|
||||
protected readonly blogCategoryRepository_: typeof BlogCategoryRepository
|
||||
protected readonly blogPostRepository_: typeof BlogPostRepository
|
||||
protected readonly blogTagRepository_: typeof BlogTagRepository
|
||||
|
||||
constructor({ blogCategoryRepository, blogPostRepository, blogTagRepository }) {
|
||||
constructor({ productRepository, productCollectionRepository, blogCategoryRepository, blogPostRepository, blogTagRepository }) {
|
||||
super(arguments[0])
|
||||
this.productRepository_ = productRepository
|
||||
this.productCollectionRepository_ = productCollectionRepository
|
||||
this.blogCategoryRepository_ = blogCategoryRepository
|
||||
this.blogPostRepository_ = blogPostRepository
|
||||
this.blogTagRepository_ = blogTagRepository
|
||||
@@ -198,8 +204,41 @@ export default class BlogService extends TransactionBaseService {
|
||||
}
|
||||
|
||||
async addBlogPost(post) {
|
||||
const { handle, title, author, published, content, description, keywords, category_id, tags, products, collections, metadata } = post
|
||||
const { handle, title, author, published, content, description, keywords, category_id, tag_ids, product_ids, collection_ids, metadata } = post
|
||||
if (!title) throw new Error("Adding a blog post requires a title")
|
||||
let tags = []
|
||||
if (tag_ids) {
|
||||
/* @ts-ignore */
|
||||
const blogTagRepository = this.activeManager_.withRepository(this.blogTagRepository_)
|
||||
for (const tag_id of tag_ids) {
|
||||
const tag = await blogTagRepository.findOne({ where: { id: tag_id } })
|
||||
if (tag) {
|
||||
tags.push(tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
let products = []
|
||||
if (product_ids) {
|
||||
/* @ts-ignore */
|
||||
const productRepository = this.activeManager_.withRepository(this.productRepository_)
|
||||
for (const product_id of product_ids) {
|
||||
const product = await productRepository.findOne({ where: { id: product_id } })
|
||||
if (product) {
|
||||
products.push(product)
|
||||
}
|
||||
}
|
||||
}
|
||||
let collections = []
|
||||
if (collection_ids) {
|
||||
/* @ts-ignore */
|
||||
const productCollectionRepository = this.activeManager_.withRepository(this.productCollectionRepository_)
|
||||
for (const collection_id of collection_ids) {
|
||||
const collection = await productCollectionRepository.findOne({ where: { id: collection_id } })
|
||||
if (collection) {
|
||||
collections.push(collection)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* @ts-ignore */
|
||||
const blogPostRepository = this.activeManager_.withRepository(this.blogPostRepository_)
|
||||
const createdPost = blogPostRepository.create({
|
||||
@@ -221,8 +260,41 @@ export default class BlogService extends TransactionBaseService {
|
||||
}
|
||||
|
||||
async updateBlogPost(id, post) {
|
||||
const { handle, title, author, published, content, description, keywords, category_id, tags, products, collections, metadata } = post
|
||||
const { handle, title, author, published, content, description, keywords, category_id, tag_ids, product_ids, collection_ids, metadata } = post
|
||||
if (!id || !title) throw new Error("Updating a blog post requires an id and a title")
|
||||
let tags = []
|
||||
if (tag_ids) {
|
||||
/* @ts-ignore */
|
||||
const blogTagRepository = this.activeManager_.withRepository(this.blogTagRepository_)
|
||||
for (const tag_id of tag_ids) {
|
||||
const tag = await blogTagRepository.findOne({ where: { id: tag_id } })
|
||||
if (tag) {
|
||||
tags.push(tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
let products = []
|
||||
if (product_ids) {
|
||||
/* @ts-ignore */
|
||||
const productRepository = this.activeManager_.withRepository(this.productRepository_)
|
||||
for (const product_id of product_ids) {
|
||||
const product = await productRepository.findOne({ where: { id: product_id } })
|
||||
if (product) {
|
||||
products.push(product)
|
||||
}
|
||||
}
|
||||
}
|
||||
let collections = []
|
||||
if (collection_ids) {
|
||||
/* @ts-ignore */
|
||||
const productCollectionRepository = this.activeManager_.withRepository(this.productCollectionRepository_)
|
||||
for (const collection_id of collection_ids) {
|
||||
const collection = await productCollectionRepository.findOne({ where: { id: collection_id } })
|
||||
if (collection) {
|
||||
collections.push(collection)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* @ts-ignore */
|
||||
const blogPostRepository = this.activeManager_.withRepository(this.blogPostRepository_)
|
||||
const blogPost = blogPostRepository.update(id, {
|
||||
@@ -256,7 +328,7 @@ export default class BlogService extends TransactionBaseService {
|
||||
}
|
||||
|
||||
async addBlogTag(value) {
|
||||
if (!value) throw new Error("Adding a blog tag requires a title")
|
||||
if (!value) throw new Error("Adding a blog tag requires a value")
|
||||
/* @ts-ignore */
|
||||
const blogTagRepository = this.activeManager_.withRepository(this.blogTagRepository_)
|
||||
const createdTag = blogTagRepository.create({
|
||||
@@ -267,7 +339,7 @@ export default class BlogService extends TransactionBaseService {
|
||||
}
|
||||
|
||||
async updateBlogTag(id, value) {
|
||||
if (!id || !value) throw new Error("Updating a blog tag requires an id and a title")
|
||||
if (!id || !value) throw new Error("Updating a blog tag requires an id and a value")
|
||||
/* @ts-ignore */
|
||||
const blogTagRepository = this.activeManager_.withRepository(this.blogTagRepository_)
|
||||
const blogTag = blogTagRepository.update(id, {
|
||||
|
||||
Reference in New Issue
Block a user