diff --git a/packages/core/modules-sdk/src/remote-query/__fixtures__/parse-filters.ts b/packages/core/modules-sdk/src/remote-query/__fixtures__/parse-filters.ts index fdda72f545..857b0bbd37 100644 --- a/packages/core/modules-sdk/src/remote-query/__fixtures__/parse-filters.ts +++ b/packages/core/modules-sdk/src/remote-query/__fixtures__/parse-filters.ts @@ -2,6 +2,27 @@ import { defineJoinerConfig } from "@medusajs/utils" import { MedusaModule } from "../../medusa-module" 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", { schema: ` type Product { @@ -154,6 +175,7 @@ const linkProductVariantPriceSet = { MedusaModule.setJoinerConfig("product", productJoinerConfig) MedusaModule.setJoinerConfig("pricing", pricingJoinerConfig) +MedusaModule.setJoinerConfig("customProduct", customModuleJoinerConfig) MedusaModule.setJoinerConfig( "link-product-variant-price-set", linkProductVariantPriceSet diff --git a/packages/core/modules-sdk/src/remote-query/__tests__/parse-filters.spec.ts b/packages/core/modules-sdk/src/remote-query/__tests__/parse-filters.spec.ts index ee5df36d11..a2e9df7a0d 100644 --- a/packages/core/modules-sdk/src/remote-query/__tests__/parse-filters.spec.ts +++ b/packages/core/modules-sdk/src/remote-query/__tests__/parse-filters.spec.ts @@ -11,6 +11,44 @@ const entitiesMap = getEntitiesMap( describe("parse-filters", () => { 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", () => { const filters = { id: "string", diff --git a/packages/core/modules-sdk/src/remote-query/parse-filters.ts b/packages/core/modules-sdk/src/remote-query/parse-filters.ts index 74d047fc35..2c89f2ba05 100644 --- a/packages/core/modules-sdk/src/remote-query/parse-filters.ts +++ b/packages/core/modules-sdk/src/remote-query/parse-filters.ts @@ -1,8 +1,4 @@ -import { - JoinerServiceConfig, - JoinerServiceConfigAlias, - ModuleJoinerConfig, -} from "@medusajs/types" +import { JoinerServiceConfig, ModuleJoinerConfig } from "@medusajs/types" import { isObject, isString } from "@medusajs/utils" import { MedusaModule } from "../medusa-module" @@ -33,23 +29,25 @@ export function parseAndAssignFilters( const joinerConfigs = MedusaModule.getAllJoinerConfigs() for (const [filterKey, filterValue] of Object.entries(filters)) { - let entryAlias!: JoinerServiceConfigAlias + /*let entryAlias!: JoinerServiceConfigAlias*/ let entryJoinerConfig!: JoinerServiceConfig - const { joinerConfig, alias } = retrieveJoinerConfigFromPropertyName({ + const { joinerConfig /*alias*/ } = retrieveJoinerConfigFromPropertyName({ entryPoint: entryPoint, joinerConfigs, }) - entryAlias = alias + /*JoinerServiceConfigentryAlias = alias!*/ 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) { throw new Error( `Entity ${entryAlias.entity} not found in the public schema of the joiner config from ${entryJoinerConfig.serviceName}` ) - } + }*/ if (isObject(filterValue)) { for (const [nestedFilterKey, nestedFilterValue] of Object.entries( @@ -58,6 +56,7 @@ export function parseAndAssignFilters( const { joinerConfig: filterKeyJoinerConfig } = retrieveJoinerConfigFromPropertyName({ entryPoint: nestedFilterKey, + parentJoinerConfig: joinerConfig, joinerConfigs, }) @@ -85,7 +84,7 @@ export function parseAndAssignFilters( parseAndAssignFilters( { entryPoint: nestedFilterKey, - filters: nestedFilterValue, + filters: nestedFilterValue as object, remoteQueryObject: remoteQueryObject[entryPoint][filterKey], 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)) { return joinerConfigMapCache.get(entryPoint)! } 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 aliasNames = Array.isArray(alias.name) ? alias.name : [alias.name] - return aliasNames.includes(entryPoint) + return aliasNames.some((alias) => alias === entryPoint) }) if (entryPointAlias) { @@ -132,6 +153,35 @@ function retrieveJoinerConfigFromPropertyName({ entryPoint, joinerConfigs }) { 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({ entryPoint, filterKey,