chore(): Reorganize modules (#7210)

**What**
Move all modules to the modules directory
This commit is contained in:
Adrien de Peretti
2024-05-02 17:33:34 +02:00
committed by GitHub
parent 7a351eef09
commit 4eae25e1ef
870 changed files with 91 additions and 62 deletions

View File

@@ -0,0 +1,13 @@
import { moduleDefinition } from "./module-definition"
import { initializeFactory, Modules } from "@medusajs/modules-sdk"
export * from "./types"
export * from "./services"
export const initialize = initializeFactory({
moduleName: Modules.FILE,
moduleDefinition,
})
export const runMigrations = moduleDefinition.runMigrations
export const revertMigration = moduleDefinition.revertMigration
export default moduleDefinition

View File

@@ -0,0 +1,22 @@
import { Modules } from "@medusajs/modules-sdk"
import { ModuleJoinerConfig } from "@medusajs/types"
import { MapToConfig } from "@medusajs/utils"
export const LinkableKeys = {}
const entityLinkableKeysMap: MapToConfig = {}
export const entityNameToLinkableKeysMap: MapToConfig = entityLinkableKeysMap
export const joinerConfig: ModuleJoinerConfig = {
serviceName: Modules.FILE,
primaryKeys: ["id"],
linkableKeys: LinkableKeys,
alias: [
{
name: ["file", "files"],
args: {
entity: "File",
},
},
],
}

View File

@@ -0,0 +1,41 @@
import { moduleProviderLoader } from "@medusajs/modules-sdk"
import { LoaderOptions, ModuleProvider, ModulesSdkTypes } from "@medusajs/types"
import { FileProviderService } from "@services"
import {
FileProviderIdentifierRegistrationName,
FileProviderRegistrationPrefix,
} from "@types"
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)
container.register({
[FileProviderRegistrationPrefix + key]: asFunction(
(cradle) => new klass(cradle, config),
{
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}
),
})
container.registerAdd(FileProviderIdentifierRegistrationName, asValue(key))
})
}
export default async ({
container,
options,
}: LoaderOptions<
(
| ModulesSdkTypes.ModuleServiceInitializeOptions
| ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions
) & { providers: ModuleProvider[] }
>): Promise<void> => {
await moduleProviderLoader({
container,
providers: options?.providers || [],
registerServiceFn: registrationFn,
})
}

View File

@@ -0,0 +1,28 @@
import { ModuleExports } from "@medusajs/types"
import { FileModuleService } from "@services"
import loadProviders from "./loaders/providers"
import * as ModuleServices from "@services"
import { ModulesSdkUtils } from "@medusajs/utils"
export const runMigrations = () => {
return Promise.resolve()
}
export const revertMigration = () => {
return Promise.resolve()
}
const containerLoader = ModulesSdkUtils.moduleContainerLoaderFactory({
moduleModels: {},
moduleRepositories: {},
moduleServices: ModuleServices,
})
const loaders = [containerLoader, loadProviders] as any
const service = FileModuleService
export const moduleDefinition: ModuleExports = {
service,
loaders,
runMigrations,
revertMigration,
}

View File

@@ -0,0 +1,3 @@
describe("File service", function () {
it("noop", async function () {})
})

View File

