feat: Flatten the provider config for all modules (#7930)

This commit is contained in:
Stevche Radevski
2024-07-03 16:57:12 +02:00
committed by GitHub
parent b6e4435c23
commit 012a624ee4
24 changed files with 168 additions and 292 deletions
+6 -21
View File
@@ -14,20 +14,12 @@ const customPaymentProvider = {
resolve: {
services: [require("@medusajs/payment/dist/providers/system").default],
},
options: {
config: {
default_2: {},
},
},
id: "default_2",
}
const customFulfillmentProvider = {
resolve: "@medusajs/fulfillment-manual",
options: {
config: {
"test-provider": {},
},
},
id: "test-provider",
}
module.exports = {
@@ -74,11 +66,7 @@ module.exports = {
providers: [
{
resolve: "@medusajs/file-local-next",
options: {
config: {
local: {},
},
},
id: "local",
},
],
},
@@ -116,13 +104,10 @@ module.exports = {
providers: [
{
resolve: "@medusajs/notification-local",
id: "local-notification-provider",
options: {
config: {
"local-notification-provider": {
name: "Local Notification Provider",
channels: ["log", "email"],
},
},
name: "Local Notification Provider",
channels: ["log", "email"],
},
},
],
+4 -9
View File
@@ -12,11 +12,7 @@ process.env.LOG_LEVEL = "error"
const customFulfillmentProvider = {
resolve: "@medusajs/fulfillment-manual",
options: {
config: {
"test-provider": {},
},
},
id: "test-provider",
}
module.exports = defineConfig({
@@ -41,11 +37,10 @@ module.exports = defineConfig({
providers: [
{
resolve: "@medusajs/file-local-next",
id: "local",
options: {
config: {
// This is the directory where we can reliably write in CI environments
local: { upload_dir: path.join(os.tmpdir(), "uploads") },
},
// This is the directory where we can reliably write in CI environments
upload_dir: path.join(os.tmpdir(), "uploads"),
},
},
],
+5 -16
View File
@@ -14,20 +14,12 @@ const customPaymentProvider = {
resolve: {
services: [require("@medusajs/payment/dist/providers/system").default],
},
options: {
config: {
default_2: {},
},
},
id: "default_2",
}
const customFulfillmentProvider = {
resolve: "@medusajs/fulfillment-manual",
options: {
config: {
"test-provider": {},
},
},
id: "test-provider",
}
module.exports = {
@@ -101,13 +93,10 @@ module.exports = {
providers: [
{
resolve: "@medusajs/notification-local",
id: "local-notification-provider",
options: {
config: {
"local-notification-provider": {
name: "Local Notification Provider",
channels: ["log", "email"],
},
},
name: "Local Notification Provider",
channels: ["log", "email"],
},
},
],
@@ -22,6 +22,7 @@ describe("modules loader", () => {
const moduleProviders = [
{
resolve: "@providers/default",
id: "default",
options: {},
},
]
@@ -47,6 +48,7 @@ describe("modules loader", () => {
const moduleProviders = [
{
resolve: "@providers/default",
id: "default",
options: {},
},
]
@@ -66,6 +68,7 @@ describe("modules loader", () => {
const moduleProviders = [
{
resolve: "@providers/no-service",
id: "default",
options: {},
},
]
@@ -83,6 +86,7 @@ describe("modules loader", () => {
const moduleProviders = [
{
resolve: "@providers/no-default",
id: "default",
options: {},
},
]
@@ -32,8 +32,7 @@ export async function loadModuleProvider(
registerServiceFn?: (klass, container, moduleDetails) => Promise<void>
) {
let loadedProvider: any
const moduleName = provider.resolve ?? provider.provider_name ?? ""
const moduleName = provider.resolve ?? ""
try {
loadedProvider = provider.resolve
@@ -60,7 +59,10 @@ export async function loadModuleProvider(
const name = lowerCaseFirst(service.name)
if (registerServiceFn) {
// Used to register the specific type of service in the provider
await registerServiceFn(service, container, provider.options)
await registerServiceFn(service, container, {
id: provider.id,
options: provider.options,
})
} else {
container.register({
[name]: asFunction(
@@ -6,6 +6,6 @@ export type ModuleProviderExports = {
export type ModuleProvider = {
resolve: string | ModuleProviderExports
provider_name?: string
options: Record<string, unknown>
id: string
options?: Record<string, unknown>
}
@@ -21,11 +21,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"local": {},
},
},
"id": "local",
"resolve": "@medusajs/file-local-next",
},
],
@@ -36,11 +32,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"manual": {},
},
},
"id": "manual",
"resolve": "@medusajs/fulfillment-manual",
},
],
@@ -52,11 +44,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"local": {},
},
},
"id": "local",
"resolve": "@medusajs/notification-local",
},
],
@@ -123,11 +111,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"local": {},
},
},
"id": "local",
"resolve": "@medusajs/file-local-next",
},
],
@@ -138,11 +122,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"manual": {},
},
},
"id": "manual",
"resolve": "@medusajs/fulfillment-manual",
},
],
@@ -157,11 +137,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"local": {},
},
},
"id": "local",
"resolve": "@medusajs/notification-local",
},
],
@@ -228,11 +204,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"local": {},
},
},
"id": "local",
"resolve": "@medusajs/file-local-next",
},
],
@@ -243,11 +215,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"manual": {},
},
},
"id": "manual",
"resolve": "@medusajs/fulfillment-manual",
},
],
@@ -259,11 +227,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"local": {},
},
},
"id": "local",
"resolve": "@medusajs/notification-local",
},
],
@@ -332,11 +296,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"local": {},
},
},
"id": "local",
"resolve": "@medusajs/file-local-next",
},
],
@@ -347,11 +307,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"manual": {},
},
},
"id": "manual",
"resolve": "@medusajs/fulfillment-manual",
},
],
@@ -363,11 +319,7 @@ describe("defineConfig", function () {
"options": {
"providers": [
{
"options": {
"config": {
"local": {},
},
},
"id": "local",
"resolve": "@medusajs/notification-local",
},
],
@@ -90,11 +90,7 @@ export function defineConfig(config: Partial<ConfigModule> = {}): ConfigModule {
providers: [
{
resolve: "@medusajs/file-local-next",
options: {
config: {
local: {},
},
},
id: "local",
},
],
},
@@ -105,11 +101,7 @@ export function defineConfig(config: Partial<ConfigModule> = {}): ConfigModule {
providers: [
{
resolve: "@medusajs/fulfillment-manual",
options: {
config: {
manual: {},
},
},
id: "manual",
},
],
},
@@ -120,11 +112,7 @@ export function defineConfig(config: Partial<ConfigModule> = {}): ConfigModule {
providers: [
{
resolve: "@medusajs/notification-local",
options: {
config: {
local: {},
},
},
id: "local",
},
],
},
@@ -10,11 +10,7 @@ let moduleOptions = {
process.cwd() +
"/integration-tests/__fixtures__/providers/default-provider"
),
options: {
config: {
plaintextpass: {},
},
},
id: "plaintextpass",
},
],
}
+14 -21
View File
@@ -9,18 +9,19 @@ import {
} from "@types"
const registrationFn = async (klass, container, pluginOptions) => {
Object.entries(pluginOptions.config || []).map(([name, config]) => {
container.register({
[AuthProviderRegistrationPrefix + name]: asFunction(
(cradle) => new klass(cradle, config),
{
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}
),
})
container.registerAdd(AuthIdentifiersRegistrationName, asValue(name))
container.register({
[AuthProviderRegistrationPrefix + pluginOptions.id]: asFunction(
(cradle) => new klass(cradle, pluginOptions.options ?? {}),
{
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}
),
})
container.registerAdd(
AuthIdentifiersRegistrationName,
asValue(pluginOptions.id)
)
}
export default async ({
@@ -32,21 +33,13 @@ export default async ({
| ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions
) & { providers: ModuleProvider[] }
>): Promise<void> => {
// TODO: Temporary settings used by the starter, remove once the auth module is updated
const isLegacyOptions =
options?.providers?.length && !!(options?.providers[0] as any)?.name
// Note: For now we want to inject some providers out of the box
const providerConfig = [
{
resolve: EmailPassProvider,
options: {
config: {
emailpass: {},
},
},
id: "emailpass",
},
...(isLegacyOptions ? [] : options?.providers ?? []),
...(options?.providers ?? []),
]
await moduleProviderLoader({
+8 -6
View File
@@ -19,11 +19,13 @@ export type AuthModuleOptions = Partial<ModuleServiceInitializeOptions> & {
* The module provider to be registered
*/
resolve: string | ModuleProviderExports
options: {
/**
* key value pair of the provider name and the configuration to be passed to the provider constructor
*/
config: Record<string, unknown>
}
/**
* The id of the provider
*/
id: string
/**
* key value pair of the configuration to be passed to the provider constructor
*/
options?: Record<string, unknown>
}[]
}
@@ -20,11 +20,7 @@ const moduleOptions = {
process.cwd() +
"/integration-tests/__fixtures__/providers/default-provider"
),
options: {
config: {
"default-provider": {},
},
},
id: "default-provider",
},
],
}
+13 -12
View File
@@ -8,20 +8,21 @@ import {
import { Lifetime, asFunction, asValue } from "awilix"
const registrationFn = async (klass, container, pluginOptions) => {
Object.entries(pluginOptions.config || []).map(([name, config]) => {
const key = FileProviderService.getRegistrationIdentifier(klass, name)
const key = FileProviderService.getRegistrationIdentifier(
klass,
pluginOptions.id
)
container.register({
[FileProviderRegistrationPrefix + key]: asFunction(
(cradle) => new klass(cradle, config),
{
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}
),
})
container.registerAdd(FileProviderIdentifierRegistrationName, asValue(key))
container.register({
[FileProviderRegistrationPrefix + key]: asFunction(
(cradle) => new klass(cradle, pluginOptions.options ?? {}),
{
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}
),
})
container.registerAdd(FileProviderIdentifierRegistrationName, asValue(key))
}
export default async ({
+8 -6
View File
@@ -17,11 +17,13 @@ export type FileModuleOptions = Partial<ModuleServiceInitializeOptions> & {
* The module provider to be registered
*/
resolve: string | ModuleProviderExports
options: {
/**
* key value pair of the provider name and the configuration to be passed to the provider constructor
*/
config: Record<string, unknown>
}
/**
* The id of the provider
*/
id: string
/**
* key value pair of the configuration to be passed to the provider constructor
*/
options?: Record<string, unknown>
}
}
@@ -23,11 +23,7 @@ const moduleOptions = {
process.cwd() +
"/integration-tests/__fixtures__/providers/default-provider"
),
options: {
config: {
"test-provider": {},
},
},
id: "test-provider",
},
],
}
@@ -18,11 +18,7 @@ let moduleOptions = {
process.cwd() +
"/integration-tests/__fixtures__/providers/default-provider"
),
options: {
config: {
"test-provider": {},
},
},
id: "test-provider",
},
],
}
@@ -125,17 +121,13 @@ moduleIntegrationTestRunner({
definition: ModulesDefinition[Modules.FULFILLMENT],
options: {
databaseConfig,
providers: [
{
resolve: resolve(
process.cwd() +
"/integration-tests/__fixtures__/providers/default-provider"
),
options: {
config: providersConfig,
},
},
],
providers: Object.keys(providersConfig).map((id) => ({
resolve: resolve(
process.cwd() +
"/integration-tests/__fixtures__/providers/default-provider"
),
id,
})),
},
},
},
@@ -179,17 +171,13 @@ moduleIntegrationTestRunner({
definition: ModulesDefinition[Modules.FULFILLMENT],
options: {
databaseConfig,
providers: [
{
resolve: resolve(
process.cwd() +
"/integration-tests/__fixtures__/providers/default-provider"
),
options: {
config: providersConfig2,
},
},
],
providers: Object.keys(providersConfig2).map((id) => ({
resolve: resolve(
process.cwd() +
"/integration-tests/__fixtures__/providers/default-provider"
),
id,
})),
},
},
},
@@ -25,11 +25,7 @@ const moduleOptions = {
process.cwd() +
"/integration-tests/__fixtures__/providers/default-provider"
),
options: {
config: {
"test-provider": {},
},
},
id: "test-provider",
},
],
}
@@ -10,20 +10,21 @@ import { FulfillmentIdentifiersRegistrationName } from "@types"
import { Lifetime, asFunction, asValue } from "awilix"
const registrationFn = async (klass, container, pluginOptions) => {
Object.entries(pluginOptions.config || []).map(([name, config]) => {
const key = FulfillmentProviderService.getRegistrationIdentifier(
klass,
name
)
const key = FulfillmentProviderService.getRegistrationIdentifier(
klass,
pluginOptions.id
)
container.register({
["fp_" + key]: asFunction((cradle) => new klass(cradle, config), {
container.register({
["fp_" + key]: asFunction(
(cradle) => new klass(cradle, pluginOptions.options),
{
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}),
})
container.registerAdd(FulfillmentIdentifiersRegistrationName, asValue(key))
}
),
})
container.registerAdd(FulfillmentIdentifiersRegistrationName, asValue(key))
}
export default async ({
@@ -23,11 +23,13 @@ export type FulfillmentModuleOptions =
* The module provider to be registered
*/
resolve: string | ModuleProviderExports
options: {
/**
* key value pair of the provider name and the configuration to be passed to the provider constructor
*/
config: Record<string, unknown>
}
/**
* The id of the provider
*/
id: string
/**
* key value pair of the configuration to be passed to the provider constructor
*/
options?: Record<string, unknown>
}[]
}
@@ -10,13 +10,10 @@ let moduleOptions = {
process.cwd() +
"/integration-tests/__fixtures__/providers/default-provider"
),
id: "test-provider",
options: {
config: {
"test-provider": {
name: "Test provider",
channels: ["email"],
},
},
name: "Test provider",
channels: ["email"],
},
},
],
@@ -1,11 +1,5 @@
import { moduleProviderLoader } from "@medusajs/modules-sdk"
import {
DAL,
InferEntityType,
LoaderOptions,
ModuleProvider,
ModulesSdkTypes,
} from "@medusajs/types"
import { LoaderOptions, ModuleProvider, ModulesSdkTypes } from "@medusajs/types"
import {
ContainerRegistrationKeys,
lowerCaseFirst,
@@ -20,21 +14,19 @@ import {
import { Lifetime, asFunction, asValue } from "awilix"
const registrationFn = async (klass, container, pluginOptions) => {
Object.entries(pluginOptions.config || []).map(([name, config]) => {
container.register({
[NotificationProviderRegistrationPrefix + name]: asFunction(
(cradle) => new klass(cradle, config),
{
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}
),
})
container.registerAdd(
NotificationIdentifiersRegistrationName,
asValue(name)
)
container.register({
[NotificationProviderRegistrationPrefix + pluginOptions.id]: asFunction(
(cradle) => new klass(cradle, pluginOptions.options ?? {}),
{
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}
),
})
container.registerAdd(
NotificationIdentifiersRegistrationName,
asValue(pluginOptions.id)
)
}
export default async ({
@@ -74,20 +66,17 @@ async function syncDatabaseProviders({
const logger = container.resolve(ContainerRegistrationKeys.LOGGER) ?? console
const normalizedProviders = providers.map((provider) => {
const [name, config] = Object.entries(
provider.options?.config as any
)?.[0] as any
if (!name) {
if (!provider.id) {
throw new Error(
"An entry in the provider config is required to initialize notification providers"
)
}
const id = name
const config = provider.options as { channels: string[] }
return {
id,
handle: name,
name: config?.name ?? name,
id: provider.id,
handle: provider.id,
name: provider.id,
is_enabled: true,
channels: config?.channels ?? [],
}
@@ -23,11 +23,13 @@ export type NotificationModuleOptions =
* The module provider to be registered
*/
resolve: string | ModuleProviderExports
options: {
/**
* key value pair of the provider name and the configuration to be passed to the provider constructor
*/
config: Record<string, unknown>
}
/**
* The id of the provider
*/
id: string
/**
* key value pair of the configuration to be passed to the provider constructor
*/
options?: Record<string, unknown>
}[]
}
@@ -11,17 +11,15 @@ import * as providers from "../providers"
import { PaymentProviderService } from "@services"
const registrationFn = async (klass, container, pluginOptions) => {
Object.entries(pluginOptions.config || []).map(([name, config]) => {
const key = `pp_${klass.PROVIDER}_${name}`
const key = `pp_${klass.PROVIDER}_${pluginOptions.id}`
container.register({
[key]: asFunction((cradle) => new klass(cradle, config), {
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}),
})
container.registerAdd("payment_providers", asValue(key))
container.register({
[key]: asFunction((cradle) => new klass(cradle, pluginOptions.options), {
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}),
})
container.registerAdd("payment_providers", asValue(key))
}
export default async ({
@@ -35,7 +33,7 @@ export default async ({
>): Promise<void> => {
// Local providers
for (const provider of Object.values(providers)) {
await registrationFn(provider, container, { config: { default: {} } })
await registrationFn(provider, container, { id: "default" })
}
await moduleProviderLoader({
+8 -6
View File
@@ -17,11 +17,13 @@ export type PaymentModuleOptions = Partial<ModuleServiceInitializeOptions> & {
* The module provider to be registered
*/
resolve: string | ModuleProviderExports
options: {
/**
* key value pair of the provider name and the configuration to be passed to the provider constructor
*/
config: Record<string, unknown>
}
/**
* The id of the provider
*/
id: string
/**
* key value pair of the configuration to be passed to the provider constructor
*/
options?: Record<string, unknown>
}[]
}