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 authored and GitHub committed 2024-07-16 11:03:41 +02:00
1 parent ffd4b195ee
commit 8a68919ed3
4 files changed
+78 -73

No files matched your search

@@ -25,7 +25,8 @@ medusaIntegrationTestRunner({
}) })
.filter(Boolean)[0] .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({ expect(linkDefinition).toEqual({
serviceName: "currencyCurrencyRegionRegionLink", serviceName: "currencyCurrencyRegionRegionLink",
isLink: true, isLink: true,
@@ -112,7 +113,8 @@ medusaIntegrationTestRunner({
}) })
.filter(Boolean)[0] .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({ expect(linkDefinition).toEqual({
serviceName: "currencyCurrencyRegionRegionLink", serviceName: "currencyCurrencyRegionRegionLink",
isLink: true, isLink: true,
@@ -1,8 +1,10 @@
import { remoteQueryObjectFromString } from "@medusajs/utils" import {
import { StepResponse, createStep } from "@medusajs/workflows-sdk" ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
interface StepInput { interface StepInput {
entry_point: string
fields: string[] fields: string[]
variables?: Record<string, any> variables?: Record<string, any>
throw_if_key_not_found?: boolean throw_if_key_not_found?: boolean
@@ -10,18 +12,32 @@ interface StepInput {
list?: boolean list?: boolean
} }
interface EntryStepInput extends StepInput {
entry_point: string
}
interface ServiceStepInput extends StepInput {
service: string
}
export const useRemoteQueryStepId = "use-remote-query" export const useRemoteQueryStepId = "use-remote-query"
export const useRemoteQueryStep = createStep( export const useRemoteQueryStep = createStep(
useRemoteQueryStepId, useRemoteQueryStepId,
async (data: StepInput, { container }) => { async (data: EntryStepInput | ServiceStepInput, { container }) => {
const { list = true, fields, variables, entry_point: entryPoint } = data const { list = true, fields, variables } = data
const query = container.resolve("remoteQuery")
const queryObject = remoteQueryObjectFromString({ const query = container.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
entryPoint,
const isUsingEntryPoint = "entry_point" in data
const queryObjectConfig = {
fields, fields,
variables, variables,
}) entryPoint: isUsingEntryPoint ? data.entry_point : undefined,
service: !isUsingEntryPoint ? data.service : undefined,
} as Parameters<typeof remoteQueryObjectFromString>[0]
const queryObject = remoteQueryObjectFromString(queryObjectConfig)
const config = { const config = {
throwIfKeyNotFound: !!data.throw_if_key_not_found, throwIfKeyNotFound: !!data.throw_if_key_not_found,
@@ -1,5 +1,5 @@
import { LinkModulesExtraFields, ModuleJoinerConfig } from "@medusajs/types" import { LinkModulesExtraFields, ModuleJoinerConfig } from "@medusajs/types"
import { camelToSnakeCase, isObject, pluralize, toPascalCase } from "../common" import { isObject, pluralize, toPascalCase } from "../common"
import { composeLinkName } from "../link" import { composeLinkName } from "../link"
export const DefineLinkSymbol = Symbol.for("DefineLink") export const DefineLinkSymbol = Symbol.for("DefineLink")
@@ -7,6 +7,7 @@ export const DefineLinkSymbol = Symbol.for("DefineLink")
export interface DefineLinkExport { export interface DefineLinkExport {
[DefineLinkSymbol]: boolean [DefineLinkSymbol]: boolean
serviceName: string serviceName: string
entryPoint: string
} }
type InputSource = { type InputSource = {
@@ -65,71 +66,55 @@ function isToJSON(input: any): input is InputToJson {
return isObject(input) && input?.["toJSON"] 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( export function defineLink(
leftService: DefineLinkInputSource, leftService: DefineLinkInputSource,
rightService: DefineLinkInputSource, rightService: DefineLinkInputSource,
linkServiceOptions?: ExtraOptions linkServiceOptions?: ExtraOptions
): DefineLinkExport { ): DefineLinkExport {
let serviceAObj = {} as ModuleLinkableKeyConfig const serviceAObj = prepareServiceConfig(leftService)
let serviceBObj = {} as ModuleLinkableKeyConfig const serviceBObj = prepareServiceConfig(rightService)
if (isInputSource(leftService)) { const output = { [DefineLinkSymbol]: true, serviceName: "", entryPoint: "" }
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 register = function ( const register = function (
modules: ModuleJoinerConfig[] modules: ModuleJoinerConfig[]
@@ -272,12 +257,14 @@ ${serviceBObj.module}: {
aliasB aliasB
) )
output.entryPoint = aliasA + "_" + aliasB
const linkDefinition: ModuleJoinerConfig = { const linkDefinition: ModuleJoinerConfig = {
serviceName: output.serviceName, serviceName: output.serviceName,
isLink: true, isLink: true,
alias: [ alias: [
{ {
name: [aliasA + "_" + aliasB], name: [output.entryPoint],
args: { args: {
entity: toPascalCase( entity: toPascalCase(
[ [
@@ -8,7 +8,7 @@ export class Migration20240703095850 extends Migration {
'CREATE UNIQUE INDEX "IDX_user_email" ON "user" (email) WHERE deleted_at IS NULL;' '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 // 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.` `Note: If the index "IDX_user_email" fails to create, then delete any existing users with duplicate emails before retrying the migration.`
) )
} }