@@ -2,6 +2,7 @@ import path from 'path'
22
33import { readCompressedJsonFileFallback } from '@/frame/lib/read-json-file'
44import { getOpenApiVersion } from '@/versions/lib/all-versions'
5+ import findPage from '@/frame/lib/find-page'
56import type {
67 AuditLogEventT ,
78 CategorizedEvents ,
@@ -20,6 +21,61 @@ type PipelineConfig = {
2021 appendedDescriptions : Record < string , string >
2122}
2223
24+ type TitleResolutionContext = {
25+ pages : Record < string , any >
26+ redirects : Record < string , string >
27+ }
28+
29+ // Resolves docs_reference_links URLs to page titles
30+ async function resolveReferenceLinksToTitles (
31+ docsReferenceLinks : string ,
32+ context : TitleResolutionContext ,
33+ ) : Promise < string > {
34+ if ( ! docsReferenceLinks || docsReferenceLinks === 'N/A' ) {
35+ return ''
36+ }
37+
38+ // Handle multiple comma-separated or space-separated links
39+ const links = docsReferenceLinks
40+ . split ( / [ , \s ] + / )
41+ . map ( ( link ) => link . trim ( ) )
42+ . filter ( ( link ) => link && link !== 'N/A' )
43+
44+ const titles = [ ]
45+ for ( const link of links ) {
46+ try {
47+ const page = findPage ( link , context . pages , context . redirects )
48+ if ( page ) {
49+ // Create a minimal context for rendering the title
50+ const renderContext = {
51+ currentLanguage : 'en' ,
52+ currentVersion : 'free-pro-team@latest' ,
53+ pages : context . pages ,
54+ redirects : context . redirects ,
55+ }
56+ const title = await page . renderProp ( 'title' , renderContext , { textOnly : true } )
57+ titles . push ( title )
58+ } else {
59+ // If we can't resolve the link, use the original URL
60+ titles . push ( link )
61+ }
62+ } catch ( error ) {
63+ // If resolution fails, use the original URL
64+ console . warn (
65+ `Failed to resolve title for link: ${ link } ` ,
66+ error instanceof Error
67+ ? error instanceof Error
68+ ? error . message
69+ : String ( error )
70+ : String ( error ) ,
71+ )
72+ titles . push ( link )
73+ }
74+ }
75+
76+ return titles . join ( ', ' )
77+ }
78+
2379// get audit log event data for the requested page and version
2480//
2581// returns an array of event objects that look like this:
@@ -87,17 +143,19 @@ export function getCategorizedAuditLogEvents(page: string, version: string) {
87143}
88144
89145// Filters audit log events based on allowlist values.
90- //
91- // * eventsToCheck: events to consider
92- // * allowListvalues: allowlist values to filter by
93- // * currentEvents: events already collected
94- // * pipelineConfig: audit log pipeline config data
95- export function filterByAllowlistValues (
96- eventsToCheck : RawAuditLogEventT [ ] ,
97- allowListValues : string | string [ ] ,
98- currentEvents : AuditLogEventT [ ] ,
99- pipelineConfig : PipelineConfig ,
100- ) {
146+ export async function filterByAllowlistValues ( {
147+ eventsToCheck,
148+ allowListValues,
149+ currentEvents = [ ] ,
150+ pipelineConfig,
151+ titleContext,
152+ } : {
153+ eventsToCheck : RawAuditLogEventT [ ]
154+ allowListValues : string | string [ ]
155+ currentEvents ?: AuditLogEventT [ ]
156+ pipelineConfig : PipelineConfig
157+ titleContext ?: TitleResolutionContext
158+ } ) {
101159 if ( ! Array . isArray ( allowListValues ) ) allowListValues = [ allowListValues ]
102160 if ( ! currentEvents ) currentEvents = [ ]
103161
@@ -112,12 +170,27 @@ export function filterByAllowlistValues(
112170 if ( seen . has ( event . action ) ) continue
113171 seen . add ( event . action )
114172
115- const minimal = {
173+ const minimal : AuditLogEventT = {
116174 action : event . action ,
117175 description : processAndGetEventDescription ( event , eventAllowlists , pipelineConfig ) ,
118176 docs_reference_links : event . docs_reference_links ,
119177 }
120178
179+ // Resolve reference link titles if context is provided
180+ if ( titleContext && event . docs_reference_links && event . docs_reference_links !== 'N/A' ) {
181+ try {
182+ minimal . docs_reference_titles = await resolveReferenceLinksToTitles (
183+ event . docs_reference_links ,
184+ titleContext ,
185+ )
186+ } catch ( error ) {
187+ console . warn (
188+ `Failed to resolve titles for event ${ event . action } :` ,
189+ error instanceof Error ? error . message : String ( error ) ,
190+ )
191+ }
192+ }
193+
121194 minimalEvents . push ( minimal )
122195 }
123196 }
@@ -132,6 +205,7 @@ export function filterByAllowlistValues(
132205// * currentEvents: events already collected
133206// * pipelineConfig: audit log pipeline config data
134207// * auditLogPage: the audit log page the event belongs to
208+ // * titleContext: optional context for resolving reference link titles
135209//
136210// Mutates `currentGhesEvents` and updates it with any new filtered for audit
137211// log events, the object maps GHES versions to page events for that version e.g.:
@@ -148,13 +222,21 @@ export function filterByAllowlistValues(
148222// user: [...],
149223// },
150224// }
151- export function filterAndUpdateGhesDataByAllowlistValues (
152- eventsToCheck : RawAuditLogEventT [ ] ,
153- allowListValue : string ,
154- currentGhesEvents : VersionedAuditLogData ,
155- pipelineConfig : PipelineConfig ,
156- auditLogPage : string ,
157- ) {
225+ export async function filterAndUpdateGhesDataByAllowlistValues ( {
226+ eventsToCheck,
227+ allowListValue,
228+ currentGhesEvents,
229+ pipelineConfig,
230+ auditLogPage,
231+ titleContext,
232+ } : {
233+ eventsToCheck : RawAuditLogEventT [ ]
234+ allowListValue : string
235+ currentGhesEvents : VersionedAuditLogData
236+ pipelineConfig : PipelineConfig
237+ auditLogPage : string
238+ titleContext ?: TitleResolutionContext
239+ } ) {
158240 if ( ! currentGhesEvents ) currentGhesEvents = { }
159241
160242 const seenByGhesVersion = new Map ( )
@@ -173,12 +255,27 @@ export function filterAndUpdateGhesDataByAllowlistValues(
173255 if ( seenByGhesVersion . get ( fullGhesVersion ) ?. has ( event . action ) ) continue
174256
175257 if ( ghesVersionAllowlists . includes ( allowListValue ) ) {
176- const minimal = {
258+ const minimal : AuditLogEventT = {
177259 action : event . action ,
178260 description : processAndGetEventDescription ( event , ghesVersionAllowlists , pipelineConfig ) ,
179261 docs_reference_links : event . docs_reference_links ,
180262 }
181263
264+ // Resolve reference link titles if context is provided
265+ if ( titleContext && event . docs_reference_links && event . docs_reference_links !== 'N/A' ) {
266+ try {
267+ minimal . docs_reference_titles = await resolveReferenceLinksToTitles (
268+ event . docs_reference_links ,
269+ titleContext ,
270+ )
271+ } catch ( error ) {
272+ console . warn (
273+ `Failed to resolve titles for event ${ event . action } :` ,
274+ error instanceof Error ? error . message : String ( error ) ,
275+ )
276+ }
277+ }
278+
182279 // we need to initialize as we go to build up the `minimalEvents`
183280 // object that we'll return which will contain the GHES events for
184281 // each versions + page type combos e.g. when processing GHES events
0 commit comments