export function importPath(from: Path, to: Path): string { const relativePath = relative(dirname(from), dirname(to)); if (relativePath.startsWith('.')) { return relativePath; } if (!relativePath) { return generateCurrentDirImport(basename(to)); } return generateCurrentDirImport(join(relativePath, basename(to))); }
return (host: Tree, context: SchematicContext) => { const clientProject = getClientProject(host, options); if (clientProject.projectType !== 'application') { throw new SchematicsException(`Universal requires a project type of "application".`); } const clientArchitect = getClientArchitect(host, options); const outDir = getTsConfigOutDir(host, clientArchitect); const tsConfigExtends = basename(clientArchitect.build.options.tsConfig); if (!options.skipInstall) { context.addTask(new NodePackageInstallTask()); } const templateSource = apply(url('./files'), [ template({ ...strings, ...options as object, stripTsExtension: (s: string) => { return s.replace(/\.ts$/, ''); }, outDir, tsConfigExtends, }), move(clientProject.root), ]); return chain([ mergeWith(templateSource), addDependencies(), updateConfigFile(options), wrapBootstrapCall(options), addServerTransition(options), ])(host, context); };
buildProcess.once('close', (code: number) => { if (code === 0) { resolve(); } else { reject(new Error(`${basename(binary)} failed with code ${code}.`)); } });
return async (host: Tree, context: SchematicContext) => { const workspace = await getWorkspace(host); const clientProject = workspace.projects.get(options.clientProject); if (!clientProject || clientProject.extensions.projectType !== 'application') { throw new SchematicsException(`Universal requires a project type of "application".`); } const clientBuildTarget = clientProject.targets.get('build'); if (!clientBuildTarget) { throw targetBuildNotFoundError(); } const clientBuildOptions = (clientBuildTarget.options || {}) as unknown as BrowserBuilderOptions; const outDir = getTsConfigOutDir(host, clientBuildOptions.tsConfig); const clientTsConfig = normalize(clientBuildOptions.tsConfig); const tsConfigExtends = basename(clientTsConfig); // this is needed because prior to version 8, tsconfig might have been in 'src' // and we don't want to break the 'ng add @nguniversal/express-engine schematics' const rootInSrc = clientProject.root === '' && clientTsConfig.includes('src/'); const tsConfigDirectory = join(normalize(clientProject.root), rootInSrc ? 'src' : ''); if (!options.skipInstall) { context.addTask(new NodePackageInstallTask()); } const templateSource = apply(url('./files/src'), [ applyTemplates({ ...strings, ...options as object, stripTsExtension: (s: string) => s.replace(/\.ts$/, ''), }), move(join(normalize(clientProject.root), 'src')), ]); const rootSource = apply(url('./files/root'), [ applyTemplates({ ...strings, ...options as object, stripTsExtension: (s: string) => s.replace(/\.ts$/, ''), outDir, tsConfigExtends, rootInSrc, }), move(tsConfigDirectory), ]); return chain([ mergeWith(templateSource), mergeWith(rootSource), addDependencies(), updateConfigFile(options, tsConfigDirectory), wrapBootstrapCall(clientBuildOptions.main), addServerTransition(options, clientBuildOptions.main, clientProject.root), ]); };
export function parseName(path: string, name: string): Location { const nameWithoutPath = basename(name as Path); const namePath = dirname((path + '/' + name) as Path); return { name: nameWithoutPath, path: normalize('/' + namePath), }; }
function parsePath(path: string) { const pathNormalized = normalize(path) as Path; const filename = extname(pathNormalized) ? basename(pathNormalized) : ''; const directory = filename ? dirname(pathNormalized) : pathNormalized; return { path: pathNormalized, filename, directory, }; }
function optionsFromDir(moduleDir: DirEntry): ModuleOptions { const moduleName = basename(moduleDir.path); const routingModuleFileName = generateRoutingModuleFileName(moduleName); return { path: moduleDir.path, featureModuleFileName: generateFeatureModuleFileName(moduleName), featureModuleClassName: generateFeatureModuleClassName(moduleName), routingModuleFileName, routingModuleClassName: generateRoutingModuleClassName(moduleName), routingModuleImportPath: generateCurrentDirImport(routingModuleFileName), }; }
function shouldCreateModule(tree: Tree, filePath: Path): boolean { const dir = tree.getDir(normalize(dirname(filePath))); const fileName = basename(filePath); const isModuleExist = isFeatureModule(fileName) ? hasFeatureModuleInDir(dir) : hasRoutingModuleInDir(dir); if (isModuleExist) { return false; } return isFeatureModule(fileName) || hasComponentsInDir(dir); }
.map(assetPattern => { // Normalize string asset patterns to objects. if (typeof assetPattern === 'string') { const assetPath = normalize(assetPattern); const resolvedAssetPath = resolve(root, assetPath); // Check if the string asset is within sourceRoot. if (!resolvedAssetPath.startsWith(resolvedSourceRoot)) { throw new MissingAssetSourceRootException(assetPattern); } let glob: string, input: Path, output: Path; let isDirectory = false; try { isDirectory = host.isDirectory(resolvedAssetPath); } catch { isDirectory = true; } if (isDirectory) { // Folders get a recursive star glob. glob = '**/*'; // Input directory is their original path. input = assetPath; } else { // Files are their own glob. glob = basename(assetPath); // Input directory is their original dirname. input = dirname(assetPath); } // Output directory for both is the relative path from source root to input. output = relative(resolvedSourceRoot, resolve(root, input)); // Return the asset pattern in object format. return { glob, input, output }; } else { // It's already an AssetPatternObject, no need to convert. return assetPattern; } });
map(isDirectory => { let glob: string, input: Path, output: Path; if (isDirectory) { // Folders get a recursive star glob. glob = '**/*'; // Input directory is their original path. input = assetPath; } else { // Files are their own glob. glob = basename(assetPath); // Input directory is their original dirname. input = dirname(assetPath); } // Output directory for both is the relative path from source root to input. output = relative(resolvedSourceRoot, resolve(root, input)); // Return the asset pattern in object format. return { glob, input, output }; }),