#!/bin/bash # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" EXTENSIONS_ROOT="$REPO_ROOT/packages" # 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" "customer-manager" "feedback-commander" "people-manager" "unified-dashboard" ) echo "๐Ÿš€ Starting isolated extension sync..." # Ensure target directories exist for TARGET in "${TARGET_DIRS[@]}"; do mkdir -p "$TARGET" done # 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 PKG in "${EXTENSION_PACKAGES[@]}"; do PKG_PATH="$EXTENSIONS_ROOT/$PKG" if [ -d "$PKG_PATH" ]; then echo "๐Ÿ“ฆ Processing $PKG..." # 1. Build the extension (cd "$PKG_PATH" && pnpm build) EXT_NAME="$PKG" echo "๐Ÿšš Syncing $EXT_NAME..." # 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 if [ -d "$PKG_PATH/dist" ]; then cp -r "$PKG_PATH/dist" "$FINAL_TARGET/" fi done echo "โœ… $PKG synced." else echo "โŒ Extension source not found: $PKG_PATH" fi done # 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."