refactor(medusa): Loaders to TS (#1288)
* refactor(medusa): Loaders * refactor(medusa): Improve MedusaContainer typings * refactor(medusa): Improve MedusaContainer typings
This commit is contained in:
1 parent
ab2d81f786
commit
5f9197a656
16 files changed
+283
-189
No files matched your search
+13
-13
@@ -5,19 +5,19 @@
|
|||||||
/packages/medusa/src/subscribers/notification.js
|
/packages/medusa/src/subscribers/notification.js
|
||||||
/packages/medusa/src/subscribers/order.js
|
/packages/medusa/src/subscribers/order.js
|
||||||
/packages/medusa/src/subscribers/product.js
|
/packages/medusa/src/subscribers/product.js
|
||||||
/packages/medusa/src/loaders/api.js
|
/packages/medusa/src/loaders/api.ts
|
||||||
/packages/medusa/src/loaders/database.js
|
/packages/medusa/src/loaders/database.ts
|
||||||
/packages/medusa/src/loaders/defaults.js
|
/packages/medusa/src/loaders/defaults.ts
|
||||||
/packages/medusa/src/loaders/express.js
|
/packages/medusa/src/loaders/express.ts
|
||||||
/packages/medusa/src/loaders/index.js
|
/packages/medusa/src/loaders/index.ts
|
||||||
/packages/medusa/src/loaders/logger.js
|
/packages/medusa/src/loaders/logger.ts
|
||||||
/packages/medusa/src/loaders/models.js
|
/packages/medusa/src/loaders/models.ts
|
||||||
/packages/medusa/src/loaders/passport.js
|
/packages/medusa/src/loaders/passport.ts
|
||||||
/packages/medusa/src/loaders/plugins.js
|
/packages/medusa/src/loaders/plugins.ts
|
||||||
/packages/medusa/src/loaders/redis.js
|
/packages/medusa/src/loaders/redis.ts
|
||||||
/packages/medusa/src/loaders/repositories.js
|
/packages/medusa/src/loaders/repositories.ts
|
||||||
/packages/medusa/src/loaders/services.js
|
/packages/medusa/src/loaders/services.ts
|
||||||
/packages/medusa/src/loaders/subscribers.js
|
/packages/medusa/src/loaders/subscribers.ts
|
||||||
/packages/medusa/src/api/routes/admin/auth
|
/packages/medusa/src/api/routes/admin/auth
|
||||||
/packages/medusa/src/api/routes/admin/collections
|
/packages/medusa/src/api/routes/admin/collections
|
||||||
/packages/medusa/src/api/routes/store/carts
|
/packages/medusa/src/api/routes/store/carts
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
|
import { Express } from 'express'
|
||||||
import bodyParser from "body-parser"
|
import bodyParser from "body-parser"
|
||||||
import { getConfigFile } from "medusa-core-utils"
|
import { getConfigFile } from "medusa-core-utils"
|
||||||
import routes from "../api"
|
import routes from "../api"
|
||||||
|
import { AwilixContainer } from "awilix"
|
||||||
|
|
||||||
export default async ({ app, rootDirectory, container }) => {
|
type Options = {
|
||||||
const { configModule } = getConfigFile(rootDirectory, `medusa-config`)
|
app: Express;
|
||||||
|
rootDirectory: string;
|
||||||
|
container: AwilixContainer
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async ({ app, rootDirectory, container }: Options) => {
|
||||||
|
const { configModule } = getConfigFile(rootDirectory, `medusa-config`) as { configModule: Record<string, unknown> }
|
||||||
const config = (configModule && configModule.projectConfig) || {}
|
const config = (configModule && configModule.projectConfig) || {}
|
||||||
|
|
||||||
app.use(bodyParser.json())
|
app.use(bodyParser.json())
|
||||||
@@ -1,8 +1,22 @@
|
|||||||
import { createConnection } from "typeorm"
|
import { Connection, createConnection, LoggerOptions } from "typeorm"
|
||||||
|
|
||||||
import { ShortenedNamingStrategy } from "../utils/naming-strategy"
|
import { ShortenedNamingStrategy } from "../utils/naming-strategy"
|
||||||
|
import { AwilixContainer } from "awilix"
|
||||||
|
import { ConnectionOptions } from "typeorm/connection/ConnectionOptions"
|
||||||
|
|
||||||
export default async ({ container, configModule }) => {
|
export type DatabaseConfig = {
|
||||||
|
database_type: string;
|
||||||
|
database_url?: string;
|
||||||
|
database_database?: string;
|
||||||
|
database_extra?: Record<string, unknown>;
|
||||||
|
database_logging: LoggerOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
type Options = {
|
||||||
|
configModule: { projectConfig: DatabaseConfig };
|
||||||
|
container: AwilixContainer
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async ({ container, configModule }: Options): Promise<Connection> => {
|
||||||
const entities = container.resolve("db_entities")
|
const entities = container.resolve("db_entities")
|
||||||
|
|
||||||
const isSqlite = configModule.projectConfig.database_type === "sqlite"
|
const isSqlite = configModule.projectConfig.database_type === "sqlite"
|
||||||
@@ -15,7 +29,7 @@ export default async ({ container, configModule }) => {
|
|||||||
entities,
|
entities,
|
||||||
namingStrategy: new ShortenedNamingStrategy(),
|
namingStrategy: new ShortenedNamingStrategy(),
|
||||||
logging: configModule.projectConfig.database_logging || false,
|
logging: configModule.projectConfig.database_logging || false,
|
||||||
})
|
} as ConnectionOptions)
|
||||||
|
|
||||||
if (isSqlite) {
|
if (isSqlite) {
|
||||||
await connection.query(`PRAGMA foreign_keys = OFF`)
|
await connection.query(`PRAGMA foreign_keys = OFF`)
|
||||||
@@ -1,10 +1,23 @@
|
|||||||
|
import { BasePaymentService, BaseNotificationService, BaseFulfillmentService } from 'medusa-interfaces'
|
||||||
import { currencies } from "../utils/currencies"
|
import { currencies } from "../utils/currencies"
|
||||||
import { countries } from "../utils/countries"
|
import { countries } from "../utils/countries"
|
||||||
|
import { AwilixContainer } from "awilix"
|
||||||
|
import { Logger } from "../types/global"
|
||||||
|
import { EntityManager } from "typeorm"
|
||||||
|
import { CountryRepository } from "../repositories/country"
|
||||||
|
import {
|
||||||
|
FulfillmentProviderService,
|
||||||
|
NotificationService,
|
||||||
|
PaymentProviderService,
|
||||||
|
ShippingProfileService,
|
||||||
|
StoreService, TaxProviderService,
|
||||||
|
} from "../services"
|
||||||
|
import { CurrencyRepository } from "../repositories/currency"
|
||||||
|
import { AbstractTaxService } from "../interfaces"
|
||||||
|
|
||||||
const silentResolution = (container, name, logger) => {
|
const silentResolution = <T>(container: AwilixContainer, name: string, logger: Logger): T | never | undefined => {
|
||||||
try {
|
try {
|
||||||
const resolved = container.resolve(name)
|
return container.resolve<T>(name)
|
||||||
return resolved
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.name !== "AwilixResolutionError") {
|
if (err.name !== "AwilixResolutionError") {
|
||||||
throw err
|
throw err
|
||||||
@@ -27,19 +40,20 @@ const silentResolution = (container, name, logger) => {
|
|||||||
`You don't have any ${identifier} provider plugins installed. You may want to add one to your project.`
|
`You don't have any ${identifier} provider plugins installed. You may want to add one to your project.`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async ({ container }) => {
|
export default async ({ container }: { container: AwilixContainer }): Promise<void> => {
|
||||||
const storeService = container.resolve("storeService")
|
const storeService = container.resolve<StoreService>("storeService")
|
||||||
const currencyRepository = container.resolve("currencyRepository")
|
const currencyRepository = container.resolve<typeof CurrencyRepository>("currencyRepository")
|
||||||
const countryRepository = container.resolve("countryRepository")
|
const countryRepository = container.resolve<typeof CountryRepository>("countryRepository")
|
||||||
const profileService = container.resolve("shippingProfileService")
|
const profileService = container.resolve<ShippingProfileService>("shippingProfileService")
|
||||||
const logger = container.resolve("logger")
|
const logger = container.resolve<Logger>("logger")
|
||||||
|
|
||||||
const entityManager = container.resolve("manager")
|
const entityManager = container.resolve<EntityManager>("manager")
|
||||||
|
|
||||||
await entityManager.transaction(async (manager) => {
|
await entityManager.transaction(async (manager: EntityManager) => {
|
||||||
const countryRepo = manager.getCustomRepository(countryRepository)
|
const countryRepo = manager.getCustomRepository(countryRepository)
|
||||||
const hasCountries = await countryRepo.findOne()
|
const hasCountries = await countryRepo.findOne()
|
||||||
if (!hasCountries) {
|
if (!hasCountries) {
|
||||||
@@ -52,7 +66,7 @@ export default async ({ container }) => {
|
|||||||
const name = c.name.toUpperCase()
|
const name = c.name.toUpperCase()
|
||||||
const display = c.name
|
const display = c.name
|
||||||
|
|
||||||
await manager.queryRunner.query(query, [
|
await manager.queryRunner?.query(query, [
|
||||||
iso2,
|
iso2,
|
||||||
iso3,
|
iso3,
|
||||||
numeric,
|
numeric,
|
||||||
@@ -63,7 +77,7 @@ export default async ({ container }) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
await entityManager.transaction(async (manager) => {
|
await entityManager.transaction(async (manager: EntityManager) => {
|
||||||
const currencyRepo = manager.getCustomRepository(currencyRepository)
|
const currencyRepo = manager.getCustomRepository(currencyRepository)
|
||||||
const hasCurrencies = await currencyRepo.findOne()
|
const hasCurrencies = await currencyRepo.findOne()
|
||||||
if (!hasCurrencies) {
|
if (!hasCurrencies) {
|
||||||
@@ -75,45 +89,42 @@ export default async ({ container }) => {
|
|||||||
const nat = c.symbol_native
|
const nat = c.symbol_native
|
||||||
const name = c.name
|
const name = c.name
|
||||||
|
|
||||||
await manager.queryRunner.query(query, [code, sym, nat, name])
|
await manager.queryRunner?.query(query, [code, sym, nat, name])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
await entityManager.transaction(async (manager) => {
|
await entityManager.transaction(async (manager: EntityManager) => {
|
||||||
await storeService.withTransaction(manager).create()
|
await storeService.withTransaction(manager).create()
|
||||||
|
|
||||||
const pProviderService = container.resolve("paymentProviderService")
|
|
||||||
|
|
||||||
const payProviders =
|
const payProviders =
|
||||||
silentResolution(container, "paymentProviders", logger) || []
|
silentResolution<typeof BasePaymentService[]>(container, "paymentProviders", logger) || []
|
||||||
|
|
||||||
const payIds = payProviders.map((p) => p.getIdentifier())
|
const payIds = payProviders.map((p) => p.getIdentifier())
|
||||||
|
|
||||||
|
const pProviderService = container.resolve<PaymentProviderService>("paymentProviderService")
|
||||||
await pProviderService.registerInstalledProviders(payIds)
|
await pProviderService.registerInstalledProviders(payIds)
|
||||||
|
|
||||||
const nProviderService = container.resolve("notificationService")
|
|
||||||
|
|
||||||
const notiProviders =
|
const notiProviders =
|
||||||
silentResolution(container, "notificationProviders", logger) || []
|
silentResolution<typeof BaseNotificationService[]>(container, "notificationProviders", logger) || []
|
||||||
|
|
||||||
const notiIds = notiProviders.map((p) => p.getIdentifier())
|
const notiIds = notiProviders.map((p) => p.getIdentifier())
|
||||||
|
|
||||||
|
const nProviderService = container.resolve<NotificationService>("notificationService")
|
||||||
await nProviderService.registerInstalledProviders(notiIds)
|
await nProviderService.registerInstalledProviders(notiIds)
|
||||||
|
|
||||||
const fProviderService = container.resolve("fulfillmentProviderService")
|
|
||||||
|
|
||||||
const fulfilProviders =
|
const fulfilProviders =
|
||||||
silentResolution(container, "fulfillmentProviders", logger) || []
|
silentResolution<typeof BaseFulfillmentService[]>(container, "fulfillmentProviders", logger) || []
|
||||||
|
|
||||||
const fulfilIds = fulfilProviders.map((p) => p.getIdentifier())
|
const fulfilIds = fulfilProviders.map((p) => p.getIdentifier())
|
||||||
|
|
||||||
|
const fProviderService = container.resolve<FulfillmentProviderService>("fulfillmentProviderService")
|
||||||
await fProviderService.registerInstalledProviders(fulfilIds)
|
await fProviderService.registerInstalledProviders(fulfilIds)
|
||||||
|
|
||||||
const tProviderService = container.resolve("taxProviderService")
|
|
||||||
|
|
||||||
const taxProviders =
|
const taxProviders =
|
||||||
silentResolution(container, "taxProviders", logger) || []
|
silentResolution<AbstractTaxService[]>(container, "taxProviders", logger) || []
|
||||||
|
|
||||||
const taxIds = taxProviders.map((p) => p.getIdentifier())
|
const taxIds = taxProviders.map((p) => p.getIdentifier())
|
||||||
|
|
||||||
|
const tProviderService = container.resolve<TaxProviderService>("taxProviderService")
|
||||||
await tProviderService.registerInstalledProviders(taxIds)
|
await tProviderService.registerInstalledProviders(taxIds)
|
||||||
|
|
||||||
await profileService.withTransaction(manager).createDefault()
|
await profileService.withTransaction(manager).createDefault()
|
||||||
@@ -1,13 +1,19 @@
|
|||||||
|
import { Express } from 'express'
|
||||||
import session from "express-session"
|
import session from "express-session"
|
||||||
import cookieParser from "cookie-parser"
|
import cookieParser from "cookie-parser"
|
||||||
import morgan from "morgan"
|
import morgan from "morgan"
|
||||||
import redis from "redis"
|
import redis, { RedisConfig } from "redis"
|
||||||
import createStore from "connect-redis"
|
import createStore from "connect-redis"
|
||||||
|
|
||||||
import config from "../config"
|
import config from "../config"
|
||||||
|
|
||||||
export default async ({ app, configModule }) => {
|
type Options = {
|
||||||
let sameSite = false
|
app: Express;
|
||||||
|
configModule: { projectConfig: RedisConfig }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async ({ app, configModule }: Options): Promise<Express> => {
|
||||||
|
let sameSite: string | boolean = false
|
||||||
let secure = false
|
let secure = false
|
||||||
if (
|
if (
|
||||||
process.env.NODE_ENV === "production" ||
|
process.env.NODE_ENV === "production" ||
|
||||||
@@ -17,7 +23,7 @@ export default async ({ app, configModule }) => {
|
|||||||
sameSite = "none"
|
sameSite = "none"
|
||||||
}
|
}
|
||||||
|
|
||||||
let sessionOpts = {
|
const sessionOpts = {
|
||||||
resave: true,
|
resave: true,
|
||||||
saveUninitialized: true,
|
saveUninitialized: true,
|
||||||
cookieName: "session",
|
cookieName: "session",
|
||||||
@@ -28,6 +34,7 @@ export default async ({ app, configModule }) => {
|
|||||||
secure,
|
secure,
|
||||||
maxAge: 10 * 60 * 60 * 1000,
|
maxAge: 10 * 60 * 60 * 1000,
|
||||||
},
|
},
|
||||||
|
store: null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configModule.projectConfig.redis_url) {
|
if (configModule.projectConfig.redis_url) {
|
||||||
@@ -1,35 +1,58 @@
|
|||||||
import { asValue, createContainer } from "awilix"
|
|
||||||
import { getConfigFile } from "medusa-core-utils"
|
|
||||||
import { track } from "medusa-telemetry"
|
|
||||||
import "reflect-metadata"
|
import "reflect-metadata"
|
||||||
import requestIp from "request-ip"
|
|
||||||
import { getManager } from "typeorm"
|
|
||||||
import apiLoader from "./api"
|
|
||||||
import databaseLoader from "./database"
|
|
||||||
import defaultsLoader from "./defaults"
|
|
||||||
import expressLoader from "./express"
|
|
||||||
import Logger from "./logger"
|
import Logger from "./logger"
|
||||||
|
import apiLoader from "./api"
|
||||||
|
import databaseLoader, { DatabaseConfig } from "./database"
|
||||||
|
import defaultsLoader from "./defaults"
|
||||||
|
import expressLoader from "./express"
|
||||||
import modelsLoader from "./models"
|
import modelsLoader from "./models"
|
||||||
import passportLoader from "./passport"
|
import passportLoader from "./passport"
|
||||||
import pluginsLoader, { registerPluginModels } from "./plugins"
|
import pluginsLoader, { registerPluginModels } from "./plugins"
|
||||||
import redisLoader from "./redis"
|
import redisLoader, { RedisConfig } from "./redis"
|
||||||
import repositoriesLoader from "./repositories"
|
import repositoriesLoader from "./repositories"
|
||||||
|
import requestIp from "request-ip"
|
||||||
import searchIndexLoader from "./search-index"
|
import searchIndexLoader from "./search-index"
|
||||||
import servicesLoader from "./services"
|
import servicesLoader from "./services"
|
||||||
import strategiesLoader from "./strategies"
|
import strategiesLoader from "./strategies"
|
||||||
import subscribersLoader from "./subscribers"
|
import subscribersLoader from "./subscribers"
|
||||||
|
import { ClassOrFunctionReturning } from "awilix/lib/container"
|
||||||
|
import { Connection, getManager } from "typeorm"
|
||||||
|
import { Express, NextFunction, Request, Response } from "express"
|
||||||
|
import { asFunction, asValue, AwilixContainer, createContainer, Resolver } from "awilix"
|
||||||
|
import { getConfigFile } from "medusa-core-utils"
|
||||||
|
import { track } from "medusa-telemetry"
|
||||||
|
import { MedusaContainer } from "../types/global"
|
||||||
|
|
||||||
export default async ({ directory: rootDirectory, expressApp, isTest }) => {
|
type Options = {
|
||||||
const { configModule } = getConfigFile(rootDirectory, `medusa-config`)
|
directory: string;
|
||||||
|
expressApp: Express;
|
||||||
|
isTest: boolean
|
||||||
|
}
|
||||||
|
|
||||||
const container = createContainer()
|
export type ConfigModule = {
|
||||||
container.registerAdd = function (name, registration) {
|
projectConfig: DatabaseConfig & RedisConfig;
|
||||||
|
plugins: {
|
||||||
|
resolve: string;
|
||||||
|
options: Record<string, unknown>
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async (
|
||||||
|
{
|
||||||
|
directory: rootDirectory,
|
||||||
|
expressApp,
|
||||||
|
isTest
|
||||||
|
}: Options
|
||||||
|
): Promise<{ container: MedusaContainer; dbConnection: Connection; app: Express }> => {
|
||||||
|
const { configModule } = getConfigFile(rootDirectory, `medusa-config`) as { configModule: ConfigModule }
|
||||||
|
|
||||||
|
const container = createContainer() as MedusaContainer
|
||||||
|
container.registerAdd = function (this: MedusaContainer, name: string, registration: typeof asFunction | typeof asValue) {
|
||||||
const storeKey = name + "_STORE"
|
const storeKey = name + "_STORE"
|
||||||
|
|
||||||
if (this.registrations[storeKey] === undefined) {
|
if (this.registrations[storeKey] === undefined) {
|
||||||
this.register(storeKey, asValue([]))
|
this.register(storeKey, asValue([] as Resolver<unknown>[]))
|
||||||
}
|
}
|
||||||
const store = this.resolve(storeKey)
|
const store = this.resolve(storeKey) as (ClassOrFunctionReturning<unknown> | Resolver<unknown>)[]
|
||||||
|
|
||||||
if (this.registrations[name] === undefined) {
|
if (this.registrations[name] === undefined) {
|
||||||
this.register(name, asArray(store))
|
this.register(name, asArray(store))
|
||||||
@@ -40,14 +63,12 @@ export default async ({ directory: rootDirectory, expressApp, isTest }) => {
|
|||||||
}.bind(container)
|
}.bind(container)
|
||||||
|
|
||||||
// Add additional information to context of request
|
// Add additional information to context of request
|
||||||
expressApp.use((req, res, next) => {
|
expressApp.use((req: Request, res: Response, next: NextFunction) => {
|
||||||
const ipAddress = requestIp.getClientIp(req)
|
const ipAddress = requestIp.getClientIp(req) as string
|
||||||
|
|
||||||
const context = {
|
(req as any).request_context = {
|
||||||
ip_address: ipAddress,
|
ip_address: ipAddress,
|
||||||
}
|
}
|
||||||
|
|
||||||
req.request_context = context
|
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -59,7 +80,7 @@ export default async ({ directory: rootDirectory, expressApp, isTest }) => {
|
|||||||
|
|
||||||
const modelsActivity = Logger.activity("Initializing models")
|
const modelsActivity = Logger.activity("Initializing models")
|
||||||
track("MODELS_INIT_STARTED")
|
track("MODELS_INIT_STARTED")
|
||||||
modelsLoader({ container, activityId: modelsActivity, isTest })
|
modelsLoader({ container })
|
||||||
const mAct = Logger.success(modelsActivity, "Models initialized") || {}
|
const mAct = Logger.success(modelsActivity, "Models initialized") || {}
|
||||||
track("MODELS_INIT_COMPLETED", { duration: mAct.duration })
|
track("MODELS_INIT_COMPLETED", { duration: mAct.duration })
|
||||||
|
|
||||||
@@ -68,71 +89,47 @@ export default async ({ directory: rootDirectory, expressApp, isTest }) => {
|
|||||||
await registerPluginModels({
|
await registerPluginModels({
|
||||||
rootDirectory,
|
rootDirectory,
|
||||||
container,
|
container,
|
||||||
activityId: pmActivity,
|
|
||||||
})
|
})
|
||||||
const pmAct = Logger.success(pmActivity, "Plugin models initialized") || {}
|
const pmAct = Logger.success(pmActivity, "Plugin models initialized") || {}
|
||||||
track("PLUGIN_MODELS_INIT_COMPLETED", { duration: pmAct.duration })
|
track("PLUGIN_MODELS_INIT_COMPLETED", { duration: pmAct.duration })
|
||||||
|
|
||||||
const repoActivity = Logger.activity("Initializing repositories")
|
const repoActivity = Logger.activity("Initializing repositories")
|
||||||
track("REPOSITORIES_INIT_STARTED")
|
track("REPOSITORIES_INIT_STARTED")
|
||||||
repositoriesLoader({ container, activityId: repoActivity, isTest }) || {}
|
repositoriesLoader({ container })
|
||||||
const rAct = Logger.success(repoActivity, "Repositories initialized") || {}
|
const rAct = Logger.success(repoActivity, "Repositories initialized") || {}
|
||||||
track("REPOSITORIES_INIT_COMPLETED", { duration: rAct.duration })
|
track("REPOSITORIES_INIT_COMPLETED", { duration: rAct.duration })
|
||||||
|
|
||||||
const dbActivity = Logger.activity("Initializing database")
|
const dbActivity = Logger.activity("Initializing database")
|
||||||
track("DATABASE_INIT_STARTED")
|
track("DATABASE_INIT_STARTED")
|
||||||
const dbConnection = await databaseLoader({
|
const dbConnection = await databaseLoader({ container, configModule })
|
||||||
container,
|
|
||||||
configModule,
|
|
||||||
activityId: dbActivity,
|
|
||||||
isTest,
|
|
||||||
})
|
|
||||||
const dbAct = Logger.success(dbActivity, "Database initialized") || {}
|
const dbAct = Logger.success(dbActivity, "Database initialized") || {}
|
||||||
track("DATABASE_INIT_COMPLETED", { duration: dbAct.duration })
|
track("DATABASE_INIT_COMPLETED", { duration: dbAct.duration })
|
||||||
|
|
||||||
container.register({
|
container.register({ manager: asValue(dbConnection.manager), })
|
||||||
manager: asValue(dbConnection.manager),
|
|
||||||
})
|
|
||||||
|
|
||||||
const stratActivity = Logger.activity("Initializing strategies")
|
const stratActivity = Logger.activity("Initializing strategies")
|
||||||
track("STRATEGIES_INIT_STARTED")
|
track("STRATEGIES_INIT_STARTED")
|
||||||
strategiesLoader({
|
strategiesLoader({ container, configModule, isTest })
|
||||||
container,
|
|
||||||
configModule,
|
|
||||||
activityId: stratActivity,
|
|
||||||
isTest,
|
|
||||||
})
|
|
||||||
const stratAct = Logger.success(stratActivity, "Strategies initialized") || {}
|
const stratAct = Logger.success(stratActivity, "Strategies initialized") || {}
|
||||||
track("STRATEGIES_INIT_COMPLETED", { duration: stratAct.duration })
|
track("STRATEGIES_INIT_COMPLETED", { duration: stratAct.duration })
|
||||||
|
|
||||||
const servicesActivity = Logger.activity("Initializing services")
|
const servicesActivity = Logger.activity("Initializing services")
|
||||||
track("SERVICES_INIT_STARTED")
|
track("SERVICES_INIT_STARTED")
|
||||||
servicesLoader({
|
servicesLoader({ container, configModule, isTest })
|
||||||
container,
|
|
||||||
configModule,
|
|
||||||
activityId: servicesActivity,
|
|
||||||
isTest,
|
|
||||||
})
|
|
||||||
const servAct = Logger.success(servicesActivity, "Services initialized") || {}
|
const servAct = Logger.success(servicesActivity, "Services initialized") || {}
|
||||||
track("SERVICES_INIT_COMPLETED", { duration: servAct.duration })
|
track("SERVICES_INIT_COMPLETED", { duration: servAct.duration })
|
||||||
|
|
||||||
const expActivity = Logger.activity("Initializing express")
|
const expActivity = Logger.activity("Initializing express")
|
||||||
track("EXPRESS_INIT_STARTED")
|
track("EXPRESS_INIT_STARTED")
|
||||||
await expressLoader({
|
await expressLoader({ app: expressApp, configModule })
|
||||||
app: expressApp,
|
await passportLoader({ app: expressApp, container })
|
||||||
configModule,
|
|
||||||
activityId: expActivity,
|
|
||||||
})
|
|
||||||
await passportLoader({ app: expressApp, container, activityId: expActivity })
|
|
||||||
const exAct = Logger.success(expActivity, "Express intialized") || {}
|
const exAct = Logger.success(expActivity, "Express intialized") || {}
|
||||||
track("EXPRESS_INIT_COMPLETED", { duration: exAct.duration })
|
track("EXPRESS_INIT_COMPLETED", { duration: exAct.duration })
|
||||||
|
|
||||||
// Add the registered services to the request scope
|
// Add the registered services to the request scope
|
||||||
expressApp.use((req, res, next) => {
|
expressApp.use((req: Request, res: Response, next: NextFunction) => {
|
||||||
container.register({
|
container.register({ manager: asValue(getManager()) });
|
||||||
manager: asValue(getManager()),
|
(req as any).scope = container.createScope()
|
||||||
})
|
|
||||||
req.scope = container.createScope()
|
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -149,39 +146,36 @@ export default async ({ directory: rootDirectory, expressApp, isTest }) => {
|
|||||||
|
|
||||||
const subActivity = Logger.activity("Initializing subscribers")
|
const subActivity = Logger.activity("Initializing subscribers")
|
||||||
track("SUBSCRIBERS_INIT_STARTED")
|
track("SUBSCRIBERS_INIT_STARTED")
|
||||||
subscribersLoader({ container, activityId: subActivity })
|
subscribersLoader({ container })
|
||||||
const subAct = Logger.success(subActivity, "Subscribers initialized") || {}
|
const subAct = Logger.success(subActivity, "Subscribers initialized") || {}
|
||||||
track("SUBSCRIBERS_INIT_COMPLETED", { duration: subAct.duration })
|
track("SUBSCRIBERS_INIT_COMPLETED", { duration: subAct.duration })
|
||||||
|
|
||||||
const apiActivity = Logger.activity("Initializing API")
|
const apiActivity = Logger.activity("Initializing API")
|
||||||
track("API_INIT_STARTED")
|
track("API_INIT_STARTED")
|
||||||
await apiLoader({
|
await apiLoader({ container, rootDirectory, app: expressApp })
|
||||||
container,
|
|
||||||
rootDirectory,
|
|
||||||
app: expressApp,
|
|
||||||
activityId: apiActivity,
|
|
||||||
})
|
|
||||||
const apiAct = Logger.success(apiActivity, "API initialized") || {}
|
const apiAct = Logger.success(apiActivity, "API initialized") || {}
|
||||||
track("API_INIT_COMPLETED", { duration: apiAct.duration })
|
track("API_INIT_COMPLETED", { duration: apiAct.duration })
|
||||||
|
|
||||||
const defaultsActivity = Logger.activity("Initializing defaults")
|
const defaultsActivity = Logger.activity("Initializing defaults")
|
||||||
track("DEFAULTS_INIT_STARTED")
|
track("DEFAULTS_INIT_STARTED")
|
||||||
await defaultsLoader({ container, activityId: defaultsActivity })
|
await defaultsLoader({ container })
|
||||||
const dAct = Logger.success(defaultsActivity, "Defaults initialized") || {}
|
const dAct = Logger.success(defaultsActivity, "Defaults initialized") || {}
|
||||||
track("DEFAULTS_INIT_COMPLETED", { duration: dAct.duration })
|
track("DEFAULTS_INIT_COMPLETED", { duration: dAct.duration })
|
||||||
|
|
||||||
const searchActivity = Logger.activity("Initializing search engine indexing")
|
const searchActivity = Logger.activity("Initializing search engine indexing")
|
||||||
track("SEARCH_ENGINE_INDEXING_STARTED")
|
track("SEARCH_ENGINE_INDEXING_STARTED")
|
||||||
searchIndexLoader({ container, activityId: searchActivity })
|
await searchIndexLoader({ container })
|
||||||
const searchAct = Logger.success(searchActivity, "Indexing completed") || {}
|
const searchAct = Logger.success(searchActivity, "Indexing completed") || {}
|
||||||
track("SEARCH_ENGINE_INDEXING_COMPLETED", { duration: searchAct.duration })
|
track("SEARCH_ENGINE_INDEXING_COMPLETED", { duration: searchAct.duration })
|
||||||
|
|
||||||
return { container, dbConnection, app: expressApp }
|
return { container, dbConnection, app: expressApp }
|
||||||
}
|
}
|
||||||
|
|
||||||
function asArray(resolvers) {
|
function asArray(
|
||||||
|
resolvers: (ClassOrFunctionReturning<unknown> | Resolver<unknown>)[]
|
||||||
|
): { resolve: (container: AwilixContainer) => unknown[] } {
|
||||||
return {
|
return {
|
||||||
resolve: (container, opts) =>
|
resolve: (container: AwilixContainer) =>
|
||||||
resolvers.map((r) => container.build(r, opts)),
|
resolvers.map((resolver) => container.build(resolver)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
import logger from "@medusajs/medusa-cli/dist/reporter"
|
import logger from "@medusajs/medusa-cli/dist/reporter"
|
||||||
|
|
||||||
export default logger
|
export default logger
|
||||||
@@ -1,38 +1,38 @@
|
|||||||
|
import formatRegistrationName from "../utils/format-registration-name"
|
||||||
import glob from "glob"
|
import glob from "glob"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
|
import { ClassConstructor, MedusaContainer } from "../types/global"
|
||||||
import { EntitySchema } from "typeorm"
|
import { EntitySchema } from "typeorm"
|
||||||
import { asClass, asValue } from "awilix"
|
import { asClass, asValue, AwilixContainer } from "awilix"
|
||||||
|
|
||||||
import formatRegistrationName from "../utils/format-registration-name"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers all models in the model directory
|
* Registers all models in the model directory
|
||||||
*/
|
*/
|
||||||
export default ({ container }, config = { register: true }) => {
|
export default ({ container }: { container: MedusaContainer }, config = { register: true }) => {
|
||||||
const corePath = "../models/*.js"
|
const corePath = "../models/*.js"
|
||||||
const coreFull = path.join(__dirname, corePath)
|
const coreFull = path.join(__dirname, corePath)
|
||||||
|
|
||||||
const toReturn = []
|
const models: (ClassConstructor<unknown> | EntitySchema)[] = []
|
||||||
|
|
||||||
const core = glob.sync(coreFull, { cwd: __dirname })
|
const core = glob.sync(coreFull, { cwd: __dirname })
|
||||||
core.forEach((fn) => {
|
core.forEach((fn) => {
|
||||||
const loaded = require(fn)
|
const loaded = require(fn) as ClassConstructor<unknown> | EntitySchema
|
||||||
|
|
||||||
Object.entries(loaded).map(([key, val]) => {
|
Object.entries(loaded).map(([key, val]: [string, ClassConstructor<unknown> | EntitySchema]) => {
|
||||||
if (typeof val === "function" || val instanceof EntitySchema) {
|
if (typeof val === "function" || val instanceof EntitySchema) {
|
||||||
if (config.register) {
|
if (config.register) {
|
||||||
const name = formatRegistrationName(fn)
|
const name = formatRegistrationName(fn)
|
||||||
container.register({
|
container.register({
|
||||||
[name]: asClass(val),
|
[name]: asClass(val as ClassConstructor<unknown>),
|
||||||
})
|
})
|
||||||
|
|
||||||
container.registerAdd("db_entities", asValue(val))
|
container.registerAdd("db_entities", asValue(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
toReturn.push(val)
|
models.push(val)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return toReturn
|
return models
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
|
import config from "../config"
|
||||||
import passport from "passport"
|
import passport from "passport"
|
||||||
import { Strategy as LocalStrategy } from "passport-local"
|
import { AuthService } from "../services"
|
||||||
|
import { Express } from 'express'
|
||||||
|
import { MedusaContainer } from "../types/global"
|
||||||
import { Strategy as BearerStrategy } from "passport-http-bearer"
|
import { Strategy as BearerStrategy } from "passport-http-bearer"
|
||||||
import { Strategy as JWTStrategy } from "passport-jwt"
|
import { Strategy as JWTStrategy } from "passport-jwt"
|
||||||
import config from "../config"
|
import { Strategy as LocalStrategy } from "passport-local"
|
||||||
|
|
||||||
export default async ({ app, container }) => {
|
export default async ({ app, container }: { app: Express; container: MedusaContainer }): Promise<void> => {
|
||||||
const authService = container.resolve("authService")
|
const authService = container.resolve<AuthService>("authService")
|
||||||
const userService = container.resolve("userService")
|
|
||||||
|
|
||||||
// For good old email password authentication
|
// For good old email password authentication
|
||||||
passport.use(
|
passport.use(
|
||||||
@@ -17,7 +19,7 @@ export default async ({ app, container }) => {
|
|||||||
},
|
},
|
||||||
async (email, password, done) => {
|
async (email, password, done) => {
|
||||||
try {
|
try {
|
||||||
const { success, user } = authService.authenticate(email, password)
|
const { success, user } = await authService.authenticate(email, password)
|
||||||
if (success) {
|
if (success) {
|
||||||
return done(null, user)
|
return done(null, user)
|
||||||
} else {
|
} else {
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import glob from "glob"
|
import glob from "glob"
|
||||||
|
import { Express } from 'express'
|
||||||
import { EntitySchema } from "typeorm"
|
import { EntitySchema } from "typeorm"
|
||||||
import {
|
import {
|
||||||
BaseService,
|
BaseService,
|
||||||
@@ -15,16 +16,32 @@ import path from "path"
|
|||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
import { asValue, asClass, asFunction, aliasTo } from "awilix"
|
import { asValue, asClass, asFunction, aliasTo } from "awilix"
|
||||||
import { sync as existsSync } from "fs-exists-cached"
|
import { sync as existsSync } from "fs-exists-cached"
|
||||||
|
import { AbstractTaxService, isTaxCalculationStrategy } from "../interfaces"
|
||||||
import { AbstractTaxService } from "../interfaces/tax-service"
|
|
||||||
import { isTaxCalculationStrategy } from "../interfaces/tax-calculation-strategy"
|
|
||||||
import formatRegistrationName from "../utils/format-registration-name"
|
import formatRegistrationName from "../utils/format-registration-name"
|
||||||
|
import { ClassConstructor, Logger, MedusaContainer } from "../types/global"
|
||||||
|
import { ConfigModule } from "./index"
|
||||||
|
import { MiddlewareService } from "../services"
|
||||||
|
|
||||||
|
type Options = {
|
||||||
|
rootDirectory: string;
|
||||||
|
container: MedusaContainer;
|
||||||
|
app: Express;
|
||||||
|
activityId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginDetails = {
|
||||||
|
resolve: string;
|
||||||
|
name: string;
|
||||||
|
id: string;
|
||||||
|
options: Record<string, unknown>;
|
||||||
|
version: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers all services in the services directory
|
* Registers all services in the services directory
|
||||||
*/
|
*/
|
||||||
export default async ({ rootDirectory, container, app, activityId }) => {
|
export default async ({ rootDirectory, container, app, activityId }: Options): Promise<void> => {
|
||||||
const resolved = getResolvedPlugins(rootDirectory)
|
const resolved = getResolvedPlugins(rootDirectory) || []
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
resolved.map(async (pluginDetails) => {
|
resolved.map(async (pluginDetails) => {
|
||||||
@@ -42,8 +59,8 @@ export default async ({ rootDirectory, container, app, activityId }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getResolvedPlugins(rootDirectory) {
|
function getResolvedPlugins(rootDirectory: string): undefined | PluginDetails[] {
|
||||||
const { configModule } = getConfigFile(rootDirectory, `medusa-config`)
|
const { configModule } = getConfigFile(rootDirectory, `medusa-config`) as { configModule: ConfigModule }
|
||||||
|
|
||||||
if (!configModule) {
|
if (!configModule) {
|
||||||
return
|
return
|
||||||
@@ -73,8 +90,8 @@ function getResolvedPlugins(rootDirectory) {
|
|||||||
return resolved
|
return resolved
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function registerPluginModels({ rootDirectory, container }) {
|
export async function registerPluginModels({ rootDirectory, container }: { rootDirectory: string; container: MedusaContainer }): Promise<void> {
|
||||||
const resolved = getResolvedPlugins(rootDirectory)
|
const resolved = getResolvedPlugins(rootDirectory) || []
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
resolved.map(async (pluginDetails) => {
|
resolved.map(async (pluginDetails) => {
|
||||||
registerModels(pluginDetails, container)
|
registerModels(pluginDetails, container)
|
||||||
@@ -82,7 +99,7 @@ export async function registerPluginModels({ rootDirectory, container }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runLoaders(pluginDetails, container) {
|
async function runLoaders(pluginDetails: PluginDetails, container: MedusaContainer): Promise<void> {
|
||||||
const loaderFiles = glob.sync(
|
const loaderFiles = glob.sync(
|
||||||
`${pluginDetails.resolve}/loaders/[!__]*.js`,
|
`${pluginDetails.resolve}/loaders/[!__]*.js`,
|
||||||
{}
|
{}
|
||||||
@@ -95,7 +112,7 @@ async function runLoaders(pluginDetails, container) {
|
|||||||
await module(container, pluginDetails.options)
|
await module(container, pluginDetails.options)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const logger = container.resolve("logger")
|
const logger = container.resolve<Logger>("logger")
|
||||||
logger.warn(`Running loader failed: ${err.message}`)
|
logger.warn(`Running loader failed: ${err.message}`)
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
@@ -103,12 +120,12 @@ async function runLoaders(pluginDetails, container) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerMedusaApi(pluginDetails, container) {
|
function registerMedusaApi(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
||||||
registerMedusaMiddleware(pluginDetails, container)
|
registerMedusaMiddleware(pluginDetails, container)
|
||||||
registerStrategies(pluginDetails, container)
|
registerStrategies(pluginDetails, container)
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerStrategies(pluginDetails, container) {
|
function registerStrategies(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
||||||
let module
|
let module
|
||||||
try {
|
try {
|
||||||
const path = `${pluginDetails.resolve}/strategies/tax-calculation`
|
const path = `${pluginDetails.resolve}/strategies/tax-calculation`
|
||||||
@@ -128,14 +145,14 @@ function registerStrategies(pluginDetails, container) {
|
|||||||
).singleton(),
|
).singleton(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const logger = container.resolve("logger")
|
const logger = container.resolve<Logger>("logger")
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`${pluginDetails.resolve}/strategies/tax-calculation did not export a class that implements ITaxCalculationStrategy. Your Medusa server will still work, but if you have written custom tax calculation logic it will not be used. Make sure to implement the ITaxCalculationStrategy interface.`
|
`${pluginDetails.resolve}/strategies/tax-calculation did not export a class that implements ITaxCalculationStrategy. Your Medusa server will still work, but if you have written custom tax calculation logic it will not be used. Make sure to implement the ITaxCalculationStrategy interface.`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerMedusaMiddleware(pluginDetails, container) {
|
function registerMedusaMiddleware(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
||||||
let module
|
let module
|
||||||
try {
|
try {
|
||||||
module = require(`${pluginDetails.resolve}/api/medusa-middleware`).default
|
module = require(`${pluginDetails.resolve}/api/medusa-middleware`).default
|
||||||
@@ -143,7 +160,7 @@ function registerMedusaMiddleware(pluginDetails, container) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const middlewareService = container.resolve("middlewareService")
|
const middlewareService = container.resolve<MiddlewareService>("middlewareService")
|
||||||
if (module.postAuthentication) {
|
if (module.postAuthentication) {
|
||||||
middlewareService.addPostAuthentication(
|
middlewareService.addPostAuthentication(
|
||||||
module.postAuthentication,
|
module.postAuthentication,
|
||||||
@@ -163,8 +180,8 @@ function registerMedusaMiddleware(pluginDetails, container) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerCoreRouters(pluginDetails, container) {
|
function registerCoreRouters(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
||||||
const middlewareService = container.resolve("middlewareService")
|
const middlewareService = container.resolve<MiddlewareService>("middlewareService")
|
||||||
const { resolve } = pluginDetails
|
const { resolve } = pluginDetails
|
||||||
const adminFiles = glob.sync(`${resolve}/api/admin/[!__]*.js`, {})
|
const adminFiles = glob.sync(`${resolve}/api/admin/[!__]*.js`, {})
|
||||||
const storeFiles = glob.sync(`${resolve}/api/store/[!__]*.js`, {})
|
const storeFiles = glob.sync(`${resolve}/api/store/[!__]*.js`, {})
|
||||||
@@ -190,13 +207,13 @@ function registerCoreRouters(pluginDetails, container) {
|
|||||||
* Registers the plugin's api routes.
|
* Registers the plugin's api routes.
|
||||||
*/
|
*/
|
||||||
function registerApi(
|
function registerApi(
|
||||||
pluginDetails,
|
pluginDetails: PluginDetails,
|
||||||
app,
|
app: Express,
|
||||||
rootDirectory = "",
|
rootDirectory = "",
|
||||||
container,
|
container: MedusaContainer,
|
||||||
activityId
|
activityId: string
|
||||||
) {
|
): Express {
|
||||||
const logger = container.resolve("logger")
|
const logger = container.resolve<Logger>("logger")
|
||||||
logger.progress(
|
logger.progress(
|
||||||
activityId,
|
activityId,
|
||||||
`Registering custom endpoints for ${pluginDetails.name}`
|
`Registering custom endpoints for ${pluginDetails.name}`
|
||||||
@@ -230,7 +247,7 @@ function registerApi(
|
|||||||
* registered
|
* registered
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
async function registerServices(pluginDetails, container) {
|
async function registerServices(pluginDetails: PluginDetails, container: MedusaContainer): Promise<void> {
|
||||||
const files = glob.sync(`${pluginDetails.resolve}/services/[!__]*`, {})
|
const files = glob.sync(`${pluginDetails.resolve}/services/[!__]*`, {})
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
files.map(async (fn) => {
|
files.map(async (fn) => {
|
||||||
@@ -238,7 +255,7 @@ async function registerServices(pluginDetails, container) {
|
|||||||
const name = formatRegistrationName(fn)
|
const name = formatRegistrationName(fn)
|
||||||
|
|
||||||
if (!(loaded.prototype instanceof BaseService)) {
|
if (!(loaded.prototype instanceof BaseService)) {
|
||||||
const logger = container.resolve("logger")
|
const logger = container.resolve<Logger>("logger")
|
||||||
const message = `Services must inherit from BaseService, please check ${fn}`
|
const message = `Services must inherit from BaseService, please check ${fn}`
|
||||||
logger.error(message)
|
logger.error(message)
|
||||||
throw new Error(message)
|
throw new Error(message)
|
||||||
@@ -260,9 +277,9 @@ async function registerServices(pluginDetails, container) {
|
|||||||
[`pp_${loaded.identifier}`]: aliasTo(name),
|
[`pp_${loaded.identifier}`]: aliasTo(name),
|
||||||
})
|
})
|
||||||
} else if (loaded.prototype instanceof OauthService) {
|
} else if (loaded.prototype instanceof OauthService) {
|
||||||
const oauthService = container.resolve("oauthService")
|
|
||||||
|
|
||||||
const appDetails = loaded.getAppDetails(pluginDetails.options)
|
const appDetails = loaded.getAppDetails(pluginDetails.options)
|
||||||
|
|
||||||
|
const oauthService = container.resolve<typeof OauthService>("oauthService")
|
||||||
await oauthService.registerOauthApp(appDetails)
|
await oauthService.registerOauthApp(appDetails)
|
||||||
|
|
||||||
const name = appDetails.application_name
|
const name = appDetails.application_name
|
||||||
@@ -350,12 +367,11 @@ async function registerServices(pluginDetails, container) {
|
|||||||
* registered
|
* registered
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function registerSubscribers(pluginDetails, container) {
|
function registerSubscribers(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
||||||
const files = glob.sync(`${pluginDetails.resolve}/subscribers/*.js`, {})
|
const files = glob.sync(`${pluginDetails.resolve}/subscribers/*.js`, {})
|
||||||
files.forEach((fn) => {
|
files.forEach((fn) => {
|
||||||
const loaded = require(fn).default
|
const loaded = require(fn).default
|
||||||
|
|
||||||
const name = formatRegistrationName(fn)
|
|
||||||
container.build(
|
container.build(
|
||||||
asFunction(
|
asFunction(
|
||||||
(cradle) => new loaded(cradle, pluginDetails.options)
|
(cradle) => new loaded(cradle, pluginDetails.options)
|
||||||
@@ -373,12 +389,12 @@ function registerSubscribers(pluginDetails, container) {
|
|||||||
* registered
|
* registered
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function registerRepositories(pluginDetails, container) {
|
function registerRepositories(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
||||||
const files = glob.sync(`${pluginDetails.resolve}/repositories/*.js`, {})
|
const files = glob.sync(`${pluginDetails.resolve}/repositories/*.js`, {})
|
||||||
files.forEach((fn) => {
|
files.forEach((fn) => {
|
||||||
const loaded = require(fn)
|
const loaded = require(fn) as ClassConstructor<unknown>
|
||||||
|
|
||||||
Object.entries(loaded).map(([key, val]) => {
|
Object.entries(loaded).map(([, val]: [string, ClassConstructor<unknown>]) => {
|
||||||
if (typeof val === "function") {
|
if (typeof val === "function") {
|
||||||
const name = formatRegistrationName(fn)
|
const name = formatRegistrationName(fn)
|
||||||
container.register({
|
container.register({
|
||||||
@@ -400,12 +416,12 @@ function registerRepositories(pluginDetails, container) {
|
|||||||
* registered
|
* registered
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function registerModels(pluginDetails, container) {
|
function registerModels(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
||||||
const files = glob.sync(`${pluginDetails.resolve}/models/*.js`, {})
|
const files = glob.sync(`${pluginDetails.resolve}/models/*.js`, {})
|
||||||
files.forEach((fn) => {
|
files.forEach((fn) => {
|
||||||
const loaded = require(fn)
|
const loaded = require(fn) as ClassConstructor<unknown> | EntitySchema
|
||||||
|
|
||||||
Object.entries(loaded).map(([key, val]) => {
|
Object.entries(loaded).map(([, val]: [string, ClassConstructor<unknown> | EntitySchema]) => {
|
||||||
if (typeof val === "function" || val instanceof EntitySchema) {
|
if (typeof val === "function" || val instanceof EntitySchema) {
|
||||||
const name = formatRegistrationName(fn)
|
const name = formatRegistrationName(fn)
|
||||||
container.register({
|
container.register({
|
||||||
@@ -419,7 +435,7 @@ function registerModels(pluginDetails, container) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Create unique id for each plugin
|
// TODO: Create unique id for each plugin
|
||||||
function createPluginId(name) {
|
function createPluginId(name: string): string {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +447,13 @@ function createPluginId(name) {
|
|||||||
* the name of the folder where the plugin is contained.
|
* the name of the folder where the plugin is contained.
|
||||||
* @return {object} the plugin details
|
* @return {object} the plugin details
|
||||||
*/
|
*/
|
||||||
function resolvePlugin(pluginName) {
|
function resolvePlugin(pluginName: string): {
|
||||||
|
resolve: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
options: Record<string, unknown>
|
||||||
|
version: string;
|
||||||
|
} {
|
||||||
// Only find plugins when we're not given an absolute path
|
// Only find plugins when we're not given an absolute path
|
||||||
if (!existsSync(pluginName)) {
|
if (!existsSync(pluginName)) {
|
||||||
// Find the plugin in the local plugins folder
|
// Find the plugin in the local plugins folder
|
||||||
@@ -487,6 +509,7 @@ function resolvePlugin(pluginName) {
|
|||||||
resolve: resolvedPath,
|
resolve: resolvedPath,
|
||||||
id: createPluginId(packageJSON.name),
|
id: createPluginId(packageJSON.name),
|
||||||
name: packageJSON.name,
|
name: packageJSON.name,
|
||||||
|
options: {},
|
||||||
version: packageJSON.version,
|
version: packageJSON.version,
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -496,6 +519,6 @@ function resolvePlugin(pluginName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createFileContentHash(path, files) {
|
function createFileContentHash(path, files): string {
|
||||||
return path + files
|
return path + files
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,20 @@
|
|||||||
import { asValue } from "awilix"
|
import { asValue } from "awilix"
|
||||||
import RealRedis from "ioredis"
|
import RealRedis from "ioredis"
|
||||||
import FakeRedis from "ioredis-mock"
|
import FakeRedis from "ioredis-mock"
|
||||||
|
import { MedusaContainer } from "../types/global"
|
||||||
|
import { Logger } from "../types/global"
|
||||||
|
|
||||||
const redisLoader = async ({ container, configModule, logger }) => {
|
export type RedisConfig = {
|
||||||
|
redis_url?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Options = {
|
||||||
|
container: MedusaContainer;
|
||||||
|
configModule: { projectConfig: RedisConfig };
|
||||||
|
logger: Logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function redisLoader({ container, configModule, logger }: Options): Promise<void> {
|
||||||
if (configModule.projectConfig.redis_url) {
|
if (configModule.projectConfig.redis_url) {
|
||||||
// Economical way of dealing with redis clients
|
// Economical way of dealing with redis clients
|
||||||
const client = new RealRedis(configModule.projectConfig.redis_url)
|
const client = new RealRedis(configModule.projectConfig.redis_url)
|
||||||
+5
-4
@@ -1,21 +1,22 @@
|
|||||||
import glob from "glob"
|
import glob from "glob"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { Lifetime, asClass, asValue } from "awilix"
|
import { asClass } from "awilix"
|
||||||
|
|
||||||
import formatRegistrationName from "../utils/format-registration-name"
|
import formatRegistrationName from "../utils/format-registration-name"
|
||||||
|
import { ClassConstructor, MedusaContainer } from "../types/global"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers all models in the model directory
|
* Registers all models in the model directory
|
||||||
*/
|
*/
|
||||||
export default ({ container }) => {
|
export default ({ container }: { container: MedusaContainer }): void => {
|
||||||
let corePath = "../repositories/*.js"
|
let corePath = "../repositories/*.js"
|
||||||
const coreFull = path.join(__dirname, corePath)
|
const coreFull = path.join(__dirname, corePath)
|
||||||
|
|
||||||
const core = glob.sync(coreFull, { cwd: __dirname })
|
const core = glob.sync(coreFull, { cwd: __dirname })
|
||||||
core.forEach(fn => {
|
core.forEach(fn => {
|
||||||
const loaded = require(fn)
|
const loaded = require(fn) as ClassConstructor<unknown>
|
||||||
|
|
||||||
Object.entries(loaded).map(([key, val]) => {
|
Object.entries(loaded).map(([, val]: [string, ClassConstructor<unknown>]) => {
|
||||||
if (typeof val === "function") {
|
if (typeof val === "function") {
|
||||||
const name = formatRegistrationName(fn)
|
const name = formatRegistrationName(fn)
|
||||||
container.register({
|
container.register({
|
||||||
+9
-6
@@ -1,9 +1,12 @@
|
|||||||
import ProductService from "../services/product"
|
import ProductService from "../services/product"
|
||||||
import { indexTypes } from "medusa-core-utils"
|
import { indexTypes } from "medusa-core-utils"
|
||||||
|
import { MedusaContainer } from "../types/global"
|
||||||
|
import DefaultSearchService from "../services/search"
|
||||||
|
import { Logger } from "../types/global"
|
||||||
|
|
||||||
async function loadProductsIntoSearchEngine(container) {
|
async function loadProductsIntoSearchEngine(container: MedusaContainer): Promise<void> {
|
||||||
const searchService = container.resolve("searchService")
|
const searchService = container.resolve<DefaultSearchService>("searchService")
|
||||||
const productService = container.resolve("productService")
|
const productService = container.resolve<ProductService>("productService")
|
||||||
|
|
||||||
const TAKE = 20
|
const TAKE = 20
|
||||||
let hasMore = true
|
let hasMore = true
|
||||||
@@ -58,9 +61,9 @@ async function loadProductsIntoSearchEngine(container) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async ({ container }) => {
|
export default async ({ container }: { container: MedusaContainer }): Promise<void> => {
|
||||||
const searchService = container.resolve("searchService")
|
const searchService = container.resolve<DefaultSearchService>("searchService")
|
||||||
const logger = container.resolve("logger")
|
const logger = container.resolve<Logger>("logger")
|
||||||
if (searchService.isDefault) {
|
if (searchService.isDefault) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
"No search engine provider was found: make sure to include a search plugin to enable searching"
|
"No search engine provider was found: make sure to include a search plugin to enable searching"
|
||||||
@@ -1,13 +1,20 @@
|
|||||||
import glob from "glob"
|
import glob from "glob"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { asFunction } from "awilix"
|
import { asFunction } from "awilix"
|
||||||
|
|
||||||
import formatRegistrationName from "../utils/format-registration-name"
|
import formatRegistrationName from "../utils/format-registration-name"
|
||||||
|
import { MedusaContainer } from "../types/global"
|
||||||
|
import { ConfigModule } from "./index"
|
||||||
|
|
||||||
|
type Options = {
|
||||||
|
container: MedusaContainer;
|
||||||
|
configModule: ConfigModule
|
||||||
|
isTest: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers all services in the services directory
|
* Registers all services in the services directory
|
||||||
*/
|
*/
|
||||||
export default ({ container, configModule, isTest }) => {
|
export default ({ container, configModule, isTest }: Options): void => {
|
||||||
const useMock =
|
const useMock =
|
||||||
typeof isTest !== "undefined" ? isTest : process.env.NODE_ENV === "test"
|
typeof isTest !== "undefined" ? isTest : process.env.NODE_ENV === "test"
|
||||||
|
|
||||||
+2
-1
@@ -1,11 +1,12 @@
|
|||||||
import glob from "glob"
|
import glob from "glob"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { asFunction } from "awilix"
|
import { asFunction } from "awilix"
|
||||||
|
import { MedusaContainer } from "../types/global"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers all subscribers in the subscribers directory
|
* Registers all subscribers in the subscribers directory
|
||||||
*/
|
*/
|
||||||
export default ({ container }) => {
|
export default ({ container }: { container: MedusaContainer }) => {
|
||||||
const isTest = process.env.NODE_ENV === "test"
|
const isTest = process.env.NODE_ENV === "test"
|
||||||
|
|
||||||
const corePath = isTest
|
const corePath = isTest
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { asFunction, asValue, AwilixContainer } from "awilix"
|
||||||
|
import { Logger as _Logger } from "winston"
|
||||||
|
|
||||||
|
export type ClassConstructor<T> = {
|
||||||
|
new (...args: any[]): T;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type MedusaContainer = AwilixContainer & { registerAdd: <T>(name: string, registration: T ) => MedusaContainer }
|
||||||
|
|
||||||
|
export type Logger = _Logger & { progress: (activityId: string, msg: string) => void }
|
||||||
Reference in new issue
Block a user