UNPKG

@luzmo/ngx-embed

Version:

This is an Angular library for embedding [Luzmo](https://luzmo.com) dashboards in your Angular application.

151 lines 7.72 kB
import { execSync } from 'node:child_process'; import { SchematicsException, chain } from '@angular-devkit/schematics'; import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import { addRootImport } from '@schematics/angular/utility'; function getLatestStableVersion(packageName, context) { try { // Get all versions and filter for stable ones const command = `npm view ${packageName} versions --json`; const versionsOutput = execSync(command, { encoding: 'utf8' }).trim(); const versions = JSON.parse(versionsOutput); // Filter out pre-release versions (containing alpha, beta, rc, etc.) const stableVersions = versions.filter((version) => { const isPrerelease = /-(alpha|beta|rc|pre|dev|snapshot|canary)/i.test(version); return !isPrerelease; }); if (stableVersions.length === 0) { context.logger.warn('⚠️ No stable versions found, using fallback'); return '7.0.0'; } // Get the latest stable version (last in the sorted array) const latestStable = stableVersions.at(-1); context.logger.info(`✅ Found latest stable version: ${latestStable}`); return latestStable; } catch (_a) { context.logger.warn('⚠️ Could not fetch latest stable version from npm registry'); return '7.0.0'; // fallback to stable version } } function addPackageToPackageJson() { return (tree, context) => { const packageJsonPath = '/package.json'; if (!tree.exists(packageJsonPath)) { throw new SchematicsException('Could not find package.json'); } const packageJsonContent = tree.read(packageJsonPath); if (!packageJsonContent) { throw new SchematicsException('Could not read package.json'); } const packageJson = JSON.parse(packageJsonContent.toString()); if (!packageJson.dependencies) { packageJson.dependencies = {}; } // Add the package if it's not already present if (!packageJson.dependencies['@luzmo/ngx-embed']) { context.logger.info('🔍 Fetching latest stable version of @luzmo/ngx-embed...'); const latestVersion = getLatestStableVersion('@luzmo/ngx-embed', context); packageJson.dependencies['@luzmo/ngx-embed'] = `^${latestVersion}`; context.logger.info(`📦 Adding @luzmo/ngx-embed@${latestVersion} to package.json`); tree.overwrite(packageJsonPath, JSON.stringify(packageJson, null, 2)); } return tree; }; } function getAvailableProjectsSync(tree) { try { const workspaceContent = tree.read('/angular.json') || tree.read('/workspace.json'); if (!workspaceContent) { throw new SchematicsException('Could not find workspace configuration file'); } const workspace = JSON.parse(workspaceContent.toString()); return Object.entries(workspace.projects || {}) .filter(([, project]) => project.projectType === 'application') .map(([name]) => name); } catch (_a) { throw new SchematicsException('Could not read workspace configuration'); } } function selectProjectInteractively(tree, context, options) { if (options.project) { // Project was specified, validate it exists const projectsToValidate = getAvailableProjectsSync(tree); if (!projectsToValidate.includes(options.project)) { throw new SchematicsException(`Project "${options.project}" not found. Available projects: ${projectsToValidate.join(', ')}`); } return options.project; } // No project specified, check available projects const availableProjects = getAvailableProjectsSync(tree); if (availableProjects.length === 0) { throw new SchematicsException('No application projects found in workspace'); } if (availableProjects.length === 1) { context.logger.info(`📦 Using the only available project: ${availableProjects[0]}`); return availableProjects[0]; } // Multiple projects found - create an interactive selection context.logger.info('\n🎯 Multiple projects found! Please select one:'); availableProjects.forEach((project, index) => { context.logger.info(` ${index + 1}. ${project}`); }); // Create formatted selection interface const projectSelections = availableProjects .map((project, index) => `│ ${String(index + 1).padStart(2)}. ng add @luzmo/ngx-embed --project=${project.padEnd(30)} │`) .join('\n'); throw new SchematicsException('\n' + '╭─ Multiple Projects Detected ────────────────────────────────────╮\n' + '│ │\n' + '│ Please specify which project to use: │\n' + '│ │\n' + projectSelections + '\n' + '│ │\n' + '╰─────────────────────────────────────────────────────────────────╯'); } function addEntityToProject(options) { return (tree, context) => { // Available entities for validation (CLI will prompt based on schema.json) const availableEntities = [ 'NgxLuzmoDashboardModule', 'NgxLuzmoDashboardComponent', 'NgxLuzmoVizItemComponent', 'NgxLuzmoIQChatComponent', 'NgxLuzmoIQAnswerComponent' ]; // Debug: Log what we received context.logger.info(`🔍 Debug: Received options - entity: ${options.entity}, project: ${options.project}`); const selectedEntity = options.entity; // CLI ensures this is provided via schema // Handle project selection interactively const validatedProject = selectProjectInteractively(tree, context, options); // Only validate if entity is actually invalid (shouldn't happen with proper schema) if (!availableEntities.includes(selectedEntity)) { throw new SchematicsException(`Entity "${selectedEntity}" is not available. Available entities: ${availableEntities.join(', ')}`); } context.logger.info(`✅ Adding ${selectedEntity} to project "${validatedProject}"`); // Use Angular's built-in utility for adding imports // This handles both NgModule and standalone apps automatically return addRootImport(validatedProject, ({ code, external }) => { if (selectedEntity === 'NgxLuzmoDashboardModule') { // For modules, add as root import context.logger.info('📦 Adding module to your app imports'); return code `${external(selectedEntity, '@luzmo/ngx-embed')}`; } // For standalone components, just add the import (user will use it in templates) context.logger.info(`📦 Import added for ${selectedEntity}. You can now use it in your components.`); return code `${external(selectedEntity, '@luzmo/ngx-embed')}`; }); }; } export function ngAdd(options) { return chain([ addPackageToPackageJson(), (tree, context) => { context.addTask(new NodePackageInstallTask()); return tree; }, addEntityToProject(options) ]); } //# sourceMappingURL=index.js.map