@nestjsplus/lib-starter
Version:
Boilerplate for building installable NestJS libraries
135 lines (115 loc) • 3.38 kB
text/typescript
import { join, Path, strings, PathFragment } from '@angular-devkit/core';
import {
apply,
move,
Rule,
SchematicContext,
SchematicsException,
template,
Tree,
url,
} from '@angular-devkit/schematics';
import { addPackageJsonDependency } from '@schematics/angular/utility/dependencies';
import {
DeclarationOptions,
ModuleDeclarator,
ModuleFinder,
} from '@nestjsplus/schematics-utils';
import { lowerCase, upperCase, dashToUnderscore } from './string-utils';
import { PROJECT_ROOT_FILES, DEFAULT_PATH_NAME } from '../constants';
/**
* Returns true if Current Working Directory (CWD) is the
* project root (folder containing package.json and nest-cli.json)
*
* @param host Tree rooted at CWD
*/
export function inProjectRoot(host: Tree): boolean {
const currDir = host.getDir('.');
return PROJECT_ROOT_FILES.every(file =>
currDir.subfiles.includes(file as PathFragment),
);
}
export function readWorkspace(host: Tree): any {
const content = host.read('./nest-cli.json').toString();
if (!content) {
return;
}
return JSON.parse(content);
}
export function readPackageJson(host: Tree): any {
const content = host.read('./package.json').toString();
if (!content) {
return;
}
return JSON.parse(content);
}
// assumes that schematic is run from workspace root, thus
// sourceRoot is a relative path from workspace root
export function buildPathRelativeToWorkspaceRoot(sourceRoot): string {
const pathDots = sourceRoot.replace(/^\//, '').split('/').length - 1;
return '../'.repeat(pathDots);
}
export function getWorkspaceRoot(host: Tree) {
const workspace = readWorkspace(host);
}
export function generateFilesFromTemplates(
options,
templateUrl,
location,
): any {
return (context: SchematicContext) =>
apply(url(templateUrl as Path), [
template({
...strings,
...options,
lowerCase,
upperCase,
dashToUnderscore,
}),
move(location),
])(context);
}
export function addRootModuleImportAndMetadata(options): any {
const moduleOptions = Object.assign({}, options);
moduleOptions.metadata = 'imports';
moduleOptions.type = 'module';
return (tree: Tree) => {
if (moduleOptions.skipImport !== undefined && moduleOptions.skipImport) {
return tree;
}
// find the app root module
moduleOptions.module = new ModuleFinder(tree).find(
moduleOptions.sourceRoot,
);
if (!moduleOptions.module) {
return tree;
}
const content = tree.read(moduleOptions.module).toString();
const declarator: ModuleDeclarator = new ModuleDeclarator();
tree.overwrite(
moduleOptions.module,
declarator.declare(content, moduleOptions as DeclarationOptions),
);
return tree;
};
}
// fixme: take array of script
export function addNpmScripts(script): Rule {
return (host: Tree) => {
const pkgPath = '/package.json';
const buffer = host.read(pkgPath);
if (buffer === null) {
throw new SchematicsException('Could not find package.json');
}
const pkg = JSON.parse(buffer.toString());
pkg.scripts[script.name] = script.action;
host.overwrite(pkgPath, JSON.stringify(pkg, null, 2));
return host;
};
}
// fixme: take array of dep
function addPackageDependencies(dep): Rule {
return (host: Tree) => {
addPackageJsonDependency(host, dep);
};
}