chore: Processing filters deeply looking at the current joiner first (#9428)
* chore: Processing filters deeply looking at the current joiner first * fix * fix
This commit is contained in:
@@ -2,6 +2,27 @@ import { defineJoinerConfig } from "@medusajs/utils"
|
|||||||
import { MedusaModule } from "../../medusa-module"
|
import { MedusaModule } from "../../medusa-module"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
|
|
||||||
|
const customModuleJoinerConfig = defineJoinerConfig("custom_user", {
|
||||||
|
schema: `
|
||||||
|
type CustomProduct {
|
||||||
|
id: ID
|
||||||
|
title: String
|
||||||
|
product: Product
|
||||||
|
}
|
||||||
|
|
||||||
|
type Product {
|
||||||
|
id: ID
|
||||||
|
title: String
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
alias: [
|
||||||
|
{
|
||||||
|
name: ["custom_products", "custom_product"],
|
||||||
|
entity: "CustomProduct",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
const productJoinerConfig = defineJoinerConfig("product", {
|
const productJoinerConfig = defineJoinerConfig("product", {
|
||||||
schema: `
|
schema: `
|
||||||
type Product {
|
type Product {
|
||||||
@@ -154,6 +175,7 @@ const linkProductVariantPriceSet = {
|
|||||||
|
|
||||||
MedusaModule.setJoinerConfig("product", productJoinerConfig)
|
MedusaModule.setJoinerConfig("product", productJoinerConfig)
|
||||||
MedusaModule.setJoinerConfig("pricing", pricingJoinerConfig)
|
MedusaModule.setJoinerConfig("pricing", pricingJoinerConfig)
|
||||||
|
MedusaModule.setJoinerConfig("customProduct", customModuleJoinerConfig)
|
||||||
MedusaModule.setJoinerConfig(
|
MedusaModule.setJoinerConfig(
|
||||||
"link-product-variant-price-set",
|
"link-product-variant-price-set",
|
||||||
linkProductVariantPriceSet
|
linkProductVariantPriceSet
|
||||||
|
|||||||
@@ -11,6 +11,44 @@ const entitiesMap = getEntitiesMap(
|
|||||||
|
|
||||||
describe("parse-filters", () => {
|
describe("parse-filters", () => {
|
||||||
describe("Without operator map usage", () => {
|
describe("Without operator map usage", () => {
|
||||||
|
it(`should parse filter for a single level module with ambiguous entity`, () => {
|
||||||
|
const filters = {
|
||||||
|
id: "string",
|
||||||
|
product: {
|
||||||
|
title: "test",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const remoteQueryObject = {
|
||||||
|
custom_product: {
|
||||||
|
fields: ["id", "product.*"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
parseAndAssignFilters(
|
||||||
|
{
|
||||||
|
remoteQueryObject,
|
||||||
|
entryPoint: "custom_product",
|
||||||
|
filters,
|
||||||
|
},
|
||||||
|
entitiesMap
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(remoteQueryObject).toEqual({
|
||||||
|
custom_product: {
|
||||||
|
fields: ["id", "product.*"],
|
||||||
|
__args: {
|
||||||
|
filters: {
|
||||||
|
id: "string",
|
||||||
|
product: {
|
||||||
|
title: "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it("should parse filter for a single level module", () => {
|
it("should parse filter for a single level module", () => {
|
||||||
const filters = {
|
const filters = {
|
||||||
id: "string",
|
id: "string",
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
import {
|
import { JoinerServiceConfig, ModuleJoinerConfig } from "@medusajs/types"
|
||||||
JoinerServiceConfig,
|
|
||||||
JoinerServiceConfigAlias,
|
|
||||||
ModuleJoinerConfig,
|
|
||||||
} from "@medusajs/types"
|
|
||||||
import { isObject, isString } from "@medusajs/utils"
|
import { isObject, isString } from "@medusajs/utils"
|
||||||
import { MedusaModule } from "../medusa-module"
|
import { MedusaModule } from "../medusa-module"
|
||||||
|
|
||||||
@@ -33,23 +29,25 @@ export function parseAndAssignFilters(
|
|||||||
const joinerConfigs = MedusaModule.getAllJoinerConfigs()
|
const joinerConfigs = MedusaModule.getAllJoinerConfigs()
|
||||||
|
|
||||||
for (const [filterKey, filterValue] of Object.entries(filters)) {
|
for (const [filterKey, filterValue] of Object.entries(filters)) {
|
||||||
let entryAlias!: JoinerServiceConfigAlias
|
/*let entryAlias!: JoinerServiceConfigAlias*/
|
||||||
let entryJoinerConfig!: JoinerServiceConfig
|
let entryJoinerConfig!: JoinerServiceConfig
|
||||||
|
|
||||||
const { joinerConfig, alias } = retrieveJoinerConfigFromPropertyName({
|
const { joinerConfig /*alias*/ } = retrieveJoinerConfigFromPropertyName({
|
||||||
entryPoint: entryPoint,
|
entryPoint: entryPoint,
|
||||||
joinerConfigs,
|
joinerConfigs,
|
||||||
})
|
})
|
||||||
|
|
||||||
entryAlias = alias
|
/*JoinerServiceConfigentryAlias = alias!*/
|
||||||
entryJoinerConfig = joinerConfig
|
entryJoinerConfig = joinerConfig
|
||||||
|
|
||||||
const entryEntity = entitiesMap[entryAlias.entity!]
|
// TODO: This check is not used further than to validate the entity is part of the graphql schema
|
||||||
|
// This can't be used right now as we have not migrated the entire code base to DML from which the graphql schema is generated
|
||||||
|
/*const entryEntity = entitiesMap[entryAlias.entity!]
|
||||||
if (!entryEntity) {
|
if (!entryEntity) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Entity ${entryAlias.entity} not found in the public schema of the joiner config from ${entryJoinerConfig.serviceName}`
|
`Entity ${entryAlias.entity} not found in the public schema of the joiner config from ${entryJoinerConfig.serviceName}`
|
||||||
)
|
)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (isObject(filterValue)) {
|
if (isObject(filterValue)) {
|
||||||
for (const [nestedFilterKey, nestedFilterValue] of Object.entries(
|
for (const [nestedFilterKey, nestedFilterValue] of Object.entries(
|
||||||
@@ -58,6 +56,7 @@ export function parseAndAssignFilters(
|
|||||||
const { joinerConfig: filterKeyJoinerConfig } =
|
const { joinerConfig: filterKeyJoinerConfig } =
|
||||||
retrieveJoinerConfigFromPropertyName({
|
retrieveJoinerConfigFromPropertyName({
|
||||||
entryPoint: nestedFilterKey,
|
entryPoint: nestedFilterKey,
|
||||||
|
parentJoinerConfig: joinerConfig,
|
||||||
joinerConfigs,
|
joinerConfigs,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -85,7 +84,7 @@ export function parseAndAssignFilters(
|
|||||||
parseAndAssignFilters(
|
parseAndAssignFilters(
|
||||||
{
|
{
|
||||||
entryPoint: nestedFilterKey,
|
entryPoint: nestedFilterKey,
|
||||||
filters: nestedFilterValue,
|
filters: nestedFilterValue as object,
|
||||||
remoteQueryObject: remoteQueryObject[entryPoint][filterKey],
|
remoteQueryObject: remoteQueryObject[entryPoint][filterKey],
|
||||||
isFieldAliasNestedRelation: isFieldAliasNestedRelation_,
|
isFieldAliasNestedRelation: isFieldAliasNestedRelation_,
|
||||||
},
|
},
|
||||||
@@ -107,16 +106,38 @@ export function parseAndAssignFilters(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function retrieveJoinerConfigFromPropertyName({ entryPoint, joinerConfigs }) {
|
function retrieveJoinerConfigFromPropertyName({
|
||||||
|
entryPoint,
|
||||||
|
parentJoinerConfig,
|
||||||
|
joinerConfigs,
|
||||||
|
}: {
|
||||||
|
entryPoint: string
|
||||||
|
parentJoinerConfig?: ModuleJoinerConfig
|
||||||
|
joinerConfigs: ModuleJoinerConfig[]
|
||||||
|
}) {
|
||||||
|
if (parentJoinerConfig) {
|
||||||
|
const res = findAliasFromJoinerConfig({
|
||||||
|
joinerConfig: parentJoinerConfig,
|
||||||
|
entryPoint,
|
||||||
|
})
|
||||||
|
if (res) {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (joinerConfigMapCache.has(entryPoint)) {
|
if (joinerConfigMapCache.has(entryPoint)) {
|
||||||
return joinerConfigMapCache.get(entryPoint)!
|
return joinerConfigMapCache.get(entryPoint)!
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const joinerConfig of joinerConfigs) {
|
for (const joinerConfig of joinerConfigs) {
|
||||||
const aliases = joinerConfig.alias
|
const joinerConfigAlias = joinerConfig.alias ?? []
|
||||||
|
const aliases = Array.isArray(joinerConfigAlias)
|
||||||
|
? joinerConfigAlias
|
||||||
|
: [joinerConfigAlias]
|
||||||
|
|
||||||
const entryPointAlias = aliases.find((alias) => {
|
const entryPointAlias = aliases.find((alias) => {
|
||||||
const aliasNames = Array.isArray(alias.name) ? alias.name : [alias.name]
|
const aliasNames = Array.isArray(alias.name) ? alias.name : [alias.name]
|
||||||
return aliasNames.includes(entryPoint)
|
return aliasNames.some((alias) => alias === entryPoint)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (entryPointAlias) {
|
if (entryPointAlias) {
|
||||||
@@ -132,6 +153,35 @@ function retrieveJoinerConfigFromPropertyName({ entryPoint, joinerConfigs }) {
|
|||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findAliasFromJoinerConfig({
|
||||||
|
joinerConfig,
|
||||||
|
entryPoint,
|
||||||
|
}: {
|
||||||
|
joinerConfig: ModuleJoinerConfig
|
||||||
|
entryPoint: string
|
||||||
|
}) {
|
||||||
|
const joinerConfigAlias = joinerConfig.alias ?? []
|
||||||
|
const aliases = Array.isArray(joinerConfigAlias)
|
||||||
|
? joinerConfigAlias
|
||||||
|
: [joinerConfigAlias]
|
||||||
|
|
||||||
|
const entryPointAlias = aliases.find((alias) => {
|
||||||
|
const aliasNames = Array.isArray(alias.name) ? alias.name : [alias.name]
|
||||||
|
return aliasNames.some((alias) => alias === entryPoint)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (entryPointAlias) {
|
||||||
|
joinerConfigMapCache.set(entryPoint, {
|
||||||
|
joinerConfig,
|
||||||
|
alias: entryPointAlias,
|
||||||
|
})
|
||||||
|
|
||||||
|
return { joinerConfig, alias: entryPointAlias }
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
function assignRemoteQueryObject({
|
function assignRemoteQueryObject({
|
||||||
entryPoint,
|
entryPoint,
|
||||||
filterKey,
|
filterKey,
|
||||||
|
|||||||
Reference in New Issue
Block a user