mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-11-04 00:28:54 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			205 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// https://gitlab.com/antora/antora/-/issues/132#note_712132072
 | 
						|
'use strict'
 | 
						|
 | 
						|
const { posix: path } = require('path')
 | 
						|
 | 
						|
module.exports.register = function({ config }) {
 | 
						|
    this.on('contentClassified', ({ contentCatalog }) => {
 | 
						|
        contentCatalog.getComponents().forEach(component => {
 | 
						|
            const componentName = component.name;
 | 
						|
            const generationToVersion = new Map();
 | 
						|
            component.versions.forEach(version => {
 | 
						|
                const generation = getGeneration(version.version);
 | 
						|
                const original = generationToVersion.get(generation);
 | 
						|
                if (original === undefined || (original.prerelease && !version.prerelease)) {
 | 
						|
                    generationToVersion.set(generation, version);
 | 
						|
                }
 | 
						|
            });
 | 
						|
 | 
						|
            const versionToGeneration = Array.from(generationToVersion.entries()).reduce((acc, entry) => {
 | 
						|
                const [ generation, version ] = entry;
 | 
						|
                acc.set(version.version, generation);
 | 
						|
                return acc;
 | 
						|
            }, new Map());
 | 
						|
 | 
						|
            contentCatalog.findBy({ component: componentName }).forEach((file) => {
 | 
						|
                const candidateVersion = file.src.version;
 | 
						|
                if (versionToGeneration.has(candidateVersion)) {
 | 
						|
                    const generation = versionToGeneration.get(candidateVersion);
 | 
						|
                    if (file.out) {
 | 
						|
                        if (file.out) {
 | 
						|
                            file.out.dirname = file.out.dirname.replace(candidateVersion, generation)
 | 
						|
                            file.out.path = file.out.path.replace(candidateVersion, generation);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    if (file.pub) {
 | 
						|
                        file.pub.url = file.pub.url.replace(candidateVersion, generation)
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            });
 | 
						|
            versionToGeneration.forEach((generation, mappedVersion) => {
 | 
						|
                contentCatalog.getComponent(componentName).versions.filter(version => version.version === mappedVersion).forEach((version) => {
 | 
						|
                    version.url = version.url.replace(mappedVersion, generation);
 | 
						|
                })
 | 
						|
                const symbolicVersionAlias = createSymbolicVersionAlias(
 | 
						|
                    componentName,
 | 
						|
                    mappedVersion,
 | 
						|
                    generation,
 | 
						|
                    'redirect:to'
 | 
						|
                )
 | 
						|
                symbolicVersionAlias.src.version = generation;
 | 
						|
                contentCatalog.addFile(symbolicVersionAlias);
 | 
						|
            });
 | 
						|
        })
 | 
						|
    })
 | 
						|
}
 | 
						|
 | 
						|
function createSymbolicVersionAlias (component, version, symbolicVersionSegment, strategy) {
 | 
						|
    if (symbolicVersionSegment == null || symbolicVersionSegment === version) return
 | 
						|
    const family = 'alias'
 | 
						|
    const baseVersionAliasSrc = { component, module: 'ROOT', family, relative: '', basename: '', stem: '', extname: '' }
 | 
						|
    const symbolicVersionAliasSrc = Object.assign({}, baseVersionAliasSrc, { version: symbolicVersionSegment })
 | 
						|
    const symbolicVersionAlias = {
 | 
						|
        src: symbolicVersionAliasSrc,
 | 
						|
        pub: computePub(
 | 
						|
            symbolicVersionAliasSrc,
 | 
						|
            computeOut(symbolicVersionAliasSrc, family, symbolicVersionSegment),
 | 
						|
            family
 | 
						|
        ),
 | 
						|
    }
 | 
						|
    const originalVersionAliasSrc = Object.assign({}, baseVersionAliasSrc, { version })
 | 
						|
    const originalVersionSegment = computeVersionSegment(component, version, 'original')
 | 
						|
    const originalVersionAlias = {
 | 
						|
        src: originalVersionAliasSrc,
 | 
						|
        pub: computePub(
 | 
						|
            originalVersionAliasSrc,
 | 
						|
            computeOut(originalVersionAliasSrc, family, originalVersionSegment),
 | 
						|
            family
 | 
						|
        ),
 | 
						|
    }
 | 
						|
    if (strategy === 'redirect:to') {
 | 
						|
        originalVersionAlias.out = undefined
 | 
						|
        originalVersionAlias.rel = symbolicVersionAlias
 | 
						|
        return originalVersionAlias
 | 
						|
    } else {
 | 
						|
        symbolicVersionAlias.out = undefined
 | 
						|
        symbolicVersionAlias.rel = originalVersionAlias
 | 
						|
        return symbolicVersionAlias
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function computeOut (src, family, version, htmlUrlExtensionStyle) {
 | 
						|
    let { component, module: module_, basename, extname, relative, stem } = src
 | 
						|
    if (component === 'ROOT') component = ''
 | 
						|
    if (module_ === 'ROOT') module_ = ''
 | 
						|
    let indexifyPathSegment = ''
 | 
						|
    let familyPathSegment = ''
 | 
						|
 | 
						|
    if (family === 'page') {
 | 
						|
        if (stem !== 'index' && htmlUrlExtensionStyle === 'indexify') {
 | 
						|
            basename = 'index.html'
 | 
						|
            indexifyPathSegment = stem
 | 
						|
        } else if (extname === '.adoc') {
 | 
						|
            basename = stem + '.html'
 | 
						|
        }
 | 
						|
    } else if (family === 'image') {
 | 
						|
        familyPathSegment = '_images'
 | 
						|
    } else if (family === 'attachment') {
 | 
						|
        familyPathSegment = '_attachments'
 | 
						|
    }
 | 
						|
    const modulePath = path.join(component, version, module_)
 | 
						|
    const dirname = path.join(modulePath, familyPathSegment, path.dirname(relative), indexifyPathSegment)
 | 
						|
    const path_ = path.join(dirname, basename)
 | 
						|
    const moduleRootPath = path.relative(dirname, modulePath) || '.'
 | 
						|
    const rootPath = path.relative(dirname, '') || '.'
 | 
						|
 | 
						|
    return { dirname, basename, path: path_, moduleRootPath, rootPath }
 | 
						|
}
 | 
						|
 | 
						|
function computePub (src, out, family, version, htmlUrlExtensionStyle) {
 | 
						|
    const pub = {}
 | 
						|
    let url
 | 
						|
    if (family === 'nav') {
 | 
						|
        const component = src.component || 'ROOT'
 | 
						|
        const urlSegments = component === 'ROOT' ? [] : [component]
 | 
						|
        if (version) urlSegments.push(version)
 | 
						|
        const module_ = src.module || 'ROOT'
 | 
						|
        if (module_ !== 'ROOT') urlSegments.push(module_)
 | 
						|
        // an artificial URL used for resolving page references in navigation model
 | 
						|
        url = '/' + urlSegments.join('/') + '/'
 | 
						|
        pub.moduleRootPath = '.'
 | 
						|
    } else if (family === 'page') {
 | 
						|
        const urlSegments = out.path.split('/')
 | 
						|
        const lastUrlSegmentIdx = urlSegments.length - 1
 | 
						|
        if (htmlUrlExtensionStyle === 'drop') {
 | 
						|
            // drop just the .html extension or, if the filename is index.html, the whole segment
 | 
						|
            const lastUrlSegment = urlSegments[lastUrlSegmentIdx]
 | 
						|
            urlSegments[lastUrlSegmentIdx] =
 | 
						|
                lastUrlSegment === 'index.html' ? '' : lastUrlSegment.substr(0, lastUrlSegment.length - 5)
 | 
						|
        } else if (htmlUrlExtensionStyle === 'indexify') {
 | 
						|
            urlSegments[lastUrlSegmentIdx] = ''
 | 
						|
        }
 | 
						|
        url = '/' + urlSegments.join('/')
 | 
						|
    } else {
 | 
						|
        url = '/' + out.path
 | 
						|
        if (family === 'alias' && !src.relative.length) pub.splat = true
 | 
						|
    }
 | 
						|
 | 
						|
    pub.url = ~url.indexOf(' ') ? url.replace(SPACE_RX, '%20') : url
 | 
						|
 | 
						|
    if (out) {
 | 
						|
        pub.moduleRootPath = out.moduleRootPath
 | 
						|
        pub.rootPath = out.rootPath
 | 
						|
    }
 | 
						|
 | 
						|
    return pub
 | 
						|
}
 | 
						|
 | 
						|
function computeVersionSegment (name, version, mode) {
 | 
						|
    if (mode === 'original') return !version || version === 'master' ? '' : version
 | 
						|
    const strategy = this.latestVersionUrlSegmentStrategy
 | 
						|
    // NOTE: special exception; revisit in Antora 3
 | 
						|
    if (!version || version === 'master') {
 | 
						|
        if (mode !== 'alias') return ''
 | 
						|
        if (strategy === 'redirect:to') return
 | 
						|
    }
 | 
						|
    if (strategy === 'redirect:to' || strategy === (mode === 'alias' ? 'redirect:from' : 'replace')) {
 | 
						|
        const component = this.getComponent(name)
 | 
						|
        const componentVersion = component && this.getComponentVersion(component, version)
 | 
						|
        if (componentVersion) {
 | 
						|
            const segment =
 | 
						|
                componentVersion === component.latest
 | 
						|
                    ? this.latestVersionUrlSegment
 | 
						|
                    : componentVersion === component.latestPrerelease
 | 
						|
                        ? this.latestPrereleaseVersionUrlSegment
 | 
						|
                        : undefined
 | 
						|
            return segment == null ? version : segment
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return version
 | 
						|
}
 | 
						|
 | 
						|
function getGeneration(version) {
 | 
						|
    if (!version) return version;
 | 
						|
    const firstIndex = version.indexOf('.')
 | 
						|
    if (firstIndex < 0) {
 | 
						|
        return version;
 | 
						|
    }
 | 
						|
    const secondIndex = version.indexOf('.', firstIndex + 1);
 | 
						|
    const result = version.substr(0, secondIndex);
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
function out(args) {
 | 
						|
    console.log(JSON.stringify(args, no_data, 2));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function no_data(key, value) {
 | 
						|
    if (key == "data" || key == "files") {
 | 
						|
        return value ? "__data__" : value;
 | 
						|
    }
 | 
						|
    return value;
 | 
						|
}
 |