feat(product, types, utils): tags, types, options, categories and collections for product module (#4535)
* Feat: create product with product module * feat: create product wip * feat: create product wip * feat: update product relation and generate image migration * lint * conitnue implementation * continue implementation and add integration tests for produceService.create * Add integration tests for product creation at the module level for the complete flow * only use persist since write operations are always wrapped in a transaction which will be committed and flushed * simplify the transaction wrapper to make future changes easier * feat: move some utils to the utils package to simplify its usage * tests: fix unit tests * feat: create variants along side the product * Add more integration tests an update migrations * chore: Update actions workflow to include packages integration tests * small types and utils cleanup * chore: Add support for database debug option * chore: Add missing types in package.json from types and util, validate that all the models are sync with medusa * expose retrieve method * fix types issues * fix unit tests and move integration tests workflow with the plugins integration tests * chore: remove migration function export from the definition to prevent them to be ran by the medusa cli just in case * fix package.json script * chore: workflows * feat: start creating the create product workflow * feat: add empty step for prices and sales channel * tests: update scripts and action envs * fix imports * feat: Add proper soft deleted support + add product deletion service public api * chore: update migrations * chore: update migrations * chore: update todo * feat: Add product deletion to the create-product workflow as compensation * chore: cleanup product utils * feat: Add support for cascade soft-remove * feat: refactor repository to take into account withDeleted * fix integration tests * Add support for force delete -> delete, cleanup repositories and improvements * Add support for restoring a product and add integration tests * cleaup + tests * types * fix integration tests * remove unnecessary comments * move specific mikro orm usage to the DAL * Cleanup workflow functions * Make deleted_at optional at the property level and add url index for the images * address feedback + cleanup * fix export * merge migrations into one * feat(product, types): added missing product variant methods (#4475) * chore: added missing product variant methods * chore: address PR feedback * chore: catch undefined case for retrieve + specs for variant service * chore: align TEntity + add changeset * chore: revert changeset, TEntity to ProductVariant * chore: write tests for pagination, unskip the test * Create chilled-mice-deliver.md * update integration fixtuers * update pipeline node version * rename github action * fix pipeline * feat(medusa, types): added missing category tests and service methods (#4499) * chore: added missing category tests and service methods * chore: added type changes to module service * chore: address pr feedback * update repositories manager usage and serialisation from the write public API * move serializisation to the DAL * rename template args * chore: added collection methods for module and collection service (#4505) * chore: added collection methods for module and collection service * Create fresh-islands-teach.md * chore: move retrieve entity to utils package * chore: make products optional in DTO type --------- Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> * feat(product): Apply transaction decorators to the services (#4512) * chore: added tags and types methods for product module * chore: remove console log * chore: fork managers on every repository call * chore: add forked manager decorator * chore: rename to inject manager from inject forked manager * chore: added product tag and type create/update/delete * chore: added collection create/update/delete * chore: fix naming * update injectManager and related behaviour * simplify get active manager * chore: reset package.json * makes the base repository methods related to manager generic * makes some wrapper generic enough * add some todos * chore: added options CRUD * clean up * chore: fix issue with deleted_at not being updated * wip * chore: added categories write operations * chore: remove async nature of injection decorator * chore: added changeset * chore: reset package.json * chore: add manager injection to all contextable methods * chore: fix unit tests --------- Co-authored-by: adrien2p <adrien.deperetti@gmail.com> Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
This commit is contained in:
co-authored by
Oliver Windall Juhl
adrien2p
Carlos R. L. Rodrigues
parent
f561601bf6
commit
131477faf0
@@ -7,21 +7,27 @@ import { Context } from "../shared-context"
|
||||
* This layer helps to separate the business logic (service layer) from accessing the
|
||||
* ORM directly and allows to switch to another ORM without changing the business logic.
|
||||
*/
|
||||
export interface RepositoryService<T = any> {
|
||||
transaction(
|
||||
task: (transactionManager: unknown) => Promise<any>,
|
||||
interface BaseRepositoryService<T = any> {
|
||||
transaction<TManager = unknown>(
|
||||
task: (transactionManager: TManager) => Promise<any>,
|
||||
context?: {
|
||||
isolationLevel?: string
|
||||
transaction?: unknown
|
||||
transaction?: TManager
|
||||
enableNestedTransactions?: boolean
|
||||
}
|
||||
): Promise<any>
|
||||
|
||||
getFreshManager<TManager = unknown>(): TManager
|
||||
|
||||
getActiveManager<TManager = unknown>(): TManager
|
||||
|
||||
serialize<TOutput extends object | object[]>(
|
||||
data: any,
|
||||
options?: any
|
||||
): Promise<TOutput>
|
||||
}
|
||||
|
||||
export interface RepositoryService<T = any> extends BaseRepositoryService<T> {
|
||||
find(options?: FindOptions<T>, context?: Context): Promise<T[]>
|
||||
|
||||
findAndCount(
|
||||
@@ -44,7 +50,7 @@ export interface RepositoryService<T = any> {
|
||||
restore(ids: string[], context?: Context): Promise<T[]>
|
||||
}
|
||||
|
||||
export interface TreeRepositoryService<T = any> extends RepositoryService<T> {
|
||||
export interface TreeRepositoryService<T = any> extends BaseRepositoryService<T> {
|
||||
find(
|
||||
options?: FindOptions<T>,
|
||||
transformOptions?: RepositoryTransformOptions,
|
||||
@@ -56,4 +62,8 @@ export interface TreeRepositoryService<T = any> extends RepositoryService<T> {
|
||||
transformOptions?: RepositoryTransformOptions,
|
||||
context?: Context
|
||||
): Promise<[T[], number]>
|
||||
|
||||
create(data: unknown, context?: Context): Promise<T>
|
||||
|
||||
delete(id: string, context?: Context): Promise<void>
|
||||
}
|
||||
|
||||
@@ -85,6 +85,26 @@ export interface ProductCategoryDTO {
|
||||
updated_at: string | Date
|
||||
}
|
||||
|
||||
export interface CreateProductCategoryDTO {
|
||||
name: string
|
||||
handle?: string
|
||||
is_active?: boolean
|
||||
is_internal?: boolean
|
||||
rank?: number
|
||||
parent_category_id: string | null
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface UpdateProductCategoryDTO {
|
||||
name?: string
|
||||
handle?: string
|
||||
is_active?: boolean
|
||||
is_internal?: boolean
|
||||
rank?: number
|
||||
parent_category_id?: string | null
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface ProductTagDTO {
|
||||
id: string
|
||||
value: string
|
||||
@@ -153,6 +173,19 @@ export interface FilterableProductTagProps
|
||||
value?: string
|
||||
}
|
||||
|
||||
export interface FilterableProductTypeProps
|
||||
extends BaseFilterable<FilterableProductTypeProps> {
|
||||
id?: string | string[]
|
||||
value?: string
|
||||
}
|
||||
|
||||
export interface FilterableProductOptionProps
|
||||
extends BaseFilterable<FilterableProductOptionProps> {
|
||||
id?: string | string[]
|
||||
title?: string
|
||||
product_id?: string | string[]
|
||||
}
|
||||
|
||||
export interface FilterableProductCollectionProps
|
||||
extends BaseFilterable<FilterableProductCollectionProps> {
|
||||
id?: string | string[]
|
||||
@@ -170,6 +203,7 @@ export interface FilterableProductVariantProps
|
||||
export interface FilterableProductCategoryProps
|
||||
extends BaseFilterable<FilterableProductCategoryProps> {
|
||||
id?: string | string[]
|
||||
name?: string | string[]
|
||||
parent_category_id?: string | string[] | null
|
||||
handle?: string | string[]
|
||||
is_active?: boolean
|
||||
@@ -181,18 +215,63 @@ export interface FilterableProductCategoryProps
|
||||
* Write DTO (module API input)
|
||||
*/
|
||||
|
||||
export interface CreateProductCollectionDTO {
|
||||
title: string
|
||||
handle?: string
|
||||
products?: ProductDTO[]
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface UpdateProductCollectionDTO {
|
||||
id: string
|
||||
value?: string
|
||||
title?: string
|
||||
handle?: string
|
||||
products?: ProductDTO[]
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface CreateProductTypeDTO {
|
||||
id?: string
|
||||
value: string
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface UpsertProductTypeDTO {
|
||||
id?: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface UpdateProductTypeDTO {
|
||||
id: string
|
||||
value?: string
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface CreateProductTagDTO {
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface UpsertProductTagDTO {
|
||||
id?: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface UpdateProductTagDTO {
|
||||
id: string
|
||||
value?: string
|
||||
}
|
||||
|
||||
export interface CreateProductOptionDTO {
|
||||
title: string
|
||||
product_id?: string
|
||||
product?: Record<any, any>
|
||||
}
|
||||
|
||||
export interface UpdateProductOptionDTO {
|
||||
id: string
|
||||
title?: string
|
||||
product_id?: string
|
||||
}
|
||||
|
||||
export interface CreateProductVariantOptionDTO {
|
||||
@@ -368,6 +447,7 @@ export interface UpdateProductVariantOnlyDTO {
|
||||
}
|
||||
|
||||
export interface CreateProductOptionOnlyDTO {
|
||||
product: { id: string }
|
||||
product_id?: string
|
||||
product?: Record<any, any>
|
||||
title: string
|
||||
}
|
||||
|
||||
@@ -1,16 +1,30 @@
|
||||
import {
|
||||
CreateProductDTO,
|
||||
CreateProductTagDTO,
|
||||
CreateProductTypeDTO,
|
||||
CreateProductOptionDTO,
|
||||
CreateProductCategoryDTO,
|
||||
UpdateProductTagDTO,
|
||||
UpdateProductTypeDTO,
|
||||
UpdateProductOptionDTO,
|
||||
UpdateProductCategoryDTO,
|
||||
UpdateProductDTO,
|
||||
FilterableProductCategoryProps,
|
||||
FilterableProductCollectionProps,
|
||||
FilterableProductProps,
|
||||
FilterableProductTagProps,
|
||||
FilterableProductTypeProps,
|
||||
FilterableProductOptionProps,
|
||||
FilterableProductVariantProps,
|
||||
ProductCategoryDTO,
|
||||
ProductCollectionDTO,
|
||||
ProductDTO,
|
||||
ProductTagDTO,
|
||||
ProductTypeDTO,
|
||||
ProductOptionDTO,
|
||||
ProductVariantDTO,
|
||||
CreateProductCollectionDTO,
|
||||
UpdateProductCollectionDTO,
|
||||
} from "./common"
|
||||
|
||||
import { Context } from "../shared-context"
|
||||
@@ -38,12 +52,105 @@ export interface IProductModuleService {
|
||||
sharedContext?: Context
|
||||
): Promise<[ProductDTO[], number]>
|
||||
|
||||
retrieveTag(
|
||||
tagId: string,
|
||||
config?: FindConfig<ProductTagDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<ProductTagDTO>
|
||||
|
||||
listTags(
|
||||
filters?: FilterableProductTagProps,
|
||||
config?: FindConfig<ProductTagDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<ProductTagDTO[]>
|
||||
|
||||
listAndCountTags(
|
||||
filters?: FilterableProductTagProps,
|
||||
config?: FindConfig<ProductTagDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<[ProductTagDTO[], number]>
|
||||
|
||||
createTags(
|
||||
data: CreateProductTagDTO[],
|
||||
sharedContext?: Context,
|
||||
): Promise<ProductTagDTO[]>
|
||||
|
||||
updateTags(
|
||||
data: UpdateProductTagDTO[],
|
||||
sharedContext?: Context,
|
||||
): Promise<ProductTagDTO[]>
|
||||
|
||||
deleteTags(
|
||||
productTagIds: string[],
|
||||
sharedContext?: Context,
|
||||
): Promise<void>
|
||||
|
||||
retrieveType(
|
||||
typeId: string,
|
||||
config?: FindConfig<ProductTypeDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<ProductTypeDTO>
|
||||
|
||||
listTypes(
|
||||
filters?: FilterableProductTypeProps,
|
||||
config?: FindConfig<ProductTypeDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<ProductTypeDTO[]>
|
||||
|
||||
listAndCountTypes(
|
||||
filters?: FilterableProductTypeProps,
|
||||
config?: FindConfig<ProductTypeDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<[ProductTypeDTO[], number]>
|
||||
|
||||
createTypes(
|
||||
data: CreateProductTypeDTO[],
|
||||
sharedContext?: Context,
|
||||
): Promise<ProductTypeDTO[]>
|
||||
|
||||
updateTypes(
|
||||
data: UpdateProductTypeDTO[],
|
||||
sharedContext?: Context,
|
||||
): Promise<ProductTypeDTO[]>
|
||||
|
||||
deleteTypes(
|
||||
productTypeIds: string[],
|
||||
sharedContext?: Context,
|
||||
): Promise<void>
|
||||
|
||||
retrieveOption(
|
||||
optionId: string,
|
||||
config?: FindConfig<ProductOptionDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<ProductOptionDTO>
|
||||
|
||||
listOptions(
|
||||
filters?: FilterableProductOptionProps,
|
||||
config?: FindConfig<ProductOptionDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<ProductOptionDTO[]>
|
||||
|
||||
listAndCountOptions(
|
||||
filters?: FilterableProductOptionProps,
|
||||
config?: FindConfig<ProductOptionDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<[ProductOptionDTO[], number]>
|
||||
|
||||
createOptions(
|
||||
data: CreateProductOptionDTO[],
|
||||
sharedContext?: Context,
|
||||
): Promise<ProductOptionDTO[]>
|
||||
|
||||
updateOptions(
|
||||
data: UpdateProductOptionDTO[],
|
||||
sharedContext?: Context,
|
||||
): Promise<ProductOptionDTO[]>
|
||||
|
||||
deleteOptions(
|
||||
productOptionIds: string[],
|
||||
sharedContext?: Context,
|
||||
): Promise<void>
|
||||
|
||||
retrieveVariant(
|
||||
productVariantId: string,
|
||||
config?: FindConfig<ProductVariantDTO>,
|
||||
@@ -80,6 +187,21 @@ export interface IProductModuleService {
|
||||
sharedContext?: Context
|
||||
): Promise<[ProductCollectionDTO[], number]>
|
||||
|
||||
createCollections(
|
||||
data: CreateProductCollectionDTO[],
|
||||
sharedContext?: Context,
|
||||
): Promise<ProductCollectionDTO[]>
|
||||
|
||||
updateCollections(
|
||||
data: UpdateProductCollectionDTO[],
|
||||
sharedContext?: Context,
|
||||
): Promise<ProductCollectionDTO[]>
|
||||
|
||||
deleteCollections(
|
||||
productCollectionIds: string[],
|
||||
sharedContext?: Context,
|
||||
): Promise<void>
|
||||
|
||||
retrieveCategory(
|
||||
productCategoryId: string,
|
||||
config?: FindConfig<ProductCategoryDTO>,
|
||||
@@ -98,6 +220,22 @@ export interface IProductModuleService {
|
||||
sharedContext?: Context
|
||||
): Promise<[ProductCategoryDTO[], number]>
|
||||
|
||||
createCategory(
|
||||
data: CreateProductCategoryDTO,
|
||||
sharedContext?: Context,
|
||||
): Promise<ProductCategoryDTO>
|
||||
|
||||
updateCategory(
|
||||
categoryId: string,
|
||||
data: UpdateProductCategoryDTO,
|
||||
sharedContext?: Context,
|
||||
): Promise<ProductCategoryDTO>
|
||||
|
||||
deleteCategory(
|
||||
categoryId: string,
|
||||
sharedContext?: Context,
|
||||
): Promise<void>
|
||||
|
||||
create(
|
||||
data: CreateProductDTO[],
|
||||
sharedContext?: Context
|
||||
|
||||
@@ -2,10 +2,12 @@ import { EntityManager } from "typeorm"
|
||||
|
||||
export type SharedContext = {
|
||||
transactionManager?: EntityManager
|
||||
manager?: EntityManager
|
||||
}
|
||||
|
||||
export type Context<TManager = unknown> = {
|
||||
transactionManager?: TManager
|
||||
manager?: TManager
|
||||
isolationLevel?: string
|
||||
enableNestedTransactions?: boolean
|
||||
transactionId?: string
|
||||
|
||||
Reference in New Issue
Block a user