feat(medusa): Extend file-service interface + move to core (#1577)
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
import aws from "aws-sdk"
|
import aws from "aws-sdk"
|
||||||
import { FileService } from "medusa-interfaces"
|
import { AbstractFileService } from '@medusajs/medusa'
|
||||||
|
|
||||||
class MinioService extends FileService {
|
class MinioService extends AbstractFileService {
|
||||||
|
|
||||||
constructor({}, options) {
|
constructor({}, options) {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
@@ -15,14 +16,14 @@ class MinioService extends FileService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
upload(file) {
|
upload(file) {
|
||||||
aws.config.setPromisesDependency()
|
aws.config.setPromisesDependency(null)
|
||||||
aws.config.update({
|
aws.config.update({
|
||||||
accessKeyId: this.accessKeyId_,
|
accessKeyId: this.accessKeyId_,
|
||||||
secretAccessKey: this.secretAccessKey_,
|
secretAccessKey: this.secretAccessKey_,
|
||||||
endpoint: this.endpoint_,
|
endpoint: this.endpoint_,
|
||||||
s3ForcePathStyle: this.s3ForcePathStyle_,
|
s3ForcePathStyle: this.s3ForcePathStyle_,
|
||||||
signatureVersion: this.signatureVersion_,
|
signatureVersion: this.signatureVersion_,
|
||||||
})
|
}, true)
|
||||||
|
|
||||||
const s3 = new aws.S3()
|
const s3 = new aws.S3()
|
||||||
const params = {
|
const params = {
|
||||||
@@ -46,14 +47,14 @@ class MinioService extends FileService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete(file) {
|
delete(file) {
|
||||||
aws.config.setPromisesDependency()
|
aws.config.setPromisesDependency(null)
|
||||||
aws.config.update({
|
aws.config.update({
|
||||||
accessKeyId: this.accessKeyId_,
|
accessKeyId: this.accessKeyId_,
|
||||||
secretAccessKey: this.secretAccessKey_,
|
secretAccessKey: this.secretAccessKey_,
|
||||||
endpoint: this.endpoint_,
|
endpoint: this.endpoint_,
|
||||||
s3ForcePathStyle: this.s3ForcePathStyle_,
|
s3ForcePathStyle: this.s3ForcePathStyle_,
|
||||||
signatureVersion: this.signatureVersion_,
|
signatureVersion: this.signatureVersion_,
|
||||||
})
|
}, true)
|
||||||
|
|
||||||
const s3 = new aws.S3()
|
const s3 = new aws.S3()
|
||||||
const params = {
|
const params = {
|
||||||
@@ -71,6 +72,18 @@ class MinioService extends FileService {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getUploadStreamDescriptor(fileData) {
|
||||||
|
throw new Error("Method not implemented.")
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDownloadStream(fileData) {
|
||||||
|
throw new Error("Method not implemented.")
|
||||||
|
}
|
||||||
|
|
||||||
|
async getPresignedDownloadUrl(fileData) {
|
||||||
|
throw new Error("Method not implemented.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MinioService
|
export default MinioService
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
import aws from "aws-sdk"
|
import aws from "aws-sdk"
|
||||||
import { FileService } from "medusa-interfaces"
|
import { AbstractFileService } from '@medusajs/medusa'
|
||||||
|
|
||||||
class S3Service extends FileService {
|
class S3Service extends AbstractFileService {
|
||||||
constructor({}, options) {
|
constructor({}, options) {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
@@ -15,13 +15,13 @@ class S3Service extends FileService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
upload(file) {
|
upload(file) {
|
||||||
aws.config.setPromisesDependency()
|
aws.config.setPromisesDependency(null)
|
||||||
aws.config.update({
|
aws.config.update({
|
||||||
accessKeyId: this.accessKeyId_,
|
accessKeyId: this.accessKeyId_,
|
||||||
secretAccessKey: this.secretAccessKey_,
|
secretAccessKey: this.secretAccessKey_,
|
||||||
region: this.region_,
|
region: this.region_,
|
||||||
endpoint: this.endpoint_,
|
endpoint: this.endpoint_,
|
||||||
})
|
}, true)
|
||||||
|
|
||||||
const s3 = new aws.S3()
|
const s3 = new aws.S3()
|
||||||
var params = {
|
var params = {
|
||||||
@@ -44,13 +44,13 @@ class S3Service extends FileService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete(file) {
|
delete(file) {
|
||||||
aws.config.setPromisesDependency()
|
aws.config.setPromisesDependency(null)
|
||||||
aws.config.update({
|
aws.config.update({
|
||||||
accessKeyId: this.accessKeyId_,
|
accessKeyId: this.accessKeyId_,
|
||||||
secretAccessKey: this.secretAccessKey_,
|
secretAccessKey: this.secretAccessKey_,
|
||||||
region: this.region_,
|
region: this.region_,
|
||||||
endpoint: this.endpoint_,
|
endpoint: this.endpoint_,
|
||||||
})
|
}, true)
|
||||||
|
|
||||||
const s3 = new aws.S3()
|
const s3 = new aws.S3()
|
||||||
var params = {
|
var params = {
|
||||||
@@ -68,6 +68,18 @@ class S3Service extends FileService {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getUploadStreamDescriptor(fileData) {
|
||||||
|
throw new Error("Method not implemented.")
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDownloadStream(fileData) {
|
||||||
|
throw new Error("Method not implemented.")
|
||||||
|
}
|
||||||
|
|
||||||
|
async getPresignedDownloadUrl(fileData) {
|
||||||
|
throw new Error("Method not implemented.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default S3Service
|
export default S3Service
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
import aws from "aws-sdk"
|
import aws from "aws-sdk"
|
||||||
import { parse } from "path"
|
import { parse } from "path"
|
||||||
import { FileService } from "medusa-interfaces"
|
import { AbstractFileService, FileServiceUploadResult } from "@medusajs/medusa"
|
||||||
|
import { EntityManager } from "typeorm"
|
||||||
|
import stream from "stream"
|
||||||
|
|
||||||
class DigitalOceanService extends FileService {
|
class DigitalOceanService extends AbstractFileService {
|
||||||
constructor({}, options) {
|
constructor({}, options) {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
@@ -16,13 +18,16 @@ class DigitalOceanService extends FileService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
upload(file) {
|
upload(file) {
|
||||||
aws.config.setPromisesDependency()
|
aws.config.setPromisesDependency(null)
|
||||||
aws.config.update({
|
aws.config.update(
|
||||||
accessKeyId: this.accessKeyId_,
|
{
|
||||||
secretAccessKey: this.secretAccessKey_,
|
accessKeyId: this.accessKeyId_,
|
||||||
region: this.region_,
|
secretAccessKey: this.secretAccessKey_,
|
||||||
endpoint: this.endpoint_,
|
region: this.region_,
|
||||||
})
|
endpoint: this.endpoint_,
|
||||||
|
},
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
const parsedFilename = parse(file.originalname)
|
const parsedFilename = parse(file.originalname)
|
||||||
const fileKey = `${parsedFilename.name}-${Date.now()}${parsedFilename.ext}`
|
const fileKey = `${parsedFilename.name}-${Date.now()}${parsedFilename.ext}`
|
||||||
@@ -51,13 +56,16 @@ class DigitalOceanService extends FileService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete(file) {
|
delete(file) {
|
||||||
aws.config.setPromisesDependency()
|
aws.config.setPromisesDependency(null)
|
||||||
aws.config.update({
|
aws.config.update(
|
||||||
accessKeyId: this.accessKeyId_,
|
{
|
||||||
secretAccessKey: this.secretAccessKey_,
|
accessKeyId: this.accessKeyId_,
|
||||||
region: this.region_,
|
secretAccessKey: this.secretAccessKey_,
|
||||||
endpoint: this.endpoint_,
|
region: this.region_,
|
||||||
})
|
endpoint: this.endpoint_,
|
||||||
|
},
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
const s3 = new aws.S3()
|
const s3 = new aws.S3()
|
||||||
var params = {
|
var params = {
|
||||||
@@ -75,6 +83,18 @@ class DigitalOceanService extends FileService {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getUploadStreamDescriptor(fileData) {
|
||||||
|
throw new Error("Method not implemented.")
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDownloadStream(fileData) {
|
||||||
|
throw new Error("Method not implemented.")
|
||||||
|
}
|
||||||
|
|
||||||
|
async getPresignedDownloadUrl(fileData) {
|
||||||
|
throw new Error("Method not implemented.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DigitalOceanService
|
export default DigitalOceanService
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
"@babel/core": "^7.14.3",
|
"@babel/core": "^7.14.3",
|
||||||
"@babel/preset-typescript": "^7.13.0",
|
"@babel/preset-typescript": "^7.13.0",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
|
"@types/multer": "^1.4.7",
|
||||||
"@types/jest": "^27.5.0",
|
"@types/jest": "^27.5.0",
|
||||||
"@types/jsonwebtoken": "^8.5.5",
|
"@types/jsonwebtoken": "^8.5.5",
|
||||||
"babel-preset-medusa-package": "^1.1.19",
|
"babel-preset-medusa-package": "^1.1.19",
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import stream from "stream"
|
||||||
|
import { TransactionBaseService } from "./transaction-base-service"
|
||||||
|
|
||||||
|
export type FileServiceUploadResult = {
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FileServiceGetUploadStreamResult = {
|
||||||
|
writeStream: stream.PassThrough
|
||||||
|
promise: Promise<any>
|
||||||
|
url: string
|
||||||
|
fileKey: string
|
||||||
|
[x: string]: unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
export type GetUploadedFileType = {
|
||||||
|
fileKey: string
|
||||||
|
[x: string]: unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UploadStreamDescriptorType = {
|
||||||
|
name: string
|
||||||
|
ext?: string
|
||||||
|
acl?: string
|
||||||
|
[x: string]: unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IFileService<T extends TransactionBaseService<any>>
|
||||||
|
extends TransactionBaseService<T> {
|
||||||
|
/**
|
||||||
|
* upload file to fileservice
|
||||||
|
* @param file Multer file from express multipart/form-data
|
||||||
|
* */
|
||||||
|
upload(file: Express.Multer.File): Promise<FileServiceUploadResult>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove file from fileservice
|
||||||
|
* @param fileData Remove file described by record
|
||||||
|
* */
|
||||||
|
delete(fileData: Record<string, any>): void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* upload file to fileservice from stream
|
||||||
|
* @param fileData file metadata relevant for fileservice to create and upload the file
|
||||||
|
* @param fileStream readable stream of the file to upload
|
||||||
|
* */
|
||||||
|
getUploadStreamDescriptor(
|
||||||
|
fileData: UploadStreamDescriptorType
|
||||||
|
): Promise<FileServiceGetUploadStreamResult>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* download file from fileservice as stream
|
||||||
|
* @param fileData file metadata relevant for fileservice to download the file
|
||||||
|
* @returns readable stream of the file to download
|
||||||
|
* */
|
||||||
|
getDownloadStream(
|
||||||
|
fileData: GetUploadedFileType
|
||||||
|
): Promise<NodeJS.ReadableStream>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a presigned download url to obtain a file
|
||||||
|
* @param fileData file metadata relevant for fileservice to download the file
|
||||||
|
* @returns presigned url to download the file
|
||||||
|
* */
|
||||||
|
getPresignedDownloadUrl(fileData: GetUploadedFileType): Promise<string>
|
||||||
|
}
|
||||||
|
export abstract class AbstractFileService<T extends TransactionBaseService<any>>
|
||||||
|
extends TransactionBaseService<T>
|
||||||
|
implements IFileService<T>
|
||||||
|
{
|
||||||
|
abstract upload(
|
||||||
|
fileData: Express.Multer.File
|
||||||
|
): Promise<FileServiceUploadResult>
|
||||||
|
|
||||||
|
abstract delete(fileData: Record<string, any>): void
|
||||||
|
|
||||||
|
abstract getUploadStreamDescriptor(
|
||||||
|
fileData: UploadStreamDescriptorType
|
||||||
|
): Promise<FileServiceGetUploadStreamResult>
|
||||||
|
|
||||||
|
abstract getDownloadStream(
|
||||||
|
fileData: GetUploadedFileType
|
||||||
|
): Promise<NodeJS.ReadableStream>
|
||||||
|
|
||||||
|
abstract getPresignedDownloadUrl(
|
||||||
|
fileData: GetUploadedFileType
|
||||||
|
): Promise<string>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isFileService = (object: unknown): boolean => {
|
||||||
|
return object instanceof AbstractFileService
|
||||||
|
}
|
||||||
@@ -2,5 +2,6 @@ export * from "./tax-calculation-strategy"
|
|||||||
export * from "./cart-completion-strategy"
|
export * from "./cart-completion-strategy"
|
||||||
export * from "./tax-service"
|
export * from "./tax-service"
|
||||||
export * from "./transaction-base-service"
|
export * from "./transaction-base-service"
|
||||||
|
export * from "./file-service"
|
||||||
export * from "./models/base-entity"
|
export * from "./models/base-entity"
|
||||||
export * from "./models/soft-deletable-entity"
|
export * from "./models/soft-deletable-entity"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import glob from "glob"
|
import glob from "glob"
|
||||||
import { Express } from 'express'
|
import { Express } from "express"
|
||||||
import { EntitySchema } from "typeorm"
|
import { EntitySchema } from "typeorm"
|
||||||
import {
|
import {
|
||||||
BaseService,
|
BaseService,
|
||||||
@@ -16,9 +16,20 @@ 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 {
|
||||||
|
AbstractFileService,
|
||||||
|
AbstractTaxService,
|
||||||
|
isFileService,
|
||||||
|
isTaxCalculationStrategy,
|
||||||
|
TransactionBaseService,
|
||||||
|
} from "../interfaces"
|
||||||
import formatRegistrationName from "../utils/format-registration-name"
|
import formatRegistrationName from "../utils/format-registration-name"
|
||||||
import { ClassConstructor, ConfigModule, Logger, MedusaContainer } from "../types/global"
|
import {
|
||||||
|
ClassConstructor,
|
||||||
|
ConfigModule,
|
||||||
|
Logger,
|
||||||
|
MedusaContainer,
|
||||||
|
} from "../types/global"
|
||||||
import { MiddlewareService } from "../services"
|
import { MiddlewareService } from "../services"
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
@@ -40,7 +51,13 @@ type PluginDetails = {
|
|||||||
/**
|
/**
|
||||||
* Registers all services in the services directory
|
* Registers all services in the services directory
|
||||||
*/
|
*/
|
||||||
export default async ({ rootDirectory, container, app, configModule, activityId }: Options): Promise<void> => {
|
export default async ({
|
||||||
|
rootDirectory,
|
||||||
|
container,
|
||||||
|
app,
|
||||||
|
configModule,
|
||||||
|
activityId,
|
||||||
|
}: Options): Promise<void> => {
|
||||||
const resolved = getResolvedPlugins(rootDirectory, configModule) || []
|
const resolved = getResolvedPlugins(rootDirectory, configModule) || []
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
@@ -59,7 +76,10 @@ export default async ({ rootDirectory, container, app, configModule, activityId
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getResolvedPlugins(rootDirectory: string, configModule: ConfigModule): undefined | PluginDetails[] {
|
function getResolvedPlugins(
|
||||||
|
rootDirectory: string,
|
||||||
|
configModule: ConfigModule
|
||||||
|
): undefined | PluginDetails[] {
|
||||||
const { plugins } = configModule
|
const { plugins } = configModule
|
||||||
|
|
||||||
const resolved = plugins.map((plugin) => {
|
const resolved = plugins.map((plugin) => {
|
||||||
@@ -85,10 +105,14 @@ function getResolvedPlugins(rootDirectory: string, configModule: ConfigModule):
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function registerPluginModels({
|
export async function registerPluginModels({
|
||||||
rootDirectory,
|
rootDirectory,
|
||||||
container,
|
container,
|
||||||
configModule
|
configModule,
|
||||||
}: { rootDirectory: string; container: MedusaContainer; configModule: ConfigModule; }): Promise<void> {
|
}: {
|
||||||
|
rootDirectory: string
|
||||||
|
container: MedusaContainer
|
||||||
|
configModule: ConfigModule
|
||||||
|
}): Promise<void> {
|
||||||
const resolved = getResolvedPlugins(rootDirectory, configModule) || []
|
const resolved = getResolvedPlugins(rootDirectory, configModule) || []
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
resolved.map(async (pluginDetails) => {
|
resolved.map(async (pluginDetails) => {
|
||||||
@@ -97,7 +121,10 @@ export async function registerPluginModels({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runLoaders(pluginDetails: PluginDetails, container: MedusaContainer): Promise<void> {
|
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`,
|
||||||
{}
|
{}
|
||||||
@@ -118,12 +145,18 @@ async function runLoaders(pluginDetails: PluginDetails, container: MedusaContain
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerMedusaApi(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
function registerMedusaApi(
|
||||||
|
pluginDetails: PluginDetails,
|
||||||
|
container: MedusaContainer
|
||||||
|
): void {
|
||||||
registerMedusaMiddleware(pluginDetails, container)
|
registerMedusaMiddleware(pluginDetails, container)
|
||||||
registerStrategies(pluginDetails, container)
|
registerStrategies(pluginDetails, container)
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerStrategies(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
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`
|
||||||
@@ -150,7 +183,10 @@ function registerStrategies(pluginDetails: PluginDetails, container: MedusaConta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerMedusaMiddleware(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
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
|
||||||
@@ -158,7 +194,8 @@ function registerMedusaMiddleware(pluginDetails: PluginDetails, container: Medus
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const middlewareService = container.resolve<MiddlewareService>("middlewareService")
|
const middlewareService =
|
||||||
|
container.resolve<MiddlewareService>("middlewareService")
|
||||||
if (module.postAuthentication) {
|
if (module.postAuthentication) {
|
||||||
middlewareService.addPostAuthentication(
|
middlewareService.addPostAuthentication(
|
||||||
module.postAuthentication,
|
module.postAuthentication,
|
||||||
@@ -178,8 +215,12 @@ function registerMedusaMiddleware(pluginDetails: PluginDetails, container: Medus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerCoreRouters(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
function registerCoreRouters(
|
||||||
const middlewareService = container.resolve<MiddlewareService>("middlewareService")
|
pluginDetails: PluginDetails,
|
||||||
|
container: MedusaContainer
|
||||||
|
): void {
|
||||||
|
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`, {})
|
||||||
@@ -245,16 +286,22 @@ function registerApi(
|
|||||||
* registered
|
* registered
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
export async function registerServices(pluginDetails: PluginDetails, container: MedusaContainer): Promise<void> {
|
export async function registerServices(
|
||||||
|
pluginDetails: PluginDetails,
|
||||||
|
container: MedusaContainer
|
||||||
|
): Promise<void> {
|
||||||
const files = glob.sync(`${pluginDetails.resolve}/services/[!__]*.js`, {})
|
const files = glob.sync(`${pluginDetails.resolve}/services/[!__]*.js`, {})
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
files.map(async (fn) => {
|
files.map(async (fn) => {
|
||||||
const loaded = require(fn).default
|
const loaded = require(fn).default
|
||||||
const name = formatRegistrationName(fn)
|
const name = formatRegistrationName(fn)
|
||||||
|
|
||||||
if (!(loaded.prototype instanceof BaseService)) {
|
if (
|
||||||
|
!(loaded.prototype instanceof BaseService) &&
|
||||||
|
!(loaded.prototype instanceof TransactionBaseService)
|
||||||
|
) {
|
||||||
const logger = container.resolve<Logger>("logger")
|
const logger = container.resolve<Logger>("logger")
|
||||||
const message = `Services must inherit from BaseService, please check ${fn}`
|
const message = `File must be a valid service implementation, please check ${fn}`
|
||||||
logger.error(message)
|
logger.error(message)
|
||||||
throw new Error(message)
|
throw new Error(message)
|
||||||
}
|
}
|
||||||
@@ -277,7 +324,8 @@ export async function registerServices(pluginDetails: PluginDetails, container:
|
|||||||
} else if (loaded.prototype instanceof OauthService) {
|
} else if (loaded.prototype instanceof OauthService) {
|
||||||
const appDetails = loaded.getAppDetails(pluginDetails.options)
|
const appDetails = loaded.getAppDetails(pluginDetails.options)
|
||||||
|
|
||||||
const oauthService = container.resolve<typeof OauthService>("oauthService")
|
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
|
||||||
@@ -324,6 +372,15 @@ export async function registerServices(pluginDetails: PluginDetails, container:
|
|||||||
),
|
),
|
||||||
[`fileService`]: aliasTo(name),
|
[`fileService`]: aliasTo(name),
|
||||||
})
|
})
|
||||||
|
} else if (isFileService(loaded.prototype)) {
|
||||||
|
// Add the service directly to the container in order to make simple
|
||||||
|
// resolution if we already know which file storage provider we need to use
|
||||||
|
container.register({
|
||||||
|
[name]: asFunction(
|
||||||
|
(cradle) => new loaded(cradle, pluginDetails.options)
|
||||||
|
),
|
||||||
|
[`fileService`]: aliasTo(name),
|
||||||
|
})
|
||||||
} else if (loaded.prototype instanceof SearchService) {
|
} else if (loaded.prototype instanceof SearchService) {
|
||||||
// Add the service directly to the container in order to make simple
|
// Add the service directly to the container in order to make simple
|
||||||
// resolution if we already know which search provider we need to use
|
// resolution if we already know which search provider we need to use
|
||||||
@@ -365,7 +422,10 @@ export async function registerServices(pluginDetails: PluginDetails, container:
|
|||||||
* registered
|
* registered
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function registerSubscribers(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
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
|
||||||
@@ -387,19 +447,24 @@ function registerSubscribers(pluginDetails: PluginDetails, container: MedusaCont
|
|||||||
* registered
|
* registered
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function registerRepositories(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
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) as ClassConstructor<unknown>
|
const loaded = require(fn) as ClassConstructor<unknown>
|
||||||
|
|
||||||
Object.entries(loaded).map(([, val]: [string, ClassConstructor<unknown>]) => {
|
Object.entries(loaded).map(
|
||||||
if (typeof val === "function") {
|
([, val]: [string, ClassConstructor<unknown>]) => {
|
||||||
const name = formatRegistrationName(fn)
|
if (typeof val === "function") {
|
||||||
container.register({
|
const name = formatRegistrationName(fn)
|
||||||
[name]: asClass(val),
|
container.register({
|
||||||
})
|
[name]: asClass(val),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,21 +479,26 @@ function registerRepositories(pluginDetails: PluginDetails, container: MedusaCon
|
|||||||
* registered
|
* registered
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function registerModels(pluginDetails: PluginDetails, container: MedusaContainer): void {
|
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) as ClassConstructor<unknown> | EntitySchema
|
const loaded = require(fn) as ClassConstructor<unknown> | EntitySchema
|
||||||
|
|
||||||
Object.entries(loaded).map(([, val]: [string, ClassConstructor<unknown> | EntitySchema]) => {
|
Object.entries(loaded).map(
|
||||||
if (typeof val === "function" || val instanceof EntitySchema) {
|
([, val]: [string, ClassConstructor<unknown> | EntitySchema]) => {
|
||||||
const name = formatRegistrationName(fn)
|
if (typeof val === "function" || val instanceof EntitySchema) {
|
||||||
container.register({
|
const name = formatRegistrationName(fn)
|
||||||
[name]: asValue(val),
|
container.register({
|
||||||
})
|
[name]: asValue(val),
|
||||||
|
})
|
||||||
|
|
||||||
container.registerAdd("db_entities", asValue(val))
|
container.registerAdd("db_entities", asValue(val))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,11 +516,11 @@ function createPluginId(name: string): string {
|
|||||||
* @return {object} the plugin details
|
* @return {object} the plugin details
|
||||||
*/
|
*/
|
||||||
function resolvePlugin(pluginName: string): {
|
function resolvePlugin(pluginName: string): {
|
||||||
resolve: string;
|
resolve: string
|
||||||
id: string;
|
id: string
|
||||||
name: string;
|
name: string
|
||||||
options: Record<string, unknown>
|
options: Record<string, unknown>
|
||||||
version: string;
|
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)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user