UNPKG

ngx-extended-pdf-viewer

Version:

Embedding PDF files in your Angular application. Highly configurable viewer including the toolbar, sidebar, and all the features you're used to.

734 lines 35.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSourceFile = getSourceFile; exports.addToModule = addToModule; exports.ngAdd = ngAdd; exports.updateAngularJsonRule = updateAngularJsonRule; exports.findModule = findModule; const core_1 = require("@angular-devkit/core"); const schematics_1 = require("@angular-devkit/schematics"); const tasks_1 = require("@angular-devkit/schematics/tasks"); const change_1 = require("@schematics/angular/utility/change"); const find_module_1 = require("@schematics/angular/utility/find-module"); const ts = require("typescript"); const ast_utils_1 = require("./ast-utils"); /** * Builder/executor names that produce a browser bundle and therefore need * the library's assets configured. `angular.json` stores this name under * `builder`; Nx project.json stores it under `executor`. Match either. */ const SUPPORTED_BROWSER_BUILDERS = [ '@angular-devkit/build-angular:browser', '@angular-devkit/build-angular:application', '@angular/build:application', // Angular 17+ modern builder, default in 22 '@nrwl/angular:webpack-browser', '@nx/angular:webpack-browser', '@nx/angular:application', '@nx/angular:browser', '@nx/vite:build', '@nrwl/vite:build', ]; /** * Detects the Angular version from package.json */ function detectAngularVersion(tree) { const packageJsonBuffer = tree.read('/package.json'); if (!packageJsonBuffer) { return null; } const packageJson = JSON.parse(packageJsonBuffer.toString()); const angularCore = packageJson.dependencies?.['@angular/core'] || packageJson.devDependencies?.['@angular/core'] || packageJson.peerDependencies?.['@angular/core']; if (angularCore) { // Extract version number from version string (e.g., "^17.0.0", "~16.2.5", "18.0.0-rc.0") const versionMatch = angularCore.match(/(\d+)\.(\d+)\.(\d+)/); if (versionMatch) { return { major: parseInt(versionMatch[1], 10), minor: parseInt(versionMatch[2], 10), patch: parseInt(versionMatch[3], 10), }; } } return null; } /** * Checks if the Angular version is supported */ function isSupportedAngularVersion(version) { if (!version) { console.log('Warning: Could not detect Angular version. Proceeding with default configuration.'); return true; } const isSupported = version.major >= 17 && version.major <= 22; if (!isSupported) { console.log(`Warning: Angular ${version.major}.${version.minor}.${version.patch} may not be fully tested.`); console.log('Supported Angular versions: 17.x - 21.x (22.x may work but is untested)'); } return true; // Still proceed, but with warning } /** * Reads file given path and returns TypeScript source file. */ function getSourceFile(host, path) { const buffer = host.read(path); if (!buffer) { throw new schematics_1.SchematicsException(`Could not find file for path: ${path}`); } const content = buffer.toString(); const source = ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true); return source; } /** * Import and add module to specific module path. */ function addToModule(host, modulePath, moduleName, src) { const moduleSource = getSourceFile(host, modulePath); const changes = (0, ast_utils_1.addImportToModule)(moduleSource, modulePath, moduleName, src); const recorder = host.beginUpdate(modulePath); changes.forEach((change) => { if (change instanceof change_1.InsertChange) { recorder.insertLeft(change.pos, change.toAdd); } }); host.commitUpdate(recorder); } function ngAdd(options) { return (tree, context) => { // Detect and validate Angular version const angularVersion = detectAngularVersion(tree); isSupportedAngularVersion(angularVersion); // Inform users about Angular 21+ zoneless support if (angularVersion && angularVersion.major >= 21) { console.log(''); console.log('✅ Angular 21+ detected - Zoneless support enabled!'); console.log(' ngx-extended-pdf-viewer fully supports Angular 21+ zoneless change detection.'); console.log(' The library will automatically detect and work in both zone.js and zoneless modes.'); console.log(''); console.log(' No configuration required for zoneless mode (default in Angular 21+).'); console.log(''); console.log(' Optional: To use zone.js instead, add to your app.config.ts:'); console.log(' provideZoneChangeDetection({ eventCoalescing: true })'); console.log(''); } // Load workspace config to get default project const workspaceConfig = loadWorkspaceConfig(tree); let projectName = options.project; if (!projectName || projectName === '') { projectName = options.defaultProject || workspaceConfig.defaultProject; } if (!projectName) { const availableProjects = Object.keys(workspaceConfig.projects); throw new schematics_1.SchematicsException(`No project specified and no default project found. Available projects: ${availableProjects.join(', ')}`); } // Set the resolved project name back to options for downstream code options.project = projectName; // Validate project configuration const workspaceConfigForValidation = validateProjectConfiguration(tree, projectName); const project = getProjectConfig(workspaceConfigForValidation, projectName); // Check if this is a library vs application (prefer projectType over path heuristics) const isLibrary = project.projectType === 'library' || (project.projectType !== 'application' && project.root && (project.root.startsWith('libs/') || project.root.includes('/libs/'))); // For applications, verify it has a browser/application build target. // We accept all builder/executor names we've seen in the wild: // - @angular-devkit/build-angular:browser (Angular 6-16) // - @angular-devkit/build-angular:application (Angular 17+ legacy) // - @angular/build:application (Angular 17+ modern, default in 22) // - Nx variants // angular.json stores this under `builder`; Nx project.json under `executor`. // We check both fields so the schematic works in both ecosystems. let hasBrowserBuild = false; if (!isLibrary) { const buildConfig = project.architect || project.targets; if (buildConfig) { hasBrowserBuild = Object.values(buildConfig).some((target) => { const builderName = target.executor || target.builder; return builderName && SUPPORTED_BROWSER_BUILDERS.some((b) => builderName.includes(b)); }); } } // Set defaults only if not already specified by user if (!options.path) { options.path = isLibrary ? 'lib/example-pdf-viewer' : 'app/example-pdf-viewer'; } if (!options.name) { options.name = 'example-pdf-viewer'; } if (options.skipImport === undefined) { options.skipImport = false; } const stable = options.stable; const exampleComponent = options.exampleComponent; // Schedule package installation - this is the main purpose of ng-add context.addTask(new tasks_1.NodePackageInstallTask()); if (exampleComponent && !isLibrary) { // Only generate example components for applications const folder = detectProjectStructure(tree, projectName, options.defaultProject); return (0, schematics_1.chain)([addDeclarationToNgModule(options), generateExampleComponent(folder, stable, options), updateAngularJsonRule(projectName, stable)]); } else if (exampleComponent && isLibrary) { console.log(`Skipping example component generation for library project "${projectName}".`); console.log("Libraries typically don't need example PDF viewer components."); return tree; // No asset configuration for libraries } // Deployment hint: pdf.js ships as `.mjs` modules. Browsers refuse to // execute them unless the server returns a JavaScript MIME type, but // some servers default to `application/octet-stream` for `.mjs`. We // can't reach the user's web server from a schematic, so we just warn. printDeploymentHints(); // For applications with browser build or libraries, update configuration if (!isLibrary && hasBrowserBuild) { return (0, schematics_1.chain)([updateAngularJsonRule(projectName, stable)]); } else if (isLibrary) { console.log(`Skipping asset configuration for library project "${projectName}".`); console.log("Libraries don't typically need browser assets configured."); return tree; // No configuration changes for libraries } else { console.log(`Warning: Project "${projectName}" doesn't appear to have a browser build target.`); console.log('Assets may not be configured correctly. You may need to manually add assets to your build configuration.'); return tree; } }; } function printDeploymentHints() { console.log(''); console.log('ℹ️ Deployment checklist for ngx-extended-pdf-viewer'); console.log(' pdf.js is loaded as ES modules. Some web servers default `.mjs`'); console.log(' to `application/octet-stream`, and browsers refuse to execute it.'); console.log(' Ensure your server returns a JavaScript MIME type for `.mjs`:'); console.log(' nginx : add `application/javascript mjs;` to a `types {}` block'); console.log(' Apache : `AddType application/javascript .mjs`'); console.log(' IIS : add `<mimeMap fileExtension=".mjs" mimeType="application/javascript" />`'); console.log(''); } /** * Detects the project structure to determine the correct source folder * Handles Angular CLI, Nx, and hybrid project structures */ function detectProjectStructure(tree, projectName, defaultProject) { const workspaceConfig = loadWorkspaceConfig(tree); const project = getProjectConfig(workspaceConfig, projectName); // Use sourceRoot if available (common in Nx) if (project.sourceRoot) { return `/${project.sourceRoot}`; } // Use root + src if available if (project.root) { const srcPath = `/${project.root}/src`; if (tree.exists(srcPath)) { return srcPath; } return `/${project.root}`; } // Fallback to Angular CLI-style detection const isDefaultProject = projectName === defaultProject; if (isDefaultProject) { // For root project, assume standard src structure return '/src'; } else { // Try different common project paths const possiblePaths = [ `/apps/${projectName}/src`, // Nx apps `/libs/${projectName}/src`, // Nx libs `/projects/${projectName}/src`, // Angular CLI `/apps/${projectName}`, // Nx apps without src `/libs/${projectName}`, // Nx libs without src `/projects/${projectName}`, // Angular CLI without src ]; for (const path of possiblePaths) { if (tree.exists(path)) { return path; } } // Last resort - assume standard structure return `/projects/${projectName}/src`; } } /** * Detects workspace type and loads configuration (Angular CLI, Nx, or hybrid) */ function loadWorkspaceConfig(tree) { // Try angular.json first (Angular CLI or migrated Nx) let configBuffer = tree.read('/angular.json'); if (configBuffer) { const config = JSON.parse(configBuffer.toString()); const projects = config.projects || {}; // If angular.json exists but has no projects, continue to Nx scan // (common in modern Nx hybrids where projects live in project.json files) if (Object.keys(projects).length > 0) { return { projects, type: 'angular', configPath: '/angular.json', defaultProject: config.defaultProject, }; } } // Try workspace.json (older Nx) configBuffer = tree.read('/workspace.json'); if (configBuffer) { const config = JSON.parse(configBuffer.toString()); return { projects: config.projects || {}, type: 'nx', configPath: '/workspace.json', defaultProject: config.defaultProject, }; } // Try nx.json with project.json files (modern Nx) const nxJsonBuffer = tree.read('/nx.json'); if (nxJsonBuffer) { const nxConfig = JSON.parse(nxJsonBuffer.toString()); const projects = {}; // Scan for project.json files const projectDirs = ['/apps', '/libs', '/projects']; for (const dir of projectDirs) { if (tree.exists(dir)) { const dirEntry = tree.getDir(dir); dirEntry.subdirs.forEach((subdir) => { const projectJsonPath = `${dir}/${subdir}/project.json`; if (tree.exists(projectJsonPath)) { const projectBuffer = tree.read(projectJsonPath); if (projectBuffer) { const projectConfig = JSON.parse(projectBuffer.toString()); // Use project name from config, fall back to folder name const projectName = projectConfig.name || subdir; projects[projectName] = { ...projectConfig, root: `${dir}/${subdir}`.substring(1), // Remove leading slash for consistency sourceRoot: `${dir}/${subdir}/src`.substring(1), }; } } }); } } return { projects, type: 'nx', configPath: '/nx.json', defaultProject: nxConfig.defaultProject, }; } throw new schematics_1.SchematicsException('Could not find workspace configuration (angular.json, workspace.json, or nx.json). This might not be an Angular or Nx project.'); } /** * Gets project configuration from workspace, handling both Angular CLI and Nx */ function getProjectConfig(workspaceConfig, projectName) { const project = workspaceConfig.projects[projectName]; if (!project) { const availableProjects = Object.keys(workspaceConfig.projects); throw new schematics_1.SchematicsException(`Project "${projectName}" not found in ${workspaceConfig.configPath}. Available projects: ${availableProjects.join(', ')}`); } return project; } /** * Validates the project configuration before proceeding */ function validateProjectConfiguration(tree, projectName) { const workspaceConfig = loadWorkspaceConfig(tree); const project = getProjectConfig(workspaceConfig, projectName); // Check for build configuration const buildConfig = project.architect || project.targets; if (!buildConfig) { throw new schematics_1.SchematicsException(`No build configuration found for project "${projectName}". The project might be misconfigured.`); } return workspaceConfig; } /** * ngx-extended-pdf-viewer's compiled JS bundle is ~1.2 MB — Angular CLI's * default 1 MB `initial` budget fails `ng build --configuration production` * the very first time the consumer builds. The pdf.js `.mjs` / `.wasm` / * font files (~4 MB) live under the `assets` array and are NOT included * in the budget; this raises only what's actually needed for the JS * bundle plus reasonable headroom for the consumer's own code. * * Idempotent: won't lower an already-raised budget. */ function relaxInitialBundleBudget(targetConfig, targetName) { const prod = targetConfig?.configurations?.production; if (!prod || !Array.isArray(prod.budgets)) return; let changed = false; prod.budgets = prod.budgets.map((b) => { if (b.type !== 'initial') return b; const parse = (v) => { if (typeof v !== 'string') return Number(v) || 0; const m = v.match(/^(\d+(?:\.\d+)?)\s*(kb|mb)?$/i); if (!m) return 0; return Number(m[1]) * (m[2]?.toLowerCase() === 'mb' ? 1024 * 1024 : 1024); }; // Library wrapper is ~1.2 MB; 2 MB warning leaves ~800 KB of consumer // headroom before warnings, 3 MB before errors. const want = { maximumWarning: '2mb', maximumError: '3mb' }; const newB = { ...b }; if (parse(b.maximumWarning) < parse(want.maximumWarning)) { newB.maximumWarning = want.maximumWarning; changed = true; } if (parse(b.maximumError) < parse(want.maximumError)) { newB.maximumError = want.maximumError; changed = true; } return newB; }); if (changed) { console.log(`Relaxed initial-bundle budget on ${targetName} (2mb warning / 3mb error) — the ngx-extended-pdf-viewer wrapper alone is ~1.2 MB.`); } } function updateAngularJsonRule(projectName, stable) { return (tree, _context) => { return updateAngularJson(tree, projectName, stable); }; } function updateAngularJson(tree, projectName, stable) { const workspaceConfig = loadWorkspaceConfig(tree); const project = getProjectConfig(workspaceConfig, projectName); let updated = false; // Handle both "architect" (Angular 6+) and "targets" (older versions) configurations const buildConfig = project.architect || project.targets; if (!buildConfig) { throw new schematics_1.SchematicsException(`No build configuration found for project "${projectName}".`); } // Helper function to normalize paths by removing trailing slashes const normalizePath = (path) => path.replace(/\/+$/, ''); // Helper function to add assets to a target's options const addAssetsToTarget = (target, targetName) => { if (!target?.options) { console.log(`No options found for ${targetName} target in project ${projectName}`); return false; } if (!target.options.assets) { target.options.assets = []; } // Detect Angular version to determine correct assets source folder const angularVersion = detectAngularVersion(tree); console.log('Angular version', angularVersion); const usePublicFolder = angularVersion && angularVersion.major >= 17; console.log('Use public folder:', usePublicFolder); // Prepare normalized asset paths const inputPath = stable ? 'node_modules/ngx-extended-pdf-viewer/assets/' : 'node_modules/ngx-extended-pdf-viewer/bleeding-edge/'; let assetsSourcePath; if (stable) { assetsSourcePath = 'assets'; } else { assetsSourcePath = 'bleeding-edge'; } const normalizedInputPath = normalizePath(inputPath); // Check if assets already exist to avoid duplicates (with path normalization) const existingAsset = target.options.assets.find((asset) => { // Handle object-form assets if (typeof asset === 'object' && asset !== null && asset.input !== null && asset.input !== undefined) { return normalizePath(asset.input) === normalizedInputPath; } // Handle string-form assets (though less common for this use case) if (typeof asset === 'string') { return normalizePath(asset) === normalizedInputPath; } return false; }); if (!existingAsset) { target.options.assets.push({ glob: '**/*', input: inputPath, output: assetsSourcePath, }); console.log(`Added assets to ${targetName} target in project ${projectName}`); return true; } else { console.log(`Assets already exist in ${targetName} target for project ${projectName}`); return false; } }; // First, try to find a build target by builder/executor. angular.json // stores the builder under `builder`; Nx project.json uses `executor`. let foundBuildTarget = false; for (const [targetName, target] of Object.entries(buildConfig)) { const targetConfig = target; const builderName = targetConfig.executor || targetConfig.builder; if (builderName && SUPPORTED_BROWSER_BUILDERS.some((b) => builderName.includes(b))) { if (addAssetsToTarget(targetConfig, targetName)) { updated = true; foundBuildTarget = true; } relaxInitialBundleBudget(targetConfig, targetName); break; // Only update one build target } } // If no executor-based target found, fall back to name heuristics (only build targets) if (!foundBuildTarget) { const buildTargetNames = ['build', 'application', 'esbuild', 'webpack', 'build-angular']; for (const targetName of buildTargetNames) { if (buildConfig[targetName]) { if (addAssetsToTarget(buildConfig[targetName], targetName)) { updated = true; } break; // Only update one build target } } } // If no suitable targets found, provide helpful error message if (!updated) { const availableTargets = buildConfig ? Object.keys(buildConfig) : []; console.log("Couldn't find suitable build target in workspace config"); console.log(`Available targets for project ${projectName}: ${availableTargets.join(', ')}`); console.log('Please manually add the following to your workspace config assets array:'); console.log('{'); console.log(" glob: '**/*',"); if (stable) { const angularVersion = detectAngularVersion(tree); const usePublicFolder = angularVersion && angularVersion.major >= 17; const outputPath = usePublicFolder ? 'public' : 'assets'; console.log(" input: 'node_modules/ngx-extended-pdf-viewer/assets/',"); console.log(` output: '${outputPath}',`); } else { console.log(" input: 'node_modules/ngx-extended-pdf-viewer/bleeding-edge/',"); console.log(" output: 'bleeding-edge',"); } console.log('}'); return tree; } // Write back the updated configuration if (workspaceConfig.type === 'nx' && workspaceConfig.configPath === '/nx.json') { // For modern Nx with project.json files, update the individual project.json const projectJsonPath = `/${project.root}/project.json`; if (tree.exists(projectJsonPath)) { const updatedProjectJson = JSON.stringify(project, null, 2); tree.overwrite(projectJsonPath, updatedProjectJson); } } else { // For angular.json or workspace.json const configBuffer = tree.read(workspaceConfig.configPath); if (configBuffer) { const config = JSON.parse(configBuffer.toString()); config.projects[projectName] = project; const updatedConfig = JSON.stringify(config, null, 2); tree.overwrite(workspaceConfig.configPath, updatedConfig); } } return tree; } function generateExampleComponent(folder, stable, options) { return (tree, context) => { context.logger.info('=== generateExampleComponent called ==='); // Detect Angular version and check folder existence const angularVersion = detectAngularVersion(tree); const usePublicFolder = angularVersion && angularVersion.major >= 17; context.logger.info(`Angular version: ${JSON.stringify(angularVersion)}`); context.logger.info(`Use public folder: ${usePublicFolder}`); // Get project configuration const workspaceConfig = loadWorkspaceConfig(tree); const project = getProjectConfig(workspaceConfig, options.project); const projectRoot = project.root || ''; context.logger.info(`Project root: ${projectRoot}`); // Check if assets or public folder exists const assetsPath = `${projectRoot ? projectRoot + '/' : ''}src/assets`; const publicPath = `${projectRoot ? projectRoot + '/' : ''}public`; context.logger.info('Checking paths:'); context.logger.info(` assetsPath: ${assetsPath} -> exists: ${tree.exists(assetsPath)}`); context.logger.info(` publicPath: ${publicPath} -> exists: ${tree.exists(publicPath)}`); let targetAssetsFolder; if (tree.exists(assetsPath)) { targetAssetsFolder = assetsPath; context.logger.info(`✓ Using assets folder (${assetsPath})`); } else if (usePublicFolder && tree.exists(publicPath)) { targetAssetsFolder = publicPath; context.logger.info(`✓ Using public folder (${publicPath})`); } else { // Fallback: create the appropriate folder targetAssetsFolder = usePublicFolder ? publicPath : assetsPath; context.logger.info(`✓ Fallback: creating ${targetAssetsFolder} folder`); } context.logger.info(`Final target folder: ${targetAssetsFolder}`); // Determine the correct PDF path for the component template const pdfPath = targetAssetsFolder === publicPath ? '' : '/assets'; context.logger.info(`PDF path for component template: "${pdfPath}"`); // Create two template sources - one for components, one for assets context.logger.info('Creating component template source...'); const componentTemplateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [ (0, schematics_1.applyTemplates)({ classify: core_1.strings.classify, dasherize: core_1.strings.dasherize, stable, standalone: options.standalone, pdfPath: pdfPath, }), // Filter out the assets folder from component templates (templateTree) => { context.logger.info('Component template - filtering assets...'); const filesBefore = []; templateTree.visit(path => filesBefore.push(path)); context.logger.info(`Template files before filter: ${filesBefore.join(', ')}`); // Delete all assets files/folders from component template const assetsToDelete = []; templateTree.visit((path) => { if (path.startsWith('/assets')) { assetsToDelete.push(path); } }); assetsToDelete.forEach(path => { context.logger.info(`Deleting asset from component template: ${path}`); templateTree.delete(path); }); const filesAfter = []; templateTree.visit(path => filesAfter.push(path)); context.logger.info(`Template files after filter: ${filesAfter.join(', ')}`); return templateTree; }, (0, schematics_1.move)((0, core_1.normalize)(folder)), ]); context.logger.info('Creating assets template source...'); // Separate template source for assets that copies to the correct target folder const assetsTemplateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [ // Filter to only include assets (templateTree) => { context.logger.info('Assets template - processing...'); const filesBefore = []; templateTree.visit(path => filesBefore.push(path)); context.logger.info(`Template files before asset filter: ${filesBefore.join(', ')}`); const assetsDir = templateTree.getDir('/assets'); if (assetsDir) { context.logger.info('Found assets directory, keeping only assets...'); // Keep only assets, remove everything else templateTree.visit((path) => { if (!path.startsWith('/assets')) { context.logger.info(`Deleting non-asset: ${path}`); templateTree.delete(path); } else { context.logger.info(`Keeping asset: ${path}`); } }); // If targeting public folder, rename /assets/* to /* to remove the assets prefix if (targetAssetsFolder === publicPath) { context.logger.info('Renaming assets to remove /assets prefix for public folder'); const assetsToRename = []; // Collect all assets that need to be renamed templateTree.visit((path) => { if (path.startsWith('/assets/')) { const entry = templateTree.get(path); if (entry && entry.content) { const newPath = path.substring('/assets'.length); // Remove /assets prefix assetsToRename.push({ oldPath: path, newPath, content: entry.content }); } } }); // Delete old paths and create new ones assetsToRename.forEach(({ oldPath, newPath, content }) => { context.logger.info(`Renaming ${oldPath} to ${newPath}`); templateTree.delete(oldPath); templateTree.create(newPath, content); }); } } else { context.logger.info('No assets directory found in template'); } const filesAfter = []; templateTree.visit(path => filesAfter.push(path)); context.logger.info(`Template files after asset filter: ${filesAfter.join(', ')}`); return templateTree; }, // Move assets to target location (0, schematics_1.move)((0, core_1.normalize)(`/${targetAssetsFolder}`)), ]); context.logger.info('Applying both template sources...'); return (0, schematics_1.chain)([ (0, schematics_1.mergeWith)(componentTemplateSource), (0, schematics_1.mergeWith)(assetsTemplateSource), ])(tree, context); }; } function addDeclarationToNgModule(options) { return (host) => { if (options.standalone) { return host; } const workspaceConfig = loadWorkspaceConfig(host); const project = getProjectConfig(workspaceConfig, options.project); if (options.skipImport || !options.module) { // Use project sourceRoot to find the correct module search paths const sourceRoot = project.sourceRoot || (0, core_1.join)(project.root || '', 'src').replace(/\\/g, '/'); const searchPaths = [ `${sourceRoot}/app`, sourceRoot, (0, core_1.normalize)((0, core_1.join)(sourceRoot, '..')), // Bubble up one level if needed ]; let foundModule; for (const searchPath of searchPaths) { foundModule = findModule(host, searchPath); if (foundModule) break; } options.module = foundModule; if (!options.module) { options.standalone = true; return host; } } const modulePath = options.module; const text = host.read(modulePath); if (text === null) { throw new schematics_1.SchematicsException(`File ${modulePath} does not exist.`); } const sourceText = text.toString('utf-8'); const source = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true); // Use project sourceRoot for component base path const sourceRoot = project.sourceRoot || (0, core_1.join)(project.root || '', 'src').replace(/\\/g, '/'); const componentBasePath = `/${sourceRoot}`; const componentPath = `${componentBasePath}/${options.path}/${core_1.strings.dasherize(options.name)}.component`; const relativePath = (0, find_module_1.buildRelativePath)(modulePath, componentPath); const componentChanges = (0, ast_utils_1.addDeclarationToModule)(source, modulePath, core_1.strings.classify(`${options.name}Component`), relativePath); const moduleChanges = (0, ast_utils_1.addImportToModule)(source, modulePath, core_1.strings.classify(`NgxExtendedPdfViewerModule`), 'ngx-extended-pdf-viewer'); const recorder = host.beginUpdate(modulePath); for (const change of componentChanges) { if (change instanceof change_1.InsertChange) { recorder.insertLeft(change.pos, change.toAdd); } } for (const change of moduleChanges) { if (change instanceof change_1.InsertChange) { recorder.insertLeft(change.pos, change.toAdd); } } host.commitUpdate(recorder); return host; }; } function findModule(host, generateDir, moduleExt = find_module_1.MODULE_EXT, routingModuleExt = find_module_1.ROUTING_MODULE_EXT) { let dir = host.getDir(`/${generateDir}`); let foundRoutingModule = false; while (dir) { const allMatches = dir.subfiles.filter((p) => p.endsWith(moduleExt)); const filteredMatches = allMatches.filter((p) => !p.endsWith(routingModuleExt)); foundRoutingModule = foundRoutingModule || allMatches.length !== filteredMatches.length; if (filteredMatches.length == 1) { return (0, core_1.join)(dir.path, filteredMatches[0]); } else if (filteredMatches.length > 1) { throw new Error('More than one module matches. Use the skip-import option to skip importing ' + 'the component into the closest module or use the module option to specify a module.'); } dir = dir.parent; } console.error(''); console.error("Error: Couldn't find a module. Assuming this is a stand-alone project. You need to add these lines to the decorator of the ExamplePdfViewerComponent:"); console.error(''); console.error('standalone: true,'); console.error('imports: [NgxExtendedPdfViewerModule],'); console.error(''); return undefined; } //# sourceMappingURL=index.js.map