feat(*): Modules export entities and fields (#5242)

This commit is contained in:
Carlos R. L. Rodrigues
2023-10-03 14:20:43 -07:00
committed by GitHub
parent eeceec791c
commit 130cbc1f43
27 changed files with 801 additions and 226 deletions
+108 -73
View File
@@ -1,3 +1,5 @@
import { mergeTypeDefs } from "@graphql-tools/merge"
import { makeExecutableSchema } from "@graphql-tools/schema"
import { RemoteFetchDataCallback } from "@medusajs/orchestration"
import {
ExternalModuleDeclaration,
@@ -12,13 +14,14 @@ import {
} from "@medusajs/types"
import {
ContainerRegistrationKeys,
isObject,
ModulesSdkUtils,
isObject,
} from "@medusajs/utils"
import { MODULE_PACKAGE_NAMES, Modules } from "./definitions"
import { MedusaModule } from "./medusa-module"
import { RemoteLink } from "./remote-link"
import { RemoteQuery } from "./remote-query"
import { cleanGraphQLSchema } from "./utils"
export type MedusaModuleConfig = {
[key: string | Modules]:
@@ -46,72 +49,19 @@ export type SharedResources = {
}
}
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
}): Promise<{
modules: Record<string, LoadedModule | LoadedModule[]>
link: RemoteLink | undefined
query: (
query: string | RemoteJoinerQuery | object,
variables?: Record<string, unknown>
) => Promise<any>
}> {
const modules: MedusaModuleConfig =
modulesConfig ??
(
await import(
modulesConfigPath ??
process.cwd() + (modulesConfigFileName ?? "/modules-config")
)
).default
const dbData = ModulesSdkUtils.loadDatabaseConfig(
"medusa",
sharedResourcesConfig as ModuleServiceInitializeOptions,
true
)!
if (
dbData.clientUrl &&
!injectedDependencies[ContainerRegistrationKeys.PG_CONNECTION]
) {
injectedDependencies[ContainerRegistrationKeys.PG_CONNECTION] =
ModulesSdkUtils.createPgConnection({
...(sharedResourcesConfig?.database ?? {}),
...dbData,
})
}
const allModules: Record<string, LoadedModule | LoadedModule[]> = {}
async function loadModules(modulesConfig, injectedDependencies) {
const allModules = {}
await Promise.all(
Object.keys(modules).map(async (moduleName) => {
const mod = modules[moduleName] as MedusaModuleConfig
Object.keys(modulesConfig).map(async (moduleName) => {
const mod = modulesConfig[moduleName]
let path: string
let declaration: any = {}
let definition: ModuleDefinition | undefined = undefined
if (isObject(mod)) {
const mod_ = mod as unknown as InternalModuleDeclaration
path = mod_.resolve ?? MODULE_PACKAGE_NAMES[moduleName]
definition = mod_.definition
declaration = { ...mod }
delete declaration.definition
} else {
@@ -119,7 +69,6 @@ export async function MedusaApp({
}
declaration.scope ??= MODULE_SCOPE.INTERNAL
if (
declaration.scope === MODULE_SCOPE.INTERNAL &&
!declaration.resources
@@ -133,7 +82,7 @@ export async function MedusaApp({
declaration,
undefined,
injectedDependencies,
(isObject(mod) ? mod.definition : undefined) as ModuleDefinition
definition
)) as LoadedModule
if (allModules[moduleName] && !Array.isArray(allModules[moduleName])) {
@@ -145,33 +94,117 @@ export async function MedusaApp({
} else {
allModules[moduleName] = loaded[moduleName]
}
return loaded
})
)
return allModules
}
let link: RemoteLink | undefined = undefined
let query: (
query: string | RemoteJoinerQuery | object,
variables?: Record<string, unknown>
) => Promise<any>
async function initializeLinks(linkModules, injectedDependencies) {
try {
const { initialize: initializeLinks } = await import(
"@medusajs/link-modules" as string
)
await initializeLinks({}, linkModules, injectedDependencies)
link = new RemoteLink()
return new RemoteLink()
} catch (err) {
console.warn("Error initializing link modules.", err)
return undefined
}
}
function cleanAndMergeSchema(loadedSchema) {
const { schema: cleanedSchema, notFound } = cleanGraphQLSchema(loadedSchema)
const mergedSchema = mergeTypeDefs(cleanedSchema)
return { schema: makeExecutableSchema({ typeDefs: mergedSchema }), notFound }
}
function getLoadedSchema(): string {
return MedusaModule.getAllJoinerConfigs()
.map((joinerConfig) => joinerConfig?.schema ?? "")
.join("\n")
}
function registerCustomJoinerConfigs(servicesConfig: ModuleJoinerConfig[]) {
for (const config of servicesConfig) {
if (!config.serviceName || config.isReadOnlyLink) {
continue
}
MedusaModule.setJoinerConfig(config.serviceName, config)
}
}
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: (
query: string | RemoteJoinerQuery | object,
variables?: Record<string, unknown>
) => Promise<any>
entitiesMap?: Record<string, any>
notFound?: Record<string, Record<string, string>>
}> {
const modules: MedusaModuleConfig =
modulesConfig ??
(
await import(
modulesConfigPath ??
process.cwd() + (modulesConfigFileName ?? "/modules-config")
)
).default
const dbData = ModulesSdkUtils.loadDatabaseConfig(
"medusa",
sharedResourcesConfig as ModuleServiceInitializeOptions,
true
)!
registerCustomJoinerConfigs(servicesConfig ?? [])
if (
dbData.clientUrl &&
!injectedDependencies[ContainerRegistrationKeys.PG_CONNECTION]
) {
injectedDependencies[ContainerRegistrationKeys.PG_CONNECTION] =
ModulesSdkUtils.createPgConnection({
...(sharedResourcesConfig?.database ?? {}),
...dbData,
})
}
const allModules = await loadModules(modules, injectedDependencies)
const link = await initializeLinks(linkModules, injectedDependencies)
const loadedSchema = getLoadedSchema()
const { schema, notFound } = cleanAndMergeSchema(loadedSchema)
const remoteQuery = new RemoteQuery({
servicesConfig,
customRemoteFetchData: remoteFetchData,
})
query = async (
const query = async (
query: string | RemoteJoinerQuery | object,
variables?: Record<string, unknown>
) => {
@@ -182,5 +215,7 @@ export async function MedusaApp({
modules: allModules,
link,
query,
entitiesMap: schema.getTypeMap(),
notFound,
}
}