Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(link-modules,modules-sdk,pricing): Medusa App Migrations + Core compatible migrations #5317

Merged
merged 18 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/poor-zebras-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@medusajs/link-modules": patch
"@medusajs/modules-sdk": patch
"@medusajs/pricing": patch
---

feat(link-modules,modules-sdk,pricing): Medusa App Migrations + Core compatible migrations
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export const ProductVariantPriceSet: ModuleJoinerConfig = {
relationships: [
{
serviceName: Modules.PRODUCT,
// TODO: Remove this when product module is the default product service
isInternalService: true,
Comment on lines +24 to +25
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: what does this do?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to load it from the core and not as being a module.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need that if the product module is not required to run the pricing module, in that case the pricing modue is linked to the internal core service and the pivot table is managed in the core

primaryKey: "id",
foreignKey: "variant_id",
alias: "variant",
Expand Down
4 changes: 1 addition & 3 deletions packages/link-modules/src/initialize/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,7 @@ export async function runMigrations(
)
)

if (modulesLoadedKeys.includes(serviceKey)) {
continue
} else if (allLinks.has(serviceKey)) {
if (allLinks.has(serviceKey)) {
throw new Error(`Link module ${serviceKey} already exists.`)
}

Expand Down
69 changes: 61 additions & 8 deletions packages/modules-sdk/src/medusa-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ExternalModuleDeclaration,
InternalModuleDeclaration,
LoadedModule,
LoaderOptions,
MODULE_RESOURCE_TYPE,
MODULE_SCOPE,
ModuleDefinition,
Expand All @@ -23,6 +24,13 @@ import { RemoteLink } from "./remote-link"
import { RemoteQuery } from "./remote-query"
import { cleanGraphQLSchema } from "./utils"

const LinkModulePackage = "@medusajs/link-modules"

export type RunMigrationFn = (
options: Omit<LoaderOptions<ModuleServiceInitializeOptions>, "container">,
injectedDependencies?: Record<any, any>
) => Promise<void>

export type MedusaModuleConfig = {
[key: string | Modules]:
| Partial<InternalModuleDeclaration | ExternalModuleDeclaration>
Expand Down Expand Up @@ -51,6 +59,7 @@ export type SharedResources = {

async function loadModules(modulesConfig, injectedDependencies) {
const allModules = {}

await Promise.all(
Object.keys(modulesConfig).map(async (moduleName) => {
const mod = modulesConfig[moduleName]
Expand Down Expand Up @@ -99,16 +108,24 @@ async function loadModules(modulesConfig, injectedDependencies) {
return allModules
}

async function initializeLinks(linkModules, injectedDependencies) {
async function initializeLinks(config, linkModules, injectedDependencies) {
try {
const { initialize: initializeLinks } = await import(
"@medusajs/link-modules" as string
const { initialize, runMigrations } = await import(LinkModulePackage)
const linkResolution = await initialize(
config,
linkModules,
injectedDependencies
)
await initializeLinks({}, linkModules, injectedDependencies)
return new RemoteLink()

return { remoteLink: new RemoteLink(), linkResolution, runMigrations }
} catch (err) {
console.warn("Error initializing link modules.", err)
return undefined

return {
remoteLink: undefined,
linkResolution: undefined,
runMigrations: undefined,
}
}
}

Expand Down Expand Up @@ -166,6 +183,7 @@ export async function MedusaApp(
) => Promise<any>
entitiesMap?: Record<string, any>
notFound?: Record<string, Record<string, string>>
runMigrations: RunMigrationFn
}> {
const modules: MedusaModuleConfig =
modulesConfig ??
Expand All @@ -175,6 +193,7 @@ export async function MedusaApp(
process.cwd() + (modulesConfigFileName ?? "/modules-config")
)
).default

const dbData = ModulesSdkUtils.loadDatabaseConfig(
"medusa",
sharedResourcesConfig as ModuleServiceInitializeOptions,
Expand All @@ -194,8 +213,25 @@ export async function MedusaApp(
})
}

// remove the link module from the modules
const linkModule = modules[LinkModulePackage]
delete modules[LinkModulePackage]
let linkModuleOptions = {}

if (isObject(linkModule)) {
linkModuleOptions = linkModule
}

const allModules = await loadModules(modules, injectedDependencies)
const link = await initializeLinks(linkModules, injectedDependencies)
const {
remoteLink,
linkResolution,
runMigrations: linkModuleMigration,
} = await initializeLinks(
linkModuleOptions,
linkModules,
injectedDependencies
)

const loadedSchema = getLoadedSchema()
const { schema, notFound } = cleanAndMergeSchema(loadedSchema)
Expand All @@ -204,18 +240,35 @@ export async function MedusaApp(
servicesConfig,
customRemoteFetchData: remoteFetchData,
})

const query = async (
query: string | RemoteJoinerQuery | object,
variables?: Record<string, unknown>
) => {
return await remoteQuery.query(query, variables)
}

const runMigrations: RunMigrationFn = async (): Promise<void> => {
for (const moduleName of Object.keys(allModules)) {
const loadedModule = allModules[moduleName]

await MedusaModule.migrateUp(
loadedModule.definition.key,
loadedModule.resolutionPath,
loadedModule.options
)
}

linkModuleMigration &&
(await linkModuleMigration(linkResolution.options, injectedDependencies))
}

return {
modules: allModules,
link,
link: remoteLink,
query,
entitiesMap: schema.getTypeMap(),
notFound,
runMigrations,
}
}
6 changes: 3 additions & 3 deletions packages/pricing/src/migrations/Migration20230929122253.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { Migration } from "@mikro-orm/migrations"
export class Migration20230929122253 extends Migration {
async up(): Promise<void> {
this.addSql(
'create table "currency" ("code" text not null, "symbol" text not null, "symbol_native" text not null, "name" text not null, constraint "currency_pkey" primary key ("code"));'
'create table if not exists "currency" ("code" text not null, "symbol" text not null, "symbol_native" text not null, "name" text not null, constraint "currency_pkey" primary key ("code"));'
)

this.addSql(
'create table "money_amount" ("id" text not null, "currency_code" text null, "amount" numeric null, "min_quantity" numeric null, "max_quantity" numeric null, constraint "money_amount_pkey" primary key ("id"));'
'create table if not exists "money_amount" ("id" text not null, "currency_code" text null, "amount" numeric null, "min_quantity" numeric null, "max_quantity" numeric null, constraint "money_amount_pkey" primary key ("id"));'
)
this.addSql(
'create index "IDX_money_amount_currency_code" on "money_amount" ("currency_code");'
'create index if not exists "IDX_money_amount_currency_code" on "money_amount" ("currency_code");'
)

this.addSql(
Expand Down
9 changes: 0 additions & 9 deletions packages/pricing/src/models/currency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,6 @@ class Currency {

@Property({ columnType: "text" })
name: string

// @Property({ persist: false })
// get includes_tax() {
// // TODO: This comes from a feature flag
// // Figure out how we're handling FF in modules
// // For now, returning default as true
// // This should also not fall on the hands of the model
// return true
// }
}

export default Currency