feat(admin-bundler,admin-vite-plugin,medusa): Add support for loading Admin Extensions from plugins (#10869)

Should not be merged before https://github.com/medusajs/medusa/pull/10895

**What**
- Introduces a new `plugin` command to `admin-bundler`, currently not used anywhere but will be called from `medusa build:plugin`
- Discovers plugins with extensions and add passes the to `admin-vite-plugin`.
- Updates `admin-vite-plugin` so its able to read built admin extensions.

Resolves CMRC-830, CMRC-839
This commit is contained in:
Kasper Fabricius Kristensen
2025-01-13 11:45:33 +01:00
committed by GitHub
parent 253b642418
commit 1ba2fadf22
13 changed files with 316 additions and 92 deletions

View File

@@ -14,6 +14,7 @@ import {
type ExportNamedDeclaration,
type NodePath,
type ParserOptions,
type VariableDeclarator,
} from "./babel"
export function normalizePath(file: string) {
@@ -48,7 +49,7 @@ export function generateModule(code: string) {
}
}
const VALID_FILE_EXTENSIONS = [".tsx", ".jsx"]
export const VALID_FILE_EXTENSIONS = [".tsx", ".jsx", ".js"]
/**
* Crawls a directory and returns all files that match the criteria.
@@ -96,8 +97,25 @@ export async function crawl(
* Extracts and returns the properties of a `config` object from a named export declaration.
*/
export function getConfigObjectProperties(
path: NodePath<ExportNamedDeclaration>
path: NodePath<ExportNamedDeclaration | VariableDeclarator>
) {
if (isVariableDeclarator(path.node)) {
const configDeclaration = isIdentifier(path.node.id, { name: "config" })
? path.node
: null
if (
configDeclaration &&
isCallExpression(configDeclaration.init) &&
configDeclaration.init.arguments.length > 0 &&
isObjectExpression(configDeclaration.init.arguments[0])
) {
return configDeclaration.init.arguments[0].properties
}
return null
}
const declaration = path.node.declaration
if (isVariableDeclaration(declaration)) {
@@ -126,6 +144,30 @@ export async function hasDefaultExport(
ExportDefaultDeclaration() {
hasDefaultExport = true
},
AssignmentExpression(path) {
if (
path.node.left.type === "MemberExpression" &&
path.node.left.object.type === "Identifier" &&
path.node.left.object.name === "exports" &&
path.node.left.property.type === "Identifier" &&
path.node.left.property.name === "default"
) {
hasDefaultExport = true
}
},
ExportNamedDeclaration(path) {
const specifiers = path.node.specifiers
if (
specifiers?.some(
(s) =>
s.type === "ExportSpecifier" &&
s.exported.type === "Identifier" &&
s.exported.name === "default"
)
) {
hasDefaultExport = true
}
},
})
return hasDefaultExport
}