chore(medusa,orchestration,link-modules,modules-sdk): internal services as modules (#4925)
This commit is contained in:
committed by
GitHub
parent
85fa90d9c6
commit
a4906d0ac0
8
.changeset/young-teachers-sit.md
Normal file
8
.changeset/young-teachers-sit.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"@medusajs/orchestration": minor
|
||||
"@medusajs/link-modules": minor
|
||||
"@medusajs/modules-sdk": minor
|
||||
"@medusajs/medusa": minor
|
||||
---
|
||||
|
||||
Use MedusaApp on core and initial JoinerConfig for internal services
|
||||
@@ -2,6 +2,7 @@ const path = require("path")
|
||||
const express = require("express")
|
||||
const importFrom = require("import-from")
|
||||
const chokidar = require("chokidar")
|
||||
const { WorkflowManager } = require("@medusajs/orchestration")
|
||||
|
||||
process.env.DEV_MODE = !!process[Symbol.for("ts-node.register.instance")]
|
||||
process.env.NODE_ENV = process.env.DEV_MODE && "development"
|
||||
@@ -107,6 +108,8 @@ const watchFiles = () => {
|
||||
}
|
||||
}
|
||||
|
||||
WorkflowManager.unregisterAll()
|
||||
|
||||
await bootstrapApp()
|
||||
IS_RELOADING = false
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||
import { LINKS } from "../links"
|
||||
|
||||
export const ProductShippingProfile: ModuleJoinerConfig = {
|
||||
serviceName: LINKS.ProductShippingProfile,
|
||||
isLink: true,
|
||||
databaseConfig: {
|
||||
tableName: "product_shipping_profile",
|
||||
idPrefix: "psprof",
|
||||
},
|
||||
alias: [
|
||||
{
|
||||
name: "product_shipping_profile",
|
||||
},
|
||||
],
|
||||
primaryKeys: ["id", "product_id", "profile_id"],
|
||||
relationships: [
|
||||
{
|
||||
serviceName: Modules.PRODUCT,
|
||||
primaryKey: "id",
|
||||
foreignKey: "product_id",
|
||||
alias: "product",
|
||||
},
|
||||
{
|
||||
serviceName: "shippingProfileService",
|
||||
primaryKey: "id",
|
||||
foreignKey: "profile_id",
|
||||
alias: "shipping_profile",
|
||||
},
|
||||
],
|
||||
extends: [
|
||||
{
|
||||
serviceName: Modules.PRODUCT,
|
||||
relationship: {
|
||||
serviceName: LINKS.ProductShippingProfile,
|
||||
primaryKey: "product_id",
|
||||
foreignKey: "id",
|
||||
alias: "shipping_profile",
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceName: "shippingProfileService",
|
||||
relationship: {
|
||||
serviceName: LINKS.ProductShippingProfile,
|
||||
primaryKey: "profile_id",
|
||||
foreignKey: "id",
|
||||
alias: "product_link",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -14,4 +14,12 @@ export const LINKS = {
|
||||
Modules.PRICING,
|
||||
"money_amount_id"
|
||||
),
|
||||
|
||||
// Internal services
|
||||
ProductShippingProfile: composeLinkName(
|
||||
Modules.PRODUCT,
|
||||
"variant_id",
|
||||
"shippingProfileService",
|
||||
"profile_id"
|
||||
),
|
||||
}
|
||||
|
||||
77
packages/medusa/src/joiner-config.ts
Normal file
77
packages/medusa/src/joiner-config.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||
|
||||
export const joinerConfig: ModuleJoinerConfig[] = [
|
||||
{
|
||||
serviceName: "cartService",
|
||||
primaryKeys: ["id"],
|
||||
linkableKeys: ["cart_id"],
|
||||
alias: [
|
||||
{
|
||||
name: "cart",
|
||||
},
|
||||
],
|
||||
relationships: [
|
||||
{
|
||||
serviceName: Modules.PRODUCT,
|
||||
primaryKey: "id",
|
||||
foreignKey: "variant_id",
|
||||
alias: "variant",
|
||||
args: {
|
||||
methodSuffix: "Variants",
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceName: "regionService",
|
||||
primaryKey: "id",
|
||||
foreignKey: "region_id",
|
||||
alias: "region",
|
||||
},
|
||||
{
|
||||
serviceName: "customerService",
|
||||
primaryKey: "id",
|
||||
foreignKey: "customer_id",
|
||||
alias: "customer",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
serviceName: "shippingProfileService",
|
||||
primaryKeys: ["id"],
|
||||
linkableKeys: ["profile_id"],
|
||||
alias: [
|
||||
{
|
||||
name: "shipping_profile",
|
||||
},
|
||||
{
|
||||
name: "shipping_profiles",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
serviceName: "regionService",
|
||||
primaryKeys: ["id"],
|
||||
linkableKeys: ["region_id"],
|
||||
alias: [
|
||||
{
|
||||
name: "region",
|
||||
},
|
||||
{
|
||||
name: "regions",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
serviceName: "customerService",
|
||||
primaryKeys: ["id"],
|
||||
linkableKeys: ["customer_id"],
|
||||
alias: [
|
||||
{
|
||||
name: "customer",
|
||||
},
|
||||
{
|
||||
name: "customers",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,10 @@
|
||||
import { FlagSettings } from "../../types/feature-flags"
|
||||
|
||||
const IsolateProductDomainFeatureFlag: FlagSettings = {
|
||||
key: "isolate_product_domain",
|
||||
default_val: false,
|
||||
env_key: "MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN",
|
||||
description: "[WIP] Isolate product domain dependencies from the core",
|
||||
}
|
||||
|
||||
export default IsolateProductDomainFeatureFlag
|
||||
@@ -1,20 +1,28 @@
|
||||
import { MedusaApp, moduleLoader, registerModules } from "@medusajs/modules-sdk"
|
||||
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
||||
import { asValue } from "awilix"
|
||||
import { Express, NextFunction, Request, Response } from "express"
|
||||
import { createMedusaContainer } from "medusa-core-utils"
|
||||
import { track } from "medusa-telemetry"
|
||||
import { EOL } from "os"
|
||||
import "reflect-metadata"
|
||||
import requestIp from "request-ip"
|
||||
import { Connection } from "typeorm"
|
||||
import { joinerConfig } from "../joiner-config"
|
||||
import modulesConfig from "../modules-config"
|
||||
import { MedusaContainer } from "../types/global"
|
||||
import { remoteQueryFetchData } from "../utils"
|
||||
import apiLoader from "./api"
|
||||
import loadConfig from "./config"
|
||||
import databaseLoader, { dataSource } from "./database"
|
||||
import defaultsLoader from "./defaults"
|
||||
import expressLoader from "./express"
|
||||
import featureFlagsLoader from "./feature-flags"
|
||||
import IsolateProductDomainFeatureFlag from "./feature-flags/isolate-product-domain"
|
||||
import Logger from "./logger"
|
||||
import modelsLoader from "./models"
|
||||
import passportLoader from "./passport"
|
||||
import pgConnectionLoader from "./pg-connection"
|
||||
import pluginsLoader, { registerPluginModels } from "./plugins"
|
||||
import redisLoader from "./redis"
|
||||
import repositoriesLoader from "./repositories"
|
||||
@@ -23,11 +31,6 @@ import servicesLoader from "./services"
|
||||
import strategiesLoader from "./strategies"
|
||||
import subscribersLoader from "./subscribers"
|
||||
|
||||
import { moduleLoader, registerModules } from "@medusajs/modules-sdk"
|
||||
import { createMedusaContainer } from "medusa-core-utils"
|
||||
import pgConnectionLoader from "./pg-connection"
|
||||
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
||||
|
||||
type Options = {
|
||||
directory: string
|
||||
expressApp: Express
|
||||
@@ -182,5 +185,20 @@ export default async ({
|
||||
Logger.success(searchActivity, "Indexing event emitted") || {}
|
||||
track("SEARCH_ENGINE_INDEXING_COMPLETED", { duration: searchAct.duration })
|
||||
|
||||
if (featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)) {
|
||||
const { query } = await MedusaApp({
|
||||
modulesConfig,
|
||||
servicesConfig: joinerConfig,
|
||||
remoteFetchData: remoteQueryFetchData(container),
|
||||
injectedDependencies: {
|
||||
[ContainerRegistrationKeys.PG_CONNECTION]: container.resolve(
|
||||
ContainerRegistrationKeys.PG_CONNECTION
|
||||
),
|
||||
},
|
||||
})
|
||||
|
||||
container.register("remoteQuery", asValue(query))
|
||||
}
|
||||
|
||||
return { container, dbConnection, app: expressApp }
|
||||
}
|
||||
|
||||
9
packages/medusa/src/modules-config.ts
Normal file
9
packages/medusa/src/modules-config.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { MedusaModuleConfig, Modules } from "@medusajs/modules-sdk"
|
||||
|
||||
const modules: MedusaModuleConfig = [
|
||||
{
|
||||
module: Modules.PRODUCT,
|
||||
},
|
||||
]
|
||||
|
||||
export default modules
|
||||
@@ -11,8 +11,9 @@ export * from "./is-object"
|
||||
export * from "./is-string"
|
||||
export * from "./omit-deep"
|
||||
export * from "./product-category"
|
||||
export * from "./remote-query-fetch-data"
|
||||
export * from "./remove-undefined-properties"
|
||||
export * from "./set-metadata"
|
||||
export * from "./validate-id"
|
||||
export * from "./validators/is-type"
|
||||
export { registerOverriddenValidators, validator } from "./validator"
|
||||
export * from "./validators/is-type"
|
||||
|
||||
53
packages/medusa/src/utils/remote-query-fetch-data.ts
Normal file
53
packages/medusa/src/utils/remote-query-fetch-data.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { MedusaModule, RemoteQuery } from "@medusajs/modules-sdk"
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
|
||||
export function remoteQueryFetchData(container: MedusaContainer) {
|
||||
return async (expand, keyField, ids, relationship) => {
|
||||
const serviceConfig = expand.serviceConfig
|
||||
const service = container.resolve(serviceConfig.serviceName, {
|
||||
allowUnregistered: true,
|
||||
})
|
||||
|
||||
if (MedusaModule.isInstalled(serviceConfig.serviceName)) {
|
||||
return
|
||||
}
|
||||
|
||||
const filters = {}
|
||||
const options = {
|
||||
...RemoteQuery.getAllFieldsAndRelations(expand),
|
||||
}
|
||||
|
||||
if (ids) {
|
||||
filters[keyField] = ids
|
||||
}
|
||||
|
||||
const hasPagination = Object.keys(options).some((key) =>
|
||||
["skip"].includes(key)
|
||||
)
|
||||
|
||||
let methodName = hasPagination ? "listAndCount" : "list"
|
||||
|
||||
if (relationship?.args?.methodSuffix) {
|
||||
methodName += relationship.args.methodSuffix
|
||||
} else if (serviceConfig?.args?.methodSuffix) {
|
||||
methodName += serviceConfig.args.methodSuffix
|
||||
}
|
||||
|
||||
const result = await service[methodName](filters, options)
|
||||
|
||||
if (hasPagination) {
|
||||
const [data, count] = result
|
||||
return {
|
||||
data: {
|
||||
rows: data,
|
||||
metadata: {},
|
||||
},
|
||||
path: "rows",
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
data: result,
|
||||
} as any
|
||||
}
|
||||
}
|
||||
@@ -36,20 +36,30 @@ export type SharedResources = {
|
||||
}
|
||||
}
|
||||
|
||||
export async function MedusaApp({
|
||||
sharedResourcesConfig,
|
||||
modulesConfigPath,
|
||||
modulesConfig,
|
||||
linkModules,
|
||||
remoteFetchData,
|
||||
}: {
|
||||
sharedResourcesConfig?: SharedResources
|
||||
loadedModules?: LoadedModule[]
|
||||
modulesConfigPath?: string
|
||||
modulesConfig?: MedusaModuleConfig
|
||||
linkModules?: ModuleJoinerConfig | ModuleJoinerConfig[]
|
||||
remoteFetchData?: RemoteFetchDataCallback
|
||||
} = {}): Promise<{
|
||||
export async function MedusaApp(
|
||||
{
|
||||
sharedResourcesConfig,
|
||||
servicesConfig,
|
||||
modulesConfigPath,
|
||||
modulesConfigFileName,
|
||||
modulesConfig,
|
||||
linkModules,
|
||||
remoteFetchData,
|
||||
injectedDependencies,
|
||||
}: {
|
||||
sharedResourcesConfig?: SharedResources
|
||||
loadedModules?: LoadedModule[]
|
||||
servicesConfig?: ModuleJoinerConfig[]
|
||||
modulesConfigPath?: string
|
||||
modulesConfigFileName?: string
|
||||
modulesConfig?: MedusaModuleConfig
|
||||
linkModules?: ModuleJoinerConfig | ModuleJoinerConfig[]
|
||||
remoteFetchData?: RemoteFetchDataCallback
|
||||
injectedDependencies?: any
|
||||
} = {
|
||||
injectedDependencies: {},
|
||||
}
|
||||
): Promise<{
|
||||
modules: Record<string, LoadedModule | LoadedModule[]>
|
||||
link: RemoteLink | undefined
|
||||
query: (
|
||||
@@ -59,10 +69,12 @@ export async function MedusaApp({
|
||||
}> {
|
||||
const modules: MedusaModuleConfig =
|
||||
modulesConfig ??
|
||||
(await import(process.cwd() + (modulesConfigPath ?? "/modules-config")))
|
||||
.default
|
||||
|
||||
const injectedDependencies: any = {}
|
||||
(
|
||||
await import(
|
||||
modulesConfigPath ??
|
||||
process.cwd() + (modulesConfigFileName ?? "/modules-config")
|
||||
)
|
||||
).default
|
||||
|
||||
const dbData = ModulesSdkUtils.loadDatabaseConfig(
|
||||
"medusa",
|
||||
@@ -167,7 +179,10 @@ export async function MedusaApp({
|
||||
console.warn("Error initializing link modules.", err)
|
||||
}
|
||||
|
||||
const remoteQuery = new RemoteQuery(undefined, remoteFetchData)
|
||||
const remoteQuery = new RemoteQuery({
|
||||
servicesConfig,
|
||||
customRemoteFetchData: remoteFetchData,
|
||||
})
|
||||
query = async (
|
||||
query: string | RemoteJoinerQuery,
|
||||
variables?: Record<string, unknown>
|
||||
|
||||
@@ -17,8 +17,17 @@ export class RemoteQuery {
|
||||
private customRemoteFetchData?: RemoteFetchDataCallback
|
||||
|
||||
constructor(
|
||||
modulesLoaded?: LoadedModule[],
|
||||
customRemoteFetchData?: RemoteFetchDataCallback
|
||||
{
|
||||
modulesLoaded,
|
||||
customRemoteFetchData,
|
||||
servicesConfig,
|
||||
}: {
|
||||
modulesLoaded?: LoadedModule[]
|
||||
customRemoteFetchData?: RemoteFetchDataCallback
|
||||
servicesConfig?: ModuleJoinerConfig[]
|
||||
} = {
|
||||
servicesConfig: [],
|
||||
}
|
||||
) {
|
||||
if (!modulesLoaded?.length) {
|
||||
modulesLoaded = MedusaModule.getLoadedModules().map(
|
||||
@@ -26,7 +35,6 @@ export class RemoteQuery {
|
||||
)
|
||||
}
|
||||
|
||||
const servicesConfig: ModuleJoinerConfig[] = []
|
||||
for (const mod of modulesLoaded) {
|
||||
if (!mod.__definition.isQueryable) {
|
||||
continue
|
||||
@@ -41,7 +49,7 @@ export class RemoteQuery {
|
||||
}
|
||||
|
||||
this.modulesMap.set(serviceName, mod)
|
||||
servicesConfig.push(mod.__joinerConfig)
|
||||
servicesConfig!.push(mod.__joinerConfig)
|
||||
}
|
||||
|
||||
this.customRemoteFetchData = customRemoteFetchData
|
||||
@@ -65,7 +73,7 @@ export class RemoteQuery {
|
||||
this.remoteJoiner.setFetchDataCallback(remoteFetchData)
|
||||
}
|
||||
|
||||
private static getAllFieldsAndRelations(
|
||||
public static getAllFieldsAndRelations(
|
||||
data: any,
|
||||
prefix = "",
|
||||
args: Record<string, unknown[]> = {}
|
||||
|
||||
@@ -317,13 +317,13 @@ describe("RemoteJoiner", () => {
|
||||
|
||||
expect(serviceMock.productService).toHaveBeenCalledTimes(2)
|
||||
expect(serviceMock.productService).toHaveBeenNthCalledWith(1, {
|
||||
fields: ["name", "id"],
|
||||
options: { id: expect.arrayContaining([103, 102]) },
|
||||
})
|
||||
|
||||
expect(serviceMock.productService).toHaveBeenNthCalledWith(2, {
|
||||
fields: ["handler", "id"],
|
||||
options: { id: expect.arrayContaining([101, 103]) },
|
||||
})
|
||||
|
||||
expect(serviceMock.productService).toHaveBeenNthCalledWith(2, {
|
||||
fields: ["name", "id"],
|
||||
options: { id: expect.arrayContaining([103, 102]) },
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -290,46 +290,38 @@ export class RemoteJoiner {
|
||||
if (!parsedExpands) {
|
||||
return
|
||||
}
|
||||
|
||||
const stack: [
|
||||
any[],
|
||||
Partial<RemoteJoinerQuery>,
|
||||
Map<string, RemoteExpandProperty>,
|
||||
string,
|
||||
Set<string>
|
||||
][] = [[items, query, parsedExpands, BASE_PATH, new Set()]]
|
||||
const resolvedPaths = new Set<string>()
|
||||
const stack: [any[], Partial<RemoteJoinerQuery>, string][] = [
|
||||
[items, query, BASE_PATH],
|
||||
]
|
||||
|
||||
while (stack.length > 0) {
|
||||
const [
|
||||
currentItems,
|
||||
currentQuery,
|
||||
currentParsedExpands,
|
||||
basePath,
|
||||
resolvedPaths,
|
||||
] = stack.pop()!
|
||||
const [currentItems, currentQuery, basePath] = stack.pop()!
|
||||
|
||||
for (const [expandedPath, expand] of currentParsedExpands.entries()) {
|
||||
const isImmediateChildPath = basePath === expand.parent
|
||||
for (const [expandedPath, expand] of parsedExpands.entries()) {
|
||||
const isParentPath = expandedPath.startsWith(basePath)
|
||||
|
||||
if (!isImmediateChildPath || resolvedPaths.has(expandedPath)) {
|
||||
if (!isParentPath || resolvedPaths.has(expandedPath)) {
|
||||
continue
|
||||
}
|
||||
|
||||
resolvedPaths.add(expandedPath)
|
||||
|
||||
const property = expand.property || ""
|
||||
const parentServiceConfig = this.getServiceConfig(
|
||||
currentQuery.service,
|
||||
currentQuery.alias
|
||||
)
|
||||
|
||||
await this.expandProperty(currentItems, parentServiceConfig!, expand)
|
||||
let curItems = currentItems
|
||||
const expandedPathLevels = expandedPath.split(".")
|
||||
for (let idx = 1; idx < expandedPathLevels.length - 1; idx++) {
|
||||
curItems = RemoteJoiner.getNestedItems(
|
||||
curItems,
|
||||
expandedPathLevels[idx]
|
||||
)
|
||||
}
|
||||
|
||||
await this.expandProperty(curItems, expand.parentConfig!, expand)
|
||||
const nestedItems = RemoteJoiner.getNestedItems(currentItems, property)
|
||||
|
||||
if (nestedItems.length > 0) {
|
||||
const relationship = expand.serviceConfig
|
||||
|
||||
let nextProp = currentQuery
|
||||
if (relationship) {
|
||||
const relQuery = {
|
||||
@@ -337,14 +329,7 @@ export class RemoteJoiner {
|
||||
}
|
||||
nextProp = relQuery
|
||||
}
|
||||
|
||||
stack.push([
|
||||
nestedItems,
|
||||
nextProp,
|
||||
currentParsedExpands,
|
||||
expandedPath,
|
||||
new Set(),
|
||||
])
|
||||
stack.push([nestedItems, nextProp, expandedPath])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -538,12 +523,14 @@ export class RemoteJoiner {
|
||||
}
|
||||
|
||||
if (!parsedExpands.has(fullPath)) {
|
||||
const parentPath = [BASE_PATH, ...currentPath].join(".")
|
||||
parsedExpands.set(fullPath, {
|
||||
property: prop,
|
||||
serviceConfig: currentServiceConfig,
|
||||
fields,
|
||||
args,
|
||||
parent: [BASE_PATH, ...currentPath].join("."),
|
||||
parent: parentPath,
|
||||
parentConfig: parsedExpands.get(parentPath).serviceConfig,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -556,53 +543,41 @@ export class RemoteJoiner {
|
||||
private groupExpands(
|
||||
parsedExpands: Map<string, RemoteExpandProperty>
|
||||
): Map<string, RemoteExpandProperty> {
|
||||
const sortedParsedExpands = new Map(
|
||||
Array.from(parsedExpands.entries()).sort()
|
||||
)
|
||||
|
||||
const mergedExpands = new Map<string, RemoteExpandProperty>(
|
||||
sortedParsedExpands
|
||||
)
|
||||
const mergedExpands = new Map<string, RemoteExpandProperty>(parsedExpands)
|
||||
const mergedPaths = new Map<string, string>()
|
||||
|
||||
let lastServiceName = ""
|
||||
|
||||
for (const [path, expand] of sortedParsedExpands.entries()) {
|
||||
for (const [path, expand] of mergedExpands.entries()) {
|
||||
const currentServiceName = expand.serviceConfig.serviceName
|
||||
|
||||
let parentPath = expand.parent
|
||||
|
||||
// Check if the parentPath was merged before
|
||||
while (mergedPaths.has(parentPath)) {
|
||||
parentPath = mergedPaths.get(parentPath)!
|
||||
}
|
||||
|
||||
const canMerge = currentServiceName === lastServiceName
|
||||
|
||||
if (mergedExpands.has(parentPath) && canMerge) {
|
||||
const parentExpand = mergedExpands.get(parentPath)!
|
||||
|
||||
if (parentExpand.serviceConfig.serviceName === currentServiceName) {
|
||||
const nestedKeys = path.split(".").slice(parentPath.split(".").length)
|
||||
|
||||
let targetExpand: any = parentExpand
|
||||
|
||||
for (let key of nestedKeys) {
|
||||
if (!targetExpand.expands) {
|
||||
targetExpand.expands = {}
|
||||
}
|
||||
if (!targetExpand.expands[key]) {
|
||||
targetExpand.expands[key] = {} as any
|
||||
}
|
||||
targetExpand = targetExpand.expands[key]
|
||||
}
|
||||
|
||||
targetExpand.fields = expand.fields
|
||||
targetExpand.args = expand.args
|
||||
mergedPaths.set(path, parentPath)
|
||||
while (parentPath) {
|
||||
const parentExpand = mergedExpands.get(parentPath)
|
||||
if (
|
||||
!parentExpand ||
|
||||
parentExpand.serviceConfig.serviceName !== currentServiceName
|
||||
) {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
lastServiceName = currentServiceName
|
||||
|
||||
// Merge the current expand into its parent
|
||||
const nestedKeys = path.split(".").slice(parentPath.split(".").length)
|
||||
let targetExpand = parentExpand as Omit<
|
||||
RemoteExpandProperty,
|
||||
"expands"
|
||||
> & { expands?: {} }
|
||||
|
||||
for (const key of nestedKeys) {
|
||||
targetExpand.expands ??= {}
|
||||
targetExpand = targetExpand.expands[key] ??= {}
|
||||
}
|
||||
|
||||
targetExpand.fields = expand.fields
|
||||
targetExpand.args = expand.args
|
||||
|
||||
mergedExpands.delete(path)
|
||||
mergedPaths.set(path, parentPath)
|
||||
|
||||
parentPath = parentExpand.parent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ export interface RemoteNestedExpands {
|
||||
export interface RemoteExpandProperty {
|
||||
property: string
|
||||
parent: string
|
||||
parentConfig?: JoinerServiceConfig
|
||||
serviceConfig: JoinerServiceConfig
|
||||
fields: string[]
|
||||
args?: JoinerArgument[]
|
||||
|
||||
Reference in New Issue
Block a user