From 7b0ceeffb4616c3f4e0cf51aba2ab381c61ea5d7 Mon Sep 17 00:00:00 2001 From: Patrick <116003638+patrick-medusajs@users.noreply.github.com> Date: Wed, 9 Nov 2022 11:10:17 -0500 Subject: [PATCH] feat: /store api product types (#2552) ## What Allow users to fetch ProductTypes from the storefront API. ## Why This endpoint will allow developers to implement better faceted product search in Medusa without the need for search plugin. Developers will be able to use this to render refinement lists based on types, like this: ![image](https://user-images.githubusercontent.com/116003638/200417828-863065de-3607-49db-bd72-62a6815129fa.png) ## How Endpoint `GET /store/products/types` and `GET /store/product-types` (use [product types listing in admin](https://github.com/medusajs/medusa/blob/master/packages/medusa/src/api/routes/admin/products/list-types.ts) as reference) Support added in @medusajs/medusa-js Support added in medusa-react ## Testing Similar automated tests as `GET /admin/products/types` and `GET /admin/product-types` --- Resolves CORE-699 --- .changeset/early-birds-juggle.md | 7 + .../api/__tests__/admin/product-type.js | 15 +- .../store/__snapshots__/product-type.js.snap | 29 +++ .../api/__tests__/store/product-type.js | 154 +++++++++++++++ packages/medusa-js/src/index.ts | 3 + .../src/resources/admin/product-types.ts | 7 +- .../medusa-js/src/resources/admin/products.ts | 3 + .../medusa-js/src/resources/product-types.ts | 31 +++ .../medusa-react/src/hooks/store/index.ts | 1 + .../src/hooks/store/product-types/index.ts | 1 + .../src/hooks/store/product-types/queries.ts | 32 +++ packages/medusa/src/api/index.js | 1 + .../admin/product-types/list-product-types.ts | 20 +- .../api/routes/admin/products/list-types.ts | 1 + packages/medusa/src/api/routes/store/index.js | 2 + .../api/routes/store/product-types/index.ts | 50 +++++ .../store/product-types/list-product-types.ts | 186 ++++++++++++++++++ packages/medusa/src/services/product-type.ts | 6 +- 18 files changed, 517 insertions(+), 32 deletions(-) create mode 100644 .changeset/early-birds-juggle.md create mode 100644 integration-tests/api/__tests__/store/__snapshots__/product-type.js.snap create mode 100644 integration-tests/api/__tests__/store/product-type.js create mode 100644 packages/medusa-js/src/resources/product-types.ts create mode 100644 packages/medusa-react/src/hooks/store/product-types/index.ts create mode 100644 packages/medusa-react/src/hooks/store/product-types/queries.ts create mode 100644 packages/medusa/src/api/routes/store/product-types/index.ts create mode 100644 packages/medusa/src/api/routes/store/product-types/list-product-types.ts diff --git a/.changeset/early-birds-juggle.md b/.changeset/early-birds-juggle.md new file mode 100644 index 0000000000..96da5f8263 --- /dev/null +++ b/.changeset/early-birds-juggle.md @@ -0,0 +1,7 @@ +--- +"@medusajs/medusa": patch +"@medusajs/medusa-js": patch +"medusa-react": patch +--- + +feat(medusa, medusa-js, medusa-react): /store api product types diff --git a/integration-tests/api/__tests__/admin/product-type.js b/integration-tests/api/__tests__/admin/product-type.js index 1fca3ce9dd..b9c9b18f14 100644 --- a/integration-tests/api/__tests__/admin/product-type.js +++ b/integration-tests/api/__tests__/admin/product-type.js @@ -55,11 +55,7 @@ describe("/admin/product-types", () => { it("returns a list of product types", async () => { const api = useApi() - const res = await api - .get("/admin/product-types", adminReqConfig) - .catch((err) => { - console.log(err) - }) + const res = await api.get("/admin/product-types", adminReqConfig) expect(res.status).toEqual(200) @@ -74,11 +70,10 @@ describe("/admin/product-types", () => { it("returns a list of product types matching free text search param", async () => { const api = useApi() - const res = await api - .get("/admin/product-types?q=test-type-new", adminReqConfig) - .catch((err) => { - console.log(err) - }) + const res = await api.get( + "/admin/product-types?q=test-type-new", + adminReqConfig + ) expect(res.status).toEqual(200) diff --git a/integration-tests/api/__tests__/store/__snapshots__/product-type.js.snap b/integration-tests/api/__tests__/store/__snapshots__/product-type.js.snap new file mode 100644 index 0000000000..7af7fd03a5 --- /dev/null +++ b/integration-tests/api/__tests__/store/__snapshots__/product-type.js.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`/store/product-types GET /store/product-types returns a list of product types 1`] = ` +Array [ + Object { + "created_at": Any, + "id": "test-type-new", + "updated_at": Any, + "value": "test-type-new", + }, + Object { + "created_at": Any, + "id": "test-type", + "updated_at": Any, + "value": "test-type", + }, +] +`; + +exports[`/store/product-types GET /store/product-types returns a list of product types matching free text search param 1`] = ` +Array [ + Object { + "created_at": Any, + "id": "test-type-new", + "updated_at": Any, + "value": "test-type-new", + }, +] +`; diff --git a/integration-tests/api/__tests__/store/product-type.js b/integration-tests/api/__tests__/store/product-type.js new file mode 100644 index 0000000000..9dae07294a --- /dev/null +++ b/integration-tests/api/__tests__/store/product-type.js @@ -0,0 +1,154 @@ +const path = require("path") + +const { IdMap } = require("medusa-test-utils") + +const setupServer = require("../../../helpers/setup-server") +const { useApi } = require("../../../helpers/use-api") +const { initDb, useDb } = require("../../../helpers/use-db") + +const productSeeder = require("../../helpers/product-seeder") +const { + DiscountRuleType, + AllocationType, + DiscountConditionType, + DiscountConditionOperator, +} = require("@medusajs/medusa") +const { simpleDiscountFactory } = require("../../factories") + +jest.setTimeout(50000) + +describe("/store/product-types", () => { + let medusaProcess + let dbConnection + + beforeAll(async () => { + const cwd = path.resolve(path.join(__dirname, "..", "..")) + dbConnection = await initDb({ cwd }) + medusaProcess = await setupServer({ cwd }) + }) + + afterAll(async () => { + const db = useDb() + await db.shutdown() + + medusaProcess.kill() + }) + + describe("GET /store/product-types", () => { + beforeEach(async () => { + await productSeeder(dbConnection) + }) + + afterEach(async () => { + const db = useDb() + await db.teardown() + }) + + it("returns a list of product types", async () => { + const api = useApi() + + const res = await api.get("/store/product-types") + + expect(res.status).toEqual(200) + + const typeMatch = { + created_at: expect.any(String), + updated_at: expect.any(String), + } + + expect(res.data.product_types).toMatchSnapshot([typeMatch, typeMatch]) + }) + + it("returns a list of product types matching free text search param", async () => { + const api = useApi() + + const res = await api.get("/store/product-types?q=test-type-new") + + expect(res.status).toEqual(200) + + const typeMatch = { + created_at: expect.any(String), + updated_at: expect.any(String), + } + + // The value of the type should match the search param + expect(res.data.product_types.map((pt) => pt.value)).toEqual([ + "test-type-new", + ]) + + // Should only return one type as there is only one match to the search param + expect(res.data.product_types).toMatchSnapshot([typeMatch]) + }) + + it("returns a list of product type filtered by discount condition id", async () => { + const api = useApi() + + const resTypes = await api.get("/store/product-types") + + const type1 = resTypes.data.product_types[0] + const type2 = resTypes.data.product_types[1] + + const buildDiscountData = (code, conditionId, types) => { + return { + code, + rule: { + type: DiscountRuleType.PERCENTAGE, + value: 10, + allocation: AllocationType.TOTAL, + conditions: [ + { + id: conditionId, + type: DiscountConditionType.PRODUCT_TYPES, + operator: DiscountConditionOperator.IN, + product_types: types, + }, + ], + }, + } + } + + const discountConditionId = IdMap.getId("discount-condition-type-1") + await simpleDiscountFactory( + dbConnection, + buildDiscountData("code-1", discountConditionId, [type1.id]) + ) + + const discountConditionId2 = IdMap.getId("discount-condition-type-2") + await simpleDiscountFactory( + dbConnection, + buildDiscountData("code-2", discountConditionId2, [type2.id]) + ) + + let res = await api.get( + `/store/product-types?discount_condition_id=${discountConditionId}` + ) + + expect(res.status).toEqual(200) + expect(res.data.product_types).toHaveLength(1) + expect(res.data.product_types).toEqual( + expect.arrayContaining([expect.objectContaining({ id: type1.id })]) + ) + + res = await api.get( + `/store/product-types?discount_condition_id=${discountConditionId2}` + ) + + expect(res.status).toEqual(200) + expect(res.data.product_types).toHaveLength(1) + expect(res.data.product_types).toEqual( + expect.arrayContaining([expect.objectContaining({ id: type2.id })]) + ) + + res = await api.get(`/store/product-types`) + + expect(res.status).toEqual(200) + expect(res.data.product_types).toHaveLength(2) + expect(res.data.product_types).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: type1.id }), + expect.objectContaining({ id: type2.id }), + ]) + ) + }) + }) +}) diff --git a/packages/medusa-js/src/index.ts b/packages/medusa-js/src/index.ts index 6c482a922e..dba8ba49df 100644 --- a/packages/medusa-js/src/index.ts +++ b/packages/medusa-js/src/index.ts @@ -10,6 +10,7 @@ import OrdersResource from "./resources/orders" import OrderEditsResource from "./resources/order-edits" import PaymentMethodsResource from "./resources/payment-methods" import ProductsResource from "./resources/products" +import ProductTypesResource from "./resources/product-types" import RegionsResource from "./resources/regions" import ReturnReasonsResource from "./resources/return-reasons" import ReturnsResource from "./resources/returns" @@ -27,6 +28,7 @@ class Medusa { public orders: OrdersResource public orderEdits: OrderEditsResource public products: ProductsResource + public productTypes: ProductTypesResource public regions: RegionsResource public returnReasons: ReturnReasonsResource public returns: ReturnsResource @@ -48,6 +50,7 @@ class Medusa { this.orders = new OrdersResource(this.client) this.orderEdits = new OrderEditsResource(this.client) this.products = new ProductsResource(this.client) + this.productTypes = new ProductTypesResource(this.client) this.regions = new RegionsResource(this.client) this.returnReasons = new ReturnReasonsResource(this.client) this.returns = new ReturnsResource(this.client) diff --git a/packages/medusa-js/src/resources/admin/product-types.ts b/packages/medusa-js/src/resources/admin/product-types.ts index 13f048614f..1fba4052c6 100644 --- a/packages/medusa-js/src/resources/admin/product-types.ts +++ b/packages/medusa-js/src/resources/admin/product-types.ts @@ -8,16 +8,17 @@ import BaseResource from "../base" class AdminProductTypesResource extends BaseResource { list( - query?: AdminGetProductTypesParams + query?: AdminGetProductTypesParams, + customHeaders: Record = {} ): ResponsePromise { let path = `/admin/product-types` if (query) { const queryString = qs.stringify(query) - path = `/admin/product-types?${queryString}` + path += `?${queryString}` } - return this.client.request("GET", path) + return this.client.request("GET", path, undefined, {}, customHeaders) } } diff --git a/packages/medusa-js/src/resources/admin/products.ts b/packages/medusa-js/src/resources/admin/products.ts index 0074799188..12dfc350f7 100644 --- a/packages/medusa-js/src/resources/admin/products.ts +++ b/packages/medusa-js/src/resources/admin/products.ts @@ -67,6 +67,9 @@ class AdminProductsResource extends BaseResource { return this.client.request("GET", path, undefined, {}, customHeaders) } + /** + * @deprecated Use {@link AdminProductTypesResource.list} instead. + */ listTypes( customHeaders: Record = {} ): ResponsePromise { diff --git a/packages/medusa-js/src/resources/product-types.ts b/packages/medusa-js/src/resources/product-types.ts new file mode 100644 index 0000000000..9370e25d4c --- /dev/null +++ b/packages/medusa-js/src/resources/product-types.ts @@ -0,0 +1,31 @@ +import { + StoreGetProductTypesParams, + StoreProductTypesListRes, +} from "@medusajs/medusa" +import qs from "qs" +import { ResponsePromise } from "../typings" +import BaseResource from "./base" + +class ProductTypesResource extends BaseResource { + /** + * @description Retrieves a list of product types + * @param {StoreGetProductTypesParams} query is optional. Can contain a limit and offset for the returned list + * @param customHeaders + * @return {ResponsePromise} + */ + list( + query?: StoreGetProductTypesParams, + customHeaders: Record = {} + ): ResponsePromise { + let path = `/store/product-types` + + if (query) { + const queryString = qs.stringify(query) + path += `?${queryString}` + } + + return this.client.request("GET", path, undefined, {}, customHeaders) + } +} + +export default ProductTypesResource diff --git a/packages/medusa-react/src/hooks/store/index.ts b/packages/medusa-react/src/hooks/store/index.ts index c9f29778b9..ca2227f8f2 100644 --- a/packages/medusa-react/src/hooks/store/index.ts +++ b/packages/medusa-react/src/hooks/store/index.ts @@ -1,4 +1,5 @@ export * from "./products/" +export * from "./product-types/" export * from "./carts/" export * from "./shipping-options/" export * from "./regions/" diff --git a/packages/medusa-react/src/hooks/store/product-types/index.ts b/packages/medusa-react/src/hooks/store/product-types/index.ts new file mode 100644 index 0000000000..f3593df2df --- /dev/null +++ b/packages/medusa-react/src/hooks/store/product-types/index.ts @@ -0,0 +1 @@ +export * from "./queries" diff --git a/packages/medusa-react/src/hooks/store/product-types/queries.ts b/packages/medusa-react/src/hooks/store/product-types/queries.ts new file mode 100644 index 0000000000..de20a0f344 --- /dev/null +++ b/packages/medusa-react/src/hooks/store/product-types/queries.ts @@ -0,0 +1,32 @@ +import { + StoreGetProductTypesParams, + StoreProductTypesListRes, +} from "@medusajs/medusa" +import { Response } from "@medusajs/medusa-js" +import { useQuery } from "react-query" +import { useMedusa } from "../../../contexts" +import { UseQueryOptionsWrapper } from "../../../types" +import { queryKeysFactory } from "../../utils" + +const PRODUCT_TYPES_QUERY_KEY = `product_types` as const + +export const productTypeKeys = queryKeysFactory(PRODUCT_TYPES_QUERY_KEY) + +type ProductTypesQueryKeys = typeof productTypeKeys + +export const useProductTypes = ( + query?: StoreGetProductTypesParams, + options?: UseQueryOptionsWrapper< + Response, + Error, + ReturnType + > +) => { + const { client } = useMedusa() + const { data, ...rest } = useQuery( + productTypeKeys.list(query), + () => client.productTypes.list(query), + options + ) + return { ...data, ...rest } as const +} diff --git a/packages/medusa/src/api/index.js b/packages/medusa/src/api/index.js index 6055ad30e7..0cbfa9e7aa 100644 --- a/packages/medusa/src/api/index.js +++ b/packages/medusa/src/api/index.js @@ -56,6 +56,7 @@ export * from "./routes/store/gift-cards" export * from "./routes/store/order-edits" export * from "./routes/store/orders" export * from "./routes/store/products" +export * from "./routes/store/product-types" export * from "./routes/store/regions" export * from "./routes/store/return-reasons" export * from "./routes/store/returns" diff --git a/packages/medusa/src/api/routes/admin/product-types/list-product-types.ts b/packages/medusa/src/api/routes/admin/product-types/list-product-types.ts index 462c5a6552..7f79d2824d 100644 --- a/packages/medusa/src/api/routes/admin/product-types/list-product-types.ts +++ b/packages/medusa/src/api/routes/admin/product-types/list-product-types.ts @@ -1,12 +1,12 @@ import { DateComparisonOperator, + FindPaginationParams, StringComparisonOperator, } from "../../../../types/common" -import { IsNumber, IsOptional, IsString } from "class-validator" +import { IsOptional, IsString } from "class-validator" import { IsType } from "../../../../utils/validators/is-type" import ProductTypeService from "../../../../services/product-type" -import { Type } from "class-transformer" /** * @oas [get] /product-types @@ -15,7 +15,7 @@ import { Type } from "class-transformer" * description: "Retrieve a list of Product Types." * x-authenticated: true * parameters: - * - (query) limit=10 {integer} The number of types to return. + * - (query) limit=20 {integer} The number of types to return. * - (query) offset=0 {integer} The number of items to skip before the results. * - (query) order {string} The field to sort items by. * - (query) discount_condition_id {string} The discount condition id on which to filter the product types. @@ -154,20 +154,8 @@ export default async (req, res) => { }) } -export class AdminGetProductTypesPaginationParams { - @IsNumber() - @IsOptional() - @Type(() => Number) - limit? = 10 - - @IsNumber() - @IsOptional() - @Type(() => Number) - offset? = 0 -} - // eslint-disable-next-line max-len -export class AdminGetProductTypesParams extends AdminGetProductTypesPaginationParams { +export class AdminGetProductTypesParams extends FindPaginationParams { @IsType([String, [String], StringComparisonOperator]) @IsOptional() id?: string | string[] | StringComparisonOperator diff --git a/packages/medusa/src/api/routes/admin/products/list-types.ts b/packages/medusa/src/api/routes/admin/products/list-types.ts index f2b0f026b3..ba25cb54eb 100644 --- a/packages/medusa/src/api/routes/admin/products/list-types.ts +++ b/packages/medusa/src/api/routes/admin/products/list-types.ts @@ -2,6 +2,7 @@ import { ProductService } from "../../../../services" /** * @oas [get] /products/types + * deprecated: true * operationId: "GetProductsTypes" * summary: "List Product Types" * description: "Retrieves a list of Product Types." diff --git a/packages/medusa/src/api/routes/store/index.js b/packages/medusa/src/api/routes/store/index.js index 0e81516f45..926f1a7cfb 100644 --- a/packages/medusa/src/api/routes/store/index.js +++ b/packages/medusa/src/api/routes/store/index.js @@ -9,6 +9,7 @@ import giftCardRoutes from "./gift-cards" import orderRoutes from "./orders" import orderEditRoutes from "./order-edits" import productRoutes from "./products" +import productTypesRoutes from "../admin/product-types" import regionRoutes from "./regions" import returnReasonRoutes from "./return-reasons" import returnRoutes from "./returns" @@ -35,6 +36,7 @@ export default (app, container, config) => { collectionRoutes(route) customerRoutes(route, container) productRoutes(route) + productTypesRoutes(route) orderRoutes(route) orderEditRoutes(route) cartRoutes(route, container) diff --git a/packages/medusa/src/api/routes/store/product-types/index.ts b/packages/medusa/src/api/routes/store/product-types/index.ts new file mode 100644 index 0000000000..a55ba436c1 --- /dev/null +++ b/packages/medusa/src/api/routes/store/product-types/index.ts @@ -0,0 +1,50 @@ +import { Router } from "express" +import { ProductType } from "../../../.." +import { PaginatedResponse } from "../../../../types/common" +import middlewares, { transformQuery } from "../../../middlewares" +import "reflect-metadata" +import { StoreGetProductTypesParams } from "./list-product-types" + +const route = Router() + +export default (app) => { + app.use("/product-types", route) + + route.get( + "/", + transformQuery(StoreGetProductTypesParams, { + defaultFields: defaultStoreProductTypeFields, + defaultRelations: defaultStoreProductTypeRelations, + allowedFields: allowedStoreProductTypeFields, + isList: true, + }), + middlewares.wrap(require("./list-product-types").default) + ) + + return app +} + +export const allowedStoreProductTypeFields = [ + "id", + "value", + "created_at", + "updated_at", +] + +export const defaultStoreProductTypeFields = [ + "id", + "value", + "created_at", + "updated_at", +] +export const defaultStoreProductTypeRelations = [] + +export type StoreProductTypesListRes = PaginatedResponse & { + product_types: ProductType[] +} + +export type StoreProductTypesRes = { + product_type: ProductType +} + +export * from "./list-product-types" diff --git a/packages/medusa/src/api/routes/store/product-types/list-product-types.ts b/packages/medusa/src/api/routes/store/product-types/list-product-types.ts new file mode 100644 index 0000000000..7db7ba3275 --- /dev/null +++ b/packages/medusa/src/api/routes/store/product-types/list-product-types.ts @@ -0,0 +1,186 @@ +import { + DateComparisonOperator, + FindPaginationParams, + StringComparisonOperator, +} from "../../../../types/common" +import { IsOptional, IsString } from "class-validator" + +import { IsType } from "../../../../utils/validators/is-type" +import ProductTypeService from "../../../../services/product-type" + +/** + * @oas [get] /product-types + * operationId: "GetProductTypes" + * summary: "List Product Types" + * description: "Retrieve a list of Product Types." + * x-authenticated: true + * parameters: + * - (query) limit=20 {integer} The number of types to return. + * - (query) offset=0 {integer} The number of items to skip before the results. + * - (query) order {string} The field to sort items by. + * - (query) discount_condition_id {string} The discount condition id on which to filter the product types. + * - in: query + * name: value + * style: form + * explode: false + * description: The type values to search for + * schema: + * type: array + * items: + * type: string + * - in: query + * name: id + * style: form + * explode: false + * description: The type IDs to search for + * schema: + * type: array + * items: + * type: string + * - (query) q {string} A query string to search values for + * - in: query + * name: created_at + * description: Date comparison for when resulting product types were created. + * schema: + * type: object + * properties: + * lt: + * type: string + * description: filter by dates less than this date + * format: date + * gt: + * type: string + * description: filter by dates greater than this date + * format: date + * lte: + * type: string + * description: filter by dates less than or equal to this date + * format: date + * gte: + * type: string + * description: filter by dates greater than or equal to this date + * format: date + * - in: query + * name: updated_at + * description: Date comparison for when resulting product types were updated. + * schema: + * type: object + * properties: + * lt: + * type: string + * description: filter by dates less than this date + * format: date + * gt: + * type: string + * description: filter by dates greater than this date + * format: date + * lte: + * type: string + * description: filter by dates less than or equal to this date + * format: date + * gte: + * type: string + * description: filter by dates greater than or equal to this date + * format: date + * x-codeSamples: + * - lang: JavaScript + * label: JS Client + * source: | + * import Medusa from "@medusajs/medusa-js" + * const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 }) + * // must be previously logged in or use api token + * medusa.store.productTypes.list() + * .then(({ product_types }) => { + * console.log(product_types.length); + * }); + * - lang: Shell + * label: cURL + * source: | + * curl --location --request GET 'https://medusa-url.com/store/product-types' \ + * --header 'Authorization: Bearer {api_token}' + * security: + * - api_token: [] + * - cookie_auth: [] + * tags: + * - Product Type + * responses: + * "200": + * description: OK + * content: + * application/json: + * schema: + * properties: + * product_types: + * $ref: "#/components/schemas/product_type" + * count: + * type: integer + * description: The total number of items available + * offset: + * type: integer + * description: The number of items skipped before these items + * limit: + * type: integer + * description: The number of items per page + * "400": + * $ref: "#/components/responses/400_error" + * "401": + * $ref: "#/components/responses/unauthorized" + * "404": + * $ref: "#/components/responses/not_found_error" + * "409": + * $ref: "#/components/responses/invalid_state_error" + * "422": + * $ref: "#/components/responses/invalid_request_error" + * "500": + * $ref: "#/components/responses/500_error" + */ +export default async (req, res) => { + const typeService: ProductTypeService = + req.scope.resolve("productTypeService") + + const { listConfig, filterableFields } = req + const { skip, take } = req.listConfig + + const [types, count] = await typeService.listAndCount( + filterableFields, + listConfig + ) + + res.status(200).json({ + product_types: types, + count, + offset: skip, + limit: take, + }) +} + +// eslint-disable-next-line max-len +export class StoreGetProductTypesParams extends FindPaginationParams { + @IsType([String, [String], StringComparisonOperator]) + @IsOptional() + id?: string | string[] | StringComparisonOperator + + @IsString() + @IsOptional() + q?: string + + @IsType([String, [String], StringComparisonOperator]) + @IsOptional() + value?: string | string[] | StringComparisonOperator + + @IsType([DateComparisonOperator]) + @IsOptional() + created_at?: DateComparisonOperator + + @IsType([DateComparisonOperator]) + @IsOptional() + updated_at?: DateComparisonOperator + + @IsString() + @IsOptional() + order?: string + + @IsString() + @IsOptional() + discount_condition_id?: string +} diff --git a/packages/medusa/src/services/product-type.ts b/packages/medusa/src/services/product-type.ts index 10be231648..618042a491 100644 --- a/packages/medusa/src/services/product-type.ts +++ b/packages/medusa/src/services/product-type.ts @@ -20,7 +20,7 @@ class ProductTypeService extends TransactionBaseService { } /** - * Gets a product by id. + * Gets a product type by id. * Throws in case of DB Error and if product was not found. * @param id - id of the product to get. * @param config - object that defines what should be included in the @@ -39,7 +39,7 @@ class ProductTypeService extends TransactionBaseService { if (!type) { throw new MedusaError( MedusaError.Types.NOT_FOUND, - `Product with id: ${id} was not found` + `Product type with id: ${id} was not found` ) } @@ -64,7 +64,7 @@ class ProductTypeService extends TransactionBaseService { } /** - * Lists product tags and adds count. + * Lists product types and adds count. * @param selector - the query object for find * @param config - the config to be used for find * @return the result of the find operation