JSPM

  • Created
  • Published
  • Downloads 43
  • Score
    100M100P100Q75562F
  • License MIT

Extends functionalities from medusajs

Package Exports

  • medusa-extender
  • medusa-extender/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (medusa-extender) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Medusa

Extend medusa to fit your needs

Awesome npm version

Getting started

Installation

npm i medusa-extender

Introduction

This packages exports the necessary bits and pieces to extend medusajs

Dependency graph

Dependency graph

Api doc

Read more about it

Usage

Medusa

Medusa is the entry point from medusa-extender and does not correspond to medusa itself

This is the main entry point that will allow to start your medusa server, including your custom extensions.

Here is an example of how it works

async function bootstrap() {
    const expressInstance = express();
    
    const rootDir = resolve(__dirname);
    await new Medusa(rootDir, expressInstance)
        .consume(
            // Your custom middlewares goes there
        )
        .load();
    
    expressInstance.listen(config.serverConfig.port, () => {
        logger.info('Server successfully started on port ' + config.serverConfig.port);
    });
}

bootstrap();

API

consume

This method take an array of MedusaMiddlewareStatic and return an instance of Medusa.

public consume(...middlewares: MedusaMiddlewareStatic[]): Medusa;

here is an example of a custom middleware that will be handled by medusa

import { NextFunction, Response } from 'express';
import {
    MedusaAuthenticatedRequest,
    MedusaMiddleware,
    MedusaResolverKeys,
    MedusaRouteOptions,
    MedusaUtils,
} from 'medusa-extender';

export default class MyCustomMiddleware
    implements MedusaMiddleware<typeof MyCustomMiddleware>
{
    // Indicate that it is a middleware that will be applied after the authentication
    public static isPostAuth = true;
    // Indicate that it is a middleware that should be handler by medusa. Otherwise it is manage by your project
    public static isHandledByMedusa = true;

    public static get routesOptions(): MedusaRouteOptions {
        return {
            path: '/admin/products/',
            method: 'post',
        };
    }

    public consume(options): (req: MedusaAuthenticatedRequest, res: Response, next: NextFunction) => void | Promise<void> {
        return (req: MedusaAuthenticatedRequest, res: Response, next: NextFunction): void => {
            // Your custom implementation goes here
            return next();
        };
    }
}

load

This basically start the medusa engine which comes from @medusa/medusa itself.

MedusaEventEmitter

this module allow you to emit event that will be then handled by your registered services in the medusa container. The main purpuse of it is to be able to intercept entity event and add custom login to them.

Usage

For that purpose an utility is provided that allow multiple to attach a new subscriver on the active connection handled by the medusa container.

Here is an example

@EventSubscriber()
export default class StoreSubscriber
    implements EntitySubscriberInterface<Store>, MedusaEntitySubscriber<typeof StoreSubscriber>
{
    static attachTo(connection: Connection): void {
        MedusaUtils.attachOrReplaceEntitySubscriber(connection, StoreSubscriber);
    }

    public listenTo(): typeof Store {
        return Store;
    }

    /**
     * Relay the event to the handlers.
     * @param event Event to pass to the event handler
     */
    public async beforeUpdate(event: UpdateEvent<Store>): Promise<any> {
        return await medusaEventEmitter.emitAsync(OnMedusaEvent.Before.UpdateEvent(Store), {
            event,
            transactionalEntityManager: event.manager,
        });
    }

    /**
     * Relay the event to the handlers.
     * @param event Event to pass to the event handler
     */
    public async beforeRemove(event: RemoveEvent<Store>): Promise<any> {
        return await medusaEventEmitter.emitAsync(OnMedusaEvent.Before.RemoveEvent(Store), {
            event,
            transactionalEntityManager: event.manager,
        });
    }
}

Those events will be attached attached/removed for each request to be sure that if any services are request scoped that you can access the actual cradle.

Types

Read more about it

Repository

When you create a new entity that extends an existing entity, you must create the appropriate repository that will reflect the new entity type but without breaking the original one used by medusa.

Usage

For that purpose an utility is provided that allow multiple class extension.

Here is an example

import { EntityRepository, Repository } from 'typeorm';
import { UserRepository as MedusaUserRepository } from '@medusajs/medusa/dist/repositories/user';
import { MedusaRepository, MedusaUtils } from 'medusa-extender';
import User from '../entities/user.entity';

@EntityRepository(User)
class UserRepository extends Repository<User> implements MedusaRepository<MedusaUserRepository, typeof UserRepository> {
    static overriddenType = MedusaUserRepository;
    static isHandledByMedusa = true;
}

export default MedusaUtils.repositoryMixin<User>(UserRepository, MedusaUserRepository);