load resources from starter kit and introduce srcDir configuration
This commit is contained in:
1 parent
73c917fdce
commit
3dbb256ddf
35 files changed
+174
-120
No files matched your search
@@ -862,6 +862,10 @@ export type ConfigModule = {
|
|||||||
* :::
|
* :::
|
||||||
*/
|
*/
|
||||||
featureFlags: Record<string, boolean | string>
|
featureFlags: Record<string, boolean | string>
|
||||||
|
|
||||||
|
directories?: {
|
||||||
|
srcDir?: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PluginDetails = {
|
export type PluginDetails = {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { FindConfig } from "../common"
|
import { FindConfig } from "../common"
|
||||||
import { RestoreReturn, SoftDeleteReturn } from "../dal"
|
|
||||||
import { IModuleService } from "../modules-sdk"
|
import { IModuleService } from "../modules-sdk"
|
||||||
import { Context } from "../shared-context"
|
import { Context } from "../shared-context"
|
||||||
import { FilterableCurrencyProps, CurrencyDTO } from "./common"
|
import { FilterableCurrencyProps, CurrencyDTO } from "./common"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Dictionary, FilterQuery, OperatorMap, Order } from "./utils"
|
import { Dictionary, FilterQuery, Order } from "./utils"
|
||||||
|
|
||||||
export { FilterQuery, OperatorMap } from "./utils"
|
export { FilterQuery, OperatorMap } from "./utils"
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ interface BaseRepositoryService<T = any> {
|
|||||||
): Promise<TOutput>
|
): Promise<TOutput>
|
||||||
}
|
}
|
||||||
|
|
||||||
type DtoBasedMutationMethods = "create" | "update"
|
|
||||||
|
|
||||||
export interface RepositoryService<T = any> extends BaseRepositoryService<T> {
|
export interface RepositoryService<T = any> extends BaseRepositoryService<T> {
|
||||||
find(options?: FindOptions<T>, context?: Context): Promise<T[]>
|
find(options?: FindOptions<T>, context?: Context): Promise<T[]>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { BaseFilterable, OperatorMap } from "../../dal"
|
import { BaseFilterable } from "../../dal"
|
||||||
import { BaseProduct } from "../product/common"
|
import { BaseProduct } from "../product/common"
|
||||||
|
|
||||||
export interface BaseProductCollection {
|
export interface BaseProductCollection {
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import { BaseFilterable, OperatorMap } from "../dal"
|
import { BaseFilterable, OperatorMap } from "../dal"
|
||||||
|
|
||||||
import { StringComparisonOperator } from "../common/common"
|
|
||||||
import { FulfillmentSetDTO } from "../fulfillment"
|
import { FulfillmentSetDTO } from "../fulfillment"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import {
|
|||||||
FilterableStockLocationProps,
|
FilterableStockLocationProps,
|
||||||
StockLocationDTO,
|
StockLocationDTO,
|
||||||
UpdateStockLocationInput,
|
UpdateStockLocationInput,
|
||||||
UpdateStockLocationNextInput,
|
|
||||||
UpsertStockLocationInput,
|
UpsertStockLocationInput,
|
||||||
} from "./common"
|
} from "./common"
|
||||||
import { RestoreReturn, SoftDeleteReturn } from "../dal"
|
import { RestoreReturn, SoftDeleteReturn } from "../dal"
|
||||||
|
|||||||
@@ -7,10 +7,6 @@ import {
|
|||||||
MedusaResponse,
|
MedusaResponse,
|
||||||
} from "../../../../types/routing"
|
} from "../../../../types/routing"
|
||||||
|
|
||||||
import {
|
|
||||||
ContainerRegistrationKeys,
|
|
||||||
remoteQueryObjectFromString,
|
|
||||||
} from "@medusajs/utils"
|
|
||||||
import { refetchApiKey } from "../helpers"
|
import { refetchApiKey } from "../helpers"
|
||||||
import { AdminUpdateApiKeyType } from "../validators"
|
import { AdminUpdateApiKeyType } from "../validators"
|
||||||
|
|
||||||
@@ -31,7 +27,7 @@ export const POST = async (
|
|||||||
req: AuthenticatedMedusaRequest<AdminUpdateApiKeyType>,
|
req: AuthenticatedMedusaRequest<AdminUpdateApiKeyType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const { result, errors } = await updateApiKeysWorkflow(req.scope).run({
|
const { errors } = await updateApiKeysWorkflow(req.scope).run({
|
||||||
input: {
|
input: {
|
||||||
selector: { id: req.params.id },
|
selector: { id: req.params.id },
|
||||||
update: req.validatedBody,
|
update: req.validatedBody,
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export const POST = async (
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const { result, errors } = await updateCampaigns.run({
|
const { errors } = await updateCampaigns.run({
|
||||||
input: { campaignsData },
|
input: { campaignsData },
|
||||||
throwOnError: false,
|
throwOnError: false,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const POST = async (
|
|||||||
const { add = [], remove = [] } = req.validatedBody
|
const { add = [], remove = [] } = req.validatedBody
|
||||||
|
|
||||||
const workflow = batchLinkProductsToCollectionWorkflow(req.scope)
|
const workflow = batchLinkProductsToCollectionWorkflow(req.scope)
|
||||||
const { result, errors } = await workflow.run({
|
const { errors } = await workflow.run({
|
||||||
input: {
|
input: {
|
||||||
id,
|
id,
|
||||||
add,
|
add,
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export const POST = async (
|
|||||||
req: AuthenticatedMedusaRequest<AdminUpdateCollectionType>,
|
req: AuthenticatedMedusaRequest<AdminUpdateCollectionType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const { result, errors } = await updateCollectionsWorkflow(req.scope).run({
|
const { errors } = await updateCollectionsWorkflow(req.scope).run({
|
||||||
input: {
|
input: {
|
||||||
selector: { id: req.params.id },
|
selector: { id: req.params.id },
|
||||||
update: req.validatedBody,
|
update: req.validatedBody,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export const POST = async (
|
|||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const updateGroups = updateCustomerGroupsWorkflow(req.scope)
|
const updateGroups = updateCustomerGroupsWorkflow(req.scope)
|
||||||
const { result, errors } = await updateGroups.run({
|
const { errors } = await updateGroups.run({
|
||||||
input: {
|
input: {
|
||||||
selector: { id: req.params.id },
|
selector: { id: req.params.id },
|
||||||
update: req.validatedBody,
|
update: req.validatedBody,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export const POST = async (
|
|||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const updateAddresses = updateCustomerAddressesWorkflow(req.scope)
|
const updateAddresses = updateCustomerAddressesWorkflow(req.scope)
|
||||||
const { result, errors } = await updateAddresses.run({
|
const { errors } = await updateAddresses.run({
|
||||||
input: {
|
input: {
|
||||||
selector: { id: req.params.address_id, customer_id: req.params.id },
|
selector: { id: req.params.address_id, customer_id: req.params.id },
|
||||||
update: req.validatedBody,
|
update: req.validatedBody,
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export const POST = async (
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const { result, errors } = await createAddresses.run({
|
const { errors } = await createAddresses.run({
|
||||||
input: { addresses },
|
input: { addresses },
|
||||||
throwOnError: false,
|
throwOnError: false,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export const POST = async (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const workflow = batchPriceListPricesWorkflow(req.scope)
|
const workflow = batchPriceListPricesWorkflow(req.scope)
|
||||||
const { result, errors } = await workflow.run({
|
const { errors } = await workflow.run({
|
||||||
input: {
|
input: {
|
||||||
data: {
|
data: {
|
||||||
id,
|
id,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export const POST = async (
|
|||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const workflow = updatePricingRuleTypesWorkflow(req.scope)
|
const workflow = updatePricingRuleTypesWorkflow(req.scope)
|
||||||
const { result, errors } = await workflow.run({
|
const { errors } = await workflow.run({
|
||||||
input: {
|
input: {
|
||||||
data: [{ ...req.validatedBody, id: req.params.id }],
|
data: [{ ...req.validatedBody, id: req.params.id }],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export const POST = async (
|
|||||||
const productId = req.params.id
|
const productId = req.params.id
|
||||||
const optionId = req.params.option_id
|
const optionId = req.params.option_id
|
||||||
|
|
||||||
const { result, errors } = await updateProductOptionsWorkflow(req.scope).run({
|
const { errors } = await updateProductOptionsWorkflow(req.scope).run({
|
||||||
input: {
|
input: {
|
||||||
selector: { id: optionId, product_id: productId },
|
selector: { id: optionId, product_id: productId },
|
||||||
update: req.validatedBody,
|
update: req.validatedBody,
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export const POST = async (
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const { result, errors } = await createProductOptionsWorkflow(req.scope).run({
|
const { errors } = await createProductOptionsWorkflow(req.scope).run({
|
||||||
input: { product_options: input },
|
input: { product_options: input },
|
||||||
throwOnError: false,
|
throwOnError: false,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -56,12 +56,10 @@ export const POST = async (
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const { result, errors } = await createProductVariantsWorkflow(req.scope).run(
|
const { errors } = await createProductVariantsWorkflow(req.scope).run({
|
||||||
{
|
|
||||||
input: { product_variants: input },
|
input: { product_variants: input },
|
||||||
throwOnError: false,
|
throwOnError: false,
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
if (Array.isArray(errors) && errors[0]) {
|
if (Array.isArray(errors) && errors[0]) {
|
||||||
throw errors[0].error
|
throw errors[0].error
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export const POST = async (
|
|||||||
} as any,
|
} as any,
|
||||||
]
|
]
|
||||||
|
|
||||||
const { result, errors } = await updatePromotions.run({
|
const { errors } = await updatePromotions.run({
|
||||||
input: { promotionsData },
|
input: { promotionsData },
|
||||||
throwOnError: false,
|
throwOnError: false,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export const POST = async (
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
const { result } = await workflow.run({ input })
|
await workflow.run({ input })
|
||||||
|
|
||||||
const user = await refetchUser(
|
const user = await refetchUser(
|
||||||
req.params.id,
|
req.params.id,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Express } from "express"
|
|||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
app: Express
|
app: Express
|
||||||
configModule: ConfigModule
|
adminConfig: ConfigModule["admin"]
|
||||||
}
|
}
|
||||||
|
|
||||||
type IntializedOptions = Required<
|
type IntializedOptions = Required<
|
||||||
@@ -11,17 +11,15 @@ type IntializedOptions = Required<
|
|||||||
> &
|
> &
|
||||||
AdminOptions
|
AdminOptions
|
||||||
|
|
||||||
export default async function adminLoader({ app, configModule }: Options) {
|
export default async function adminLoader({ app, adminConfig }: Options) {
|
||||||
const { admin } = configModule
|
|
||||||
|
|
||||||
const adminOptions: IntializedOptions = {
|
const adminOptions: IntializedOptions = {
|
||||||
disable: false,
|
disable: false,
|
||||||
path: "/app",
|
path: "/app",
|
||||||
outDir: "./build",
|
outDir: "./build",
|
||||||
...admin,
|
...adminConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (admin?.disable) {
|
if (adminOptions?.disable) {
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
import { ConfigModule } from "@medusajs/types"
|
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
||||||
import { FlagRouter } from "@medusajs/utils"
|
|
||||||
import { AwilixContainer } from "awilix"
|
|
||||||
import { Express } from "express"
|
import { Express } from "express"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import qs from "qs"
|
import qs from "qs"
|
||||||
import { RoutesLoader } from "./helpers/routing"
|
import { RoutesLoader } from "./helpers/routing"
|
||||||
|
import { MedusaContainer, PluginDetails } from "@medusajs/types"
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
app: Express
|
app: Express
|
||||||
container: AwilixContainer
|
plugins: PluginDetails[]
|
||||||
configModule: ConfigModule
|
container: MedusaContainer
|
||||||
featureFlagRouter?: FlagRouter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async ({ app, configModule }: Options) => {
|
export default async ({ app, container, plugins }: Options) => {
|
||||||
// This is a workaround for the issue described here: https://github.com/expressjs/express/issues/3454
|
// This is a workaround for the issue described here: https://github.com/expressjs/express/issues/3454
|
||||||
// We parse the url and get the qs to be parsed and override the query prop from the request
|
// We parse the url and get the qs to be parsed and override the query prop from the request
|
||||||
app.use(function (req, res, next) {
|
app.use(function (req, res, next) {
|
||||||
@@ -26,6 +24,10 @@ export default async ({ app, configModule }: Options) => {
|
|||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const configModule = container.resolve(
|
||||||
|
ContainerRegistrationKeys.CONFIG_MODULE
|
||||||
|
)
|
||||||
|
|
||||||
// TODO: Figure out why this is causing issues with test when placed inside ./api.ts
|
// TODO: Figure out why this is causing issues with test when placed inside ./api.ts
|
||||||
// Adding this here temporarily
|
// Adding this here temporarily
|
||||||
// Test: (packages/medusa/src/api/routes/admin/currencies/update-currency.ts)
|
// Test: (packages/medusa/src/api/routes/admin/currencies/update-currency.ts)
|
||||||
@@ -40,9 +42,20 @@ export default async ({ app, configModule }: Options) => {
|
|||||||
}).load()
|
}).load()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw Error(
|
throw Error(
|
||||||
"An error occurred while registering Medusa Core API Routes. See error in logs for more details."
|
"An error occurred while registering Medusa Core API Routes. See error in logs for more details.",
|
||||||
|
{ cause: err }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
plugins.map(async (pluginDetails) => {
|
||||||
|
return new RoutesLoader({
|
||||||
|
app: app,
|
||||||
|
configModule,
|
||||||
|
rootDir: path.join(pluginDetails.resolve, "api"),
|
||||||
|
}).load()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
@@ -102,5 +102,8 @@ export default (rootDirectory: string): ConfigModule => {
|
|||||||
modules: configModule.modules ?? {},
|
modules: configModule.modules ?? {},
|
||||||
featureFlags: configModule?.featureFlags ?? {},
|
featureFlags: configModule?.featureFlags ?? {},
|
||||||
plugins: configModule?.plugins ?? [],
|
plugins: configModule?.plugins ?? [],
|
||||||
|
directories: configModule?.directories ?? {
|
||||||
|
srcDir: "dist",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,22 @@
|
|||||||
import { PluginDetails } from "@medusajs/types"
|
|
||||||
import { glob } from "glob"
|
import { glob } from "glob"
|
||||||
import { getResolvedPlugins } from "./resolve-plugins"
|
import { PluginDetails } from "@medusajs/types"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* import files from the workflows directory to run the registration of the wofklows
|
* import files from the workflows directory to run the registration of the wofklows
|
||||||
* @param pluginDetails
|
* @param pluginDetails
|
||||||
*/
|
*/
|
||||||
async function registerWorkflows(pluginDetails: PluginDetails): Promise<void> {
|
export async function registerWorkflows(
|
||||||
const files = glob.sync(`${pluginDetails.resolve}/workflows/*.js`, {})
|
plugins: PluginDetails[]
|
||||||
await Promise.all(files.map(async (file) => import(file)))
|
): Promise<void> {
|
||||||
|
await Promise.all(
|
||||||
|
plugins.map(async (pluginDetails) => {
|
||||||
|
const files = glob.sync(
|
||||||
|
`${pluginDetails.resolve}/workflows/*.{ts,js,mjs,mts}`,
|
||||||
|
{
|
||||||
|
ignore: ["**/*.d.ts", "**/*.map"],
|
||||||
}
|
}
|
||||||
|
)
|
||||||
export async function registerProjectWorkflows({
|
return Promise.all(files.map(async (file) => import(file)))
|
||||||
rootDirectory,
|
})
|
||||||
configModule,
|
)
|
||||||
}) {
|
|
||||||
const [resolved] =
|
|
||||||
getResolvedPlugins(rootDirectory, configModule, "dist", true) || []
|
|
||||||
await registerWorkflows(resolved)
|
|
||||||
}
|
}
|
||||||
@@ -106,15 +106,22 @@ function resolvePlugin(pluginName: string): {
|
|||||||
|
|
||||||
export function getResolvedPlugins(
|
export function getResolvedPlugins(
|
||||||
rootDirectory: string,
|
rootDirectory: string,
|
||||||
configModule: ConfigModule,
|
configModule: {
|
||||||
extensionDirectoryPath = "dist",
|
plugins: ConfigModule["plugins"]
|
||||||
|
directories?: ConfigModule["directories"]
|
||||||
|
},
|
||||||
isMedusaProject = false
|
isMedusaProject = false
|
||||||
): undefined | PluginDetails[] {
|
): undefined | PluginDetails[] {
|
||||||
const { plugins } = configModule
|
|
||||||
|
|
||||||
if (isMedusaProject) {
|
if (isMedusaProject) {
|
||||||
|
/**
|
||||||
|
* Grab directory for loading resources inside a starter kit from
|
||||||
|
* the medusa-config file.
|
||||||
|
*
|
||||||
|
* This is because, we do not have a "dist" directory inside a starter
|
||||||
|
* kit. Instead we discover resources from the "src" directory.
|
||||||
|
*/
|
||||||
|
const extensionDirectoryPath = configModule.directories?.srcDir ?? "dist"
|
||||||
const extensionDirectory = path.join(rootDirectory, extensionDirectoryPath)
|
const extensionDirectory = path.join(rootDirectory, extensionDirectoryPath)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
resolve: extensionDirectory,
|
resolve: extensionDirectory,
|
||||||
@@ -126,7 +133,8 @@ export function getResolvedPlugins(
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const resolved = plugins.map((plugin) => {
|
const extensionDirectoryPath = "dist"
|
||||||
|
const resolved = configModule?.plugins.map((plugin) => {
|
||||||
if (isString(plugin)) {
|
if (isString(plugin)) {
|
||||||
return resolvePlugin(plugin)
|
return resolvePlugin(plugin)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
|
import { ConfigModule } from "@medusajs/types"
|
||||||
|
|
||||||
export const customersGlobalMiddlewareMock = jest.fn()
|
export const customersGlobalMiddlewareMock = jest.fn()
|
||||||
export const customersCreateMiddlewareMock = jest.fn()
|
export const customersCreateMiddlewareMock = jest.fn()
|
||||||
export const storeGlobalMiddlewareMock = jest.fn()
|
export const storeGlobalMiddlewareMock = jest.fn()
|
||||||
|
|
||||||
export const config = {
|
export const config: ConfigModule = {
|
||||||
projectConfig: {
|
projectConfig: {
|
||||||
database_logging: false,
|
database_logging: false,
|
||||||
http: {
|
http: {
|
||||||
|
authCors: "http://localhost:9000",
|
||||||
storeCors: "http://localhost:8000",
|
storeCors: "http://localhost:8000",
|
||||||
adminCors: "http://localhost:7001",
|
adminCors: "http://localhost:7001",
|
||||||
jwtSecret: "supersecret",
|
jwtSecret: "supersecret",
|
||||||
|
|||||||
+14
-9
@@ -3,14 +3,18 @@ import {
|
|||||||
ModulesDefinition,
|
ModulesDefinition,
|
||||||
registerMedusaModule,
|
registerMedusaModule,
|
||||||
} from "@medusajs/modules-sdk"
|
} from "@medusajs/modules-sdk"
|
||||||
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
import {
|
||||||
import { asValue, createContainer } from "awilix"
|
ContainerRegistrationKeys,
|
||||||
|
createMedusaContainer,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
import { asValue } from "awilix"
|
||||||
import express from "express"
|
import express from "express"
|
||||||
import jwt from "jsonwebtoken"
|
import jwt from "jsonwebtoken"
|
||||||
import { MockManager } from "medusa-test-utils"
|
import { MockManager } from "medusa-test-utils"
|
||||||
import querystring from "querystring"
|
import querystring from "querystring"
|
||||||
import supertest from "supertest"
|
import supertest from "supertest"
|
||||||
import apiLoader from "../../../../api"
|
import apiLoader from "../../../../api"
|
||||||
|
import { getResolvedPlugins } from "../../../../helpers/resolve-plugins"
|
||||||
import featureFlagLoader, { featureFlagRouter } from "../../../../feature-flags"
|
import featureFlagLoader, { featureFlagRouter } from "../../../../feature-flags"
|
||||||
import passportLoader from "../../../../passport"
|
import passportLoader from "../../../../passport"
|
||||||
|
|
||||||
@@ -42,7 +46,7 @@ export const createServer = async (rootDir) => {
|
|||||||
)[moduleKey]
|
)[moduleKey]
|
||||||
})
|
})
|
||||||
|
|
||||||
const container = createContainer()
|
const container = createMedusaContainer()
|
||||||
|
|
||||||
container.registerAdd = function (name, registration) {
|
container.registerAdd = function (name, registration) {
|
||||||
const storeKey = name + "_STORE"
|
const storeKey = name + "_STORE"
|
||||||
@@ -83,8 +87,10 @@ export const createServer = async (rootDir) => {
|
|||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const plugins = getResolvedPlugins(rootDir, config) || []
|
||||||
|
|
||||||
featureFlagLoader(config)
|
featureFlagLoader(config)
|
||||||
await passportLoader({ app: app, container, configModule: config })
|
await passportLoader({ app: app, configModule: config })
|
||||||
await moduleLoader({ container, moduleResolutions })
|
await moduleLoader({ container, moduleResolutions })
|
||||||
|
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
@@ -103,14 +109,13 @@ export const createServer = async (rootDir) => {
|
|||||||
await apiLoader({
|
await apiLoader({
|
||||||
container,
|
container,
|
||||||
app: app,
|
app: app,
|
||||||
configModule: config,
|
plugins,
|
||||||
featureFlagRouter,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const superRequest = supertest(app)
|
const superRequest = supertest(app)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
request: async (method, url, opts = {}) => {
|
request: async (method, url, opts: any = {}) => {
|
||||||
const { payload, query, headers = {} } = opts
|
const { payload, query, headers = {} } = opts
|
||||||
|
|
||||||
const queryParams = query && querystring.stringify(query)
|
const queryParams = query && querystring.stringify(query)
|
||||||
@@ -124,7 +129,7 @@ export const createServer = async (rootDir) => {
|
|||||||
user_id: opts.adminSession.userId || opts.adminSession.jwt?.userId,
|
user_id: opts.adminSession.userId || opts.adminSession.jwt?.userId,
|
||||||
domain: "admin",
|
domain: "admin",
|
||||||
},
|
},
|
||||||
config.projectConfig.http.jwtSecret
|
config.projectConfig.http.jwtSecret!
|
||||||
)
|
)
|
||||||
|
|
||||||
headers.Authorization = `Bearer ${token}`
|
headers.Authorization = `Bearer ${token}`
|
||||||
@@ -137,7 +142,7 @@ export const createServer = async (rootDir) => {
|
|||||||
opts.clientSession.jwt?.customer_id,
|
opts.clientSession.jwt?.customer_id,
|
||||||
domain: "store",
|
domain: "store",
|
||||||
},
|
},
|
||||||
config.projectConfig.http.jwtSecret
|
config.projectConfig.http.jwtSecret!
|
||||||
)
|
)
|
||||||
|
|
||||||
headers.Authorization = `Bearer ${token}`
|
headers.Authorization = `Bearer ${token}`
|
||||||
@@ -568,8 +568,6 @@ export class RoutesLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mostSpecificConfig?.bodyParser) {
|
if (mostSpecificConfig?.bodyParser) {
|
||||||
const sizeLimit = mostSpecificConfig?.bodyParser?.sizeLimit
|
|
||||||
|
|
||||||
this.router[method.toLowerCase()](
|
this.router[method.toLowerCase()](
|
||||||
path,
|
path,
|
||||||
...getBodyParserMiddleware(mostSpecificConfig?.bodyParser)
|
...getBodyParserMiddleware(mostSpecificConfig?.bodyParser)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createDefaultsWorkflow } from "@medusajs/core-flows"
|
import { createDefaultsWorkflow } from "@medusajs/core-flows"
|
||||||
import { ConfigModule } from "@medusajs/types"
|
import { ConfigModule, MedusaContainer } from "@medusajs/types"
|
||||||
import { ContainerRegistrationKeys, promiseAll } from "@medusajs/utils"
|
import { ContainerRegistrationKeys, promiseAll } from "@medusajs/utils"
|
||||||
import { asValue } from "awilix"
|
import { asValue } from "awilix"
|
||||||
import { Express, NextFunction, Request, Response } from "express"
|
import { Express, NextFunction, Request, Response } from "express"
|
||||||
@@ -7,17 +7,19 @@ import { createMedusaContainer } from "medusa-core-utils"
|
|||||||
import requestIp from "request-ip"
|
import requestIp from "request-ip"
|
||||||
import { v4 } from "uuid"
|
import { v4 } from "uuid"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { MedusaContainer } from "../types/global"
|
|
||||||
import adminLoader from "./admin"
|
import adminLoader from "./admin"
|
||||||
import apiLoader from "./api"
|
import apiLoader from "./api"
|
||||||
import loadConfig from "./config"
|
import loadConfig from "./config"
|
||||||
import expressLoader from "./express"
|
import expressLoader from "./express"
|
||||||
import featureFlagsLoader from "./feature-flags"
|
import featureFlagsLoader from "./feature-flags"
|
||||||
import { registerProjectWorkflows } from "./helpers/register-workflows"
|
import { registerWorkflows } from "./helpers/register-workflows"
|
||||||
import Logger from "./logger"
|
import Logger from "./logger"
|
||||||
import loadMedusaApp from "./medusa-app"
|
import loadMedusaApp from "./medusa-app"
|
||||||
import pgConnectionLoader from "./pg-connection"
|
import registerPgConnection from "./pg-connection"
|
||||||
import { SubscriberLoader } from "./helpers/subscribers"
|
import { SubscriberLoader } from "./helpers/subscribers"
|
||||||
|
import { getResolvedPlugins } from "./helpers/resolve-plugins"
|
||||||
|
import { PluginDetails } from "@medusajs/types"
|
||||||
|
import glob from "glob"
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
directory: string
|
directory: string
|
||||||
@@ -28,17 +30,45 @@ const isWorkerMode = (configModule) => {
|
|||||||
return configModule.projectConfig.worker_mode === "worker"
|
return configModule.projectConfig.worker_mode === "worker"
|
||||||
}
|
}
|
||||||
|
|
||||||
async function subscribersLoader(container) {
|
async function subscribersLoader(
|
||||||
const subscribersPath = path.join(__dirname, "../subscribers")
|
plugins: PluginDetails[],
|
||||||
await new SubscriberLoader(subscribersPath, container).load()
|
container: MedusaContainer
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* Load subscribers from the medusa/medusa package
|
||||||
|
*/
|
||||||
|
await new SubscriberLoader(
|
||||||
|
path.join(__dirname, "../subscribers"),
|
||||||
|
container
|
||||||
|
).load()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load subscribers from all the plugins.
|
||||||
|
*/
|
||||||
|
await Promise.all(
|
||||||
|
plugins.map(async (pluginDetails) => {
|
||||||
|
const files = glob.sync(
|
||||||
|
`${pluginDetails.resolve}/subscribers/*.{ts,js,mjs,mts}`,
|
||||||
|
{
|
||||||
|
ignore: ["**/*.d.ts", "**/*.map"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return Promise.all(
|
||||||
|
files.map(async (file) => new SubscriberLoader(file, container).load())
|
||||||
|
)
|
||||||
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadEntrypoints(
|
async function loadEntrypoints(
|
||||||
configModule,
|
plugins: PluginDetails[],
|
||||||
container,
|
container: MedusaContainer,
|
||||||
expressApp,
|
expressApp: Express
|
||||||
featureFlagRouter
|
|
||||||
) {
|
) {
|
||||||
|
const configModule: ConfigModule = container.resolve(
|
||||||
|
ContainerRegistrationKeys.CONFIG_MODULE
|
||||||
|
)
|
||||||
|
|
||||||
if (isWorkerMode(configModule)) {
|
if (isWorkerMode(configModule)) {
|
||||||
return async () => {}
|
return async () => {}
|
||||||
}
|
}
|
||||||
@@ -59,33 +89,22 @@ async function loadEntrypoints(
|
|||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
await adminLoader({ app: expressApp, configModule })
|
await adminLoader({ app: expressApp, adminConfig: configModule.admin })
|
||||||
await subscribersLoader(container)
|
await subscribersLoader(plugins, container)
|
||||||
await apiLoader({
|
await apiLoader({
|
||||||
container,
|
container,
|
||||||
|
plugins,
|
||||||
app: expressApp,
|
app: expressApp,
|
||||||
configModule,
|
|
||||||
featureFlagRouter,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return shutdown
|
return shutdown
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async ({
|
async function initializeContainer(rootDirectory: string) {
|
||||||
directory: rootDirectory,
|
const container = createMedusaContainer()
|
||||||
expressApp,
|
|
||||||
}: Options): Promise<{
|
|
||||||
configModule: ConfigModule
|
|
||||||
container: MedusaContainer
|
|
||||||
app: Express
|
|
||||||
pgConnection: unknown
|
|
||||||
shutdown: () => Promise<void>
|
|
||||||
prepareShutdown: () => Promise<void>
|
|
||||||
}> => {
|
|
||||||
const configModule = loadConfig(rootDirectory)
|
const configModule = loadConfig(rootDirectory)
|
||||||
const featureFlagRouter = featureFlagsLoader(configModule, Logger)
|
const featureFlagRouter = featureFlagsLoader(configModule, Logger)
|
||||||
const container = createMedusaContainer()
|
|
||||||
const pgConnection = await pgConnectionLoader({ container, configModule })
|
|
||||||
container.register({
|
container.register({
|
||||||
[ContainerRegistrationKeys.LOGGER]: asValue(Logger),
|
[ContainerRegistrationKeys.LOGGER]: asValue(Logger),
|
||||||
[ContainerRegistrationKeys.FEATURE_FLAG_ROUTER]: asValue(featureFlagRouter),
|
[ContainerRegistrationKeys.FEATURE_FLAG_ROUTER]: asValue(featureFlagRouter),
|
||||||
@@ -93,28 +112,45 @@ export default async ({
|
|||||||
[ContainerRegistrationKeys.REMOTE_QUERY]: asValue(null),
|
[ContainerRegistrationKeys.REMOTE_QUERY]: asValue(null),
|
||||||
})
|
})
|
||||||
|
|
||||||
// Workflows are registered before the app to allow modules to run workflows as part of bootstrapping
|
await registerPgConnection({ container, configModule })
|
||||||
// e.g. the workflow engine will resume workflows that were running when the server was shut down
|
return container
|
||||||
await registerProjectWorkflows({ rootDirectory, configModule })
|
}
|
||||||
|
|
||||||
|
export default async ({
|
||||||
|
directory: rootDirectory,
|
||||||
|
expressApp,
|
||||||
|
}: Options): Promise<{
|
||||||
|
container: MedusaContainer
|
||||||
|
app: Express
|
||||||
|
shutdown: () => Promise<void>
|
||||||
|
prepareShutdown: () => Promise<void>
|
||||||
|
}> => {
|
||||||
|
const container = await initializeContainer(rootDirectory)
|
||||||
|
const configModule = container.resolve(
|
||||||
|
ContainerRegistrationKeys.CONFIG_MODULE
|
||||||
|
)
|
||||||
|
|
||||||
|
const plugins = getResolvedPlugins(rootDirectory, configModule, true) || []
|
||||||
|
await registerWorkflows(plugins)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
onApplicationShutdown: medusaAppOnApplicationShutdown,
|
onApplicationShutdown: medusaAppOnApplicationShutdown,
|
||||||
onApplicationPrepareShutdown: medusaAppOnApplicationPrepareShutdown,
|
onApplicationPrepareShutdown: medusaAppOnApplicationPrepareShutdown,
|
||||||
} = await loadMedusaApp({
|
} = await loadMedusaApp({
|
||||||
configModule,
|
|
||||||
container,
|
container,
|
||||||
})
|
})
|
||||||
|
|
||||||
const entrypointsShutdown = await loadEntrypoints(
|
const entrypointsShutdown = await loadEntrypoints(
|
||||||
configModule,
|
plugins,
|
||||||
container,
|
container,
|
||||||
expressApp,
|
expressApp
|
||||||
featureFlagRouter
|
|
||||||
)
|
)
|
||||||
|
|
||||||
await createDefaultsWorkflow(container).run()
|
await createDefaultsWorkflow(container).run()
|
||||||
|
|
||||||
const shutdown = async () => {
|
const shutdown = async () => {
|
||||||
|
const pgConnection = container.resolve(
|
||||||
|
ContainerRegistrationKeys.PG_CONNECTION
|
||||||
|
)
|
||||||
await medusaAppOnApplicationShutdown()
|
await medusaAppOnApplicationShutdown()
|
||||||
|
|
||||||
await promiseAll([
|
await promiseAll([
|
||||||
@@ -126,10 +162,8 @@ export default async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
configModule,
|
|
||||||
container,
|
container,
|
||||||
app: expressApp,
|
app: expressApp,
|
||||||
pgConnection,
|
|
||||||
shutdown,
|
shutdown,
|
||||||
prepareShutdown: medusaAppOnApplicationPrepareShutdown,
|
prepareShutdown: medusaAppOnApplicationPrepareShutdown,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
} from "@medusajs/modules-sdk"
|
} from "@medusajs/modules-sdk"
|
||||||
import {
|
import {
|
||||||
CommonTypes,
|
CommonTypes,
|
||||||
|
ConfigModule,
|
||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
LoadedModule,
|
LoadedModule,
|
||||||
MedusaContainer,
|
MedusaContainer,
|
||||||
@@ -143,13 +144,8 @@ export async function revertMedusaApp({
|
|||||||
|
|
||||||
export const loadMedusaApp = async (
|
export const loadMedusaApp = async (
|
||||||
{
|
{
|
||||||
configModule,
|
|
||||||
container,
|
container,
|
||||||
}: {
|
}: {
|
||||||
configModule: {
|
|
||||||
modules?: CommonTypes.ConfigModule["modules"]
|
|
||||||
projectConfig: CommonTypes.ConfigModule["projectConfig"]
|
|
||||||
}
|
|
||||||
container: MedusaContainer
|
container: MedusaContainer
|
||||||
},
|
},
|
||||||
config = { registerInContainer: true }
|
config = { registerInContainer: true }
|
||||||
@@ -163,6 +159,10 @@ export const loadMedusaApp = async (
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const configModule: ConfigModule = container.resolve(
|
||||||
|
ContainerRegistrationKeys.CONFIG_MODULE
|
||||||
|
)
|
||||||
|
|
||||||
const sharedResourcesConfig = {
|
const sharedResourcesConfig = {
|
||||||
database: {
|
database: {
|
||||||
clientUrl: configModule.projectConfig.database_url,
|
clientUrl: configModule.projectConfig.database_url,
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { ContainerRegistrationKeys, ModulesSdkUtils } from "@medusajs/utils"
|
|||||||
import { asValue, AwilixContainer } from "awilix"
|
import { asValue, AwilixContainer } from "awilix"
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
configModule: ConfigModule
|
|
||||||
container: AwilixContainer
|
container: AwilixContainer
|
||||||
|
configModule: ConfigModule
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async ({ container, configModule }: Options): Promise<any> => {
|
export default async ({ container, configModule }: Options): Promise<any> => {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import { toCamelCase, upperCaseFirst } from "@medusajs/utils"
|
|||||||
export function formatRegistrationName(path: string): string {
|
export function formatRegistrationName(path: string): string {
|
||||||
const parsed = parse(path)
|
const parsed = parse(path)
|
||||||
const parsedDir = parse(parsed.dir)
|
const parsedDir = parse(parsed.dir)
|
||||||
const rawname = parsed.name
|
|
||||||
let directoryNamespace = parsedDir.name
|
let directoryNamespace = parsedDir.name
|
||||||
|
|
||||||
if (directoryNamespace.startsWith("__")) {
|
if (directoryNamespace.startsWith("__")) {
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ export function prepareListQuery<T extends RequestQueryFields, TEntity>(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const allAllowedFields = new Set(allowedFields) // In case there is no allowedFields, allow all fields
|
|
||||||
const notAllowedFields: string[] = []
|
const notAllowedFields: string[] = []
|
||||||
|
|
||||||
if (allowedFields.length) {
|
if (allowedFields.length) {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"strictFunctionTypes": true,
|
"strictFunctionTypes": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
"noImplicitThis": true,
|
"noImplicitThis": true,
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
|||||||
Reference in new issue
Block a user