Feat(medusa,modules-sdk): Modules SDK package (#3294)
This commit is contained in:
committed by
GitHub
parent
f3bf351d21
commit
ad7f56506f
3
.gitignore
vendored
3
.gitignore
vendored
@@ -19,4 +19,5 @@ www/**/.yarn/*
|
||||
|
||||
.idea
|
||||
.turbo
|
||||
build/**
|
||||
build/**
|
||||
**/dist
|
||||
@@ -24,6 +24,9 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^4.4.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@medusajs/modules-sdk": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"watch": "tsc --build --watch",
|
||||
"prepare": "cross-env NODE_ENV=production yarn run build",
|
||||
|
||||
@@ -2,7 +2,7 @@ import ConnectionLoader from "./loaders/connection"
|
||||
import InventoryService from "./services/inventory"
|
||||
import * as InventoryModels from "./models"
|
||||
import * as SchemaMigration from "./migrations/schema-migrations/1665748086258-inventory_setup"
|
||||
import { ModuleExports } from "@medusajs/medusa"
|
||||
import { ModuleExports } from "@medusajs/modules-sdk"
|
||||
|
||||
const service = InventoryService
|
||||
const migrations = [SchemaMigration]
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { ConfigurableModuleDeclaration, LoaderOptions } from "@medusajs/medusa"
|
||||
import {
|
||||
ConfigurableModuleDeclaration,
|
||||
LoaderOptions,
|
||||
} from "@medusajs/modules-sdk"
|
||||
|
||||
export default async (
|
||||
{ configModule }: LoaderOptions,
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import {
|
||||
ConfigurableModuleDeclaration,
|
||||
MODULE_RESOURCE_TYPE,
|
||||
} from "@medusajs/modules-sdk"
|
||||
|
||||
import {
|
||||
CreateInventoryItemInput,
|
||||
CreateInventoryLevelInput,
|
||||
CreateReservationItemInput,
|
||||
@@ -11,7 +15,6 @@ import {
|
||||
IInventoryService,
|
||||
InventoryItemDTO,
|
||||
InventoryLevelDTO,
|
||||
MODULE_RESOURCE_TYPE,
|
||||
ReservationItemDTO,
|
||||
TransactionBaseService,
|
||||
UpdateInventoryLevelInput,
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@medusajs/medusa-cli": "^1.3.8",
|
||||
"@medusajs/modules-sdk": "*",
|
||||
"@types/ioredis": "^4.28.10",
|
||||
"@types/lodash": "^4.14.191",
|
||||
"awilix": "^8.0.0",
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
} from "../../../../services"
|
||||
import { ExtendedStoreDTO } from "../../../../types/store"
|
||||
import { FlagRouter } from "../../../../utils/flag-router"
|
||||
import { ModulesHelper } from "../../../../utils/module-helper"
|
||||
import { ModulesHelper } from "@medusajs/modules-sdk"
|
||||
|
||||
/**
|
||||
* @oas [get] /admin/store
|
||||
|
||||
@@ -5,7 +5,7 @@ import { isString } from "lodash"
|
||||
import { sync as existsSync } from "fs-exists-cached"
|
||||
import { getConfigFile, createRequireFromPath } from "medusa-core-utils"
|
||||
import { handleConfigError } from "../../loaders/config"
|
||||
import registerModuleDefinitions from "../../loaders/module-definitions"
|
||||
import { registerModules } from "@medusajs/modules-sdk"
|
||||
|
||||
function createFileContentHash(path, files) {
|
||||
return path + files
|
||||
@@ -92,7 +92,7 @@ function resolvePlugin(pluginName) {
|
||||
export function getInternalModules(configModule) {
|
||||
const modules = []
|
||||
|
||||
const moduleResolutions = registerModuleDefinitions(configModule)
|
||||
const moduleResolutions = registerModules(configModule)
|
||||
|
||||
for (const moduleResolution of Object.values(moduleResolutions)) {
|
||||
if (
|
||||
|
||||
@@ -7,12 +7,14 @@ import "reflect-metadata"
|
||||
import supertest from "supertest"
|
||||
import apiLoader from "../loaders/api"
|
||||
import featureFlagLoader, { featureFlagRouter } from "../loaders/feature-flags"
|
||||
import { moduleHelper } from "../loaders/module"
|
||||
import {
|
||||
moduleLoader,
|
||||
moduleHelper,
|
||||
registerModules,
|
||||
} from "@medusajs/modules-sdk"
|
||||
import passportLoader from "../loaders/passport"
|
||||
import servicesLoader from "../loaders/services"
|
||||
import strategiesLoader from "../loaders/strategies"
|
||||
import registerModuleDefinitions from "../loaders/module-definitions"
|
||||
import moduleLoader from "../loaders/module"
|
||||
|
||||
const adminSessionOpts = {
|
||||
cookieName: "session",
|
||||
@@ -26,7 +28,7 @@ const clientSessionOpts = {
|
||||
secret: "test",
|
||||
}
|
||||
|
||||
const moduleResolutions = registerModuleDefinitions({})
|
||||
const moduleResolutions = registerModules({})
|
||||
const config = {
|
||||
projectConfig: {
|
||||
jwt_secret: "supersecret",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getConfigFile } from "medusa-core-utils"
|
||||
import { ConfigModule } from "../types/global"
|
||||
import logger from "./logger"
|
||||
import registerModuleDefinitions from "./module-definitions"
|
||||
import { registerModules } from "@medusajs/modules-sdk"
|
||||
|
||||
const isProduction = ["production", "prod"].includes(process.env.NODE_ENV || "")
|
||||
|
||||
@@ -65,7 +65,7 @@ export default (rootDirectory: string): ConfigModule => {
|
||||
)
|
||||
}
|
||||
|
||||
const moduleResolutions = registerModuleDefinitions(configModule)
|
||||
const moduleResolutions = registerModules(configModule)
|
||||
|
||||
return {
|
||||
projectConfig: {
|
||||
|
||||
@@ -21,7 +21,6 @@ import expressLoader from "./express"
|
||||
import featureFlagsLoader from "./feature-flags"
|
||||
import Logger from "./logger"
|
||||
import modelsLoader from "./models"
|
||||
import moduleLoader from "./module"
|
||||
import passportLoader from "./passport"
|
||||
import pluginsLoader, { registerPluginModels } from "./plugins"
|
||||
import redisLoader from "./redis"
|
||||
@@ -31,6 +30,8 @@ import servicesLoader from "./services"
|
||||
import strategiesLoader from "./strategies"
|
||||
import subscribersLoader from "./subscribers"
|
||||
|
||||
import { moduleLoader } from "@medusajs/modules-sdk"
|
||||
|
||||
type Options = {
|
||||
directory: string
|
||||
expressApp: Express
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
ConfigurableModuleDeclaration,
|
||||
ModuleResolution,
|
||||
} from "@medusajs/modules-sdk"
|
||||
import { AwilixContainer } from "awilix"
|
||||
import { Request } from "express"
|
||||
import { LoggerOptions } from "typeorm"
|
||||
@@ -38,69 +42,8 @@ export type Logger = _Logger & {
|
||||
warn: (msg: string) => void
|
||||
}
|
||||
|
||||
export enum MODULE_SCOPE {
|
||||
INTERNAL = "internal",
|
||||
EXTERNAL = "external",
|
||||
}
|
||||
|
||||
export enum MODULE_RESOURCE_TYPE {
|
||||
SHARED = "shared",
|
||||
ISOLATED = "isolated",
|
||||
}
|
||||
|
||||
export type ConfigurableModuleDeclaration = {
|
||||
scope: MODULE_SCOPE.INTERNAL
|
||||
resources: MODULE_RESOURCE_TYPE
|
||||
resolve?: string
|
||||
options?: Record<string, unknown>
|
||||
}
|
||||
/*
|
||||
| {
|
||||
scope: MODULE_SCOPE.external
|
||||
server: {
|
||||
type: "built-in" | "rest" | "tsrpc" | "grpc" | "gql"
|
||||
url: string
|
||||
options?: Record<string, unknown>
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
export type ModuleResolution = {
|
||||
resolutionPath: string | false
|
||||
definition: ModuleDefinition
|
||||
options?: Record<string, unknown>
|
||||
moduleDeclaration?: ConfigurableModuleDeclaration
|
||||
}
|
||||
|
||||
export type ModuleDefinition = {
|
||||
key: string
|
||||
registrationName: string
|
||||
defaultPackage: string | false
|
||||
label: string
|
||||
canOverride?: boolean
|
||||
isRequired?: boolean
|
||||
defaultModuleDeclaration: ConfigurableModuleDeclaration
|
||||
}
|
||||
|
||||
export type LoaderOptions = {
|
||||
container: MedusaContainer
|
||||
configModule: ConfigModule
|
||||
options?: Record<string, unknown>
|
||||
logger?: Logger
|
||||
}
|
||||
|
||||
export type Constructor<T> = new (...args: any[]) => T
|
||||
|
||||
export type ModuleExports = {
|
||||
loaders: ((
|
||||
options: LoaderOptions,
|
||||
moduleDeclaration?: ConfigurableModuleDeclaration
|
||||
) => Promise<void>)[]
|
||||
service: Constructor<any>
|
||||
migrations?: any[] // TODO: revisit migrations type
|
||||
models?: Constructor<any>[]
|
||||
}
|
||||
|
||||
type SessionOptions = {
|
||||
name?: string
|
||||
resave?: boolean
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* @schema ModulesResponse
|
||||
* type: array
|
||||
* items:
|
||||
* type: object
|
||||
* required:
|
||||
* - module
|
||||
* - resolution
|
||||
* properties:
|
||||
* module:
|
||||
* description: The key of the module.
|
||||
* type: string
|
||||
* resolution:
|
||||
* description: The resolution path of the module or false if module is not installed.
|
||||
* type: string
|
||||
*/
|
||||
export type ModulesResponse = {
|
||||
module: string
|
||||
resolution: string | false
|
||||
}[]
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Store, PaymentProvider, FulfillmentProvider } from "../models"
|
||||
import { FeatureFlagsResponse } from "./feature-flags"
|
||||
import { ModulesResponse } from "./modules"
|
||||
import { ModulesResponse } from "@medusajs/modules-sdk"
|
||||
|
||||
export type UpdateStoreInput = {
|
||||
name?: string
|
||||
@@ -13,6 +13,23 @@ export type UpdateStoreInput = {
|
||||
default_sales_channel_id?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @schema ModulesResponse
|
||||
* type: array
|
||||
* items:
|
||||
* type: object
|
||||
* required:
|
||||
* - module
|
||||
* - resolution
|
||||
* properties:
|
||||
* module:
|
||||
* description: The key of the module.
|
||||
* type: string
|
||||
* resolution:
|
||||
* description: The resolution path of the module or false if module is not installed.
|
||||
* type: string
|
||||
*/
|
||||
|
||||
/**
|
||||
* @schema ExtendedStoreDTO
|
||||
* allOf:
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"es5",
|
||||
"es6",
|
||||
"es2019"
|
||||
],
|
||||
"lib": ["es5", "es6", "es2019"],
|
||||
"target": "es5",
|
||||
"outDir": "./dist",
|
||||
"esModuleInterop": true,
|
||||
@@ -21,7 +17,7 @@
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"downlevelIteration": true, // to use ES5 specific tooling
|
||||
"resolveJsonModule": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["./src/**/*", "index.d.ts"],
|
||||
"exclude": [
|
||||
@@ -31,4 +27,4 @@
|
||||
"./src/**/__fixtures__",
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
13
packages/modules-sdk/jest.config.js
Normal file
13
packages/modules-sdk/jest.config.js
Normal file
@@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
globals: {
|
||||
"ts-jest": {
|
||||
tsConfig: "tsconfig.json",
|
||||
isolatedModules: false,
|
||||
},
|
||||
},
|
||||
transform: {
|
||||
"^.+\\.[jt]s?$": "ts-jest",
|
||||
},
|
||||
testEnvironment: `node`,
|
||||
moduleFileExtensions: [`js`, `ts`],
|
||||
}
|
||||
37
packages/modules-sdk/package.json
Normal file
37
packages/modules-sdk/package.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "@medusajs/modules-sdk",
|
||||
"version": "0.0.1",
|
||||
"description": "SDK for medusa modules",
|
||||
"main": "dist/index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/medusajs/medusa",
|
||||
"directory": "packages/modules-sdk"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"author": "Medusa",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"cross-env": "^5.2.1",
|
||||
"jest": "^25.5.4",
|
||||
"ts-jest": "^25.5.1",
|
||||
"typescript": "^4.4.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"awilix": "^8.0.0",
|
||||
"medusa-telemetry": "^0.0.16",
|
||||
"resolve-cwd": "^3.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "cross-env NODE_ENV=production yarn run build",
|
||||
"build": "tsc --build",
|
||||
"test": "jest",
|
||||
"test:unit": "jest"
|
||||
},
|
||||
"peerDependencies": {}
|
||||
}
|
||||
@@ -1,8 +1,4 @@
|
||||
import {
|
||||
ModuleDefinition,
|
||||
MODULE_RESOURCE_TYPE,
|
||||
MODULE_SCOPE,
|
||||
} from "../../types/global"
|
||||
import { ModuleDefinition, MODULE_RESOURCE_TYPE, MODULE_SCOPE } from "./types"
|
||||
|
||||
export const MODULE_DEFINITIONS: ModuleDefinition[] = [
|
||||
{
|
||||
6
packages/modules-sdk/src/index.ts
Normal file
6
packages/modules-sdk/src/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export * from "./types"
|
||||
export * from "./loaders"
|
||||
|
||||
export * from "./module-helper"
|
||||
|
||||
export * from "./definitions"
|
||||
@@ -3,9 +3,9 @@ import {
|
||||
ModuleDefinition,
|
||||
MODULE_RESOURCE_TYPE,
|
||||
MODULE_SCOPE,
|
||||
} from "../../types/global"
|
||||
import ModuleDefinitionLoader from "../module-definitions"
|
||||
import MODULE_DEFINITIONS from "../module-definitions/definitions"
|
||||
} from "../../types"
|
||||
import { registerModules } from "../module-definition"
|
||||
import MODULE_DEFINITIONS from "../../definitions"
|
||||
|
||||
const RESOLVED_PACKAGE = "@medusajs/test-service-resolved"
|
||||
jest.mock("resolve-cwd", () => jest.fn(() => RESOLVED_PACKAGE))
|
||||
@@ -35,7 +35,7 @@ describe("module definitions loader", () => {
|
||||
it("Resolves module with default definition given empty config", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
|
||||
const res = ModuleDefinitionLoader({ modules: {} } as ConfigModule)
|
||||
const res = registerModules({ modules: {} } as ConfigModule)
|
||||
|
||||
expect(res[defaultDefinition.key]).toEqual({
|
||||
resolutionPath: defaultDefinition.defaultPackage,
|
||||
@@ -52,7 +52,7 @@ describe("module definitions loader", () => {
|
||||
it("Resolves module with no resolution path when given false", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
|
||||
const res = ModuleDefinitionLoader({
|
||||
const res = registerModules({
|
||||
modules: { [defaultDefinition.key]: false },
|
||||
} as ConfigModule)
|
||||
|
||||
@@ -68,7 +68,7 @@ describe("module definitions loader", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition, isRequired: true })
|
||||
|
||||
try {
|
||||
ModuleDefinitionLoader({
|
||||
registerModules({
|
||||
modules: { [defaultDefinition.key]: false },
|
||||
} as ConfigModule)
|
||||
} catch (err) {
|
||||
@@ -86,7 +86,7 @@ describe("module definitions loader", () => {
|
||||
|
||||
MODULE_DEFINITIONS.push(definition)
|
||||
|
||||
const res = ModuleDefinitionLoader({
|
||||
const res = registerModules({
|
||||
modules: {},
|
||||
} as ConfigModule)
|
||||
|
||||
@@ -106,7 +106,7 @@ describe("module definitions loader", () => {
|
||||
it("Resolves module with default definition given empty config", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
|
||||
const res = ModuleDefinitionLoader({
|
||||
const res = registerModules({
|
||||
modules: {
|
||||
[defaultDefinition.key]: defaultDefinition.defaultPackage,
|
||||
},
|
||||
@@ -128,7 +128,7 @@ describe("module definitions loader", () => {
|
||||
it("Resolves resolution path and provides empty options when none are provided", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
|
||||
const res = ModuleDefinitionLoader({
|
||||
const res = registerModules({
|
||||
modules: {
|
||||
[defaultDefinition.key]: {
|
||||
resolve: defaultDefinition.defaultPackage,
|
||||
@@ -152,7 +152,7 @@ describe("module definitions loader", () => {
|
||||
it("Resolves default resolution path and provides options when only options are provided", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
|
||||
const res = ModuleDefinitionLoader({
|
||||
const res = registerModules({
|
||||
modules: {
|
||||
[defaultDefinition.key]: {
|
||||
options: { test: 123 },
|
||||
@@ -175,7 +175,7 @@ describe("module definitions loader", () => {
|
||||
it("Resolves resolution path and provides options when only options are provided", () => {
|
||||
MODULE_DEFINITIONS.push({ ...defaultDefinition })
|
||||
|
||||
const res = ModuleDefinitionLoader({
|
||||
const res = registerModules({
|
||||
modules: {
|
||||
[defaultDefinition.key]: {
|
||||
resolve: defaultDefinition.defaultPackage,
|
||||
@@ -4,17 +4,17 @@ import {
|
||||
AwilixContainer,
|
||||
ClassOrFunctionReturning,
|
||||
createContainer,
|
||||
Resolver
|
||||
Resolver,
|
||||
} from "awilix"
|
||||
import {
|
||||
ConfigModule,
|
||||
MedusaContainer,
|
||||
ModuleResolution,
|
||||
MODULE_RESOURCE_TYPE,
|
||||
MODULE_SCOPE
|
||||
} from "../../types/global"
|
||||
import Logger from "../logger"
|
||||
import registerModules from "../module"
|
||||
MODULE_SCOPE,
|
||||
} from "../../types"
|
||||
|
||||
import { moduleLoader } from "../module-loader"
|
||||
import { trackInstallation } from "../__mocks__/medusa-telemetry"
|
||||
|
||||
function asArray(
|
||||
@@ -26,18 +26,16 @@ function asArray(
|
||||
}
|
||||
}
|
||||
|
||||
const logger = {
|
||||
warn: jest.fn(),
|
||||
} as any
|
||||
|
||||
const buildConfigModule = (
|
||||
configParts: Partial<ConfigModule>
|
||||
): ConfigModule => {
|
||||
return {
|
||||
projectConfig: {
|
||||
database_type: "sqlite",
|
||||
database_logging: "all",
|
||||
},
|
||||
featureFlags: {},
|
||||
modules: {},
|
||||
moduleResolutions: {},
|
||||
plugins: [],
|
||||
...configParts,
|
||||
}
|
||||
}
|
||||
@@ -105,7 +103,7 @@ describe("modules loader", () => {
|
||||
const configModule = buildConfigModule({
|
||||
moduleResolutions,
|
||||
})
|
||||
await registerModules({ container, configModule, logger: Logger })
|
||||
await moduleLoader({ container, configModule, logger })
|
||||
|
||||
const testService = container.resolve(
|
||||
moduleResolutions.testService.definition.key
|
||||
@@ -138,7 +136,7 @@ describe("modules loader", () => {
|
||||
moduleResolutions,
|
||||
})
|
||||
|
||||
await registerModules({ container, configModule, logger: Logger })
|
||||
await moduleLoader({ container, configModule, logger })
|
||||
|
||||
const testService = container.resolve(
|
||||
moduleResolutions.testService.definition.key,
|
||||
@@ -177,15 +175,11 @@ describe("modules loader", () => {
|
||||
},
|
||||
}
|
||||
|
||||
const logger: typeof Logger = {
|
||||
warn: jest.fn(),
|
||||
}
|
||||
|
||||
const configModule = buildConfigModule({
|
||||
moduleResolutions,
|
||||
})
|
||||
|
||||
await registerModules({ container, configModule, logger })
|
||||
await moduleLoader({ container, configModule, logger })
|
||||
|
||||
expect(logger.warn).toHaveBeenCalledWith(
|
||||
"Could not resolve module: TestService. Error: Loaders for module TestService failed: loader"
|
||||
@@ -213,15 +207,11 @@ describe("modules loader", () => {
|
||||
},
|
||||
}
|
||||
|
||||
const logger: typeof Logger = {
|
||||
warn: jest.fn(),
|
||||
}
|
||||
|
||||
const configModule = buildConfigModule({
|
||||
moduleResolutions,
|
||||
})
|
||||
|
||||
await registerModules({ container, configModule, logger })
|
||||
await moduleLoader({ container, configModule, logger })
|
||||
|
||||
expect(logger.warn).toHaveBeenCalledWith(
|
||||
"Could not resolve module: TestService. Error: No service found in module. Make sure that your module exports a service."
|
||||
@@ -255,7 +245,7 @@ describe("modules loader", () => {
|
||||
moduleResolutions,
|
||||
})
|
||||
try {
|
||||
await registerModules({ container, configModule, logger: Logger })
|
||||
await moduleLoader({ container, configModule, logger })
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual(
|
||||
"No service found in module. Make sure that your module exports a service."
|
||||
@@ -290,7 +280,7 @@ describe("modules loader", () => {
|
||||
moduleResolutions,
|
||||
})
|
||||
try {
|
||||
await registerModules({ container, configModule, logger: Logger })
|
||||
await moduleLoader({ container, configModule, logger })
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual(
|
||||
"The module TestService has to define its scope (internal | external)"
|
||||
@@ -325,7 +315,7 @@ describe("modules loader", () => {
|
||||
moduleResolutions,
|
||||
})
|
||||
try {
|
||||
await registerModules({ container, configModule, logger: Logger })
|
||||
await moduleLoader({ container, configModule, logger })
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual(
|
||||
"The module TestService is missing its resources config"
|
||||
3
packages/modules-sdk/src/loaders/index.ts
Normal file
3
packages/modules-sdk/src/loaders/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from "./module-loader"
|
||||
|
||||
export * from "./module-definition"
|
||||
@@ -1,9 +1,9 @@
|
||||
import resolveCwd from "resolve-cwd"
|
||||
|
||||
import { ConfigModule, ModuleResolution } from "../../types/global"
|
||||
import MODULE_DEFINITIONS from "./definitions"
|
||||
import { ConfigModule, ModuleResolution } from "../types"
|
||||
import MODULE_DEFINITIONS from "../definitions"
|
||||
|
||||
export default ({ modules }: ConfigModule) => {
|
||||
export const registerModules = ({ modules }: ConfigModule) => {
|
||||
const moduleResolutions = {} as Record<string, ModuleResolution>
|
||||
const projectModules = modules ?? {}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { asClass, asFunction, asValue } from "awilix"
|
||||
import { asFunction, asValue } from "awilix"
|
||||
import { trackInstallation } from "medusa-telemetry"
|
||||
import { EntitySchema } from "typeorm"
|
||||
import {
|
||||
ClassConstructor,
|
||||
ConfigModule,
|
||||
@@ -11,8 +10,9 @@ import {
|
||||
ModuleResolution,
|
||||
MODULE_RESOURCE_TYPE,
|
||||
MODULE_SCOPE,
|
||||
} from "../types/global"
|
||||
import { ModulesHelper } from "../utils/module-helper"
|
||||
} from "../types/module"
|
||||
|
||||
import { ModulesHelper } from "../module-helper"
|
||||
|
||||
export const moduleHelper = new ModulesHelper()
|
||||
|
||||
@@ -118,7 +118,7 @@ const registerModule = async (
|
||||
)
|
||||
}
|
||||
|
||||
export default async ({
|
||||
export const moduleLoader = async ({
|
||||
container,
|
||||
configModule,
|
||||
logger,
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ModuleResolution } from "../types/global"
|
||||
import { ModulesResponse } from "../types/modules"
|
||||
import { ModuleResolution, ModulesResponse } from "./types/module"
|
||||
|
||||
export class ModulesHelper {
|
||||
private modules_: Record<string, ModuleResolution> = {}
|
||||
1
packages/modules-sdk/src/types/index.ts
Normal file
1
packages/modules-sdk/src/types/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./module"
|
||||
103
packages/modules-sdk/src/types/module.ts
Normal file
103
packages/modules-sdk/src/types/module.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import { AwilixContainer } from "awilix"
|
||||
import { Logger as _Logger } from "winston"
|
||||
|
||||
export type LogLevel =
|
||||
| "query"
|
||||
| "schema"
|
||||
| "error"
|
||||
| "warn"
|
||||
| "info"
|
||||
| "log"
|
||||
| "migration"
|
||||
export type LoggerOptions = boolean | "all" | LogLevel[]
|
||||
|
||||
export type ClassConstructor<T> = {
|
||||
new (...args: unknown[]): T
|
||||
}
|
||||
|
||||
export type MedusaContainer = AwilixContainer & {
|
||||
registerAdd: <T>(name: string, registration: T) => MedusaContainer
|
||||
}
|
||||
|
||||
export type Logger = _Logger & {
|
||||
progress: (activityId: string, msg: string) => void
|
||||
info: (msg: string) => void
|
||||
warn: (msg: string) => void
|
||||
}
|
||||
|
||||
export enum MODULE_SCOPE {
|
||||
INTERNAL = "internal",
|
||||
EXTERNAL = "external",
|
||||
}
|
||||
|
||||
export enum MODULE_RESOURCE_TYPE {
|
||||
SHARED = "shared",
|
||||
ISOLATED = "isolated",
|
||||
}
|
||||
|
||||
export type ConfigurableModuleDeclaration = {
|
||||
scope: MODULE_SCOPE.INTERNAL
|
||||
resources: MODULE_RESOURCE_TYPE
|
||||
resolve?: string
|
||||
options?: Record<string, unknown>
|
||||
}
|
||||
/*
|
||||
| {
|
||||
scope: MODULE_SCOPE.external
|
||||
server: {
|
||||
type: "built-in" | "rest" | "tsrpc" | "grpc" | "gql"
|
||||
url: string
|
||||
options?: Record<string, unknown>
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
export type ModuleResolution = {
|
||||
resolutionPath: string | false
|
||||
definition: ModuleDefinition
|
||||
options?: Record<string, unknown>
|
||||
moduleDeclaration?: ConfigurableModuleDeclaration
|
||||
}
|
||||
|
||||
export type ModuleDefinition = {
|
||||
key: string
|
||||
registrationName: string
|
||||
defaultPackage: string | false
|
||||
label: string
|
||||
canOverride?: boolean
|
||||
isRequired?: boolean
|
||||
defaultModuleDeclaration: ConfigurableModuleDeclaration
|
||||
}
|
||||
|
||||
export type LoaderOptions = {
|
||||
container: MedusaContainer
|
||||
configModule: ConfigModule
|
||||
options?: Record<string, unknown>
|
||||
logger?: Logger
|
||||
}
|
||||
|
||||
export type Constructor<T> = new (...args: any[]) => T
|
||||
|
||||
export type ModuleExports = {
|
||||
loaders: ((
|
||||
options: LoaderOptions,
|
||||
moduleDeclaration?: ConfigurableModuleDeclaration
|
||||
) => Promise<void>)[]
|
||||
service: Constructor<any>
|
||||
migrations?: any[]
|
||||
models?: Constructor<any>[]
|
||||
}
|
||||
|
||||
export type ConfigModule = {
|
||||
options?: Record<string, any>
|
||||
modules?: Record<
|
||||
string,
|
||||
false | string | Partial<ConfigurableModuleDeclaration>
|
||||
>
|
||||
moduleResolutions?: Record<string, ModuleResolution>
|
||||
}
|
||||
|
||||
export type ModulesResponse = {
|
||||
module: string
|
||||
resolution: string | false
|
||||
}[]
|
||||
32
packages/modules-sdk/tsconfig.json
Normal file
32
packages/modules-sdk/tsconfig.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"es5",
|
||||
"es6",
|
||||
"es2019"
|
||||
],
|
||||
"target": "es5",
|
||||
"outDir": "./dist",
|
||||
"esModuleInterop": true,
|
||||
"declaration": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"sourceMap": true,
|
||||
"noImplicitReturns": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"noImplicitThis": true,
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"downlevelIteration": true // to use ES5 specific tooling
|
||||
},
|
||||
"include": ["./src/**/*", "index.d.ts"],
|
||||
"exclude": [
|
||||
"./dist/**/*",
|
||||
"./src/**/__tests__",
|
||||
"./src/**/__mocks__",
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
@@ -24,6 +24,9 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^4.4.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@medusajs/modules-sdk": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"watch": "tsc --build --watch",
|
||||
"prepare": "cross-env NODE_ENV=production yarn run build",
|
||||
|
||||
@@ -2,7 +2,7 @@ import ConnectionLoader from "./loaders/connection"
|
||||
import StockLocationService from "./services/stock-location"
|
||||
import * as SchemaMigration from "./migrations/schema-migrations/1665749860179-setup"
|
||||
import * as StockLocationModels from "./models"
|
||||
import { ModuleExports } from "@medusajs/medusa"
|
||||
import { ModuleExports } from "@medusajs/modules-sdk"
|
||||
|
||||
const service = StockLocationService
|
||||
const migrations = [SchemaMigration]
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { ConfigurableModuleDeclaration, LoaderOptions } from "@medusajs/medusa"
|
||||
import {
|
||||
ConfigurableModuleDeclaration,
|
||||
LoaderOptions,
|
||||
} from "@medusajs/modules-sdk"
|
||||
|
||||
export default async (
|
||||
{ configModule }: LoaderOptions,
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import {
|
||||
buildQuery,
|
||||
ConfigurableModuleDeclaration,
|
||||
CreateStockLocationInput,
|
||||
FilterableStockLocationProps,
|
||||
FindConfig,
|
||||
IEventBusService,
|
||||
MODULE_RESOURCE_TYPE,
|
||||
setMetadata,
|
||||
StockLocationAddressInput,
|
||||
TransactionBaseService,
|
||||
UpdateStockLocationInput,
|
||||
} from "@medusajs/medusa"
|
||||
|
||||
import {
|
||||
ConfigurableModuleDeclaration,
|
||||
MODULE_RESOURCE_TYPE,
|
||||
} from "@medusajs/modules-sdk"
|
||||
|
||||
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||
import { EntityManager } from "typeorm"
|
||||
|
||||
@@ -232,7 +236,7 @@ export default class StockLocationService extends TransactionBaseService {
|
||||
const locationAddressRepo = manager.getRepository(StockLocationAddress)
|
||||
|
||||
const existingAddress = await locationAddressRepo.findOne({
|
||||
where: { id: addressId }
|
||||
where: { id: addressId },
|
||||
})
|
||||
if (!existingAddress) {
|
||||
throw new MedusaError(
|
||||
|
||||
17
yarn.lock
17
yarn.lock
@@ -5219,6 +5219,7 @@ __metadata:
|
||||
resolution: "@medusajs/inventory@workspace:packages/inventory"
|
||||
dependencies:
|
||||
"@medusajs/medusa": "*"
|
||||
"@medusajs/modules-sdk": "*"
|
||||
cross-env: ^5.2.1
|
||||
jest: ^25.5.4
|
||||
ts-jest: ^25.5.1
|
||||
@@ -5322,6 +5323,7 @@ __metadata:
|
||||
"@babel/core": ^7.14.3
|
||||
"@babel/preset-typescript": ^7.13.0
|
||||
"@medusajs/medusa-cli": ^1.3.8
|
||||
"@medusajs/modules-sdk": "*"
|
||||
"@types/express": ^4.17.17
|
||||
"@types/ioredis": ^4.28.10
|
||||
"@types/jest": ^27.5.2
|
||||
@@ -5385,6 +5387,20 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@medusajs/modules-sdk@*, @medusajs/modules-sdk@workspace:packages/modules-sdk":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@medusajs/modules-sdk@workspace:packages/modules-sdk"
|
||||
dependencies:
|
||||
awilix: ^8.0.0
|
||||
cross-env: ^5.2.1
|
||||
jest: ^25.5.4
|
||||
medusa-telemetry: ^0.0.16
|
||||
resolve-cwd: ^3.0.0
|
||||
ts-jest: ^25.5.1
|
||||
typescript: ^4.4.4
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@medusajs/openapi-typescript-codegen@*, @medusajs/openapi-typescript-codegen@workspace:packages/oas/openapi-typescript-codegen":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@medusajs/openapi-typescript-codegen@workspace:packages/oas/openapi-typescript-codegen"
|
||||
@@ -5427,6 +5443,7 @@ __metadata:
|
||||
resolution: "@medusajs/stock-location@workspace:packages/stock-location"
|
||||
dependencies:
|
||||
"@medusajs/medusa": ^1.7.7
|
||||
"@medusajs/modules-sdk": "*"
|
||||
cross-env: ^5.2.1
|
||||
jest: ^25.5.4
|
||||
ts-jest: ^25.5.1
|
||||
|
||||
Reference in New Issue
Block a user