Core utilities for Medusa e-commerce platform including error handling, DI container, amount calculations, and configuration parsing
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Enhanced Awilix dependency injection container with additional registration patterns optimized for Medusa's service architecture, including array-based registration and scoped container creation.
Extended Awilix container type with additional methods for enhanced dependency injection patterns.
import { AwilixContainer } from "awilix";
type MedusaContainer = AwilixContainer & {
/** Register multiple services under the same name as an array */
registerAdd: <T>(name: string, registration: T) => MedusaContainer;
/** Create a scoped container with inherited registerAdd functionality */
createScope: () => MedusaContainer;
};Creates an enhanced Medusa container with additional registration capabilities.
/**
* Creates an enhanced Awilix container with additional registration methods
* @param args - Arguments passed to Awilix createContainer function
* @returns Enhanced container with registerAdd and enhanced createScope methods
*/
function createMedusaContainer(...args): MedusaContainer;Usage Examples:
import { createMedusaContainer } from "medusa-core-utils";
import { asClass, asFunction, asValue } from "awilix";
// Create a new container
const container = createMedusaContainer();
// Standard Awilix registration
container.register({
userService: asClass(UserService).singleton(),
database: asValue(databaseConnection),
logger: asFunction(() => new Logger()).singleton()
});
// Enhanced array-based registration with registerAdd
container.registerAdd("eventHandlers", asClass(UserCreatedHandler));
container.registerAdd("eventHandlers", asClass(UserUpdatedHandler));
container.registerAdd("eventHandlers", asClass(UserDeletedHandler));
// Resolve all event handlers as an array
const handlers = container.resolve("eventHandlers");
// handlers is an array containing instances of all registered handlers
// Create scoped containers
const requestScope = container.createScope();
requestScope.register({
requestId: asValue(generateRequestId()),
currentUser: asValue(user)
});Register multiple services under the same name, creating an array of resolved services.
/**
* Register a service to be added to an array of services under the given name
* @param name - The name to register the service under
* @param registration - The Awilix registration (asClass, asFunction, asValue)
* @returns The container instance for chaining
*/
registerAdd<T>(name: string, registration: T): MedusaContainer;Usage Examples:
import { createMedusaContainer } from "medusa-core-utils";
import { asClass, asFunction } from "awilix";
const container = createMedusaContainer();
// Register multiple middleware functions
container.registerAdd("middleware", asFunction(() => authMiddleware));
container.registerAdd("middleware", asFunction(() => loggingMiddleware));
container.registerAdd("middleware", asFunction(() => errorHandlingMiddleware));
// Register multiple validators
container.registerAdd("validators", asClass(EmailValidator));
container.registerAdd("validators", asClass(PhoneValidator));
container.registerAdd("validators", asClass(AddressValidator));
// Resolve all registered items as arrays
const middlewareList = container.resolve("middleware");
const validatorList = container.resolve("validators");
// Use in application
middlewareList.forEach(middleware => app.use(middleware));
validatorList.forEach(validator => registerValidator(validator));Create isolated container scopes that inherit from the parent container while maintaining enhanced functionality.
/**
* Create a scoped container that inherits registrations from parent
* @returns New scoped container with registerAdd functionality
*/
createScope(): MedusaContainer;Usage Examples:
import { createMedusaContainer } from "medusa-core-utils";
import { asValue, asClass } from "awilix";
const container = createMedusaContainer();
// Register global services
container.register({
database: asValue(databaseConnection),
logger: asClass(Logger).singleton()
});
// Create request-scoped container
app.use((req, res, next) => {
const requestScope = container.createScope();
// Add request-specific registrations
requestScope.register({
requestId: asValue(req.id),
currentUser: asValue(req.user),
requestLogger: asValue(logger.child({ requestId: req.id }))
});
// Request scope can still use registerAdd
requestScope.registerAdd("requestHandlers", asClass(AuthHandler));
requestScope.registerAdd("requestHandlers", asClass(ValidationHandler));
req.container = requestScope;
next();
});
// In route handlers
app.get("/users", (req, res) => {
const userService = req.container.resolve("userService");
const handlers = req.container.resolve("requestHandlers");
// Process request with scoped dependencies
});