Skip to content

Commit

Permalink
Merge branch 'develop' into fix/location_id-in-list-inventory-item-qu…
Browse files Browse the repository at this point in the history
…ery-params
  • Loading branch information
olivermrbl authored Feb 26, 2023
2 parents 9fdb889 + 6323868 commit ce3b79a
Show file tree
Hide file tree
Showing 43 changed files with 419 additions and 171 deletions.
5 changes: 5 additions & 0 deletions .changeset/brown-brooms-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---

feat(medusa): allow appending all category descendants with a param in list endpoint
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ www/**/.yarn/*

.idea
.turbo
build/**
build/**
**/dist
56 changes: 52 additions & 4 deletions integration-tests/api/__tests__/admin/product-category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,21 +124,23 @@ describe("/admin/product-categories", () => {

productCategoryParent = await simpleProductCategoryFactory(dbConnection, {
name: "Mens",
handle: "mens",
})

productCategory = await simpleProductCategoryFactory(dbConnection, {
name: "sweater",
handle: "sweater",
parent_category: productCategoryParent,
is_internal: true,
})

productCategoryChild = await simpleProductCategoryFactory(dbConnection, {
name: "cashmere",
handle: "cashmere",
parent_category: productCategory,
})

productCategoryChild2 = await simpleProductCategoryFactory(dbConnection, {
name: "specific cashmere",
parent_category: productCategoryChild,
})
})

afterEach(async () => {
Expand All @@ -155,7 +157,7 @@ describe("/admin/product-categories", () => {
)

expect(response.status).toEqual(200)
expect(response.data.count).toEqual(3)
expect(response.data.count).toEqual(4)
expect(response.data.offset).toEqual(0)
expect(response.data.limit).toEqual(100)
expect(response.data.product_categories).toEqual(
Expand Down Expand Up @@ -185,6 +187,17 @@ describe("/admin/product-categories", () => {
parent_category: expect.objectContaining({
id: productCategory.id,
}),
category_children: [
expect.objectContaining({
id: productCategoryChild2.id,
})
],
}),
expect.objectContaining({
id: productCategoryChild2.id,
parent_category: expect.objectContaining({
id: productCategoryChild.id,
}),
category_children: [],
}),
])
Expand Down Expand Up @@ -238,6 +251,41 @@ describe("/admin/product-categories", () => {
expect(nullCategoryResponse.data.count).toEqual(1)
expect(nullCategoryResponse.data.product_categories[0].id).toEqual(productCategoryParent.id)
})

it("adds all descendants to categories in a nested way", async () => {
const api = useApi()

const response = await api.get(
`/admin/product-categories?parent_category_id=null&include_descendants_tree=true`,
adminHeaders
)

expect(response.status).toEqual(200)
expect(response.data.count).toEqual(1)
expect(response.data.product_categories).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: productCategoryParent.id,
category_children: [
expect.objectContaining({
id: productCategory.id,
category_children: [
expect.objectContaining({
id: productCategoryChild.id,
category_children: [
expect.objectContaining({
id: productCategoryChild2.id,
category_children: []
})
],
})
]
})
],
}),
])
)
})
})