@@ -0,0 +1,131 @@
import {
Context,
CreateFileDTO,
FileDTO,
ModuleJoinerConfig,
FileTypes,
FilterableFileProps,
FindConfig,
} from "@medusajs/types"
import { joinerConfig } from "../joiner-config"
import FileProviderService from "./file-provider-service"
import { MedusaError } from "medusa-core-utils"
type InjectedDependencies = {
fileProviderService: FileProviderService
}
export default class FileModuleService implements FileTypes.IFileModuleService {
protected readonly fileProviderService_: FileProviderService
constructor({ fileProviderService }: InjectedDependencies) {
this.fileProviderService_ = fileProviderService
}
__joinerConfig(): ModuleJoinerConfig {
return joinerConfig
}
create(data: CreateFileDTO[], sharedContext?: Context): Promise<FileDTO[]>
create(data: CreateFileDTO, sharedContext?: Context): Promise<FileDTO>
async create(
data: CreateFileDTO[] | CreateFileDTO
): Promise<FileDTO[] | FileDTO> {
const input = Array.isArray(data) ? data : [data]
// TODO: Validate file mime type, have config for allowed types
const files = await Promise.all(
input.map((file) => this.fileProviderService_.upload(file))
)
const result = files.map((file) => ({
id: file.key,
url: file.url,
}))
return Array.isArray(data) ? result : result[0]
}
async delete(ids: string[], sharedContext?: Context): Promise<void>
async delete(id: string, sharedContext?: Context): Promise<void>
async delete(ids: string[] | string): Promise<void> {
const input = Array.isArray(ids) ? ids : [ids]
await Promise.all(
input.map((id) => this.fileProviderService_.delete({ fileKey: id }))
)
return
}
async retrieve(id: string): Promise<FileDTO> {
const res = await this.fileProviderService_.getPresignedDownloadUrl({
fileKey: id,
})
return {
id,
url: res,
}
}
async list(
filters?: FilterableFileProps,
config?: FindConfig<FileDTO>,
sharedContext?: Context
): Promise<FileDTO[]> {
const id = Array.isArray(filters?.id) ? filters?.id?.[0] : filters?.id
if (!id) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Listing of files is only supported when filtering by ID."
)
}
const res = await this.fileProviderService_.getPresignedDownloadUrl({
fileKey: id,
})
if (!res) {
return []
}
return [
{
id,
url: res,
},
]
}
async listAndCount(
filters?: FilterableFileProps,
config?: FindConfig<FileDTO>,
sharedContext?: Context
): Promise<[FileDTO[], number]> {
const id = Array.isArray(filters?.id) ? filters?.id?.[0] : filters?.id
if (!id) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Listing and counting of files is only supported when filtering by ID."
)
}
const res = await this.fileProviderService_.getPresignedDownloadUrl({
fileKey: id,
})
if (!res) {
return [[], 0]
}
return [
[
{
id,
url: res,
},
],
1,
]
}
}

View File

@@ -0,0 +1,51 @@
import { Constructor, DAL, FileTypes } from "@medusajs/types"
import { MedusaError } from "medusa-core-utils"
import { FileProviderRegistrationPrefix } from "@types"
type InjectedDependencies = {
[
key: `${typeof FileProviderRegistrationPrefix}${string}`
]: FileTypes.IFileProvider
}
export default class FileProviderService {
protected readonly fileProvider_: FileTypes.IFileProvider
constructor(container: InjectedDependencies) {
const fileProviderKeys = Object.keys(container).filter((k) =>
k.startsWith(FileProviderRegistrationPrefix)
)
if (fileProviderKeys.length !== 1) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`File module should be initialized with exactly one provider`
)
}
this.fileProvider_ = container[fileProviderKeys[0]]
}
static getRegistrationIdentifier(
providerClass: Constructor<FileTypes.IFileProvider>,
optionName?: string
) {
return `${(providerClass as any).identifier}_${optionName}`
}
upload(
file: FileTypes.ProviderUploadFileDTO
): Promise<FileTypes.ProviderFileResultDTO> {
return this.fileProvider_.upload(file)
}
delete(fileData: FileTypes.ProviderDeleteFileDTO): Promise<void> {
return this.fileProvider_.delete(fileData)
}
getPresignedDownloadUrl(
fileData: FileTypes.ProviderGetFileDTO
): Promise<string> {
return this.fileProvider_.getPresignedDownloadUrl(fileData)
}
}

View File

@@ -0,0 +1,2 @@
export { default as FileModuleService } from "./file-module-service"
export { default as FileProviderService } from "./file-provider-service"

View File

@@ -0,0 +1,27 @@
import {
ModuleProviderExports,
ModuleServiceInitializeOptions,
} from "@medusajs/types"
export const FileProviderIdentifierRegistrationName =
"file_providers_identifier"
export const FileProviderRegistrationPrefix = "fs_"
export type FileModuleOptions = Partial<ModuleServiceInitializeOptions> & {
/**
* Providers to be registered
*/
provider?: {
/**
* 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>
}
}
}