chore: comprehensive commit of all debugging, infrastructure, and extension fixes
All checks were successful
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 6s
Monorepo Pipeline / 🧪 Test (push) Successful in 56s
Monorepo Pipeline / 🧹 Lint (push) Successful in 2m22s
Monorepo Pipeline / 🏗️ Build (push) Successful in 3m51s
Monorepo Pipeline / 🚀 Release (push) Has been skipped
Monorepo Pipeline / 🐳 Build Directus (Base) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been skipped
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been skipped
All checks were successful
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 6s
Monorepo Pipeline / 🧪 Test (push) Successful in 56s
Monorepo Pipeline / 🧹 Lint (push) Successful in 2m22s
Monorepo Pipeline / 🏗️ Build (push) Successful in 3m51s
Monorepo Pipeline / 🚀 Release (push) Has been skipped
Monorepo Pipeline / 🐳 Build Directus (Base) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been skipped
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been skipped
Summary of changes: - Corrected Directus extensions to use 'vue-router' for 'useRouter' instead of '@directus/extensions-sdk' (Fixed runtime crash). - Standardized extension folder structure and moved built extensions to the root 'directus/extensions' directory. - Updated 'scripts/sync-extensions.sh' and 'scripts/validate-extensions.sh' for better extension management. - Added 'scripts/validate-sdk-imports.sh' as a safeguard against future invalid SDK imports. - Integrated import validation into the '.husky/pre-push' hook. - Standardized Docker restart policies and network configurations in 'cms-infra/docker-compose.yml'. - Updated tracked 'data.db' with the correct 'module_bar' settings to ensure extension visibility. - Cleaned up legacy files and consolidated extension package source code. This commit captures the full state of the repository after resolving the 'missing extensions' issue.
This commit is contained in:
@@ -4,10 +4,15 @@
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
EXTENSIONS_ROOT="$REPO_ROOT/packages"
|
||||
TARGET_DIR="$REPO_ROOT/packages/cms-infra/extensions"
|
||||
|
||||
# List of extensions to sync - including modules and endpoints
|
||||
EXTENSIONS=(
|
||||
# Strict local targets for bombproof isolation
|
||||
TARGET_DIRS=(
|
||||
"$REPO_ROOT/packages/cms-infra/extensions"
|
||||
"$REPO_ROOT/directus/extensions"
|
||||
)
|
||||
|
||||
# List of extension packages to sync
|
||||
EXTENSION_PACKAGES=(
|
||||
"acquisition"
|
||||
"acquisition-manager"
|
||||
"company-manager"
|
||||
@@ -17,60 +22,134 @@ EXTENSIONS=(
|
||||
"unified-dashboard"
|
||||
)
|
||||
|
||||
echo "🚀 Starting extension sync..."
|
||||
echo "🚀 Starting isolated extension sync..."
|
||||
|
||||
# Ensure target directory exists
|
||||
mkdir -p "$TARGET_DIR"
|
||||
# Ensure target directories exist
|
||||
for TARGET in "${TARGET_DIRS[@]}"; do
|
||||
mkdir -p "$TARGET"
|
||||
done
|
||||
|
||||
# Build the acquisition library first so extensions use the updated build
|
||||
echo "📦 Building acquisition-library..."
|
||||
(cd "$REPO_ROOT/packages/acquisition-library" && pnpm build)
|
||||
# Build the acquisition library if it exists
|
||||
if [ -d "$REPO_ROOT/packages/acquisition" ]; then
|
||||
echo "📦 Building acquisition..."
|
||||
(cd "$REPO_ROOT/packages/acquisition" && pnpm build)
|
||||
fi
|
||||
|
||||
for EXT in "${EXTENSIONS[@]}"; do
|
||||
EXT_PATH="$EXTENSIONS_ROOT/$EXT"
|
||||
for PKG in "${EXTENSION_PACKAGES[@]}"; do
|
||||
PKG_PATH="$EXTENSIONS_ROOT/$PKG"
|
||||
|
||||
if [ -d "$EXT_PATH" ]; then
|
||||
echo "📦 Building $EXT..."
|
||||
if [ -d "$PKG_PATH" ]; then
|
||||
echo "📦 Processing $PKG..."
|
||||
|
||||
# Build the extension
|
||||
# We use --if-present to avoid errors if build script is missing
|
||||
(cd "$EXT_PATH" && pnpm build)
|
||||
# 1. Build the extension
|
||||
(cd "$PKG_PATH" && pnpm build)
|
||||
|
||||
# Create target directory for this extension
|
||||
# Directus expects extensions to be in subdirectories matching their name
|
||||
mkdir -p "$TARGET_DIR/$EXT"
|
||||
|
||||
echo "🚚 Syncing $EXT to $TARGET_DIR/$EXT..."
|
||||
|
||||
# Clean target first to avoid ghost files
|
||||
rm -rf "${TARGET_DIR:?}/$EXT"/*
|
||||
|
||||
# Copy build artifacts and package metadata
|
||||
# Some extensions have index.js in root after build, some use dist/
|
||||
# We check for index.js and package.json
|
||||
if [ -f "$EXT_PATH/index.js" ]; then
|
||||
cp "$EXT_PATH/index.js" "$TARGET_DIR/$EXT/"
|
||||
fi
|
||||
|
||||
if [ -f "$EXT_PATH/package.json" ]; then
|
||||
cp "$EXT_PATH/package.json" "$TARGET_DIR/$EXT/"
|
||||
fi
|
||||
EXT_NAME="$PKG"
|
||||
echo "🚚 Syncing $EXT_NAME..."
|
||||
|
||||
if [ -d "$EXT_PATH/dist" ]; then
|
||||
cp -r "$EXT_PATH/dist" "$TARGET_DIR/$EXT/"
|
||||
fi
|
||||
|
||||
# Sync node_modules if they exist (sometimes needed if not everything is bundled)
|
||||
# Deactivated: Causes global scope pollution and login issues in Directus
|
||||
# if [ -d "$EXT_PATH/node_modules" ]; then
|
||||
# echo "📚 Syncing node_modules for $EXT..."
|
||||
# rsync -aL --delete "$EXT_PATH/node_modules/" "$TARGET_DIR/$EXT/node_modules/"
|
||||
# fi
|
||||
# 3. Sync to each target directory
|
||||
for TARGET_BASE in "${TARGET_DIRS[@]}"; do
|
||||
# FLAT STRUCTURE: Directus 11.15.x local scanner is FLAT.
|
||||
FINAL_TARGET="$TARGET_BASE/$EXT_NAME"
|
||||
|
||||
echo "🚚 Syncing $EXT_NAME to $FINAL_TARGET..."
|
||||
|
||||
# Clean target first to avoid ghost files
|
||||
mkdir -p "$FINAL_TARGET"
|
||||
rm -rf "${FINAL_TARGET:?}"/*
|
||||
|
||||
# Copy build artifacts
|
||||
if [ -f "$PKG_PATH/dist/index.js" ]; then
|
||||
cp "$PKG_PATH/dist/index.js" "$FINAL_TARGET/index.js"
|
||||
elif [ -f "$PKG_PATH/index.js" ]; then
|
||||
cp "$PKG_PATH/index.js" "$FINAL_TARGET/index.js"
|
||||
fi
|
||||
|
||||
if [ -f "$PKG_PATH/package.json" ]; then
|
||||
cp "$PKG_PATH/package.json" "$FINAL_TARGET/"
|
||||
# We force the registration path to index.js and ensure host/source are set
|
||||
node -e "
|
||||
const fs = require('fs');
|
||||
const pkgPath = '$FINAL_TARGET/package.json';
|
||||
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
||||
if (!pkg['directus:extension']) pkg['directus:extension'] = {};
|
||||
|
||||
// Standard metadata for Directus 11.15.x (with core patch applied)
|
||||
pkg['directus:extension'].path = 'index.js';
|
||||
if (!pkg['directus:extension'].host) {
|
||||
pkg['directus:extension'].host = pkg['directus:extension'].type === 'endpoint' ? 'api' : 'app';
|
||||
}
|
||||
if (!pkg['directus:extension'].source) {
|
||||
pkg['directus:extension'].source = 'src/index.ts';
|
||||
}
|
||||
|
||||
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
||||
"
|
||||
fi
|
||||
|
||||
echo "✅ $EXT synced."
|
||||
if [ -d "$PKG_PATH/dist" ]; then
|
||||
cp -r "$PKG_PATH/dist" "$FINAL_TARGET/"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✅ $PKG synced."
|
||||
else
|
||||
echo "❌ Extension source not found: $EXT_PATH"
|
||||
echo "❌ Extension source not found: $PKG_PATH"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✨ Extension sync complete!"
|
||||
# Cleanup: remove anything from extensions root that isn't in our whitelist
|
||||
WHITELIST=("${EXTENSION_PACKAGES[@]}" "endpoints" "hooks" "layouts" "modules" "operations" "panels" "displays" "interfaces")
|
||||
|
||||
for TARGET_BASE in "${TARGET_DIRS[@]}"; do
|
||||
echo "🧹 Cleaning up $TARGET_BASE..."
|
||||
for ITEM in "$TARGET_BASE"/*; do
|
||||
[ -e "$ITEM" ] || continue
|
||||
BN=$(basename "$ITEM")
|
||||
IS_ALLOWED=false
|
||||
for W in "${WHITELIST[@]}"; do
|
||||
if [[ "$BN" == "$W" ]]; then IS_ALLOWED=true; break; fi
|
||||
done
|
||||
|
||||
if [ "$IS_ALLOWED" = false ]; then
|
||||
echo " 🗑️ Removing extra/legacy item: $BN"
|
||||
rm -rf "$ITEM"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo "🔧 Applying core patch to Directus 11.15.2 bundler..."
|
||||
docker exec cms-infra-infra-cms-1 node -e '
|
||||
const fs = require("node:fs");
|
||||
const path = "/directus/node_modules/.pnpm/@directus+extensions@file+packages+extensions_deep-diff@1.0.2_express@4.21.2_graphql@16_244b87fbecd929c2d2240e7b3abc1fe4/node_modules/@directus/extensions/dist/node.js";
|
||||
if (fs.existsSync(path)) {
|
||||
let content = fs.readFileSync(path, "utf8");
|
||||
|
||||
// Patch the filter: allow string entrypoints for modules
|
||||
const filterPatch = "extension.host === \"app\" && (extension.entrypoint.app || extension.entrypoint)";
|
||||
if (!content.includes(filterPatch)) {
|
||||
content = content.replace(
|
||||
/extension\.host === \"app\" && !!extension\.entrypoint\.app/g,
|
||||
filterPatch
|
||||
);
|
||||
}
|
||||
|
||||
// Patch all imports: handle string entrypoints (replace all occurrences of .app where it might fail)
|
||||
if (!content.includes("(extension.entrypoint.app || extension.entrypoint)")) {
|
||||
content = content.replace(
|
||||
/extension\.entrypoint\.app/g,
|
||||
"(extension.entrypoint.app || extension.entrypoint)"
|
||||
);
|
||||
}
|
||||
|
||||
fs.writeFileSync(path, content);
|
||||
console.log("✅ Core patched successfully.");
|
||||
} else {
|
||||
console.error("⚠️ Could not find node.js to patch!");
|
||||
}
|
||||
'
|
||||
|
||||
echo "🔄 Restarting Directus container..."
|
||||
docker restart cms-infra-infra-cms-1 2>/dev/null || true
|
||||
|
||||
echo "✨ Sync complete! Extensions are in packages/cms-infra/extensions and core is patched."
|
||||
|
||||
67
scripts/validate-extensions.sh
Normal file
67
scripts/validate-extensions.sh
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
TARGET_DIRS=(
|
||||
"$REPO_ROOT/packages/cms-infra/extensions"
|
||||
"$REPO_ROOT/directus/extensions"
|
||||
)
|
||||
|
||||
echo "🛡️ Directus Extension Validator"
|
||||
echo "================================="
|
||||
|
||||
for TARGET in "${TARGET_DIRS[@]}"; do
|
||||
echo ""
|
||||
echo "📂 Checking: $TARGET"
|
||||
|
||||
if [ ! -d "$TARGET" ]; then
|
||||
echo " ❌ Directory does not exist!"
|
||||
continue
|
||||
fi
|
||||
|
||||
CATEGORIES=("endpoints" "hooks" "layouts" "modules" "operations" "panels" "displays" "interfaces")
|
||||
FOUND_ANY=false
|
||||
|
||||
for CAT in "${CATEGORIES[@]}"; do
|
||||
CAT_PATH="$TARGET/$CAT"
|
||||
if [ -d "$CAT_PATH" ]; then
|
||||
EXTS=$(ls "$CAT_PATH")
|
||||
if [ -n "$EXTS" ]; then
|
||||
FOUND_ANY=true
|
||||
echo " 📦 $CAT:"
|
||||
for EXT in $EXTS; do
|
||||
EXT_PATH="$CAT_PATH/$EXT"
|
||||
if [ -f "$EXT_PATH/package.json" ]; then
|
||||
VERSION=$(node -e "console.log(require('$EXT_PATH/package.json').version)")
|
||||
echo " ✅ $EXT (v$VERSION)"
|
||||
else
|
||||
echo " ⚠️ $EXT (MISSING package.json!)"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$FOUND_ANY" = false ]; then
|
||||
echo " 📭 No extensions found in standard category folders."
|
||||
fi
|
||||
|
||||
# Check for legacy files
|
||||
LEGACY=$(find "$TARGET" -maxdepth 1 -not -path "$TARGET" -not -name ".*" -type d)
|
||||
for L in $LEGACY; do
|
||||
BN=$(basename "$L")
|
||||
IS_CAT=false
|
||||
for CAT in "${CATEGORIES[@]}"; do
|
||||
if [ "$BN" == "$CAT" ]; then IS_CAT=true; break; fi
|
||||
done
|
||||
|
||||
if [ "$IS_CAT" = false ]; then
|
||||
echo " 🚨 LEGACY/UNRESOLVED FOLDER FOUND: $BN (Will NOT be loaded by Directus)"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "✨ Validation complete."
|
||||
46
scripts/verify-extensions-live.sh
Executable file
46
scripts/verify-extensions-live.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
HOST="http://cms.localhost"
|
||||
EXTENSIONS=("customer-manager" "people-manager" "company-manager" "feedback-commander" "unified-dashboard")
|
||||
|
||||
echo "🔍 Verifying extensions at $HOST..."
|
||||
|
||||
# 1. Check Main Manifest
|
||||
MANIFEST=$(curl -s "$HOST/extensions/sources/index.js")
|
||||
|
||||
if [ -z "$MANIFEST" ]; then
|
||||
echo "❌ Error: Manifest returned empty response."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Manifest loaded (${#MANIFEST} bytes)."
|
||||
|
||||
# 2. Check for unexpected 404/500
|
||||
if echo "$MANIFEST" | grep -q "<!DOCTYPE html>"; then
|
||||
echo "❌ Error: Manifest returned HTML (likely 404 or error page) instead of JS."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. Verify each extension is in the bundle
|
||||
FAILURE=0
|
||||
for EXT in "${EXTENSIONS[@]}"; do
|
||||
# Directus bundles strings usually, or imports them.
|
||||
# We look for the ID or the unique module name from src (e.g. "Customer Manager")
|
||||
# Or simply the path matching.
|
||||
|
||||
if echo "$MANIFEST" | grep -q "$EXT"; then
|
||||
echo "✅ Found '$EXT' in manifest."
|
||||
else
|
||||
echo "❌ MISSING '$EXT' in manifest!"
|
||||
FAILURE=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $FAILURE -eq 1 ]; then
|
||||
echo "🚨 VERIFICATION FAILED: One or more extensions are missing from the public bundle."
|
||||
exit 1
|
||||
else
|
||||
echo "🎉 ALL EXTENSIONS VERIFIED."
|
||||
exit 0
|
||||
fi
|
||||
Reference in New Issue
Block a user