feat(index): add filterable fields to link definition (#11898)

* feat(index): add filterable fields to link definition

* rm comment

* break recursion

* validate read only links

* validate filterable

* gql schema array

* link parents

* isInverse

* push id when not present

* Fix ciruclar relationships and add tests to ensure proper behaviour (part 1)

* log and fallback to entity.alias

* cleanup and fixes

* cleanup and fixes

* cleanup and fixes

* fix get attributes

* gql type

* unit test

* array inference

* rm only

* package.json

* pacvkage.json

* fix link retrieval on duplicated entity type and aliases + tests

* link parents as array

* Match only parent entity

* rm comment

* remove hard coded schema

* extend types

* unit test

* test

* types

* pagination type

* type

* fix integration tests

* Improve performance of in selection

* use @@ to filter property

* escape jsonPath

* add Event Bus by default

* changeset

* rm postgres analyze

* estimate count

* new query

* parent aliases

* inner query w/ filter and sort relations

* address comments

---------

Co-authored-by: adrien2p <adrien.deperetti@gmail.com>
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Carlos R. L. Rodrigues
2025-04-29 07:10:31 -03:00
committed by GitHub
parent 8a3f639f01
commit b868a4ef4d
37 changed files with 3285 additions and 755 deletions

View File

@@ -18,6 +18,7 @@ type InputSource = {
alias?: string
linkable: string
primaryKey: string
filterable?: string[]
}
type ReadOnlyInputSource = {
@@ -42,6 +43,7 @@ type InputOptions = {
field?: string
isList?: boolean
deleteCascade?: boolean
filterable?: string[]
}
type Shortcut = {
@@ -87,6 +89,7 @@ type ModuleLinkableKeyConfig = {
alias: string
hasMany?: boolean
shortcut?: Shortcut | Shortcut[]
filterable?: string[]
}
function isInputOptions(input: any): input is InputOptions {
@@ -141,6 +144,7 @@ function prepareServiceConfig(
isList: false,
hasMany: false,
deleteCascade: false,
filterable: source.filterable,
module: source.serviceName,
entity: source.entity,
}
@@ -159,6 +163,7 @@ function prepareServiceConfig(
isList: input.isList ?? false,
hasMany,
deleteCascade: input.deleteCascade ?? false,
filterable: input.filterable,
module: source.serviceName,
entity: source.entity,
}
@@ -192,6 +197,17 @@ export function defineLink(
const serviceBObj = prepareServiceConfig(rightService)
if (linkServiceOptions?.readOnly) {
if (!leftService.linkable || !leftService.field) {
throw new Error(
`ReadOnly link requires "linkable" and "field" to be defined for the left service.`
)
} else if (
(leftService as DefineLinkInputSource).filterable ||
(rightService as DefineLinkInputSource).filterable
) {
throw new Error(`ReadOnly link does not support filterable fields.`)
}
return defineReadOnlyLink(
serviceAObj,
serviceBObj,
@@ -378,6 +394,7 @@ ${serviceBObj.module}: {
methodSuffix: serviceAMethodSuffix,
},
deleteCascade: serviceAObj.deleteCascade,
filterable: serviceAObj.filterable,
hasMany: serviceAObj.hasMany,
},
{
@@ -390,6 +407,7 @@ ${serviceBObj.module}: {
methodSuffix: serviceBMethodSuffix,
},
deleteCascade: serviceBObj.deleteCascade,
filterable: serviceBObj.filterable,
hasMany: serviceBObj.hasMany,
},
],

View File

@@ -1,11 +1,13 @@
type QueryContextType = {
import { QueryContextType } from "@medusajs/types"
type QueryContexFnType = {
(query: Record<string, unknown>): Record<string, unknown>
isQueryContext: (obj: any) => boolean
}
const __type = "QueryContext"
function QueryContextFn(query: Record<string, unknown>) {
function QueryContextFn(query: Record<string, unknown>): QueryContextType {
return {
...query,
__type,
@@ -16,4 +18,4 @@ QueryContextFn.isQueryContext = (obj: any) => {
return obj.__type === __type
}
export const QueryContext: QueryContextType = QueryContextFn
export const QueryContext: QueryContexFnType = QueryContextFn