describe("POST /admin/product-categories", () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/inventory/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
"typeorm": "^0.3.11",
"typescript": "^4.4.4"
},
"dependencies": {
"@medusajs/modules-sdk": "*"
},
"scripts": {
"watch": "tsc --build --watch",
"prepare": "cross-env NODE_ENV=production yarn run build",
Expand Down
2 changes: 1 addition & 1 deletion packages/inventory/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import ConnectionLoader from "./loaders/connection"
import InventoryService from "./services/inventory"
import * as InventoryModels from "./models"
import * as SchemaMigration from "./migrations/schema-migrations/1665748086258-inventory_setup"
import { ModuleExports } from "@medusajs/medusa"
import { ModuleExports } from "@medusajs/modules-sdk"

const service = InventoryService
const migrations = [SchemaMigration]
Expand Down
5 changes: 4 additions & 1 deletion packages/inventory/src/loaders/connection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { ConfigurableModuleDeclaration, LoaderOptions } from "@medusajs/medusa"
import {
ConfigurableModuleDeclaration,
LoaderOptions,
} from "@medusajs/modules-sdk"

export default async (
{ configModule }: LoaderOptions,
Expand Down
5 changes: 4 additions & 1 deletion packages/inventory/src/services/inventory.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import {
ConfigurableModuleDeclaration,
MODULE_RESOURCE_TYPE,
} from "@medusajs/modules-sdk"

import {
CreateInventoryItemInput,
CreateInventoryLevelInput,
CreateReservationItemInput,
Expand All @@ -11,7 +15,6 @@ import {
IInventoryService,
InventoryItemDTO,
InventoryLevelDTO,
MODULE_RESOURCE_TYPE,
ReservationItemDTO,
TransactionBaseService,
UpdateInventoryLevelInput,
Expand Down
1 change: 1 addition & 0 deletions packages/medusa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
},
"dependencies": {
"@medusajs/medusa-cli": "^1.3.8",
"@medusajs/modules-sdk": "*",
"@types/ioredis": "^4.28.10",
"@types/lodash": "^4.14.191",
"awilix": "^8.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { extendedFindParamsMixin } from "../../../../types/common"
* - (query) q {string} Query used for searching product category names orhandles.
* - (query) is_internal {boolean} Search for only internal categories.
* - (query) is_active {boolean} Search for only active categories
* - (query) include_descendants_tree {boolean} Include all nested descendants of category
* - (query) parent_category_id {string} Returns categories scoped by parent
* - (query) offset=0 {integer} How many product categories to skip in the result.
* - (query) limit=100 {integer} Limit the number of product categories returned.
Expand Down Expand Up @@ -92,6 +93,10 @@ export class AdminGetProductCategoriesParams extends extendedFindParamsMixin({
@IsOptional()
q?: string

@IsString()
@IsOptional()
include_descendants_tree?: boolean

@IsString()
@IsOptional()
is_internal?: boolean
Expand Down
2 changes: 1 addition & 1 deletion packages/medusa/src/api/routes/admin/store/get-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from "../../../../services"
import { ExtendedStoreDTO } from "../../../../types/store"
import { FlagRouter } from "../../../../utils/flag-router"
import { ModulesHelper } from "../../../../utils/module-helper"
import { ModulesHelper } from "@medusajs/modules-sdk"

/**
* @oas [get] /admin/store
Expand Down
4 changes: 2 additions & 2 deletions packages/medusa/src/commands/utils/get-migrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { isString } from "lodash"
import { sync as existsSync } from "fs-exists-cached"
import { getConfigFile, createRequireFromPath } from "medusa-core-utils"
import { handleConfigError } from "../../loaders/config"
import registerModuleDefinitions from "../../loaders/module-definitions"
import { registerModules } from "@medusajs/modules-sdk"

function createFileContentHash(path, files) {
return path + files
Expand Down Expand Up @@ -92,7 +92,7 @@ function resolvePlugin(pluginName) {
export function getInternalModules(configModule) {
const modules = []

const moduleResolutions = registerModuleDefinitions(configModule)
const moduleResolutions = registerModules(configModule)

for (const moduleResolution of Object.values(moduleResolutions)) {
if (
Expand Down
10 changes: 6 additions & 4 deletions packages/medusa/src/helpers/test-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import "reflect-metadata"
import supertest from "supertest"
import apiLoader from "../loaders/api"
import featureFlagLoader, { featureFlagRouter } from "../loaders/feature-flags"
import { moduleHelper } from "../loaders/module"
import {
moduleLoader,
moduleHelper,
registerModules,
} from "@medusajs/modules-sdk"
import passportLoader from "../loaders/passport"
import servicesLoader from "../loaders/services"
import strategiesLoader from "../loaders/strategies"
import registerModuleDefinitions from "../loaders/module-definitions"
import moduleLoader from "../loaders/module"

const adminSessionOpts = {
cookieName: "session",
Expand All @@ -26,7 +28,7 @@ const clientSessionOpts = {
secret: "test",
}

const moduleResolutions = registerModuleDefinitions({})
const moduleResolutions = registerModules({})
const config = {
projectConfig: {
jwt_secret: "supersecret",
Expand Down
4 changes: 2 additions & 2 deletions packages/medusa/src/loaders/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getConfigFile } from "medusa-core-utils"
import { ConfigModule } from "../types/global"
import logger from "./logger"
import registerModuleDefinitions from "./module-definitions"
import { registerModules } from "@medusajs/modules-sdk"

const isProduction = ["production", "prod"].includes(process.env.NODE_ENV || "")

Expand Down Expand Up @@ -65,7 +65,7 @@ export default (rootDirectory: string): ConfigModule => {
)
}

const moduleResolutions = registerModuleDefinitions(configModule)
const moduleResolutions = registerModules(configModule)

return {
projectConfig: {
Expand Down
3 changes: 2 additions & 1 deletion packages/medusa/src/loaders/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import expressLoader from "./express"
import featureFlagsLoader from "./feature-flags"
import Logger from "./logger"
import modelsLoader from "./models"
import moduleLoader from "./module"
import passportLoader from "./passport"
import pluginsLoader, { registerPluginModels } from "./plugins"
import redisLoader from "./redis"
Expand All @@ -31,6 +30,8 @@ import servicesLoader from "./services"
import strategiesLoader from "./strategies"
import subscribersLoader from "./subscribers"

import { moduleLoader } from "@medusajs/modules-sdk"

type Options = {
directory: string
expressApp: Express
Expand Down
11 changes: 11 additions & 0 deletions packages/medusa/src/services/__tests__/product-category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ describe("ProductCategoryService", () => {
expect(result.length).toEqual(1)
expect(result[0].id).toEqual(validID)
expect(productCategoryRepository.getFreeTextSearchResultsAndCount).toHaveBeenCalledTimes(1)
expect(productCategoryRepository.findDescendantsTree).not.toBeCalled()
expect(productCategoryRepository.getFreeTextSearchResultsAndCount).toHaveBeenCalledWith(
{
order: {
Expand All @@ -77,6 +78,16 @@ describe("ProductCategoryService", () => {
expect(result).toEqual([])
expect(count).toEqual(0)
})

it("successfully calls tree descendants when requested to be included", async () => {
const validID = IdMap.getId(validProdCategoryId)
const [result, count] = await productCategoryService
.listAndCount({ include_descendants_tree: true })

expect(result[0].id).toEqual(validID)
expect(productCategoryRepository.getFreeTextSearchResultsAndCount).toHaveBeenCalledTimes(1)
expect(productCategoryRepository.findDescendantsTree).toHaveBeenCalledTimes(1)
})
})

describe("create", () => {
Expand Down
33 changes: 26 additions & 7 deletions packages/medusa/src/services/product-category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { EntityManager } from "typeorm"
import { TransactionBaseService } from "../interfaces"
import { ProductCategory } from "../models"
import { ProductCategoryRepository } from "../repositories/product-category"
import { FindConfig, QuerySelector, Selector } from "../types/common"
import {
FindConfig,
QuerySelector,
TreeQuerySelector,
Selector,
} from "../types/common"
import { buildQuery } from "../utils"
import { EventBusService } from "."
import {
Expand Down Expand Up @@ -49,14 +54,17 @@ class ProductCategoryService extends TransactionBaseService {
* as the second element.
*/
async listAndCount(
selector: QuerySelector<ProductCategory>,
selector: TreeQuerySelector<ProductCategory>,
config: FindConfig<ProductCategory> = {
skip: 0,
take: 100,
order: { created_at: "DESC" },
},
treeSelector: QuerySelector<ProductCategory> = {}
): Promise<[ProductCategory[], number]> {
const includeDescendantsTree = selector.include_descendants_tree
delete selector.include_descendants_tree

const productCategoryRepo = this.activeManager_.withRepository(
this.productCategoryRepo_
)
Expand All @@ -71,11 +79,22 @@ class ProductCategoryService extends TransactionBaseService {

const query = buildQuery(selector_, config)

return await productCategoryRepo.getFreeTextSearchResultsAndCount(
query,
q,
treeSelector
)
let [productCategories, count] =
await productCategoryRepo.getFreeTextSearchResultsAndCount(
query,
q,
treeSelector
)

if (includeDescendantsTree) {
productCategories = await Promise.all(
productCategories.map(async (productCategory) =>
productCategoryRepo.findDescendantsTree(productCategory)
)
)
}

return [productCategories, count]
}

/**
Expand Down
3 changes: 3 additions & 0 deletions packages/medusa/src/types/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ export type ExtendedFindConfig<TEntity> = (
}

export type QuerySelector<TEntity> = Selector<TEntity> & { q?: string }
export type TreeQuerySelector<TEntity> = QuerySelector<TEntity> & {
include_descendants_tree?: boolean
}

export type Selector<TEntity> = {
[key in keyof TEntity]?:
Expand Down
Loading

0 comments on commit ce3b79a

Please sign in to comment.