feat(medusa): Convert CollectionService to TypeScript (#1976)
This commit is contained in:
1 parent
b3b69d7117
commit
42ed209518
6 files changed
+138
-85
No files matched your search
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Convert CollectionService to TypeScript
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ArrayNotEmpty, IsString } from "class-validator"
|
import { ArrayNotEmpty, IsString } from "class-validator"
|
||||||
import { Request, Response } from "express"
|
import { Request, Response } from "express"
|
||||||
import { EntityManager } from "typeorm";
|
import { EntityManager } from "typeorm"
|
||||||
|
|
||||||
import ProductCollectionService from "../../../../services/product-collection"
|
import ProductCollectionService from "../../../../services/product-collection"
|
||||||
|
|
||||||
@@ -39,7 +39,9 @@ import ProductCollectionService from "../../../../services/product-collection"
|
|||||||
*/
|
*/
|
||||||
export default async (req: Request, res: Response) => {
|
export default async (req: Request, res: Response) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
const { validatedBody } = req as { validatedBody: AdminPostProductsToCollectionReq }
|
const { validatedBody } = req as {
|
||||||
|
validatedBody: AdminPostProductsToCollectionReq
|
||||||
|
}
|
||||||
|
|
||||||
const productCollectionService: ProductCollectionService = req.scope.resolve(
|
const productCollectionService: ProductCollectionService = req.scope.resolve(
|
||||||
"productCollectionService"
|
"productCollectionService"
|
||||||
@@ -47,10 +49,9 @@ export default async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
const manager: EntityManager = req.scope.resolve("manager")
|
const manager: EntityManager = req.scope.resolve("manager")
|
||||||
const collection = await manager.transaction(async (transactionManager) => {
|
const collection = await manager.transaction(async (transactionManager) => {
|
||||||
return await productCollectionService.withTransaction(transactionManager).addProducts(
|
return await productCollectionService
|
||||||
id,
|
.withTransaction(transactionManager)
|
||||||
validatedBody.product_ids
|
.addProducts(id, validatedBody.product_ids)
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
res.status(200).json({ collection })
|
res.status(200).json({ collection })
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { IsNotEmpty, IsObject, IsOptional, IsString } from "class-validator"
|
import { IsNotEmpty, IsObject, IsOptional, IsString } from "class-validator"
|
||||||
import ProductCollectionService from "../../../../services/product-collection"
|
import ProductCollectionService from "../../../../services/product-collection"
|
||||||
import { Request, Response } from "express"
|
import { Request, Response } from "express"
|
||||||
import { EntityManager } from "typeorm";
|
import { EntityManager } from "typeorm"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [post] /collections
|
* @oas [post] /collections
|
||||||
@@ -38,7 +38,7 @@ import { EntityManager } from "typeorm";
|
|||||||
* $ref: "#/components/schemas/product_collection"
|
* $ref: "#/components/schemas/product_collection"
|
||||||
*/
|
*/
|
||||||
export default async (req: Request, res: Response) => {
|
export default async (req: Request, res: Response) => {
|
||||||
const { validatedBody } = req
|
const { validatedBody } = req as { validatedBody: AdminPostCollectionsReq }
|
||||||
|
|
||||||
const productCollectionService: ProductCollectionService = req.scope.resolve(
|
const productCollectionService: ProductCollectionService = req.scope.resolve(
|
||||||
"productCollectionService"
|
"productCollectionService"
|
||||||
@@ -46,7 +46,9 @@ export default async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
const manager: EntityManager = req.scope.resolve("manager")
|
const manager: EntityManager = req.scope.resolve("manager")
|
||||||
const created = await manager.transaction(async (transactionManager) => {
|
const created = await manager.transaction(async (transactionManager) => {
|
||||||
return await productCollectionService.withTransaction(transactionManager).create(validatedBody)
|
return await productCollectionService
|
||||||
|
.withTransaction(transactionManager)
|
||||||
|
.create(validatedBody)
|
||||||
})
|
})
|
||||||
|
|
||||||
const collection = await productCollectionService.retrieve(created.id)
|
const collection = await productCollectionService.retrieve(created.id)
|
||||||
@@ -65,5 +67,5 @@ export class AdminPostCollectionsReq {
|
|||||||
|
|
||||||
@IsObject()
|
@IsObject()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
metadata?: object
|
metadata?: Record<string, unknown>
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { IsObject, IsOptional, IsString } from "class-validator"
|
import { IsObject, IsOptional, IsString } from "class-validator"
|
||||||
import { Request, Response } from "express"
|
import { Request, Response } from "express"
|
||||||
|
|
||||||
import { EntityManager } from "typeorm";
|
import { EntityManager } from "typeorm";
|
||||||
import ProductCollectionService from "../../../../services/product-collection"
|
import ProductCollectionService from "../../../../services/product-collection"
|
||||||
|
|
||||||
@@ -40,7 +39,9 @@ import ProductCollectionService from "../../../../services/product-collection"
|
|||||||
*/
|
*/
|
||||||
export default async (req: Request, res: Response) => {
|
export default async (req: Request, res: Response) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
const { validatedBody } = req
|
const { validatedBody } = req as {
|
||||||
|
validatedBody: AdminPostCollectionsCollectionReq
|
||||||
|
}
|
||||||
|
|
||||||
const productCollectionService: ProductCollectionService = req.scope.resolve(
|
const productCollectionService: ProductCollectionService = req.scope.resolve(
|
||||||
"productCollectionService"
|
"productCollectionService"
|
||||||
@@ -48,7 +49,9 @@ export default async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
const manager: EntityManager = req.scope.resolve("manager")
|
const manager: EntityManager = req.scope.resolve("manager")
|
||||||
const updated = await manager.transaction(async (transactionManager) => {
|
const updated = await manager.transaction(async (transactionManager) => {
|
||||||
return await productCollectionService.withTransaction(transactionManager).update(id, validatedBody)
|
return await productCollectionService
|
||||||
|
.withTransaction(transactionManager)
|
||||||
|
.update(id, validatedBody)
|
||||||
})
|
})
|
||||||
|
|
||||||
const collection = await productCollectionService.retrieve(updated.id)
|
const collection = await productCollectionService.retrieve(updated.id)
|
||||||
@@ -67,5 +70,5 @@ export class AdminPostCollectionsCollectionReq {
|
|||||||
|
|
||||||
@IsObject()
|
@IsObject()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
metadata?: object
|
metadata?: Record<string, unknown>
|
||||||
}
|
}
|
||||||
+102
-71
@@ -1,65 +1,71 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { MedusaError } from "medusa-core-utils"
|
||||||
import { BaseService } from "medusa-interfaces"
|
import { Brackets, EntityManager, ILike } from "typeorm"
|
||||||
import { Brackets, ILike } from "typeorm"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
|
import { ProductCollection } from "../models"
|
||||||
|
import { ProductRepository } from "../repositories/product"
|
||||||
|
import { ProductCollectionRepository } from "../repositories/product-collection"
|
||||||
|
import { ExtendedFindConfig, FindConfig, QuerySelector } from "../types/common"
|
||||||
|
import {
|
||||||
|
CreateProductCollection,
|
||||||
|
UpdateProductCollection
|
||||||
|
} from "../types/product-collection"
|
||||||
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import { formatException } from "../utils/exception-formatter"
|
import { formatException } from "../utils/exception-formatter"
|
||||||
|
import EventBusService from "./event-bus"
|
||||||
|
|
||||||
|
type InjectedDependencies = {
|
||||||
|
manager: EntityManager
|
||||||
|
eventBusService: EventBusService
|
||||||
|
productRepository: typeof ProductRepository
|
||||||
|
productCollectionRepository: typeof ProductCollectionRepository
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides layer to manipulate product collections.
|
* Provides layer to manipulate product collections.
|
||||||
* @extends BaseService
|
|
||||||
*/
|
*/
|
||||||
class ProductCollectionService extends BaseService {
|
class ProductCollectionService extends TransactionBaseService<ProductCollectionService> {
|
||||||
|
protected manager_: EntityManager
|
||||||
|
protected transactionManager_: EntityManager | undefined
|
||||||
|
|
||||||
|
protected readonly eventBus_: EventBusService
|
||||||
|
|
||||||
|
protected readonly productCollectionRepository_: typeof ProductCollectionRepository
|
||||||
|
protected readonly productRepository_: typeof ProductRepository
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
manager,
|
manager,
|
||||||
productCollectionRepository,
|
productCollectionRepository,
|
||||||
productRepository,
|
productRepository,
|
||||||
eventBusService,
|
eventBusService,
|
||||||
}) {
|
}: InjectedDependencies) {
|
||||||
super()
|
super({
|
||||||
|
manager,
|
||||||
/** @private @const {EntityManager} */
|
productCollectionRepository,
|
||||||
|
productRepository,
|
||||||
|
eventBusService,
|
||||||
|
})
|
||||||
this.manager_ = manager
|
this.manager_ = manager
|
||||||
|
|
||||||
/** @private @const {ProductCollectionRepository} */
|
|
||||||
this.productCollectionRepository_ = productCollectionRepository
|
this.productCollectionRepository_ = productCollectionRepository
|
||||||
|
|
||||||
/** @private @const {ProductRepository} */
|
|
||||||
this.productRepository_ = productRepository
|
this.productRepository_ = productRepository
|
||||||
|
|
||||||
/** @private @const {EventBus} */
|
|
||||||
this.eventBus_ = eventBusService
|
this.eventBus_ = eventBusService
|
||||||
}
|
}
|
||||||
|
|
||||||
withTransaction(transactionManager) {
|
|
||||||
if (!transactionManager) {
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
const cloned = new ProductCollectionService({
|
|
||||||
manager: transactionManager,
|
|
||||||
productCollectionRepository: this.productCollectionRepository_,
|
|
||||||
productRepository: this.productRepository_,
|
|
||||||
eventBusService: this.eventBus_,
|
|
||||||
})
|
|
||||||
|
|
||||||
cloned.transactionManager_ = transactionManager
|
|
||||||
|
|
||||||
return cloned
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a product collection by id.
|
* Retrieves a product collection by id.
|
||||||
* @param {string} collectionId - the id of the collection to retrieve.
|
* @param collectionId - the id of the collection to retrieve.
|
||||||
* @param {Object} config - the config of the collection to retrieve.
|
* @param config - the config of the collection to retrieve.
|
||||||
* @return {Promise<ProductCollection>} the collection.
|
* @return the collection.
|
||||||
*/
|
*/
|
||||||
async retrieve(collectionId, config = {}) {
|
async retrieve(
|
||||||
|
collectionId: string,
|
||||||
|
config: FindConfig<ProductCollection> = {}
|
||||||
|
): Promise<ProductCollection> {
|
||||||
const collectionRepo = this.manager_.getCustomRepository(
|
const collectionRepo = this.manager_.getCustomRepository(
|
||||||
this.productCollectionRepository_
|
this.productCollectionRepository_
|
||||||
)
|
)
|
||||||
|
|
||||||
const validatedId = this.validateId_(collectionId)
|
const query = buildQuery({ id: collectionId }, config)
|
||||||
|
|
||||||
const query = this.buildQuery_({ id: validatedId }, config)
|
|
||||||
const collection = await collectionRepo.findOne(query)
|
const collection = await collectionRepo.findOne(query)
|
||||||
|
|
||||||
if (!collection) {
|
if (!collection) {
|
||||||
@@ -74,16 +80,19 @@ class ProductCollectionService extends BaseService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a product collection by id.
|
* Retrieves a product collection by id.
|
||||||
* @param {string} collectionHandle - the handle of the collection to retrieve.
|
* @param collectionHandle - the handle of the collection to retrieve.
|
||||||
* @param {object} config - query config for request
|
* @param config - query config for request
|
||||||
* @return {Promise<ProductCollection>} the collection.
|
* @return the collection.
|
||||||
*/
|
*/
|
||||||
async retrieveByHandle(collectionHandle, config = {}) {
|
async retrieveByHandle(
|
||||||
|
collectionHandle: string,
|
||||||
|
config: FindConfig<ProductCollection> = {}
|
||||||
|
): Promise<ProductCollection> {
|
||||||
const collectionRepo = this.manager_.getCustomRepository(
|
const collectionRepo = this.manager_.getCustomRepository(
|
||||||
this.productCollectionRepository_
|
this.productCollectionRepository_
|
||||||
)
|
)
|
||||||
|
|
||||||
const query = this.buildQuery_({ handle: collectionHandle }, config)
|
const query = buildQuery({ handle: collectionHandle }, config)
|
||||||
const collection = await collectionRepo.findOne(query)
|
const collection = await collectionRepo.findOne(query)
|
||||||
|
|
||||||
if (!collection) {
|
if (!collection) {
|
||||||
@@ -98,11 +107,13 @@ class ProductCollectionService extends BaseService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a product collection
|
* Creates a product collection
|
||||||
* @param {object} collection - the collection to create
|
* @param collection - the collection to create
|
||||||
* @return {Promise<ProductCollection>} created collection
|
* @return created collection
|
||||||
*/
|
*/
|
||||||
async create(collection) {
|
async create(
|
||||||
return this.atomicPhase_(async (manager) => {
|
collection: CreateProductCollection
|
||||||
|
): Promise<ProductCollection> {
|
||||||
|
return await this.atomicPhase_(async (manager) => {
|
||||||
const collectionRepo = manager.getCustomRepository(
|
const collectionRepo = manager.getCustomRepository(
|
||||||
this.productCollectionRepository_
|
this.productCollectionRepository_
|
||||||
)
|
)
|
||||||
@@ -118,12 +129,15 @@ class ProductCollectionService extends BaseService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a product collection
|
* Updates a product collection
|
||||||
* @param {string} collectionId - id of collection to update
|
* @param collectionId - id of collection to update
|
||||||
* @param {object} update - update object
|
* @param update - update object
|
||||||
* @return {Promise<ProductCollection>} update collection
|
* @return update collection
|
||||||
*/
|
*/
|
||||||
async update(collectionId, update) {
|
async update(
|
||||||
return this.atomicPhase_(async (manager) => {
|
collectionId: string,
|
||||||
|
update: UpdateProductCollection
|
||||||
|
): Promise<ProductCollection> {
|
||||||
|
return await this.atomicPhase_(async (manager) => {
|
||||||
const collectionRepo = manager.getCustomRepository(
|
const collectionRepo = manager.getCustomRepository(
|
||||||
this.productCollectionRepository_
|
this.productCollectionRepository_
|
||||||
)
|
)
|
||||||
@@ -133,7 +147,7 @@ class ProductCollectionService extends BaseService {
|
|||||||
const { metadata, ...rest } = update
|
const { metadata, ...rest } = update
|
||||||
|
|
||||||
if (metadata) {
|
if (metadata) {
|
||||||
collection.metadata = this.setMetadata_(collection, metadata)
|
collection.metadata = setMetadata(collection, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(rest)) {
|
for (const [key, value] of Object.entries(rest)) {
|
||||||
@@ -146,11 +160,11 @@ class ProductCollectionService extends BaseService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a product collection idempotently
|
* Deletes a product collection idempotently
|
||||||
* @param {string} collectionId - id of collection to delete
|
* @param collectionId - id of collection to delete
|
||||||
* @return {Promise} empty promise
|
* @return empty promise
|
||||||
*/
|
*/
|
||||||
async delete(collectionId) {
|
async delete(collectionId: string): Promise<void> {
|
||||||
return this.atomicPhase_(async (manager) => {
|
return await this.atomicPhase_(async (manager) => {
|
||||||
const productCollectionRepo = manager.getCustomRepository(
|
const productCollectionRepo = manager.getCustomRepository(
|
||||||
this.productCollectionRepository_
|
this.productCollectionRepository_
|
||||||
)
|
)
|
||||||
@@ -167,8 +181,11 @@ class ProductCollectionService extends BaseService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async addProducts(collectionId, productIds) {
|
async addProducts(
|
||||||
return this.atomicPhase_(async (manager) => {
|
collectionId: string,
|
||||||
|
productIds: string[]
|
||||||
|
): Promise<ProductCollection> {
|
||||||
|
return await this.atomicPhase_(async (manager) => {
|
||||||
const productRepo = manager.getCustomRepository(this.productRepository_)
|
const productRepo = manager.getCustomRepository(this.productRepository_)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -185,8 +202,11 @@ class ProductCollectionService extends BaseService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async removeProducts(collectionId, productIds) {
|
async removeProducts(
|
||||||
return this.atomicPhase_(async (manager) => {
|
collectionId: string,
|
||||||
|
productIds: string[]
|
||||||
|
): Promise<void> {
|
||||||
|
return await this.atomicPhase_(async (manager) => {
|
||||||
const productRepo = manager.getCustomRepository(this.productRepository_)
|
const productRepo = manager.getCustomRepository(this.productRepository_)
|
||||||
|
|
||||||
const { id } = await this.retrieve(collectionId, { select: ["id"] })
|
const { id } = await this.retrieve(collectionId, { select: ["id"] })
|
||||||
@@ -199,26 +219,32 @@ class ProductCollectionService extends BaseService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists product collections
|
* Lists product collections
|
||||||
* @param {Object} selector - the query object for find
|
* @param selector - the query object for find
|
||||||
* @param {Object} config - the config to be used for find
|
* @param config - the config to be used for find
|
||||||
* @return {Promise} the result of the find operation
|
* @return the result of the find operation
|
||||||
*/
|
*/
|
||||||
async list(selector = {}, config = { skip: 0, take: 20 }) {
|
async list(
|
||||||
|
selector = {},
|
||||||
|
config = { skip: 0, take: 20 }
|
||||||
|
): Promise<ProductCollection[]> {
|
||||||
const productCollectionRepo = this.manager_.getCustomRepository(
|
const productCollectionRepo = this.manager_.getCustomRepository(
|
||||||
this.productCollectionRepository_
|
this.productCollectionRepository_
|
||||||
)
|
)
|
||||||
|
|
||||||
const query = this.buildQuery_(selector, config)
|
const query = buildQuery(selector, config)
|
||||||
return await productCollectionRepo.find(query)
|
return await productCollectionRepo.find(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists product collections and add count.
|
* Lists product collections and add count.
|
||||||
* @param {Object} selector - the query object for find
|
* @param selector - the query object for find
|
||||||
* @param {Object} config - the config to be used for find
|
* @param config - the config to be used for find
|
||||||
* @return {Promise} the result of the find operation
|
* @return the result of the find operation
|
||||||
*/
|
*/
|
||||||
async listAndCount(selector = {}, config = { skip: 0, take: 20 }) {
|
async listAndCount(
|
||||||
|
selector: QuerySelector<ProductCollection> = {},
|
||||||
|
config: FindConfig<ProductCollection> = { skip: 0, take: 20 }
|
||||||
|
): Promise<[ProductCollection[], number]> {
|
||||||
const productCollectionRepo = this.manager_.getCustomRepository(
|
const productCollectionRepo = this.manager_.getCustomRepository(
|
||||||
this.productCollectionRepository_
|
this.productCollectionRepository_
|
||||||
)
|
)
|
||||||
@@ -229,7 +255,12 @@ class ProductCollectionService extends BaseService {
|
|||||||
delete selector.q
|
delete selector.q
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = this.buildQuery_(selector, config)
|
const query = buildQuery(
|
||||||
|
selector,
|
||||||
|
config
|
||||||
|
) as ExtendedFindConfig<ProductCollection> & {
|
||||||
|
where: (qb: any) => void
|
||||||
|
}
|
||||||
|
|
||||||
if (q) {
|
if (q) {
|
||||||
const where = query.where
|
const where = query.where
|
||||||
@@ -239,7 +270,7 @@ class ProductCollectionService extends BaseService {
|
|||||||
delete where.created_at
|
delete where.created_at
|
||||||
delete where.updated_at
|
delete where.updated_at
|
||||||
|
|
||||||
query.where = (qb) => {
|
query.where = (qb): void => {
|
||||||
qb.where(where)
|
qb.where(where)
|
||||||
|
|
||||||
qb.andWhere(
|
qb.andWhere(
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export type CreateProductCollection = {
|
||||||
|
title: string
|
||||||
|
handle?: string
|
||||||
|
metadata?: Record<string, unknown>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateProductCollection = {
|
||||||
|
title?: string
|
||||||
|
handle?: string
|
||||||
|
metadata?: Record<string, unknown>
|
||||||
|
}
|
||||||
Reference in new issue
Block a user