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:
Riqwan Thamir
2023-07-27 09:52:17 +02:00
committed by GitHub
co-authored by Oliver Windall Juhl adrien2p Carlos R. L. Rodrigues
parent f561601bf6
commit 131477faf0
43 changed files with 4218 additions and 229 deletions
+15 -5
View File
@@ -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>
}
+81 -1
View File
@@ -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
}
+138
View File
@@ -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
View File
@@ -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