diff --git a/packages/core/core-flows/src/product/steps/batch-link-products-collection.ts b/packages/core/core-flows/src/product/steps/batch-link-products-collection.ts index 57246b305e..b524d6bcd3 100644 --- a/packages/core/core-flows/src/product/steps/batch-link-products-collection.ts +++ b/packages/core/core-flows/src/product/steps/batch-link-products-collection.ts @@ -8,7 +8,14 @@ import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk" export const batchLinkProductsToCollectionStepId = "batch-link-products-to-collection" /** - * This step creates links between product and collection records. + * This step manages the links between a collection and products. + * + * @example + * const data = batchLinkProductsToCollectionStep({ + * id: "collection_123", + * add: ["product_123"], + * remove: ["product_321"] + * }) */ export const batchLinkProductsToCollectionStep = createStep( batchLinkProductsToCollectionStepId, diff --git a/packages/core/core-flows/src/product/steps/batch-link-products-in-category.ts b/packages/core/core-flows/src/product/steps/batch-link-products-in-category.ts index 1c8e705798..3a8f996d2d 100644 --- a/packages/core/core-flows/src/product/steps/batch-link-products-in-category.ts +++ b/packages/core/core-flows/src/product/steps/batch-link-products-in-category.ts @@ -8,7 +8,14 @@ import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk" export const batchLinkProductsToCategoryStepId = "batch-link-products-to-category" /** - * This step creates links between product and category records. + * This step manages the links between a category and products. + * + * @example + * const data = batchLinkProductsToCategoryStep({ + * id: "pcat_123", + * add: ["product_123"], + * remove: ["product_321"] + * }) */ export const batchLinkProductsToCategoryStep = createStep( batchLinkProductsToCategoryStepId, diff --git a/packages/core/core-flows/src/product/steps/create-product-options.ts b/packages/core/core-flows/src/product/steps/create-product-options.ts index ea8c9701fb..9761786a76 100644 --- a/packages/core/core-flows/src/product/steps/create-product-options.ts +++ b/packages/core/core-flows/src/product/steps/create-product-options.ts @@ -5,6 +5,12 @@ import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" export const createProductOptionsStepId = "create-product-options" /** * This step creates one or more product options. + * + * @example + * const data = createProductOptionsStep([{ + * title: "Size", + * values: ["S", "M", "L"] + * }]) */ export const createProductOptionsStep = createStep( createProductOptionsStepId, diff --git a/packages/core/core-flows/src/product/steps/create-product-variants.ts b/packages/core/core-flows/src/product/steps/create-product-variants.ts index f88722b13c..69b38bf763 100644 --- a/packages/core/core-flows/src/product/steps/create-product-variants.ts +++ b/packages/core/core-flows/src/product/steps/create-product-variants.ts @@ -5,6 +5,15 @@ import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" export const createProductVariantsStepId = "create-product-variants" /** * This step creates one or more product variants. + * + * @example + * const data = createProductVariantsStep([{ + * title: "Small Shirt", + * options: { + * Size: "S", + * }, + * product_id: "prod_123", + * }]) */ export const createProductVariantsStep = createStep( createProductVariantsStepId, diff --git a/packages/core/core-flows/src/product/steps/create-products.ts b/packages/core/core-flows/src/product/steps/create-products.ts index 4a96df4bc8..0f7615175b 100644 --- a/packages/core/core-flows/src/product/steps/create-products.ts +++ b/packages/core/core-flows/src/product/steps/create-products.ts @@ -5,6 +5,25 @@ import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" export const createProductsStepId = "create-products" /** * This step creates one or more products. + * + * @example + * const data = createProductsStep([{ + * title: "Shirt", + * options: [ + * { + * title: "Size", + * values: ["S", "M", "L"] + * } + * ], + * variants: [ + * { + * title: "Small Shirt", + * options: { + * Size: "S" + * } + * } + * ] + * }]) */ export const createProductsStep = createStep( createProductsStepId, diff --git a/packages/core/core-flows/src/product/steps/create-variant-pricing-link.ts b/packages/core/core-flows/src/product/steps/create-variant-pricing-link.ts index 15d79700d0..980393cffe 100644 --- a/packages/core/core-flows/src/product/steps/create-variant-pricing-link.ts +++ b/packages/core/core-flows/src/product/steps/create-variant-pricing-link.ts @@ -1,9 +1,21 @@ import { ContainerRegistrationKeys, Modules } from "@medusajs/framework/utils" import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk" +/** + * The links to create between variant and price set records. + */ export type CreateVariantPricingLinkStepInput = { + /** + * The variant and price set record IDs to link. + */ links: { + /** + * The variant's ID. + */ variant_id: string + /** + * The price set's ID. + */ price_set_id: string }[] } @@ -11,6 +23,16 @@ export type CreateVariantPricingLinkStepInput = { export const createVariantPricingLinkStepId = "create-variant-pricing-link" /** * This step creates links between variant and price set records. + * + * @example + * const data = createVariantPricingLinkStep({ + * links: [ + * { + * variant_id: "variant_123", + * price_set_id: "pset_123" + * } + * ] + * }) */ export const createVariantPricingLinkStep = createStep( createVariantPricingLinkStepId, diff --git a/packages/core/core-flows/src/product/steps/delete-collections.ts b/packages/core/core-flows/src/product/steps/delete-collections.ts index 14f2b2ad9c..972dba99a2 100644 --- a/packages/core/core-flows/src/product/steps/delete-collections.ts +++ b/packages/core/core-flows/src/product/steps/delete-collections.ts @@ -2,13 +2,18 @@ import { IProductModuleService } from "@medusajs/framework/types" import { Modules } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The IDs of the collections to delete. + */ +export type DeleteCollectionsStepInput = string[] + export const deleteCollectionsStepId = "delete-collections" /** * This step deletes one or more collections. */ export const deleteCollectionsStep = createStep( deleteCollectionsStepId, - async (ids: string[], { container }) => { + async (ids: DeleteCollectionsStepInput, { container }) => { const service = container.resolve(Modules.PRODUCT) await service.softDeleteProductCollections(ids) diff --git a/packages/core/core-flows/src/product/steps/delete-product-options.ts b/packages/core/core-flows/src/product/steps/delete-product-options.ts index ce3b04c541..b106a4d0c2 100644 --- a/packages/core/core-flows/src/product/steps/delete-product-options.ts +++ b/packages/core/core-flows/src/product/steps/delete-product-options.ts @@ -2,13 +2,18 @@ import { IProductModuleService } from "@medusajs/framework/types" import { Modules } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The IDs of the product options to delete. + */ +export type DeleteProductOptionsStepInput = string[] + export const deleteProductOptionsStepId = "delete-product-options" /** * This step deletes one or more product options. */ export const deleteProductOptionsStep = createStep( deleteProductOptionsStepId, - async (ids: string[], { container }) => { + async (ids: DeleteProductOptionsStepInput, { container }) => { const service = container.resolve(Modules.PRODUCT) await service.softDeleteProductOptions(ids) diff --git a/packages/core/core-flows/src/product/steps/delete-product-tags.ts b/packages/core/core-flows/src/product/steps/delete-product-tags.ts index e962c8278b..04ade4dd11 100644 --- a/packages/core/core-flows/src/product/steps/delete-product-tags.ts +++ b/packages/core/core-flows/src/product/steps/delete-product-tags.ts @@ -2,13 +2,18 @@ import { IProductModuleService } from "@medusajs/framework/types" import { Modules } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The IDs of the product tags to delete. + */ +export type DeleteProductTagsStepInput = string[] + export const deleteProductTagsStepId = "delete-product-tags" /** * This step deletes one or more product tags. */ export const deleteProductTagsStep = createStep( deleteProductTagsStepId, - async (ids: string[], { container }) => { + async (ids: DeleteProductTagsStepInput, { container }) => { const service = container.resolve(Modules.PRODUCT) await service.softDeleteProductTags(ids) diff --git a/packages/core/core-flows/src/product/steps/delete-product-types.ts b/packages/core/core-flows/src/product/steps/delete-product-types.ts index c464ba51a1..32800a27d5 100644 --- a/packages/core/core-flows/src/product/steps/delete-product-types.ts +++ b/packages/core/core-flows/src/product/steps/delete-product-types.ts @@ -2,13 +2,18 @@ import { IProductModuleService } from "@medusajs/framework/types" import { Modules } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The IDs of the product types to delete. + */ +export type DeleteProductTypesStepInput = string[] + export const deleteProductTypesStepId = "delete-product-types" /** * This step deletes one or more product types. */ export const deleteProductTypesStep = createStep( deleteProductTypesStepId, - async (ids: string[], { container }) => { + async (ids: DeleteProductTypesStepInput, { container }) => { const service = container.resolve(Modules.PRODUCT) await service.softDeleteProductTypes(ids) diff --git a/packages/core/core-flows/src/product/steps/delete-product-variants.ts b/packages/core/core-flows/src/product/steps/delete-product-variants.ts index 94f0949443..3e42c06d80 100644 --- a/packages/core/core-flows/src/product/steps/delete-product-variants.ts +++ b/packages/core/core-flows/src/product/steps/delete-product-variants.ts @@ -2,13 +2,18 @@ import { IProductModuleService } from "@medusajs/framework/types" import { Modules } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The IDs of the product variants to delete. + */ +export type DeleteProductVariantsStepInput = string[] + export const deleteProductVariantsStepId = "delete-product-variants" /** * This step deletes one or more product variants. */ export const deleteProductVariantsStep = createStep( deleteProductVariantsStepId, - async (ids: string[], { container }) => { + async (ids: DeleteProductVariantsStepInput, { container }) => { const service = container.resolve(Modules.PRODUCT) await service.softDeleteProductVariants(ids) diff --git a/packages/core/core-flows/src/product/steps/delete-products.ts b/packages/core/core-flows/src/product/steps/delete-products.ts index 4080acbb67..6f649778df 100644 --- a/packages/core/core-flows/src/product/steps/delete-products.ts +++ b/packages/core/core-flows/src/product/steps/delete-products.ts @@ -2,13 +2,18 @@ import { IProductModuleService } from "@medusajs/framework/types" import { Modules } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The IDs of the products to delete. + */ +export type DeleteProductsStepInput = string[] + export const deleteProductsStepId = "delete-products" /** * This step deletes one or more products. */ export const deleteProductsStep = createStep( deleteProductsStepId, - async (ids: string[], { container }) => { + async (ids: DeleteProductsStepInput, { container }) => { const service = container.resolve(Modules.PRODUCT) await service.softDeleteProducts(ids) diff --git a/packages/core/core-flows/src/product/steps/generate-product-csv.ts b/packages/core/core-flows/src/product/steps/generate-product-csv.ts index a095bc400d..148f83089b 100644 --- a/packages/core/core-flows/src/product/steps/generate-product-csv.ts +++ b/packages/core/core-flows/src/product/steps/generate-product-csv.ts @@ -58,13 +58,42 @@ const csvSortFunction = (a: string, b: string) => { return a.localeCompare(b) } +/** + * The products to export. + */ +export type GenerateProductCsvStepInput = HttpTypes.AdminProduct[] + +/** + * The export's details. + */ +export type GenerateProductCsvStepOutput = { + /** + * The ID of the generated file as returned by the [File Module Provider](https://docs.medusajs.com/resources/architectural-modules/file). + */ + id: string + /** + * The name of the generated file as returned by the [File Module Provider](https://docs.medusajs.com/resources/architectural-modules/file). + */ + filename: string +} + export const generateProductCsvStepId = "generate-product-csv" /** - * This step generates a CSV file to be exported. + * This step generates a CSV file that exports products. The CSV + * file is created and stored using the registered [File Module Provider](https://docs.medusajs.com/resources/architectural-modules/file). + * + * @example + * const { data: products } = useQueryGraphStep({ + * entity: "product", + * fields: ["*", "variants.*", "collection.*", "categories.*"] + * }) + * + * // @ts-ignore + * const data = generateProductCsvStep(products) */ export const generateProductCsvStep = createStep( generateProductCsvStepId, - async (products: HttpTypes.AdminProduct[], { container }) => { + async (products: GenerateProductCsvStepInput, { container }) => { const regionService = container.resolve( Modules.REGION ) @@ -88,7 +117,10 @@ export const generateProductCsvStep = createStep( content: csvContent, }) - return new StepResponse({ id: file.id, filename }, file.id) + return new StepResponse( + { id: file.id, filename } as GenerateProductCsvStepOutput, + file.id + ) }, async (fileId, { container }) => { if (!fileId) { diff --git a/packages/core/core-flows/src/product/steps/get-all-products.ts b/packages/core/core-flows/src/product/steps/get-all-products.ts index 855150d6a7..775e34a48e 100644 --- a/packages/core/core-flows/src/product/steps/get-all-products.ts +++ b/packages/core/core-flows/src/product/steps/get-all-products.ts @@ -5,14 +5,44 @@ import { import { ContainerRegistrationKeys } from "@medusajs/framework/utils" import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk" +/** + * The configuration to retrieve the products. + */ export type GetAllProductsStepInput = { + /** + * The fields to select. These fields will be passed to + * [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query), so you can + * pass product properties or any relation names, including custom links. + */ select: string[] + /** + * The filters to select which products to retrieve. + */ filter?: FilterableProductProps } export const getAllProductsStepId = "get-all-products" /** - * This step retrieves all products. + * This step retrieves all products matching a set of filters. + * + * @example + * To retrieve all products: + * + * ```ts + * const data = getAllProductsStep({ + * select: ["*"], + * }) + * ``` + * + * To retrieve all products matching a filter: + * + * ```ts + * const data = getAllProductsStep({ + * select: ["*"], + * filter: { + * collection_id: "collection_123" + * } + * }) */ export const getAllProductsStep = createStep( getAllProductsStepId, diff --git a/packages/core/core-flows/src/product/steps/get-products.ts b/packages/core/core-flows/src/product/steps/get-products.ts index f554570235..ab85b415d3 100644 --- a/packages/core/core-flows/src/product/steps/get-products.ts +++ b/packages/core/core-flows/src/product/steps/get-products.ts @@ -2,13 +2,19 @@ import { IProductModuleService } from "@medusajs/framework/types" import { Modules } from "@medusajs/framework/utils" import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk" +/** + * Configurations to retrieve products. + */ export type GetProductsStepInput = { + /** + * The IDs of the products to retrieve. + */ ids?: string[] } export const getProductsStepId = "get-products" /** - * This step retrieves products. + * This step retrieves products, with ability to filter by product IDs. */ export const getProductsStep = createStep( getProductsStepId, diff --git a/packages/core/core-flows/src/product/steps/get-variant-availability.ts b/packages/core/core-flows/src/product/steps/get-variant-availability.ts index c7bcb47942..075febd2e3 100644 --- a/packages/core/core-flows/src/product/steps/get-variant-availability.ts +++ b/packages/core/core-flows/src/product/steps/get-variant-availability.ts @@ -4,14 +4,29 @@ import { getVariantAvailability, } from "@medusajs/framework/utils" +/** + * The details required to compute the inventory availability for a list of variants in a given sales channel. + */ export type GetVariantAvailabilityStepInput = { + /** + * The IDs of the variants to retrieve their availability. + */ variant_ids: string[] + /** + * The ID of the sales channel to retrieve the variant availability in. + */ sales_channel_id: string } export const getVariantAvailabilityId = "get-variant-availability" /** - * Computes the varaint availability for a list of variants in a given sales channel + * This step computes the inventory availability for a list of variants in a given sales channel. + * + * @example + * const data = getVariantAvailabilityStep({ + * variant_ids: ["variant_123"], + * sales_channel_id: "sc_123" + * }) */ export const getVariantAvailabilityStep = createStep( getVariantAvailabilityId, diff --git a/packages/core/core-flows/src/product/steps/get-variant-pricing-link.ts b/packages/core/core-flows/src/product/steps/get-variant-pricing-link.ts index 42923590a4..3be377df1a 100644 --- a/packages/core/core-flows/src/product/steps/get-variant-pricing-link.ts +++ b/packages/core/core-flows/src/product/steps/get-variant-pricing-link.ts @@ -6,7 +6,13 @@ import { } from "@medusajs/framework/utils" import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk" +/** + * The configurations to retrieve pricing links for product variants. + */ export type GetVariantPricingLinkStepInput = { + /** + * The IDs of the product variants to retrieve pricing links for. + */ ids: string[] } diff --git a/packages/core/core-flows/src/product/steps/group-products-for-batch.ts b/packages/core/core-flows/src/product/steps/group-products-for-batch.ts index b3b381f426..f62c4e0ef0 100644 --- a/packages/core/core-flows/src/product/steps/group-products-for-batch.ts +++ b/packages/core/core-flows/src/product/steps/group-products-for-batch.ts @@ -2,14 +2,72 @@ import { HttpTypes, IProductModuleService } from "@medusajs/framework/types" import { Modules } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The products to group. + */ +export type GroupProductsForBatchStepInput = (HttpTypes.AdminCreateProduct & { + /** + * The ID of the product to update. + */ + id?: string +})[] + +export type GroupProductsForBatchStepOutput = { + /** + * The products to create. + */ + create: HttpTypes.AdminCreateProduct[] + /** + * The products to update. + */ + update: (HttpTypes.AdminUpdateProduct & { id: string })[] +} + export const groupProductsForBatchStepId = "group-products-for-batch" /** - * This step groups products to be created and updated. + * This step groups products to be created or updated. + * + * @example + * const data = groupProductsForBatchStep([ + * { + * id: "prod_123", + * title: "Shirt", + * options: [ + * { + * title: "Size", + * values: ["S", "M", "L"] + * } + * ] + * }, + * { + * title: "Pants", + * options: [ + * { + * title: "Color", + * values: ["Red", "Blue"] + * } + * ], + * variants: [ + * { + * title: "Red Pants", + * options: { + * Color: "Red" + * }, + * prices: [ + * { + * amount: 10, + * currency_code: "usd" + * } + * ] + * } + * ] + * } + * ]) */ export const groupProductsForBatchStep = createStep( groupProductsForBatchStepId, async ( - data: (HttpTypes.AdminCreateProduct & { id?: string })[], + data: GroupProductsForBatchStepInput, { container } ) => { const service = container.resolve(Modules.PRODUCT) @@ -52,6 +110,8 @@ export const groupProductsForBatchStep = createStep( { toUpdate: [], toCreate: [] } ) - return new StepResponse({ create: toCreate, update: toUpdate }) + return new StepResponse( + { create: toCreate, update: toUpdate } as GroupProductsForBatchStepOutput, + ) } ) diff --git a/packages/core/core-flows/src/product/steps/index.ts b/packages/core/core-flows/src/product/steps/index.ts index 37e7f0ec67..79e3db53fa 100644 --- a/packages/core/core-flows/src/product/steps/index.ts +++ b/packages/core/core-flows/src/product/steps/index.ts @@ -14,6 +14,7 @@ export * from "./create-collections" export * from "./update-collections" export * from "./delete-collections" export * from "./batch-link-products-collection" +export * from "./batch-link-products-in-category" export * from "./create-product-types" export * from "./update-product-types" export * from "./delete-product-types" @@ -24,3 +25,4 @@ export * from "./generate-product-csv" export * from "./parse-product-csv" export * from "./group-products-for-batch" export * from "./wait-confirmation-product-import" +export * from "./get-variant-availability" \ No newline at end of file diff --git a/packages/core/core-flows/src/product/steps/parse-product-csv.ts b/packages/core/core-flows/src/product/steps/parse-product-csv.ts index 5bacf3c966..933de4ba1e 100644 --- a/packages/core/core-flows/src/product/steps/parse-product-csv.ts +++ b/packages/core/core-flows/src/product/steps/parse-product-csv.ts @@ -9,13 +9,22 @@ import { normalizeForImport } from "../helpers/normalize-for-import" import { normalizeV1Products } from "../helpers/normalize-v1-import" import { convertCsvToJson } from "../utlils" +/** + * The CSV file content to parse. + */ +export type ParseProductCsvStepInput = string + export const parseProductCsvStepId = "parse-product-csv" /** - * This step parses a CSV file holding products to import. + * This step parses a CSV file holding products to import, returning the products as + * objects that can be imported. + * + * @example + * const data = parseProductCsvStep("products.csv") */ export const parseProductCsvStep = createStep( parseProductCsvStepId, - async (fileContent: string, { container }) => { + async (fileContent: ParseProductCsvStepInput, { container }) => { const regionService = container.resolve( Modules.REGION ) diff --git a/packages/core/core-flows/src/product/steps/update-collections.ts b/packages/core/core-flows/src/product/steps/update-collections.ts index 4745509c14..7a31260f2f 100644 --- a/packages/core/core-flows/src/product/steps/update-collections.ts +++ b/packages/core/core-flows/src/product/steps/update-collections.ts @@ -5,14 +5,33 @@ import { } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The data to identify and update the product collections. + */ export type UpdateCollectionsStepInput = { + /** + * The filters to select the collections to update. + */ selector: ProductTypes.FilterableProductCollectionProps + /** + * The data to update the collections with. + */ update: ProductTypes.UpdateProductCollectionDTO } export const updateCollectionsStepId = "update-collections" /** * This step updates collections matching the specified filters. + * + * @example + * const data = updateCollectionsStep({ + * selector: { + * id: "collection_123" + * }, + * update: { + * title: "Summer Collection" + * } + * }) */ export const updateCollectionsStep = createStep( updateCollectionsStepId, diff --git a/packages/core/core-flows/src/product/steps/update-product-options.ts b/packages/core/core-flows/src/product/steps/update-product-options.ts index f29c96971b..121c5c6ff2 100644 --- a/packages/core/core-flows/src/product/steps/update-product-options.ts +++ b/packages/core/core-flows/src/product/steps/update-product-options.ts @@ -5,14 +5,33 @@ import { } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The data to identify and update the product options. + */ export type UpdateProductOptionsStepInput = { + /** + * The filters to select the product options to update. + */ selector: ProductTypes.FilterableProductOptionProps + /** + * The data to update the product options with. + */ update: ProductTypes.UpdateProductOptionDTO } export const updateProductOptionsStepId = "update-product-options" /** * This step updates product options matching the specified filters. + * + * @example + * const data = updateProductOptionsStep({ + * selector: { + * id: "popt_123" + * }, + * update: { + * title: "Size" + * } + * }) */ export const updateProductOptionsStep = createStep( updateProductOptionsStepId, diff --git a/packages/core/core-flows/src/product/steps/update-product-tags.ts b/packages/core/core-flows/src/product/steps/update-product-tags.ts index 0965693e61..b78b48b3e0 100644 --- a/packages/core/core-flows/src/product/steps/update-product-tags.ts +++ b/packages/core/core-flows/src/product/steps/update-product-tags.ts @@ -5,14 +5,33 @@ import { } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The data to identify and update the product tags. + */ export type UpdateProductTagsStepInput = { + /** + * The filters to select the product tags to update. + */ selector: ProductTypes.FilterableProductTagProps + /** + * The data to update the product tags with. + */ update: ProductTypes.UpdateProductTagDTO } export const updateProductTagsStepId = "update-product-tags" /** * This step updates product tags matching the specified filters. + * + * @example + * const data = updateProductTagsStep({ + * selector: { + * id: "popt_123" + * }, + * update: { + * value: "clothing" + * } + * }) */ export const updateProductTagsStep = createStep( updateProductTagsStepId, diff --git a/packages/core/core-flows/src/product/steps/update-product-types.ts b/packages/core/core-flows/src/product/steps/update-product-types.ts index 6d2415e474..e81b9c4ebb 100644 --- a/packages/core/core-flows/src/product/steps/update-product-types.ts +++ b/packages/core/core-flows/src/product/steps/update-product-types.ts @@ -5,14 +5,33 @@ import { } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The data to identify and update the product tags. + */ export type UpdateProductTypesStepInput = { + /** + * The filters to select the product types to update. + */ selector: ProductTypes.FilterableProductTypeProps + /** + * The data to update the product types with. + */ update: ProductTypes.UpdateProductTypeDTO } export const updateProductTypesStepId = "update-product-types" /** * This step updates product types matching the specified filters. + * + * @example + * const data = updateProductTypesStep({ + * selector: { + * id: "popt_123" + * }, + * update: { + * value: "clothing" + * } + * }) */ export const updateProductTypesStep = createStep( updateProductTypesStepId, diff --git a/packages/core/core-flows/src/product/steps/update-product-variants.ts b/packages/core/core-flows/src/product/steps/update-product-variants.ts index db9403dfc9..7556d4d358 100644 --- a/packages/core/core-flows/src/product/steps/update-product-variants.ts +++ b/packages/core/core-flows/src/product/steps/update-product-variants.ts @@ -6,18 +6,57 @@ import { } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The details of the product variants update. + */ export type UpdateProductVariantsStepInput = | { + /** + * The filters to select the product variants to update. + */ selector: ProductTypes.FilterableProductVariantProps + /** + * The data to update the product variants with. + */ update: ProductTypes.UpdateProductVariantDTO } | { + /** + * The data to create or update product variants. + */ product_variants: ProductTypes.UpsertProductVariantDTO[] } export const updateProductVariantsStepId = "update-product-variants" /** * This step updates one or more product variants. + * + * @example + * To update product variants by their ID: + * + * ```ts + * const data = updateProductVariantsStep({ + * product_variants: [ + * { + * id: "variant_123", + * title: "Small Shirt" + * } + * ] + * }) + * ``` + * + * To update product variants matching a filter: + * + * ```ts + * const data = updateProductVariantsStep({ + * selector: { + * product_id: "prod_123", + * }, + * update: { + * material: "cotton", + * } + * }) + * ``` */ export const updateProductVariantsStep = createStep( updateProductVariantsStepId, diff --git a/packages/core/core-flows/src/product/steps/update-products.ts b/packages/core/core-flows/src/product/steps/update-products.ts index acf86bcb13..599625185f 100644 --- a/packages/core/core-flows/src/product/steps/update-products.ts +++ b/packages/core/core-flows/src/product/steps/update-products.ts @@ -6,18 +6,57 @@ import { } from "@medusajs/framework/utils" import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk" +/** + * The details of the products update. + */ export type UpdateProductsStepInput = | { + /** + * The filters to select the products to update. + */ selector: ProductTypes.FilterableProductProps + /** + * The data to update the products with. + */ update: ProductTypes.UpdateProductDTO } | { + /** + * The data to create or update products. + */ products: ProductTypes.UpsertProductDTO[] } export const updateProductsStepId = "update-products" /** * This step updates one or more products. + * + * @example + * To update products by their ID: + * + * ```ts + * const data = updateProductsStep({ + * products: [ + * { + * id: "prod_123", + * title: "Shirt" + * } + * ] + * }) + * ``` + * + * To update products matching a filter: + * + * ```ts + * const data = updateProductsStep({ + * selector: { + * collection_id: "collection_123", + * }, + * update: { + * material: "cotton", + * } + * }) + * ``` */ export const updateProductsStep = createStep( updateProductsStepId, diff --git a/packages/core/core-flows/src/product/steps/wait-confirmation-product-import.ts b/packages/core/core-flows/src/product/steps/wait-confirmation-product-import.ts index 231ae19b41..1dd894acca 100644 --- a/packages/core/core-flows/src/product/steps/wait-confirmation-product-import.ts +++ b/packages/core/core-flows/src/product/steps/wait-confirmation-product-import.ts @@ -3,7 +3,10 @@ import { createStep } from "@medusajs/framework/workflows-sdk" export const waitConfirmationProductImportStepId = "wait-confirmation-product-import" /** - * This step waits until a product import is confirmed. + * This step waits until a product import is confirmed. It's useful before executing the + * {@link batchProductsWorkflow}. + * + * This step is asynchronous and will make the workflow using it a [Long-Running Workflow](https://docs.medusajs.com/learn/fundamentals/workflows/long-running-workflow). */ export const waitConfirmationProductImportStep = createStep( { diff --git a/packages/core/core-flows/src/product/workflows/batch-link-products-collection.ts b/packages/core/core-flows/src/product/workflows/batch-link-products-collection.ts index 1e4352347c..e90ac1c909 100644 --- a/packages/core/core-flows/src/product/workflows/batch-link-products-collection.ts +++ b/packages/core/core-flows/src/product/workflows/batch-link-products-collection.ts @@ -6,7 +6,24 @@ export const batchLinkProductsToCollectionWorkflowId = "batch-link-products-to-collection" /** - * This workflow creates links between product and collection records. + * This workflow manages the links between a collection and products. It's used by the + * [Manage Products of Collection Admin API Route](https://docs.medusajs.com/api/admin#collections_postcollectionsidproducts). + * + * You can use this workflow within your own custom workflows to manage the products in a collection. + * + * @example + * const { result } = await batchLinkProductsToCollectionWorkflow(container) + * .run({ + * input: { + * id: "pcol_123", + * add: ["prod_123"], + * remove: ["prod_456"], + * } + * }) + * + * @summary + * + * Manage the links between a collection and products. */ export const batchLinkProductsToCollectionWorkflow = createWorkflow( batchLinkProductsToCollectionWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/batch-product-variants.ts b/packages/core/core-flows/src/product/workflows/batch-product-variants.ts index 84194a6a60..cb823470e2 100644 --- a/packages/core/core-flows/src/product/workflows/batch-product-variants.ts +++ b/packages/core/core-flows/src/product/workflows/batch-product-variants.ts @@ -16,20 +16,61 @@ import { createProductVariantsWorkflow } from "./create-product-variants" import { updateProductVariantsWorkflow } from "./update-product-variants" import { deleteProductVariantsWorkflow } from "./delete-product-variants" +/** + * The product variants to manage. + */ +export type BatchProductVariantsWorkflowInput = BatchWorkflowInput< + CreateProductVariantWorkflowInputDTO, + UpdateProductVariantWorkflowInputDTO +> + +/** + * The result of managing the product variants. + */ +export type BatchProductVariantsWorkflowOutput = BatchWorkflowOutput + export const batchProductVariantsWorkflowId = "batch-product-variants" /** - * This workflow creates, updates, and deletes product variants. + * This workflow creates, updates, and deletes product variants. It's used by the + * [Manage Variants in a Product Admin API Route](https://docs.medusajs.com/api/admin#products_postproductsidvariantsbatch). + * + * You can use this workflow within your own custom workflows to manage the variants of a product. You can also + * use this within a [seed script](https://docs.medusajs.com/learn/fundamentals/custom-cli-scripts/seed-data) or in a custom import script. + * + * @example + * const { result } = await batchProductVariantsWorkflow(container) + * .run({ + * input: { + * create: [ + * { + * title: "Small Shirt", + * product_id: "prod_123", + * options: { + * Size: "S" + * }, + * prices: [ + * { + * amount: 10, + * currency_code: "usd" + * } + * ] + * } + * ], + * update: [ + * { + * id: "variant_123", + * title: "Red Pants" + * } + * ], + * delete: ["variant_321"] + * } + * }) */ export const batchProductVariantsWorkflow = createWorkflow( batchProductVariantsWorkflowId, ( - input: WorkflowData< - BatchWorkflowInput< - CreateProductVariantWorkflowInputDTO, - UpdateProductVariantWorkflowInputDTO - > - > - ): WorkflowResponse> => { + input: WorkflowData + ): WorkflowResponse => { const normalizedInput = transform({ input }, (data) => { return { create: data.input.create ?? [], diff --git a/packages/core/core-flows/src/product/workflows/batch-products-in-category.ts b/packages/core/core-flows/src/product/workflows/batch-products-in-category.ts index 677dc5452e..bf5f95afe6 100644 --- a/packages/core/core-flows/src/product/workflows/batch-products-in-category.ts +++ b/packages/core/core-flows/src/product/workflows/batch-products-in-category.ts @@ -5,7 +5,24 @@ import { batchLinkProductsToCategoryStep } from "../steps/batch-link-products-in export const batchLinkProductsToCategoryWorkflowId = "batch-link-products-to-category" /** - * This workflow creates links between product and category records. + * This workflow manages the links between a category and products. It's used by the + * [Manage Products of Category Admin API Route](https://docs.medusajs.com/api/admin#product-categories_postproductcategoriesidproducts). + * + * You can use this workflow within your own custom workflows to manage the products in a category. + * + * @example + * const { result } = await batchLinkProductsToCategoryWorkflow(container) + * .run({ + * input: { + * id: "pcat_123", + * add: ["prod_123"], + * remove: ["prod_321"] + * } + * }) + * + * @summary + * + * Manage the links between a collection and products. */ export const batchLinkProductsToCategoryWorkflow = createWorkflow( batchLinkProductsToCategoryWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/batch-products.ts b/packages/core/core-flows/src/product/workflows/batch-products.ts index 76e1af13d8..915f1bac75 100644 --- a/packages/core/core-flows/src/product/workflows/batch-products.ts +++ b/packages/core/core-flows/src/product/workflows/batch-products.ts @@ -16,19 +16,69 @@ import { createProductsWorkflow } from "./create-products" import { deleteProductsWorkflow } from "./delete-products" import { updateProductsWorkflow } from "./update-products" +/** + * The products to manage. + */ +export type BatchProductWorkflowInput = BatchWorkflowInput< + CreateProductWorkflowInputDTO, + UpdateProductWorkflowInputDTO +> + export const batchProductsWorkflowId = "batch-products" /** - * This workflow creates, updates, or deletes products. + * This workflow creates, updates, or deletes products. It's used by the + * [Manage Products Admin API Route](https://docs.medusajs.com/api/admin#products_postproductsbatch). + * + * You can use this workflow within your own custom workflows to manage products in bulk. This is + * also useful when writing a [seed script](https://docs.medusajs.com/learn/fundamentals/custom-cli-scripts/seed-data) or a custom import script. + * + * @example + * const { result } = await batchProductsWorkflow(container) + * .run({ + * input: { + * create: [ + * { + * title: "Shirt", + * options: [ + * { + * title: "Color", + * values: ["Red", "Brown"] + * } + * ], + * variants: [ + * { + * title: "Red Shirt", + * options: { + * "Color": "Red" + * }, + * prices: [ + * { + * amount: 10, + * currency_code: "usd" + * } + * ] + * } + * ] + * } + * ], + * update: [ + * { + * id: "prod_123", + * title: "Pants" + * } + * ], + * delete: ["prod_321"] + * } + * }) + * + * @summary + * + * Manage products in bulk. */ export const batchProductsWorkflow = createWorkflow( batchProductsWorkflowId, ( - input: WorkflowData< - BatchWorkflowInput< - CreateProductWorkflowInputDTO, - UpdateProductWorkflowInputDTO - > - > + input: WorkflowData ): WorkflowResponse> => { const res = parallelize( createProductsWorkflow.runAsStep({ diff --git a/packages/core/core-flows/src/product/workflows/create-collections.ts b/packages/core/core-flows/src/product/workflows/create-collections.ts index dd9621119e..9adafba77f 100644 --- a/packages/core/core-flows/src/product/workflows/create-collections.ts +++ b/packages/core/core-flows/src/product/workflows/create-collections.ts @@ -10,13 +10,46 @@ import { import { emitEventStep } from "../../common" import { createCollectionsStep } from "../steps" +/** + * The details of the collection to create, along with custom data that's passed to the workflow's hooks. + */ export type CreateCollectionsWorkflowInput = { + /** + * The collections to create. + */ collections: ProductTypes.CreateProductCollectionDTO[] } & AdditionalData export const createCollectionsWorkflowId = "create-collections" /** - * This workflow creates one or more collections. + * This workflow creates one or more collections. It's used by the + * [Create Collection Admin API Route](https://docs.medusajs.com/api/admin#collections_postcollections). + * + * This workflow has a hook that allows you to perform custom actions on the created collections. For example, you can pass under `additional_data` custom data that + * allows you to create custom data models linked to the product collections. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product-collection creation. + * + * @example + * const { result } = await createCollectionsWorkflow(container) + * .run({ + * input: { + * collections: [ + * { + * title: "Summer Clothing" + * } + * ], + * additional_data: { + * erp_id: "123" + * } + * } + * }) + * + * @summary + * + * Create one or more product collections. + * + * @property hooks.collectionsCreated - This hook is executed after the collections are created. You can consume this hook to perform custom actions on the created collections. */ export const createCollectionsWorkflow = createWorkflow( createCollectionsWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/create-product-tags.ts b/packages/core/core-flows/src/product/workflows/create-product-tags.ts index 5486d8cff9..970246087f 100644 --- a/packages/core/core-flows/src/product/workflows/create-product-tags.ts +++ b/packages/core/core-flows/src/product/workflows/create-product-tags.ts @@ -10,13 +10,46 @@ import { import { emitEventStep } from "../../common/steps/emit-event" import { createProductTagsStep } from "../steps" +/** + * The data to create one or more product tags, along with custom data that's passed to the workflow's hooks. + */ export type CreateProductTagsWorkflowInput = { + /** + * The product tags to create. + */ product_tags: ProductTypes.CreateProductTagDTO[] } & AdditionalData export const createProductTagsWorkflowId = "create-product-tags" /** - * This workflow creates one or more product tags. + * This workflow creates one or more product tags. It's used by the + * [Create Product Tag Admin API Route](https://docs.medusajs.com/api/admin#product-tags_postproducttags). + * + * This workflow has a hook that allows you to perform custom actions on the created product tags. For example, you can pass under `additional_data` custom data that + * allows you to create custom data models linked to the product tags. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product-tag creation. + * + * @example + * const { result } = await createProductTagsWorkflow(container) + * .run({ + * input: { + * product_tags: [ + * { + * value: "clothing" + * } + * ], + * additional_data: { + * erp_id: "123" + * } + * } + * }) + * + * @summary + * + * Create one or more product tags. + * + * @property hooks.productTagsCreated - This hook is executed after the product tags are created. You can consume this hook to perform custom actions on the created product tags. */ export const createProductTagsWorkflow = createWorkflow( createProductTagsWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/create-product-types.ts b/packages/core/core-flows/src/product/workflows/create-product-types.ts index e9c81b35df..66dc5bc36e 100644 --- a/packages/core/core-flows/src/product/workflows/create-product-types.ts +++ b/packages/core/core-flows/src/product/workflows/create-product-types.ts @@ -10,13 +10,46 @@ import { import { emitEventStep } from "../../common/steps/emit-event" import { createProductTypesStep } from "../steps" +/** + * The data to create one or more product types, along with custom data that's passed to the workflow's hooks. + */ export type CreateProductTypesWorkflowInput = { + /** + * The product types to create. + */ product_types: ProductTypes.CreateProductTypeDTO[] } & AdditionalData export const createProductTypesWorkflowId = "create-product-types" /** - * This workflow creates one or more product types. + * This workflow creates one or more product types. It's used by the + * [Create Product Type Admin API Route](https://docs.medusajs.com/api/admin#product-types_postproducttypes). + * + * This workflow has a hook that allows you to perform custom actions on the created product types. For example, you can pass under `additional_data` custom data that + * allows you to create custom data models linked to the product types. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product-type creation. + * + * @example + * const { result } = await createProductTypesWorkflow(container) + * .run({ + * input: { + * product_types: [ + * { + * value: "clothing" + * } + * ], + * additional_data: { + * erp_id: "123" + * } + * } + * }) + * + * @summary + * + * Create one or more product types. + * + * @property hooks.productTypesCreated - This hook is executed after the product types are created. You can consume this hook to perform custom actions on the created product types. */ export const createProductTypesWorkflow = createWorkflow( createProductTypesWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/create-products.ts b/packages/core/core-flows/src/product/workflows/create-products.ts index 9cecee9ebc..904dc931f4 100644 --- a/packages/core/core-flows/src/product/workflows/create-products.ts +++ b/packages/core/core-flows/src/product/workflows/create-products.ts @@ -22,13 +22,51 @@ import { associateProductsWithSalesChannelsStep } from "../../sales-channel" import { createProductsStep } from "../steps/create-products" import { createProductVariantsWorkflow } from "./create-product-variants" -interface ValidateProductInputStepInput { +/** + * The product's data to validate. + */ +export interface ValidateProductInputStepInput { + /** + * The products to validate. + */ products: CreateProductWorkflowInputDTO[] } const validateProductInputStepId = "validate-product-input" /** - * This step validates a product data before creation. + * This step validates that all provided products have options. + * If a product is missing options, an error is thrown. + * + * @example + * const data = validateProductInputStep({ + * products: [ + * { + * title: "Shirt", + * options: [ + * { + * title: "Size", + * values: ["S", "M", "L"] + * } + * ], + * variants: [ + * { + * title: "Small Shirt", + * sku: "SMALLSHIRT", + * options: { + * Size: "S" + * }, + * prices: [ + * { + * amount: 10, + * currency_code: "usd" + * } + * ], + * manage_inventory: true, + * }, + * ] + * } + * ] + * }) */ export const validateProductInputStep = createStep( validateProductInputStepId, diff --git a/packages/core/core-flows/src/product/workflows/delete-collections.ts b/packages/core/core-flows/src/product/workflows/delete-collections.ts index dae977fceb..68464b57e3 100644 --- a/packages/core/core-flows/src/product/workflows/delete-collections.ts +++ b/packages/core/core-flows/src/product/workflows/delete-collections.ts @@ -9,11 +9,39 @@ import { import { emitEventStep } from "../../common" import { deleteCollectionsStep } from "../steps" -export type DeleteCollectionsWorkflowInput = { ids: string[] } +/** + * The data to delete one or more product collections. + */ +export type DeleteCollectionsWorkflowInput = { + /** + * The IDs of the collections to delete. + */ + ids: string[] +} export const deleteCollectionsWorkflowId = "delete-collections" /** - * This workflow deletes one or more collection. + * This workflow deletes one or more product collections. It's used by the + * [Delete Product Collection Admin API Route](https://docs.medusajs.com/api/admin#collections_deletecollectionsid). + * + * This workflow has a hook that allows you to perform custom actions after the product collections are deleted. For example, + * you can delete custom records linked to the product colleciton. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product-collection deletion. + * + * @example + * const { result } = await deleteCollectionsWorkflow(container) + * .run({ + * input: { + * ids: ["pcol_123"], + * } + * }) + * + * @summary + * + * Delete one or more product collection. + * + * @property hooks.collectionsDeleted - This hook is executed after the collections are deleted. You can consume this hook to perform custom actions on the deleted collections. */ export const deleteCollectionsWorkflow = createWorkflow( deleteCollectionsWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/delete-product-options.ts b/packages/core/core-flows/src/product/workflows/delete-product-options.ts index 8bd7ec1306..df87f0ac64 100644 --- a/packages/core/core-flows/src/product/workflows/delete-product-options.ts +++ b/packages/core/core-flows/src/product/workflows/delete-product-options.ts @@ -9,11 +9,39 @@ import { import { emitEventStep } from "../../common/steps/emit-event" import { deleteProductOptionsStep } from "../steps" -export type DeleteProductOptionsWorkflowInput = { ids: string[] } +/** + * The data to delete one or more product options. + */ +export type DeleteProductOptionsWorkflowInput = { + /** + * The IDs of the options to delete. + */ + ids: string[] +} export const deleteProductOptionsWorkflowId = "delete-product-options" /** - * This workflow deletes one or more product options. + * This workflow deletes one or more product options. It's used by the + * [Delete Product Option Admin API Route](https://docs.medusajs.com/api/admin#products_deleteproductsidoptionsoption_id). + * + * This workflow has a hook that allows you to perform custom actions after the product options are deleted. For example, + * you can delete custom records linked to the product colleciton. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product-option deletion. + * + * @example + * const { result } = await deleteProductOptionsWorkflow(container) + * .run({ + * input: { + * ids: ["poption_123"], + * } + * }) + * + * @summary + * + * Delete one or more product option. + * + * @property hooks.productOptionsDeleted - This hook is executed after the options are deleted. You can consume this hook to perform custom actions on the deleted options. */ export const deleteProductOptionsWorkflow = createWorkflow( deleteProductOptionsWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/delete-product-tags.ts b/packages/core/core-flows/src/product/workflows/delete-product-tags.ts index 5728697e22..00d1661ce9 100644 --- a/packages/core/core-flows/src/product/workflows/delete-product-tags.ts +++ b/packages/core/core-flows/src/product/workflows/delete-product-tags.ts @@ -9,11 +9,39 @@ import { import { emitEventStep } from "../../common/steps/emit-event" import { deleteProductTagsStep } from "../steps" -export type DeleteProductTagsWorkflowInput = { ids: string[] } +/** + * The data to delete one or more product tags. + */ +export type DeleteProductTagsWorkflowInput = { + /** + * The IDs of the tags to delete. + */ + ids: string[] +} export const deleteProductTagsWorkflowId = "delete-product-tags" /** - * This workflow deletes one or more product tags. + * This workflow deletes one or more product tags. It's used by the + * [Delete Product Tags Admin API Route](https://docs.medusajs.com/api/admin#product-tags_deleteproducttagsid). + * + * This workflow has a hook that allows you to perform custom actions after the product tags are deleted. For example, + * you can delete custom records linked to the product tags. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product-tag deletion. + * + * @example + * const { result } = await deleteProductTagsWorkflow(container) + * .run({ + * input: { + * ids: ["ptag_123"], + * } + * }) + * + * @summary + * + * Delete one or more product tags. + * + * @property hooks.productTagsDeleted - This hook is executed after the tags are deleted. You can consume this hook to perform custom actions on the deleted tags. */ export const deleteProductTagsWorkflow = createWorkflow( deleteProductTagsWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/delete-product-types.ts b/packages/core/core-flows/src/product/workflows/delete-product-types.ts index 9eafecc0cc..95698d7d40 100644 --- a/packages/core/core-flows/src/product/workflows/delete-product-types.ts +++ b/packages/core/core-flows/src/product/workflows/delete-product-types.ts @@ -9,11 +9,39 @@ import { import { emitEventStep } from "../../common/steps/emit-event" import { deleteProductTypesStep } from "../steps" -export type DeleteProductTypesWorkflowInput = { ids: string[] } +/** + * The data to delete one or more product types. + */ +export type DeleteProductTypesWorkflowInput = { + /** + * The IDs of the types to delete. + */ + ids: string[] +} export const deleteProductTypesWorkflowId = "delete-product-types" /** - * This workflow deletes one or more product types. + * This workflow deletes one or more product types. It's used by the + * [Delete Product Types Admin API Route](https://docs.medusajs.com/api/admin#product-types_deleteproducttypesid). + * + * This workflow has a hook that allows you to perform custom actions after the product types are deleted. For example, + * you can delete custom records linked to the product types. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product-type deletion. + * + * @example + * const { result } = await deleteProductTypesWorkflow(container) + * .run({ + * input: { + * ids: ["ptyp_123"], + * } + * }) + * + * @summary + * + * Delete one or more product types. + * + * @property hooks.productTypesDeleted - This hook is executed after the types are deleted. You can consume this hook to perform custom actions on the deleted types. */ export const deleteProductTypesWorkflow = createWorkflow( deleteProductTypesWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/delete-product-variants.ts b/packages/core/core-flows/src/product/workflows/delete-product-variants.ts index 1b0cf86263..2e0572b706 100644 --- a/packages/core/core-flows/src/product/workflows/delete-product-variants.ts +++ b/packages/core/core-flows/src/product/workflows/delete-product-variants.ts @@ -17,11 +17,39 @@ import { import { deleteProductVariantsStep } from "../steps" import { deleteInventoryItemWorkflow } from "../../inventory" -export type DeleteProductVariantsWorkflowInput = { ids: string[] } +/** + * The data to delete one or more product variants. + */ +export type DeleteProductVariantsWorkflowInput = { + /** + * The IDs of the variants to delete. + */ + ids: string[] +} export const deleteProductVariantsWorkflowId = "delete-product-variants" /** - * This workflow deletes one or more product variants. + * This workflow deletes one or more product variants. It's used by the + * [Delete Product Variants Admin API Route](https://docs.medusajs.com/api/admin#products_deleteproductsidvariantsvariant_id). + * + * This workflow has a hook that allows you to perform custom actions after the product variants are deleted. For example, + * you can delete custom records linked to the product variants. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product-variant deletion. + * + * @example + * const { result } = await deleteProductVariantsWorkflow(container) + * .run({ + * input: { + * ids: ["variant_123"], + * } + * }) + * + * @summary + * + * Delete one or more product variants. + * + * @property hooks.productVariantsDeleted - This hook is executed after the variants are deleted. You can consume this hook to perform custom actions on the deleted variants. */ export const deleteProductVariantsWorkflow = createWorkflow( deleteProductVariantsWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/delete-products.ts b/packages/core/core-flows/src/product/workflows/delete-products.ts index 78c7297298..0c57e3abd1 100644 --- a/packages/core/core-flows/src/product/workflows/delete-products.ts +++ b/packages/core/core-flows/src/product/workflows/delete-products.ts @@ -16,11 +16,39 @@ import { deleteProductsStep } from "../steps/delete-products" import { getProductsStep } from "../steps/get-products" import { deleteInventoryItemWorkflow } from "../../inventory" -export type DeleteProductsWorkflowInput = { ids: string[] } +/** + * The data to delete one or more products. + */ +export type DeleteProductsWorkflowInput = { + /** + * The IDs of the products to delete. + */ + ids: string[] +} export const deleteProductsWorkflowId = "delete-products" /** - * This workflow deletes one or more products. + * This workflow deletes one or more products. It's used by the + * [Delete Products Admin API Route](https://docs.medusajs.com/api/admin#products_deleteproductsid). + * + * This workflow has a hook that allows you to perform custom actions after the products are deleted. For example, + * you can delete custom records linked to the products. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product deletion. + * + * @example + * const { result } = await deleteProductsWorkflow(container) + * .run({ + * input: { + * ids: ["product_123"], + * } + * }) + * + * @summary + * + * Delete one or more products. + * + * @property hooks.productsDeleted - This hook is executed after the products are deleted. You can consume this hook to perform custom actions on the deleted products. */ export const deleteProductsWorkflow = createWorkflow( deleteProductsWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/export-products.ts b/packages/core/core-flows/src/product/workflows/export-products.ts index 1058253e18..6739c3ac8f 100644 --- a/packages/core/core-flows/src/product/workflows/export-products.ts +++ b/packages/core/core-flows/src/product/workflows/export-products.ts @@ -10,7 +10,45 @@ import { notifyOnFailureStep, sendNotificationsStep } from "../../notification" export const exportProductsWorkflowId = "export-products" /** - * This workflow exports products matching the specified filters. + * This workflow exports products matching the specified filters. It's used by the + * [Export Products Admin API Route](https://docs.medusajs.com/api/admin#products_postproductsexport). + * + * :::note + * + * This workflow doesn't return the exported products. Instead, it sends a notification to the admin + * users that they can download the exported products. Learn more in the [API Reference](https://docs.medusajs.com/api/admin#products_postproductsexport). + * + * ::: + * + * @example + * To export all products: + * + * ```ts + * const { result } = await exportProductsWorkflow(container) + * .run({ + * input: { + * select: ["*"], + * } + * }) + * ``` + * + * To export products matching a criteria: + * + * ```ts + * const { result } = await exportProductsWorkflow(container) + * .run({ + * input: { + * select: ["*"], + * filter: { + * collection_id: "pcol_123" + * } + * } + * }) + * ``` + * + * @summary + * + * Export products with filtering capabilities. */ export const exportProductsWorkflow = createWorkflow( exportProductsWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/import-products.ts b/packages/core/core-flows/src/product/workflows/import-products.ts index 87c1ff2913..8d887d9058 100644 --- a/packages/core/core-flows/src/product/workflows/import-products.ts +++ b/packages/core/core-flows/src/product/workflows/import-products.ts @@ -15,7 +15,79 @@ import { batchProductsWorkflow } from "./batch-products" export const importProductsWorkflowId = "import-products" /** - * This workflow imports products from a CSV file. + * This workflow starts a product import from a CSV file in the background. It's used by the + * [Import Products Admin API Route](https://docs.medusajs.com/api/admin#products_postproductsimport). + * + * You can use this workflow within your custom workflows, allowing you to wrap custom logic around product import. + * For example, you can import products from another system. + * + * The workflow only starts the import, but you'll have to confirm it using the [Workflow Engine](https://docs.medusajs.com/resources/architectural-modules/workflow-engine). + * The below example shows how to confirm the import. + * + * @example + * To start the import of a CSV file: + * + * ```ts + * const { result, transaction: { transactionId } } = await importProductsWorkflow(container) + * .run({ + * input: { + * // example CSV content + * fileContent: "title,description\nShirt,This is a shirt", + * filename: "products.csv", + * } + * }) + * ``` + * + * Notice that the workflow returns a `transaction.transactionId`. You'll use this ID to confirm the import afterwards. + * + * You confirm the import using the [Workflow Engine](https://docs.medusajs.com/resources/architectural-modules/workflow-engine). + * For example, in an API route: + * + * ```ts workflow={false} + * import { + * AuthenticatedMedusaRequest, + * MedusaResponse, + * } from "@medusajs/framework/http" + * import { + * importProductsWorkflowId, + * waitConfirmationProductImportStepId, + * } from "@medusajs/core-flows" + * import { IWorkflowEngineService } from "@medusajs/framework/types" + * import { Modules, TransactionHandlerType } from "@medusajs/framework/utils" + * import { StepResponse } from "@medusajs/framework/workflows-sdk" + * + * export const POST = async ( + * req: AuthenticatedMedusaRequest, + * res: MedusaResponse + * ) => { + * const workflowEngineService: IWorkflowEngineService = req.scope.resolve( + * Modules.WORKFLOW_ENGINE + * ) + * const transactionId = req.params.transaction_id + * + * await workflowEngineService.setStepSuccess({ + * idempotencyKey: { + * action: TransactionHandlerType.INVOKE, + * transactionId, + * stepId: waitConfirmationProductImportStepId, + * workflowId: importProductsWorkflowId, + * }, + * stepResponse: new StepResponse(true), + * }) + * + * res.status(202).json({}) + * } + * ``` + * + * :::tip + * + * This example API route uses the same implementation as the [Confirm Product Import Admin API Route](https://docs.medusajs.com/api/admin#products_postproductsimporttransaction_idconfirm). + * + * ::: + * + * @summary + * + * Import products from a CSV file. */ export const importProductsWorkflow = createWorkflow( importProductsWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/update-collections.ts b/packages/core/core-flows/src/product/workflows/update-collections.ts index 62fe36b810..0c977cf459 100644 --- a/packages/core/core-flows/src/product/workflows/update-collections.ts +++ b/packages/core/core-flows/src/product/workflows/update-collections.ts @@ -10,14 +10,51 @@ import { import { emitEventStep } from "../../common" import { updateCollectionsStep } from "../steps" +/** + * The data to update one or more product collections, along with custom data that's passed to the workflow's hooks. + */ export type UpdateCollectionsWorkflowInput = { + /** + * The filters to select the collections to update. + */ selector: ProductTypes.FilterableProductCollectionProps + /** + * The data to update the collections with. + */ update: ProductTypes.UpdateProductCollectionDTO } & AdditionalData export const updateCollectionsWorkflowId = "update-collections" /** - * This workflow updates collections matching the specified filters. + * This workflow updates one or more collections. It's used by the + * [Create Collection Admin API Route](https://docs.medusajs.com/api/admin#collections_postcollectionsid). + * + * This workflow has a hook that allows you to perform custom actions on the updated collections. For example, you can pass under `additional_data` custom data that + * allows you to update custom data models linked to the product collections. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product-collection update. + * + * @example + * const { result } = await updateCollectionsWorkflow(container) + * .run({ + * input: { + * selector: { + * id: "pcol_123" + * }, + * update: { + * title: "Summer Collection" + * }, + * additional_data: { + * erp_id: "123" + * } + * } + * }) + * + * @summary + * + * Update one or more product collections. + * + * @property hooks.collectionsUpdated - This hook is executed after the collections are updated. You can consume this hook to perform custom actions on the updated collections. */ export const updateCollectionsWorkflow = createWorkflow( updateCollectionsWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/update-product-tags.ts b/packages/core/core-flows/src/product/workflows/update-product-tags.ts index c665f28e4f..36ba4b6af8 100644 --- a/packages/core/core-flows/src/product/workflows/update-product-tags.ts +++ b/packages/core/core-flows/src/product/workflows/update-product-tags.ts @@ -10,14 +10,51 @@ import { import { emitEventStep } from "../../common/steps/emit-event" import { updateProductTagsStep } from "../steps" +/** + * The data to update one or more product tags, along with custom data that's passed to the workflow's hooks. + */ export type UpdateProductTagsWorkflowInput = { + /** + * The filters to select the product tags to update. + */ selector: ProductTypes.FilterableProductTypeProps + /** + * The data to update in the product tags. + */ update: ProductTypes.UpdateProductTypeDTO } & AdditionalData export const updateProductTagsWorkflowId = "update-product-tags" /** - * This workflow updates product tags matching the specified filters. + * This workflow updates one or more product tags. It's used by the + * [Update Product Tag Admin API Route](https://docs.medusajs.com/api/admin#product-tags_postproducttagsid). + * + * This workflow has a hook that allows you to perform custom actions on the updated product tags. For example, you can pass under `additional_data` custom data that + * allows you to update custom data models linked to the product tags. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product-tag updates. + * + * @example + * const { result } = await updateProductTagsWorkflow(container) + * .run({ + * input: { + * selector: { + * id: "pcol_123" + * }, + * update: { + * value: "clothing" + * }, + * additional_data: { + * erp_id: "123" + * } + * } + * }) + * + * @summary + * + * Update one or more product tags. + * + * @property hooks.productTagsUpdated - This hook is executed after the product tags are updated. You can consume this hook to perform custom actions on the updated product tags. */ export const updateProductTagsWorkflow = createWorkflow( updateProductTagsWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/update-product-types.ts b/packages/core/core-flows/src/product/workflows/update-product-types.ts index d217424cc7..494e10cd20 100644 --- a/packages/core/core-flows/src/product/workflows/update-product-types.ts +++ b/packages/core/core-flows/src/product/workflows/update-product-types.ts @@ -10,14 +10,51 @@ import { import { emitEventStep } from "../../common/steps/emit-event" import { updateProductTypesStep } from "../steps" +/** + * The data to update one or more product types, along with custom data that's passed to the workflow's hooks. + */ type UpdateProductTypesWorkflowInput = { + /** + * The filters to select the product types to update. + */ selector: ProductTypes.FilterableProductTypeProps + /** + * The data to update in the product types. + */ update: ProductTypes.UpdateProductTypeDTO } & AdditionalData export const updateProductTypesWorkflowId = "update-product-types" /** - * This workflow updates product types matching the specified filters. + * This workflow updates one or more product types. It's used by the + * [Update Product Type Admin API Route](https://docs.medusajs.com/api/admin#product-types_postproducttypesid). + * + * This workflow has a hook that allows you to perform custom actions on the updated product types. For example, you can pass under `additional_data` custom data that + * allows you to update custom data models linked to the product types. + * + * You can also use this workflow within your own custom workflows, allowing you to wrap custom logic around product-type updates. + * + * @example + * const { result } = await updateProductTypesWorkflow(container) + * .run({ + * input: { + * selector: { + * id: "ptyp_123" + * }, + * update: { + * value: "clothing" + * }, + * additional_data: { + * erp_id: "123" + * } + * } + * }) + * + * @summary + * + * Update one or more product types. + * + * @property hooks.productTypesUpdated - This hook is executed after the product types are updated. You can consume this hook to perform custom actions on the updated product types. */ export const updateProductTypesWorkflow = createWorkflow( updateProductTypesWorkflowId, diff --git a/packages/core/core-flows/src/product/workflows/upsert-variant-prices.ts b/packages/core/core-flows/src/product/workflows/upsert-variant-prices.ts index 26b82b5079..74aa8af7c0 100644 --- a/packages/core/core-flows/src/product/workflows/upsert-variant-prices.ts +++ b/packages/core/core-flows/src/product/workflows/upsert-variant-prices.ts @@ -13,18 +13,69 @@ import { removeRemoteLinkStep, useRemoteQueryStep } from "../../common" import { createPriceSetsStep, updatePriceSetsStep } from "../../pricing" import { createVariantPricingLinkStep } from "../steps" +/** + * The data to create, update, or remove variants' prices. + */ export type UpsertVariantPricesWorkflowInput = { + /** + * The variants to create or update prices for. + */ variantPrices: { + /** + * The ID of the variant to create or update prices for. + */ variant_id: string + /** + * The ID of the product the variant belongs to. + */ product_id: string + /** + * The prices to create or update for the variant. + */ prices?: (CreatePricesDTO | UpdatePricesDTO)[] }[] + /** + * The IDs of the variants to remove all their prices. + */ previousVariantIds: string[] } export const upsertVariantPricesWorkflowId = "upsert-variant-prices" /** - * This workflow creates or updates variants' prices. + * This workflow creates, updates, or removes variants' prices. It's used by the {@link updateProductsWorkflow} + * when updating a variant's prices. + * + * You can use this workflow within your own custom workflows to manage the prices of a variant. + * + * @example + * const { result } = await upsertVariantPricesWorkflow(container) + * .run({ + * input: { + * variantPrices: [ + * { + * variant_id: "variant_123", + * product_id: "prod_123", + * prices: [ + * { + * amount: 10, + * currency_code: "usd", + * }, + * { + * id: "price_123", + * amount: 20, + * } + * ] + * } + * ], + * // these are variants to remove all their prices + * // typically used when a variant is deleted. + * previousVariantIds: ["variant_321"] + * } + * }) + * + * @summary + * + * Create, update, or remove variants' prices. */ export const upsertVariantPricesWorkflow = createWorkflow( upsertVariantPricesWorkflowId, diff --git a/packages/core/types/src/common/batch.ts b/packages/core/types/src/common/batch.ts index 7109ffc92a..bf563fe89e 100644 --- a/packages/core/types/src/common/batch.ts +++ b/packages/core/types/src/common/batch.ts @@ -3,28 +3,75 @@ export type LinkMethodRequest = { remove?: string[] } +/** + * Links to manage for a data model. + * + * For example, to add or remove links between a collection and products, + * you pass in the `id` the collection's ID, in `add` the IDs of products + * to create links to the collection, and in `remove` the IDs of products + * to remove links from the collection. + */ export type LinkWorkflowInput = { + /** + * The ID of the data model to create links to or remove links from. + */ id: string + /** + * The IDs of the other data models to create links to the record specified in `id`. + */ add?: string[] + /** + * The IDs of the other data models to remove links from the record specified in `id`. + */ remove?: string[] } +/** + * Data to manage in bulk related to a model. + */ export type BatchMethodRequest = { + /** + * Records to create in bulk. + */ create?: TCreate[] + /** + * Records to update in bulk. + */ update?: TUpdate[] + /** + * Records to delete in bulk. + */ delete?: TDelete[] } +/** + * The result of a bulk operation related to a model. + */ export type BatchMethodResponse = { + /** + * The records that were created in the bulk operation. + */ created: T[] + /** + * The records that were updated in the bulk operation. + */ updated: T[] + /** + * The IDs of the records deleted in the bulk operation. + */ deleted: string[] } +/** + * Data to manage in bulk. + */ export type BatchWorkflowInput< TCreate, TUpdate, TDelete = string > = BatchMethodRequest +/** + * The data result of a bulk operation. + */ export type BatchWorkflowOutput = BatchMethodResponse diff --git a/packages/core/types/src/workflow/product-category/index.ts b/packages/core/types/src/workflow/product-category/index.ts index 47236fd715..6cfc22df5f 100644 --- a/packages/core/types/src/workflow/product-category/index.ts +++ b/packages/core/types/src/workflow/product-category/index.ts @@ -13,5 +13,8 @@ export interface UpdateProductCategoriesWorkflowInput { update: UpdateProductCategoryDTO } +/** + * The products to manage of a category. + */ export interface BatchUpdateProductsOnCategoryWorkflowInput extends LinkWorkflowInput {} diff --git a/packages/core/types/src/workflow/product/export-products.ts b/packages/core/types/src/workflow/product/export-products.ts index 85e6ae3afc..aff88fc6cd 100644 --- a/packages/core/types/src/workflow/product/export-products.ts +++ b/packages/core/types/src/workflow/product/export-products.ts @@ -1,6 +1,17 @@ import { FilterableProductProps } from "../../product" +/** + * The configurations to export products. + */ export interface ExportProductsDTO { + /** + * The fields to select. These fields will be passed to + * [Query](https://docs.medusajs.com/learn/fundamentals/module-links/query), so you can + * pass product properties or any relation names, including custom links. + */ select: string[] + /** + * The filters to select which products to export. + */ filter?: FilterableProductProps } diff --git a/packages/core/types/src/workflow/product/import-products.ts b/packages/core/types/src/workflow/product/import-products.ts index 14de827620..1fa0b04a8f 100644 --- a/packages/core/types/src/workflow/product/import-products.ts +++ b/packages/core/types/src/workflow/product/import-products.ts @@ -1,5 +1,14 @@ +/** + * The configurations to import products. + */ export interface ImportProductsDTO { + /** + * The content of the CSV file. + */ fileContent: string + /** + * The name of the CSV file. + */ filename: string } diff --git a/packages/core/utils/src/product/get-variant-availability.ts b/packages/core/utils/src/product/get-variant-availability.ts index 1d47ffec9a..aba2b170f8 100644 --- a/packages/core/utils/src/product/get-variant-availability.ts +++ b/packages/core/utils/src/product/get-variant-availability.ts @@ -1,5 +1,22 @@ import { RemoteQueryFunction } from "@medusajs/types" +/** + * The computed inventory availability for variants in a given sales channel. + * The object's keys are the variant IDs. + */ +export type VariantAvailabilityResult = { + [variant_id: string]: { + /** + * The available inventory quantity for the variant in the sales channel. + */ + availability: number + /** + * The ID of the sales channel for which the availability was computed. + */ + sales_channel_id: string + } +} + /** * Computes the varaint availability for a list of variants in a given sales channel * @@ -23,12 +40,7 @@ import { RemoteQueryFunction } from "@medusajs/types" export async function getVariantAvailability( query: Omit, data: VariantAvailabilityData -): Promise<{ - [variant_id: string]: { - availability: number - sales_channel_id: string - } -}> { +): Promise { const { variantInventoriesMap, locationIds } = await getDataForComputation( query, data