build(docs-infra): add NgModules references to provided injectables (#41960)

Parse the `providers` property of each NgModule doc and add this doc to
the `ngModules` property of each provided injectable.

PR Close #41960
This commit is contained in:
Pete Bacon Darwin 2021-05-06 22:07:22 +01:00 committed by Alex Rickabaugh
parent 85f5cb45d2
commit 71f37c9d9c
2 changed files with 41 additions and 0 deletions

View File

@ -158,6 +158,19 @@ module.exports = function processNgModuleDocs(getDocFromAlias, createDocMessage,
processNgModuleProviders(ngModuleDoc) { processNgModuleProviders(ngModuleDoc) {
// Add providers from the NgModule decorator. // Add providers from the NgModule decorator.
const providers = ngModuleDoc.ngmoduleOptions.providers || []; const providers = ngModuleDoc.ngmoduleOptions.providers || [];
// Update injectables which are provided by this NgModule
for (const provider of providers) {
const injectable = parseProvider(provider);
const injectableDocs = getDocFromAlias(injectable, ngModuleDoc);
if (injectableDocs.length !== 1) {
continue;
}
const injectableDoc = injectableDocs[0];
injectableDoc.ngModules = injectableDoc.ngModules || [];
injectableDoc.ngModules.push(ngModuleDoc);
}
// And also add those associated via the `Injectable` `providedIn` property. // And also add those associated via the `Injectable` `providedIn` property.
if (Array.isArray(ngModuleDoc.providers)) { if (Array.isArray(ngModuleDoc.providers)) {
for (const provider of ngModuleDoc.providers) { for (const provider of ngModuleDoc.providers) {
@ -168,6 +181,7 @@ module.exports = function processNgModuleDocs(getDocFromAlias, createDocMessage,
if (providers.length > 0) { if (providers.length > 0) {
ngModuleDoc.providers = providers; ngModuleDoc.providers = providers;
} }
} }
}; };
@ -191,6 +205,15 @@ module.exports = function processNgModuleDocs(getDocFromAlias, createDocMessage,
} }
}; };
function parseProvider(provider) {
const match = /\{\s*provide:\s*(\w+)\s*,/.exec(provider);
if (match) {
return match[1];
} else {
return provider;
}
}
/** /**
* Compute the name of the array that will hold items of this type in the NgModule document. * Compute the name of the array that will hold items of this type in the NgModule document.
*/ */

View File

@ -150,6 +150,24 @@ describe('processNgModuleDocs processor', () => {
expect(nonInjectable.ngModules).toBeUndefined(); expect(nonInjectable.ngModules).toBeUndefined();
}); });
it('should link injectables that are parsed out of `@NgModule` decorators', () => {
const ngModule1 = { docType: 'ngmodule', id: 'NgModule1', ngmoduleOptions: { providers: ['Injectable1', '{ provide: Injectable2, useClass: Injectable2 }'] } };
const ngModule2 = { docType: 'ngmodule', id: 'NgModule2', ngmoduleOptions: { providers: ['{ provide: Injectable3, useValue: {} }'] } };
const injectable1 = { docType: 'class', name: 'Injectable1', aliases: ['Injectable1'] };
const injectable2 = { docType: 'class', name: 'Injectable2', aliases: ['Injectable2'] };
const injectable3 = { docType: 'class', name: 'Injectable3', aliases: ['Injectable3'] };
const aliasMap = injector.get('aliasMap');
aliasMap.addDoc(injectable1);
aliasMap.addDoc(injectable2);
aliasMap.addDoc(injectable3);
processor.$process([ngModule1, ngModule2, injectable1, injectable2, injectable3]);
expect(injectable1.ngModules).toEqual([ngModule1]);
expect(injectable2.ngModules).toEqual([ngModule1]);
expect(injectable3.ngModules).toEqual([ngModule2]);
});
it('should error if an injectable that has a `providedIn` property that references an unknown NgModule doc', () => { it('should error if an injectable that has a `providedIn` property that references an unknown NgModule doc', () => {
const log = injector.get('log'); const log = injector.get('log');
const injectable = { docType: 'class', name: 'Injectable1', decorators: [{ name: 'Injectable', argumentInfo: [{ providedIn: 'NgModuleRef' }] }] }; const injectable = { docType: 'class', name: 'Injectable1', decorators: [{ name: 'Injectable', argumentInfo: [{ providedIn: 'NgModuleRef' }] }] };