Skip to content

Instantly share code, notes, and snippets.

View phenomnomnominal's full-sized avatar
🥑
Hangry

Craig Spence phenomnomnominal

🥑
Hangry
View GitHub Profile
const FAILURE_MESSAGE = 'Found magic `loadChildren` string. Use a function with `import` instead.';
export class Rule extends Rules.AbstractRule {
public apply(sourceFile: SourceFile): Array<RuleFailure> {
// ...
// Try to fix indentation in replacement:
const { character } = sourceFile.getLineAndCharacterOfPosition(result.getStart());
fix = fix.replace(/\n/g, `\n${' '.repeat(character)}`);
const replacement = new Replacement(valueNode.getStart(), valueNode.getWidth(), fix);
const FAILURE_MESSAGE = 'Found magic `loadChildren` string. Use a function with `import` instead.';
export class Rule extends Rules.AbstractRule {
public apply(sourceFile: SourceFile): Array<RuleFailure> {
// ...
// Try to fix indentation in replacement:
const { character } = sourceFile.getLineAndCharacterOfPosition(result.getStart());
fix = fix.replace(/\n/g, `\n${' '.repeat(character)}`);
const replacement = new Replacement(valueNode.getStart(), valueNode.getWidth(), fix);
export class Rule extends Rules.AbstractRule {
public apply(sourceFile: SourceFile): Array<RuleFailure> {
// ...
let fix = preferAsync === 'async' ? this._asyncReplacement(valueNode.text) : this._promiseReplacement(valueNode.text);
// ...
}
private _promiseReplacement (loadChildren: string): string {
const [path, moduleName] = this._getChunks(loadChildren);
return `() => import('${path}').then(m => m.${moduleName})`;
// Constants:
const LOAD_CHILDREN_VALUE_QUERY = `StringLiteral[value=/.*${LOAD_CHILDREN_SPLIT}.*/]`;
const LOAD_CHILDREN_ASSIGNMENT_QUERY = `PropertyAssignment:not(:has(Identifier[name="children"])):has(Identifier[name="loadChildren"]):has(${LOAD_CHILDREN_VALUE_QUERY})`;
export class Rule extends Rules.AbstractRule {
public apply(sourceFile: SourceFile): Array<RuleFailure> {
const options = this.getOptions();
const [preferAsync] = options.ruleArguments;
return tsquery(sourceFile, LOAD_CHILDREN_ASSIGNMENT_QUERY).map(result => {
// Dependencies:
import { tsquery } from '@phenomnomnominal/tsquery';
import { Replacement, RuleFailure, Rules } from 'tslint';
import { SourceFile } from 'typescript';
// Constants:
const LOAD_CHILDREN_SPLIT = '#';
const LOAD_CHILDREN_VALUE_QUERY = `StringLiteral[value=/.*${LOAD_CHILDREN_SPLIT}.*/]`;
const LOAD_CHILDREN_ASSIGNMENT_QUERY = `PropertyAssignment:not(:has(Identifier[name="children"])):has(Identifier[name="loadChildren"]):has(${LOAD_CHILDREN_VALUE_QUERY})`;
export function listLazyRoutes(
moduleMeta: CompileNgModuleMetadata, reflector: StaticReflector): LazyRoute[] {
const allLazyRoutes: LazyRoute[] = [];
for (const {provider, module} of moduleMeta.transitiveModule.providers) {
if (tokenReference(provider.token) === reflector.ROUTES) {
const loadChildren = _collectLoadChildren(provider.useValue);
for (const route of loadChildren) {
allLazyRoutes.push(parseLazyRoute(route, reflector, module.reference));
}
}
export class RouterConfigLoader {
// ...
private loadModuleFactory(loadChildren: LoadChildren): Observable<NgModuleFactory<any>> {
if (typeof loadChildren === 'string') {
// ...
} else {
return wrapIntoObservable(loadChildren()).pipe(mergeMap((t: any) => {
if (t instanceof NgModuleFactory) {
return of (t);
} else {
/**
* A function that is called to resolve a collection of lazy-loaded routes.
*/
export type LoadChildrenCallback = () => Type<any>| NgModuleFactory<any>| Promise<Type<any>>| Observable<Type<any>>;
/**
* A string of the form `path/to/file#exportName` that acts as a URL for a set of routes to load,
* or a function that returns such a set.
*/
export type LoadChildren = string | LoadChildrenCallback;
export const ROUTES = new InjectionToken<Route[][]>('ROUTES');
export class RouterConfigLoader {
// ...
load(parentInjector: Injector, route: Route): Observable<LoadedRouterConfig> {
// ...
const moduleFactory$ = this.loadModuleFactory(route.loadChildren !);
// ...
}
@NgModule({declarations: ROUTER_DIRECTIVES, exports: ROUTER_DIRECTIVES})
export class RouterModule {
// ...
static forRoot(routes: Routes, config?: ExtraOptions): ModuleWithProviders {
return {
ngModule: RouterModule,
providers: [
// ...
provideRoutes(routes),