chore: Allow to fetch remote link using the service name or the alias from the use remote link step (#8140)

* chore: Allow to fetch remote link using the service name or the alias from the use remote link step

* revert package.json

* fix packages
This commit is contained in:
Adrien de Peretti
2024-07-16 11:03:41 +02:00
committed by GitHub
parent ffd4b195ee
commit 8a68919ed3
4 changed files with 78 additions and 73 deletions

View File

@@ -25,7 +25,8 @@ medusaIntegrationTestRunner({
})
.filter(Boolean)[0]
expect(link.serviceName).toEqual("currencyCurrencyRegionRegionLink")
expect(link.serviceName).toEqual(linkDefinition.serviceName)
expect(link.entryPoint).toEqual(linkDefinition.alias[0].name[0])
expect(linkDefinition).toEqual({
serviceName: "currencyCurrencyRegionRegionLink",
isLink: true,
@@ -112,7 +113,8 @@ medusaIntegrationTestRunner({
})
.filter(Boolean)[0]
expect(link.serviceName).toEqual("currencyCurrencyRegionRegionLink")
expect(link.serviceName).toEqual(linkDefinition.serviceName)
expect(link.entryPoint).toEqual(linkDefinition.alias[0].name[0])
expect(linkDefinition).toEqual({
serviceName: "currencyCurrencyRegionRegionLink",
isLink: true,

View File

@@ -1,8 +1,10 @@
import { remoteQueryObjectFromString } from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
interface StepInput {
entry_point: string
fields: string[]
variables?: Record<string, any>
throw_if_key_not_found?: boolean
@@ -10,18 +12,32 @@ interface StepInput {
list?: boolean
}
interface EntryStepInput extends StepInput {
entry_point: string
}
interface ServiceStepInput extends StepInput {
service: string
}
export const useRemoteQueryStepId = "use-remote-query"
export const useRemoteQueryStep = createStep(
useRemoteQueryStepId,
async (data: StepInput, { container }) => {
const { list = true, fields, variables, entry_point: entryPoint } = data
const query = container.resolve("remoteQuery")
async (data: EntryStepInput | ServiceStepInput, { container }) => {
const { list = true, fields, variables } = data
const queryObject = remoteQueryObjectFromString({
entryPoint,
const query = container.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
const isUsingEntryPoint = "entry_point" in data
const queryObjectConfig = {
fields,
variables,
})
entryPoint: isUsingEntryPoint ? data.entry_point : undefined,
service: !isUsingEntryPoint ? data.service : undefined,
} as Parameters<typeof remoteQueryObjectFromString>[0]
const queryObject = remoteQueryObjectFromString(queryObjectConfig)
const config = {
throwIfKeyNotFound: !!data.throw_if_key_not_found,

View File

@@ -1,5 +1,5 @@
import { LinkModulesExtraFields, ModuleJoinerConfig } from "@medusajs/types"
import { camelToSnakeCase, isObject, pluralize, toPascalCase } from "../common"
import { isObject, pluralize, toPascalCase } from "../common"
import { composeLinkName } from "../link"
export const DefineLinkSymbol = Symbol.for("DefineLink")
@@ -7,6 +7,7 @@ export const DefineLinkSymbol = Symbol.for("DefineLink")
export interface DefineLinkExport {
[DefineLinkSymbol]: boolean
serviceName: string
entryPoint: string
}
type InputSource = {
@@ -65,71 +66,55 @@ function isToJSON(input: any): input is InputToJson {
return isObject(input) && input?.["toJSON"]
}
function prepareServiceConfig(input: DefineLinkInputSource) {
let serviceConfig = {} as ModuleLinkableKeyConfig
if (isInputSource(input)) {
const source = isToJSON(input) ? input.toJSON() : input
serviceConfig = {
key: source.linkable,
alias: source.field,
primaryKey: source.primaryKey,
isList: false,
deleteCascade: false,
module: source.serviceName,
}
} else if (isInputOptions(input)) {
const source = isToJSON(input.linkable)
? input.linkable.toJSON()
: input.linkable
serviceConfig = {
key: source.linkable,
alias: source.field,
primaryKey: source.primaryKey,
isList: input.isList ?? false,
deleteCascade: input.deleteCascade ?? false,
module: source.serviceName,
}
} else {
throw new Error(
`Invalid linkable passed for the argument\n${JSON.stringify(
input,
null,
2
)}`
)
}
return serviceConfig
}
export function defineLink(
leftService: DefineLinkInputSource,
rightService: DefineLinkInputSource,
linkServiceOptions?: ExtraOptions
): DefineLinkExport {
let serviceAObj = {} as ModuleLinkableKeyConfig
let serviceBObj = {} as ModuleLinkableKeyConfig
const serviceAObj = prepareServiceConfig(leftService)
const serviceBObj = prepareServiceConfig(rightService)
if (isInputSource(leftService)) {
const source = isToJSON(leftService) ? leftService.toJSON() : leftService
serviceAObj = {
key: source.linkable,
alias: source.field,
primaryKey: source.primaryKey,
isList: false,
deleteCascade: false,
module: source.serviceName,
}
} else if (isInputOptions(leftService)) {
const source = isToJSON(leftService.linkable)
? leftService.linkable.toJSON()
: leftService.linkable
serviceAObj = {
key: source.linkable,
alias: source.field,
primaryKey: source.primaryKey,
isList: leftService.isList ?? false,
deleteCascade: leftService.deleteCascade ?? false,
module: source.serviceName,
}
} else {
throw new Error("Invalid linkable passed for the first argument")
}
if (isInputSource(rightService)) {
const source = isToJSON(rightService) ? rightService.toJSON() : rightService
serviceBObj = {
key: source.linkable,
alias: camelToSnakeCase(source.field),
primaryKey: source.primaryKey,
isList: false,
deleteCascade: false,
module: source.serviceName,
}
} else if (isInputOptions(rightService)) {
const source = isToJSON(rightService.linkable)
? rightService.linkable.toJSON()
: rightService.linkable
serviceBObj = {
key: source.linkable,
alias: camelToSnakeCase(source.field),
primaryKey: source.primaryKey,
isList: rightService.isList ?? false,
deleteCascade: rightService.deleteCascade ?? false,
module: source.serviceName,
}
} else {
throw new Error(`Invalid linkable passed for the second argument`)
}
const output = { [DefineLinkSymbol]: true, serviceName: "" }
const output = { [DefineLinkSymbol]: true, serviceName: "", entryPoint: "" }
const register = function (
modules: ModuleJoinerConfig[]
@@ -272,12 +257,14 @@ ${serviceBObj.module}: {
aliasB
)
output.entryPoint = aliasA + "_" + aliasB
const linkDefinition: ModuleJoinerConfig = {
serviceName: output.serviceName,
isLink: true,
alias: [
{
name: [aliasA + "_" + aliasB],
name: [output.entryPoint],
args: {
entity: toPascalCase(
[

View File

@@ -8,7 +8,7 @@ export class Migration20240703095850 extends Migration {
'CREATE UNIQUE INDEX "IDX_user_email" ON "user" (email) WHERE deleted_at IS NULL;'
)
// Adding this log here as the point of failure is not in this function, but bundled up when running all pending migration
console.warn(
console.info(
`Note: If the index "IDX_user_email" fails to create, then delete any existing users with duplicate emails before retrying the migration.`
)
}