feat(dashboard,admin-sdk,admin-shared,admin-vite-plugin): Add support for UI extensions (#7383)

* intial work

* update lock

* add routes and fix HMR of configs

* cleanup

* rm imports

* rm debug from plugin

* address feedback

* address feedback
This commit is contained in:
Kasper Fabricius Kristensen authored and GitHub committed 2024-05-23 14:02:19 +02:00
1 parent 521c252dee
commit f1176a0673
50 files changed
+1366 -1098

No files matched your search

+17 -7
View File
@@ -1,7 +1,8 @@
import { ConfigModule } from "@medusajs/types"
import { transformFile } from "@swc/core"
import { getConfigFile } from "medusa-core-utils"
import fs from "node:fs/promises"
import { existsSync } from "node:fs"
import { copyFile, mkdir, readdir, rm, writeFile } from "node:fs/promises"
import path from "path"
type BuildArgs = {
@@ -21,12 +22,12 @@ const COMPILE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"]
const IGNORE_EXTENSIONS = [".md"]
async function clean(path: string) {
await fs.rm(path, { recursive: true }).catch(() => {})
await rm(path, { recursive: true }).catch(() => {})
}
async function findFiles(dir: string): Promise<string[]> {
try {
const files = await fs.readdir(dir, { withFileTypes: true })
const files = await readdir(dir, { withFileTypes: true })
const paths = await Promise.all(
files.map(async (file) => {
const res = path.join(dir, file.name)
@@ -64,16 +65,16 @@ const writeToOut = async (
) => {
const outputPath = getOutputPath(file, config)
await fs.mkdir(outputPath.replace(/\/[^/]+$/, ""), { recursive: true })
await fs.writeFile(outputPath, content)
await mkdir(outputPath.replace(/\/[^/]+$/, ""), { recursive: true })
await writeFile(outputPath, content)
}
async function copyToOut(file: string, config: FileConfig) {
const outputPath = getOutputPath(file, config)
const dirNameRegex = new RegExp("\\" + path.sep + "([^\\" + path.sep + "]+)$")
await fs.mkdir(outputPath.replace(dirNameRegex, ""), { recursive: true })
await fs.copyFile(file, outputPath)
await mkdir(outputPath.replace(dirNameRegex, ""), { recursive: true })
await copyFile(file, outputPath)
}
const medusaTransform = async (file: string) => {
@@ -131,10 +132,19 @@ export default async function ({ directory }: BuildArgs) {
await Promise.all(files.map(medusaTransform))
const sources: string[] = []
const projectSource = path.join(directory, "src", "admin")
if (existsSync(projectSource)) {
sources.push(projectSource)
}
const adminOptions = {
disable: false,
path: "/app" as const,
outDir: "./build",
sources,
...configModule.admin,
}
+25 -4
View File
@@ -1,22 +1,43 @@
import { AdminOptions, ConfigModule } from "@medusajs/types"
import { Express } from "express"
import fs from "fs"
import path from "path"
type Options = {
app: Express
adminConfig: ConfigModule["admin"]
configModule: ConfigModule
rootDirectory: string
}
type IntializedOptions = Required<
Pick<AdminOptions, "path" | "disable" | "outDir">
> &
AdminOptions
AdminOptions & {
sources?: string[]
}
export default async function adminLoader({
app,
configModule,
rootDirectory,
}: Options) {
const { admin } = configModule
const sources: string[] = []
const projectSource = path.join(rootDirectory, "src", "admin")
// check if the projectSource exists
if (fs.existsSync(projectSource)) {
sources.push(projectSource)
}
export default async function adminLoader({ app, adminConfig }: Options) {
const adminOptions: IntializedOptions = {
disable: false,
path: "/app",
outDir: "./build",
...adminConfig,
sources,
...admin,
}
if (adminOptions?.disable) {
+10 -9
View File
@@ -1,25 +1,24 @@
import { createDefaultsWorkflow } from "@medusajs/core-flows"
import { ConfigModule, MedusaContainer } from "@medusajs/types"
import { ConfigModule, MedusaContainer, PluginDetails } from "@medusajs/types"
import { ContainerRegistrationKeys, promiseAll } from "@medusajs/utils"
import { asValue } from "awilix"
import { Express, NextFunction, Request, Response } from "express"
import glob from "glob"
import { createMedusaContainer } from "medusa-core-utils"
import path from "path"
import requestIp from "request-ip"
import { v4 } from "uuid"
import path from "path"
import adminLoader from "./admin"
import apiLoader from "./api"
import loadConfig from "./config"
import expressLoader from "./express"
import featureFlagsLoader from "./feature-flags"
import { registerWorkflows } from "./helpers/register-workflows"
import { getResolvedPlugins } from "./helpers/resolve-plugins"
import { SubscriberLoader } from "./helpers/subscribers"
import Logger from "./logger"
import loadMedusaApp from "./medusa-app"
import registerPgConnection from "./pg-connection"
import { SubscriberLoader } from "./helpers/subscribers"
import { getResolvedPlugins } from "./helpers/resolve-plugins"
import { PluginDetails } from "@medusajs/types"
import glob from "glob"
type Options = {
directory: string
@@ -63,7 +62,8 @@ async function subscribersLoader(
async function loadEntrypoints(
plugins: PluginDetails[],
container: MedusaContainer,
expressApp: Express
expressApp: Express,
rootDirectory: string
) {
const configModule: ConfigModule = container.resolve(
ContainerRegistrationKeys.CONFIG_MODULE
@@ -89,7 +89,7 @@ async function loadEntrypoints(
next()
})
await adminLoader({ app: expressApp, adminConfig: configModule.admin })
await adminLoader({ app: expressApp, configModule, rootDirectory })
await subscribersLoader(plugins, container)
await apiLoader({
container,
@@ -143,7 +143,8 @@ export default async ({
const entrypointsShutdown = await loadEntrypoints(
plugins,
container,
expressApp
expressApp,
rootDirectory
)
await createDefaultsWorkflow(container).run()