feat: Refactor the product module definitions and implementation (#6866)

There are several things done in this PR, namely:

Unify the service endpoints API to always work with a model rather than allowing to pass both ID and model (eg. both type_id and type being available in the request to create).
Start using upsertWithReplace to simplify the code and fix some deassociation bugs
Apply some changes to tests to deal with the pricing breaking changes
Correctly define the model relationships (with both ID and entity fields available)
All tests for the product are passing, which should bring us back to a great baseline.
This commit is contained in:
Stevche Radevski
2024-03-29 09:03:41 +00:00
committed by GitHub
parent e603726985
commit cbb5e6bd99
35 changed files with 1318 additions and 1374 deletions
+154 -74
View File
@@ -86,7 +86,11 @@ export interface ProductDTO {
*
* @expandable
*/
collection: ProductCollectionDTO
collection?: ProductCollectionDTO | null
/**
* The associated product collection id.
*/
collection_id?: string | null
/**
* The associated product categories.
*
@@ -98,7 +102,11 @@ export interface ProductDTO {
*
* @expandable
*/
type: ProductTypeDTO
type?: ProductTypeDTO | null
/**
* The associated product type id.
*/
type_id?: string | null
/**
* The associated product tags.
*
@@ -239,11 +247,11 @@ export interface ProductVariantDTO {
*
* @expandable
*/
product: ProductDTO
product?: ProductDTO | null
/**
* The ID of the associated product.
* The associated product id.
*/
product_id: string
product_id?: string | null
/**
* he ranking of the variant among other variants associated with the product.
*/
@@ -301,7 +309,11 @@ export interface ProductCategoryDTO {
*
* @expandable
*/
parent_category?: ProductCategoryDTO
parent_category?: ProductCategoryDTO | null
/**
* The associated parent category id.
*/
parent_category_id?: string | null
/**
* The associated child categories.
*
@@ -438,6 +450,14 @@ export interface ProductCollectionDTO {
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown> | null
/**
* When the product collection was created.
*/
created_at: string | Date
/**
* When the product collection was updated.
*/
updated_at: string | Date
/**
* When the product collection was deleted.
*/
@@ -468,6 +488,14 @@ export interface ProductTypeDTO {
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown> | null
/**
* When the product type was created.
*/
created_at: string | Date
/**
* When the product type was updated.
*/
updated_at: string | Date
/**
* When the product type was deleted.
*/
@@ -494,7 +522,11 @@ export interface ProductOptionDTO {
*
* @expandable
*/
product: ProductDTO
product?: ProductDTO | null
/**
* The associated product id.
*/
product_id?: string | null
/**
* The associated product option values.
*
@@ -505,6 +537,14 @@ export interface ProductOptionDTO {
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown> | null
/**
* When the product option was created.
*/
created_at: string | Date
/**
* When the product option was updated.
*/
updated_at: string | Date
/**
* When the product option was deleted.
*/
@@ -521,13 +561,21 @@ export interface ProductVariantOptionDTO {
*
* @expandable
*/
option_value: ProductOptionValueDTO
option_value?: ProductOptionValueDTO | null
/**
* The value of the product variant option id.
*/
option_value_id?: string | null
/**
* The associated product variant.
*
* @expandable
*/
variant: ProductVariantDTO
variant?: ProductVariantDTO | null
/**
* The associated product variant id.
*/
variant_id?: string | null
}
/**
@@ -553,6 +601,14 @@ export interface ProductImageDTO {
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown> | null
/**
* When the product image was created.
*/
created_at: string | Date
/**
* When the product image was updated.
*/
updated_at: string | Date
/**
* When the product image was deleted.
*/
@@ -585,11 +641,23 @@ export interface ProductOptionValueDTO {
*
* @expandable
*/
option: ProductOptionDTO
option?: ProductOptionDTO | null
/**
* The associated product option id.
*/
option_id?: string | null
/**
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown> | null
/**
* When the product option value was created.
*/
created_at: string | Date
/**
* When the product option value was updated.
*/
updated_at: string | Date
/**
* When the product option value was deleted.
*/
@@ -644,23 +712,6 @@ export interface FilterableProductProps
*/
value?: string[]
}
/**
* Filters on a product's categories.
*/
categories?: {
/**
* IDs to filter categories by.
*/
id?: string | string[] | OperatorMap<string>
/**
* Filter categories by whether they're internal
*/
is_internal?: boolean
/**
* Filter categories by whether they're active.
*/
is_active?: boolean
}
/**
* Filter a product by the ID of the associated type
*/
@@ -921,10 +972,6 @@ export interface UpdateProductCollectionDTO {
* A product type to create.
*/
export interface CreateProductTypeDTO {
/**
* The product type's ID.
*/
id?: string
/**
* The product type's value.
*/
@@ -935,13 +982,11 @@ export interface CreateProductTypeDTO {
metadata?: Record<string, unknown>
}
export interface UpsertProductTypeDTO {
id?: string
value: string
export interface UpsertProductTypeDTO extends UpdateProductTypeDTO {
/**
* Holds custom data in key-value pairs.
* The product type's ID.
*/
metadata?: Record<string, unknown>
id?: string
}
/**
@@ -950,10 +995,6 @@ export interface UpsertProductTypeDTO {
* The data to update in a product type. The `id` is used to identify which product type to update.
*/
export interface UpdateProductTypeDTO {
/**
* The ID of the product type to update.
*/
id: string
/**
* The new value of the product type.
*/
@@ -964,6 +1005,45 @@ export interface UpdateProductTypeDTO {
metadata?: Record<string, unknown>
}
/**
* @interface
*
* A product image to create.
*/
export interface CreateProductImageDTO {
/**
* The product image's URL.
*/
url: string
/**
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown>
}
export interface UpsertProductImageDTO extends UpdateProductImageDTO {
/**
* The product image's ID.
*/
id?: string
}
/**
* @interface
*
* The data to update in a product image. The `id` is used to identify which product image to update.
*/
export interface UpdateProductImageDTO {
/**
* The new URL of the product image.
*/
url?: string
/**
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown>
}
/**
* @interface
*
@@ -976,9 +1056,11 @@ export interface CreateProductTagDTO {
value: string
}
export interface UpsertProductTagDTO {
export interface UpsertProductTagDTO extends UpdateProductTagDTO {
/**
* The ID of the product tag to update.
*/
id?: string
value: string
}
/**
@@ -988,10 +1070,6 @@ export interface UpsertProductTagDTO {
* The data to update in a product tag. The `id` is used to identify which product tag to update.
*/
export interface UpdateProductTagDTO {
/**
* The ID of the product tag to update.
*/
id: string
/**
* The value of the product tag.
*/
@@ -1011,7 +1089,7 @@ export interface CreateProductOptionDTO {
/**
* The product option values.
*/
values: string[] | { value: string }[]
values: string[]
/**
* The ID of the associated product.
*/
@@ -1019,12 +1097,24 @@ export interface CreateProductOptionDTO {
}
export interface UpsertProductOptionDTO extends UpdateProductOptionDTO {
/**
* The ID of the product option to update.
*/
id?: string
}
export interface UpdateProductOptionDTO {
/**
* The product option's title.
*/
title?: string
values?: string[] | { value: string }[]
/**
* The product option values.
*/
values?: string[]
/**
* The ID of the associated product.
*/
product_id?: string
}
@@ -1225,11 +1315,6 @@ export interface CreateProductDTO {
* Whether the product can be discounted.
*/
discountable?: boolean
/**
* The product's images. If an array of strings is supplied, each string will be a URL and a `ProductImage` will be created
* and associated with the product. If an array of objects is supplied, you can pass along the ID of an existing `ProductImage`.
*/
images?: string[] | { id?: string; url: string }[]
/**
* The URL of the product's thumbnail.
*/
@@ -1244,25 +1329,25 @@ export interface CreateProductDTO {
*/
status?: ProductStatus
/**
* The product type to create and associate with the product.
* The product's images to upsert and associate with the product
*/
type?: CreateProductTypeDTO
images?: UpsertProductImageDTO[]
/**
* The product type to be associated with the product.
* The product type id to associate with the product.
*/
type_id?: string | null
type_id?: string
/**
* The product collection to be associated with the product.
* The product collection to associate with the product.
*/
collection_id?: string | null
collection_id?: string
/**
* The product tags to be created and associated with the product.
* The product tags to be upserted and associated with the product.
*/
tags?: CreateProductTagDTO[]
tags?: UpsertProductTagDTO[]
/**
* The product categories to associate with the product.
*/
categories?: { id: string }[]
category_ids?: string[]
/**
* The product options to be created and associated with the product.
*/
@@ -1342,11 +1427,6 @@ export interface UpdateProductDTO {
* Whether the product can be discounted.
*/
discountable?: boolean
/**
* The product's images. If an array of strings is supplied, each string will be a URL and a `ProductImage` will be created
* and associated with the product. If an array of objects is supplied, you can pass along the ID of an existing `ProductImage`.
*/
images?: string[] | { id?: string; url: string }[]
/**
* The URL of the product's thumbnail.
*/
@@ -1361,29 +1441,29 @@ export interface UpdateProductDTO {
*/
status?: ProductStatus
/**
* The product type to create and associate with the product.
* The product's images to upsert and associate with the product
*/
type?: CreateProductTypeDTO
images?: UpsertProductImageDTO[]
/**
* The product type to be associated with the product.
* The product type to associate with the product.
*/
type_id?: string | null
/**
* The product collection to be associated with the product.
* The product collection to associate with the product.
*/
collection_id?: string | null
/**
* The product tags to be created and associated with the product.
*/
tags?: CreateProductTagDTO[]
tags?: UpsertProductTagDTO[]
/**
* The product categories to associate with the product.
*/
categories?: { id: string }[]
category_ids?: string[]
/**
* The product options to be created and associated with the product.
*/
options?: CreateProductOptionDTO[]
options?: UpsertProductOptionDTO[]
/**
* The product variants to be created and associated with the product. You can also update existing product variants associated with the product.
*/
+435 -467
View File
@@ -305,6 +305,267 @@ export interface IProductModuleService extends IModuleService {
sharedContext?: Context
): Promise<[ProductDTO[], number]>
/**
* This method is used to create a list of products.
*
* @param {CreateProductDTO[]} data - The products to be created.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO[]>} The list of created products.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function createProduct (title: string) {
* const productModule = await initializeProductModule()
*
* const products = await productModule.create([
* {
* title
* }
* ])
*
* // do something with the products or return them
* }
*/
create(
data: CreateProductDTO[],
sharedContext?: Context
): Promise<ProductDTO[]>
/**
* This method is used to create a product.
*
* @param {CreateProductDTO} data - The product to be created.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO>} The created product.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function createProduct (title: string) {
* const productModule = await initializeProductModule()
*
* const product = await productModule.create(
* {
* title
* }
* )
*
* // do something with the product or return it
* }
*/
create(data: CreateProductDTO, sharedContext?: Context): Promise<ProductDTO>
/**
* This method updates existing products, or creates new ones if they don't exist.
*
* @param {CreateProductDTO[]} data - The attributes to update or create for each product.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO[]>} The updated and created products.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function upserProduct (title: string) {
* const productModule = await initializeProductModule()
*
* const createdProducts = await productModule.upsert([
* {
* title
* }
* ])
*
* // do something with the products or return them
* }
*/
upsert(
data: UpsertProductDTO[],
sharedContext?: Context
): Promise<ProductDTO[]>
/**
* This method updates the product if it exists, or creates a new ones if it doesn't.
*
* @param {CreateProductDTO} data - The attributes to update or create for the new product.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO>} The updated or created product.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function upserProduct (title: string) {
* const productModule = await initializeProductModule()
*
* const createdProduct = await productModule.upsert(
* {
* title
* }
* )
*
* // do something with the product or return it
* }
*/
upsert(
data: UpsertProductDTO[],
sharedContext?: Context
): Promise<ProductDTO[]>
/**
* This method is used to update a product.
*
* @param {string} id - The ID of the product to be updated.
* @param {UpdateProductDTO} data - The attributes of the product to be updated
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO>} The updated product.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function updateProduct (id: string, title: string) {
* const productModule = await initializeProductModule()
*
* const product = await productModule.update(id, {
* title
* }
* )
*
* // do something with the product or return it
* }
*/
update(
id: string,
data: UpdateProductDTO,
sharedContext?: Context
): Promise<ProductDTO>
/**
* This method is used to update a list of products determined by the selector filters.
*
* @param {FilterableProductProps} selector - The filters that will determine which products will be updated.
* @param {UpdateProductDTO} data - The attributes to be updated on the selected products
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO[]>} The updated products.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function updateProduct (id: string, title: string) {
* const productModule = await initializeProductModule()
*
* const products = await productModule.update({id}, {
* title
* }
* )
*
* // do something with the products or return them
* }
*/
update(
selector: FilterableProductProps,
data: UpdateProductDTO,
sharedContext?: Context
): Promise<ProductDTO[]>
/**
* This method is used to delete products. Unlike the {@link softDelete} method, this method will completely remove the products and they can no longer be accessed or retrieved.
*
* @param {string[]} productIds - The IDs of the products to be deleted.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<void>} Resolves when the products are successfully deleted.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function deleteProducts (ids: string[]) {
* const productModule = await initializeProductModule()
*
* await productModule.delete(ids)
* }
*/
delete(productIds: string[], sharedContext?: Context): Promise<void>
/**
* This method is used to delete products. Unlike the {@link delete} method, this method won't completely remove the product. It can still be accessed or retrieved using methods like {@link retrieve} if you pass the `withDeleted` property to the `config` object parameter.
*
* The soft-deleted products can be restored using the {@link restore} method.
*
* @param {string[]} productIds - The IDs of the products to soft-delete.
* @param {SoftDeleteReturn<TReturnableLinkableKeys>} config -
* Configurations determining which relations to soft delete along with the each of the products. You can pass to its `returnLinkableKeys`
* property any of the product's relation attribute names, such as `variant_id`.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<Record<string, string[]> | void>}
* An object that includes the IDs of related records that were also soft deleted, such as the ID of associated product variants. The object's keys are the ID attribute names of the product entity's relations, such as `variant_id`, and its value is an array of strings, each being the ID of a record associated with the product through this relation, such as the IDs of associated product variants.
*
* If there are no related records, the promise resolved to `void`.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function deleteProducts (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const cascadedEntities = await productModule.softDelete(ids)
*
* // do something with the returned cascaded entity IDs or return them
* }
*/
softDelete<TReturnableLinkableKeys extends string = string>(
productIds: string[],
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
/**
* This method is used to restore products which were deleted using the {@link softDelete} method.
*
* @param {string[]} productIds - The IDs of the products to restore.
* @param {RestoreReturn<TReturnableLinkableKeys>} config -
* Configurations determining which relations to restore along with each of the products. You can pass to its `returnLinkableKeys`
* property any of the product's relation attribute names, such as `variant_id`.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<Record<string, string[]> | void>}
* An object that includes the IDs of related records that were restored, such as the ID of associated product variants. The object's keys are the ID attribute names of the product entity's relations, such as `variant_id`, and its value is an array of strings, each being the ID of the record associated with the product through this relation, such as the IDs of associated product variants.
*
* If there are no related records that were restored, the promise resolved to `void`.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function restoreProducts (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const cascadedEntities = await productModule.restore(ids, {
* returnLinkableKeys: ["variant_id"]
* })
*
* // do something with the returned cascaded entity IDs or return them
* }
*/
restore<TReturnableLinkableKeys extends string = string>(
productIds: string[],
config?: RestoreReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
/**
* This method is used to retrieve a tag by its ID.
*
@@ -1679,6 +1940,112 @@ export interface IProductModuleService extends IModuleService {
sharedContext?: Context
): Promise<ProductVariantDTO[]>
/**
* This method is used to retrieve a paginated list of product variants along with the total count of available product variants satisfying the provided filters.
*
* @param {FilterableProductVariantProps} filters - The filters applied on the retrieved product variants.
* @param {FindConfig<ProductVariantDTO>} config -
* The configurations determining how the product variants are retrieved. Its properties, such as `select` or `relations`, accept the
* attributes or relations associated with a product variant.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<[ProductVariantDTO[], number]>} The list of product variants along with their total count.
*
* @example
* To retrieve a list of product variants using their IDs:
*
* ```ts
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function retrieveProductVariants (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const [variants, count] = await productModule.listAndCountVariants({
* id: ids
* })
*
* // do something with the product variants or return them
* }
* ```
*
* To specify relations that should be retrieved within the product variants:
*
* ```ts
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function retrieveProductVariants (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const [variants, count] = await productModule.listAndCountVariants({
* id: ids
* }, {
* relations: ["options"]
* })
*
* // do something with the product variants or return them
* }
* ```
*
* By default, only the first `15` records are retrieved. You can control pagination by specifying the `skip` and `take` properties of the `config` parameter:
*
* ```ts
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function retrieveProductVariants (ids: string[], skip: number, take: number) {
* const productModule = await initializeProductModule()
*
* const [variants, count] = await productModule.listAndCountVariants({
* id: ids
* }, {
* relations: ["options"],
* skip,
* take
* })
*
* // do something with the product variants or return them
* }
* ```
*
* You can also use the `$and` or `$or` properties of the `filter` parameter to use and/or conditions in your filters. For example:
*
* ```ts
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function retrieveProductVariants (ids: string[], sku: string, skip: number, take: number) {
* const productModule = await initializeProductModule()
*
* const [variants, count] = await productModule.listAndCountVariants({
* $and: [
* {
* id: ids
* },
* {
* sku
* }
* ]
* }, {
* relations: ["options"],
* skip,
* take
* })
*
* // do something with the product variants or return them
* }
* ```
*/
listAndCountVariants(
filters?: FilterableProductVariantProps,
config?: FindConfig<ProductVariantDTO>,
sharedContext?: Context
): Promise<[ProductVariantDTO[], number]>
/**
* This method is used to create product variants.
*
@@ -1880,112 +2247,6 @@ export interface IProductModuleService extends IModuleService {
sharedContext?: Context
): Promise<void>
/**
* This method is used to retrieve a paginated list of product variants along with the total count of available product variants satisfying the provided filters.
*
* @param {FilterableProductVariantProps} filters - The filters applied on the retrieved product variants.
* @param {FindConfig<ProductVariantDTO>} config -
* The configurations determining how the product variants are retrieved. Its properties, such as `select` or `relations`, accept the
* attributes or relations associated with a product variant.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<[ProductVariantDTO[], number]>} The list of product variants along with their total count.
*
* @example
* To retrieve a list of product variants using their IDs:
*
* ```ts
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function retrieveProductVariants (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const [variants, count] = await productModule.listAndCountVariants({
* id: ids
* })
*
* // do something with the product variants or return them
* }
* ```
*
* To specify relations that should be retrieved within the product variants:
*
* ```ts
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function retrieveProductVariants (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const [variants, count] = await productModule.listAndCountVariants({
* id: ids
* }, {
* relations: ["options"]
* })
*
* // do something with the product variants or return them
* }
* ```
*
* By default, only the first `15` records are retrieved. You can control pagination by specifying the `skip` and `take` properties of the `config` parameter:
*
* ```ts
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function retrieveProductVariants (ids: string[], skip: number, take: number) {
* const productModule = await initializeProductModule()
*
* const [variants, count] = await productModule.listAndCountVariants({
* id: ids
* }, {
* relations: ["options"],
* skip,
* take
* })
*
* // do something with the product variants or return them
* }
* ```
*
* You can also use the `$and` or `$or` properties of the `filter` parameter to use and/or conditions in your filters. For example:
*
* ```ts
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function retrieveProductVariants (ids: string[], sku: string, skip: number, take: number) {
* const productModule = await initializeProductModule()
*
* const [variants, count] = await productModule.listAndCountVariants({
* $and: [
* {
* id: ids
* },
* {
* sku
* }
* ]
* }, {
* relations: ["options"],
* skip,
* take
* })
*
* // do something with the product variants or return them
* }
* ```
*/
listAndCountVariants(
filters?: FilterableProductVariantProps,
config?: FindConfig<ProductVariantDTO>,
sharedContext?: Context
): Promise<[ProductVariantDTO[], number]>
/**
* This method is used to delete variants. Unlike the {@link delete} method, this method won't completely remove the variant. It can still be accessed or retrieved using methods like {@link retrieve} if you pass the `withDeleted` property to the `config` object parameter.
*
@@ -2519,6 +2780,74 @@ export interface IProductModuleService extends IModuleService {
sharedContext?: Context
): Promise<void>
/**
* This method is used to delete product collections. Unlike the {@link deleteCollections} method, this method won't completely remove the collection. It can still be accessed or retrieved using methods like {@link retrieveCollections} if you pass the `withDeleted` property to the `config` object parameter.
*
* The soft-deleted collections can be restored using the {@link restoreCollections} method.
*
* @param {string[]} collectionIds - The IDs of the collections to soft-delete.
* @param {SoftDeleteReturn<TReturnableLinkableKeys>} config -
* Configurations determining which relations to soft delete along with the each of the collections. You can pass to its `returnLinkableKeys`
* property any of the collection's relation attribute names.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<Record<string, string[]> | void>}
* An object that includes the IDs of related records that were also soft deleted. The object's keys are the ID attribute names of the collection entity's relations.
*
* If there are no related records, the promise resolved to `void`.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function deleteCollections (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const cascadedEntities = await productModule.softDeleteCollections(ids)
*
* // do something with the returned cascaded entity IDs or return them
* }
*/
softDeleteCollections<TReturnableLinkableKeys extends string = string>(
collectionIds: string[],
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
/**
* This method is used to restore collections which were deleted using the {@link softDelete} method.
*
* @param {string[]} collectionIds - The IDs of the collections to restore.
* @param {RestoreReturn<TReturnableLinkableKeys>} config -
* Configurations determining which relations to restore along with each of the collections. You can pass to its `returnLinkableKeys`
* property any of the collection's relation attribute names.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<Record<string, string[]> | void>}
* An object that includes the IDs of related records that were restored. The object's keys are the ID attribute names of the product entity's relations.
*
* If there are no related records that were restored, the promise resolved to `void`.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function restoreCollections (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const cascadedEntities = await productModule.restoreCollections(ids, {
* returnLinkableKeys: []
* })
*
* // do something with the returned cascaded entity IDs or return them
* }
*/
restoreCollections<TReturnableLinkableKeys extends string = string>(
collectionIds: string[],
config?: RestoreReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
/**
* This method is used to retrieve a product category by its ID.
*
@@ -2859,365 +3188,4 @@ export interface IProductModuleService extends IModuleService {
* }
*/
deleteCategory(categoryId: string, sharedContext?: Context): Promise<void>
/**
* This method is used to create a list of products.
*
* @param {CreateProductDTO[]} data - The products to be created.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO[]>} The list of created products.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function createProduct (title: string) {
* const productModule = await initializeProductModule()
*
* const products = await productModule.create([
* {
* title
* }
* ])
*
* // do something with the products or return them
* }
*/
create(
data: CreateProductDTO[],
sharedContext?: Context
): Promise<ProductDTO[]>
/**
* This method is used to create a product.
*
* @param {CreateProductDTO} data - The product to be created.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO>} The created product.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function createProduct (title: string) {
* const productModule = await initializeProductModule()
*
* const product = await productModule.create(
* {
* title
* }
* )
*
* // do something with the product or return it
* }
*/
create(data: CreateProductDTO, sharedContext?: Context): Promise<ProductDTO>
/**
* This method updates existing products, or creates new ones if they don't exist.
*
* @param {CreateProductDTO[]} data - The attributes to update or create for each product.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO[]>} The updated and created products.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function upserProduct (title: string) {
* const productModule = await initializeProductModule()
*
* const createdProducts = await productModule.upsert([
* {
* title
* }
* ])
*
* // do something with the products or return them
* }
*/
upsert(
data: UpsertProductDTO[],
sharedContext?: Context
): Promise<ProductDTO[]>
/**
* This method updates the product if it exists, or creates a new ones if it doesn't.
*
* @param {CreateProductDTO} data - The attributes to update or create for the new product.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO>} The updated or created product.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function upserProduct (title: string) {
* const productModule = await initializeProductModule()
*
* const createdProduct = await productModule.upsert(
* {
* title
* }
* )
*
* // do something with the product or return it
* }
*/
upsert(
data: UpsertProductDTO[],
sharedContext?: Context
): Promise<ProductDTO[]>
/**
* This method is used to update a product.
*
* @param {string} id - The ID of the product to be updated.
* @param {UpdateProductDTO} data - The attributes of the product to be updated
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO>} The updated product.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function updateProduct (id: string, title: string) {
* const productModule = await initializeProductModule()
*
* const product = await productModule.update(id, {
* title
* }
* )
*
* // do something with the product or return it
* }
*/
update(
id: string,
data: UpdateProductDTO,
sharedContext?: Context
): Promise<ProductDTO>
/**
* This method is used to update a list of products determined by the selector filters.
*
* @param {FilterableProductProps} selector - The filters that will determine which products will be updated.
* @param {UpdateProductDTO} data - The attributes to be updated on the selected products
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<ProductDTO[]>} The updated products.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function updateProduct (id: string, title: string) {
* const productModule = await initializeProductModule()
*
* const products = await productModule.update({id}, {
* title
* }
* )
*
* // do something with the products or return them
* }
*/
update(
selector: FilterableProductProps,
data: UpdateProductDTO,
sharedContext?: Context
): Promise<ProductDTO[]>
/**
* This method is used to delete products. Unlike the {@link softDelete} method, this method will completely remove the products and they can no longer be accessed or retrieved.
*
* @param {string[]} productIds - The IDs of the products to be deleted.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<void>} Resolves when the products are successfully deleted.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function deleteProducts (ids: string[]) {
* const productModule = await initializeProductModule()
*
* await productModule.delete(ids)
* }
*/
delete(productIds: string[], sharedContext?: Context): Promise<void>
/**
* This method is used to delete products. Unlike the {@link delete} method, this method won't completely remove the product. It can still be accessed or retrieved using methods like {@link retrieve} if you pass the `withDeleted` property to the `config` object parameter.
*
* The soft-deleted products can be restored using the {@link restore} method.
*
* @param {string[]} productIds - The IDs of the products to soft-delete.
* @param {SoftDeleteReturn<TReturnableLinkableKeys>} config -
* Configurations determining which relations to soft delete along with the each of the products. You can pass to its `returnLinkableKeys`
* property any of the product's relation attribute names, such as `variant_id`.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<Record<string, string[]> | void>}
* An object that includes the IDs of related records that were also soft deleted, such as the ID of associated product variants. The object's keys are the ID attribute names of the product entity's relations, such as `variant_id`, and its value is an array of strings, each being the ID of a record associated with the product through this relation, such as the IDs of associated product variants.
*
* If there are no related records, the promise resolved to `void`.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function deleteProducts (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const cascadedEntities = await productModule.softDelete(ids)
*
* // do something with the returned cascaded entity IDs or return them
* }
*/
softDelete<TReturnableLinkableKeys extends string = string>(
productIds: string[],
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
/**
* This method is used to restore products which were deleted using the {@link softDelete} method.
*
* @param {string[]} productIds - The IDs of the products to restore.
* @param {RestoreReturn<TReturnableLinkableKeys>} config -
* Configurations determining which relations to restore along with each of the products. You can pass to its `returnLinkableKeys`
* property any of the product's relation attribute names, such as `variant_id`.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<Record<string, string[]> | void>}
* An object that includes the IDs of related records that were restored, such as the ID of associated product variants. The object's keys are the ID attribute names of the product entity's relations, such as `variant_id`, and its value is an array of strings, each being the ID of the record associated with the product through this relation, such as the IDs of associated product variants.
*
* If there are no related records that were restored, the promise resolved to `void`.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function restoreProducts (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const cascadedEntities = await productModule.restore(ids, {
* returnLinkableKeys: ["variant_id"]
* })
*
* // do something with the returned cascaded entity IDs or return them
* }
*/
restore<TReturnableLinkableKeys extends string = string>(
productIds: string[],
config?: RestoreReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
/**
* This method is used to delete product collections. Unlike the {@link deleteCollections} method, this method won't completely remove the collection. It can still be accessed or retrieved using methods like {@link retrieveCollections} if you pass the `withDeleted` property to the `config` object parameter.
*
* The soft-deleted collections can be restored using the {@link restoreCollections} method.
*
* @param {string[]} collectionIds - The IDs of the collections to soft-delete.
* @param {SoftDeleteReturn<TReturnableLinkableKeys>} config -
* Configurations determining which relations to soft delete along with the each of the collections. You can pass to its `returnLinkableKeys`
* property any of the collection's relation attribute names.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<Record<string, string[]> | void>}
* An object that includes the IDs of related records that were also soft deleted. The object's keys are the ID attribute names of the collection entity's relations.
*
* If there are no related records, the promise resolved to `void`.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function deleteCollections (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const cascadedEntities = await productModule.softDeleteCollections(ids)
*
* // do something with the returned cascaded entity IDs or return them
* }
*/
softDeleteCollections<TReturnableLinkableKeys extends string = string>(
collectionIds: string[],
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
/**
* This method is used to restore collections which were deleted using the {@link softDelete} method.
*
* @param {string[]} collectionIds - The IDs of the collections to restore.
* @param {RestoreReturn<TReturnableLinkableKeys>} config -
* Configurations determining which relations to restore along with each of the collections. You can pass to its `returnLinkableKeys`
* property any of the collection's relation attribute names.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<Record<string, string[]> | void>}
* An object that includes the IDs of related records that were restored. The object's keys are the ID attribute names of the product entity's relations.
*
* If there are no related records that were restored, the promise resolved to `void`.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function restoreCollections (ids: string[]) {
* const productModule = await initializeProductModule()
*
* const cascadedEntities = await productModule.restoreCollections(ids, {
* returnLinkableKeys: []
* })
*
* // do something with the returned cascaded entity IDs or return them
* }
*/
restoreCollections<TReturnableLinkableKeys extends string = string>(
collectionIds: string[],
config?: RestoreReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
/**
* This method is used to restore product varaints that were soft deleted. Product variants are soft deleted when they're not
* provided in a product's details passed to the {@link update} method.
*
* @param {string[]} variantIds - The IDs of the variants to restore.
* @param {RestoreReturn<TReturnableLinkableKeys>} config -
* Configurations determining which relations to restore along with each of the product variants. You can pass to its `returnLinkableKeys`
* property any of the product variant's relation attribute names.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<Record<string, string[]> | void>}
* An object that includes the IDs of related records that were restored. The object's keys are the ID attribute names of the product variant entity's relations
* and its value is an array of strings, each being the ID of the record associated with the product variant through this relation.
*
* If there are no related records that were restored, the promise resolved to `void`.
*
* @example
* import {
* initialize as initializeProductModule,
* } from "@medusajs/product"
*
* async function restoreProductVariants (ids: string[]) {
* const productModule = await initializeProductModule()
*
* await productModule.restoreVariants(ids)
* }
*/
restoreVariants<TReturnableLinkableKeys extends string = string>(
variantIds: string[],
config?: RestoreReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
}