Skip to content

Commit 286e4da

Browse files
JeanMechemmalerba
authored andcommitted
docs(docs-infra): Throw error at build time for invalid links (#59162)
PR Close #59162
1 parent 6dd8cce commit 286e4da

File tree

5 files changed

+47
-20
lines changed

5 files changed

+47
-20
lines changed

adev/shared-docs/pipeline/api-gen/rendering/symbol-context.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ export function getCurrentSymbol(): string | undefined {
3838
return currentSymbol;
3939
}
4040

41-
export function logUnknownSymbol(link: string, symbol: string): void {
42-
console.warn(
43-
`WARNING: {@link ${link}} is invalid, ${symbol} or ${currentSymbol}.${symbol} is unknown in this context`,
44-
);
41+
export function unknownSymbolMessage(link: string, symbol: string): string {
42+
return `WARNING: {@link ${link}} is invalid, ${symbol} or ${currentSymbol}.${symbol} is unknown in this context`;
4543
}

adev/shared-docs/pipeline/api-gen/rendering/test/marked.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ describe('markdown to html', () => {
3434
const symbols = new Map<string, string>([
3535
['AfterRenderPhase', 'core'],
3636
['afterRender', 'core'],
37+
['EmbeddedViewRef', 'core'],
38+
['ChangeDetectionStrategy', 'core'],
39+
['ChangeDetectorRef', 'core'],
40+
['withNoHttpTransferCache', 'platform-browser'],
41+
['withHttpTransferCacheOptions', 'platform-browser'],
42+
['withI18nSupport', 'platform-browser'],
43+
['withEventReplay', 'platform-browser'],
3744
]);
3845
setSymbols(symbols);
3946
for (const entry of entryJson.entries) {

adev/shared-docs/pipeline/api-gen/rendering/test/renderable.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {getRenderable} from '../processing';
1212
import {DocEntryRenderable} from '../entities/renderables';
1313
import {initHighlighter} from '../shiki/shiki';
1414
import {configureMarkedGlobally} from '../marked/configuration';
15+
import {setSymbols} from '../symbol-context';
1516

1617
// Note: The tests will probably break if the schema of the api extraction changes.
1718
// All entries in the fake-entries are extracted from Angular's api.
@@ -28,6 +29,19 @@ describe('renderable', () => {
2829
encoding: 'utf-8',
2930
});
3031
const entryJson = JSON.parse(entryContent) as any;
32+
const symbols = new Map<string, string>([
33+
['AfterRenderPhase', 'core'],
34+
['afterRender', 'core'],
35+
['EmbeddedViewRef', 'core'],
36+
['ChangeDetectionStrategy', 'core'],
37+
['ChangeDetectorRef', 'core'],
38+
['withNoHttpTransferCache', 'platform-browser'],
39+
['withHttpTransferCacheOptions', 'platform-browser'],
40+
['withI18nSupport', 'platform-browser'],
41+
['withEventReplay', 'platform-browser'],
42+
]);
43+
setSymbols(symbols);
44+
3145
for (const entry of entryJson.entries) {
3246
const renderableJson = getRenderable(entry, '@angular/fakeentry') as DocEntryRenderable;
3347
entries.set(entry['name'], renderableJson);

adev/shared-docs/pipeline/api-gen/rendering/test/transforms/jsdoc-transforms.spec.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ describe('jsdoc transforms', () => {
7070
name: 'see',
7171
comment: '{@link /cli/build ng build}',
7272
},
73-
{
74-
name: 'see',
75-
comment: '{@link cli/build ng build}',
76-
},
7773
{
7874
name: 'see',
7975
comment: '{@link /ecosystem/rxjs-interop/output-interop Output Interop}',
@@ -135,16 +131,24 @@ describe('jsdoc transforms', () => {
135131
url: '/cli/build',
136132
});
137133

138-
// TODO: in the future when all links are valid we would throw an error instead when not starting with a slash
139-
// Links should be absolute within adev (to support both next & stable site)
140134
expect(entry.additionalLinks[11]).toEqual({
141-
label: 'ng build',
142-
url: 'cli/build',
143-
});
144-
145-
expect(entry.additionalLinks[12]).toEqual({
146135
label: 'Output Interop',
147136
url: '/ecosystem/rxjs-interop/output-interop',
148137
});
149138
});
139+
140+
it('should throw on invalid relatie @link', () => {
141+
const entryFn = () =>
142+
addHtmlAdditionalLinks({
143+
jsdocTags: [
144+
{
145+
name: 'see',
146+
comment: '{@link cli/build ng build}',
147+
},
148+
],
149+
moduleName: 'test',
150+
});
151+
152+
expect(entryFn).toThrowError(/Forbidden relative link: cli\/build ng build/);
153+
});
150154
});

adev/shared-docs/pipeline/api-gen/rendering/transforms/jsdoc-transforms.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131

3232
import {getLinkToModule} from './url-transforms';
3333
import {addApiLinksToHtml} from './code-transforms';
34-
import {getCurrentSymbol, getModuleName, logUnknownSymbol} from '../symbol-context';
34+
import {getCurrentSymbol, getModuleName, unknownSymbolMessage} from '../symbol-context';
3535

3636
export const JS_DOC_REMARKS_TAG = 'remarks';
3737
export const JS_DOC_USAGE_NOTES_TAG = 'usageNotes';
@@ -186,6 +186,12 @@ function parseAtLink(link: string): {label: string; url: string} {
186186
if (rawSymbol.startsWith('#')) {
187187
rawSymbol = rawSymbol.substring(1);
188188
} else if (rawSymbol.includes('/')) {
189+
if (!rawSymbol.startsWith('/') && !rawSymbol.startsWith('http')) {
190+
throw Error(
191+
`Forbidden relative link: ${link}. Links should be absolute and start with a slash`,
192+
);
193+
}
194+
189195
return {
190196
url: rawSymbol,
191197
label: description ?? rawSymbol.split('/').pop()!,
@@ -204,11 +210,9 @@ function parseAtLink(link: string): {label: string; url: string} {
204210
moduleName = getModuleName(`${currentSymbol}.${symbol}`);
205211

206212
if (!moduleName || !currentSymbol) {
207-
// TODO: remove the links that generate this error
208-
// TODO: throw an error when there are no more warning generated
209-
logUnknownSymbol(link, symbol);
210-
return {label, url: '#'};
213+
throw unknownSymbolMessage(link, symbol);
211214
}
215+
212216
subSymbol = symbol;
213217
symbol = currentSymbol;
214218
}

0 commit comments

Comments
 (0)