KnodesCommunity/typedoc-plugins

View on GitHub
packages/plugin-pages/src/converter/page-tree/utils.ts

Summary

Maintainability
A
0 mins
Test Coverage
A
93%
import assert from 'assert';

import { isNil, isObject, isString, startCase } from 'lodash';
import { PascalCase } from 'type-fest';
import { Reflection, normalizePath } from 'typedoc';

import { join as _join } from '@knodes/typedoc-pluginutils/path';

import { ANodeReflection } from '../../models/reflections';
import { IPageNode } from '../../options';

export const join = ( ...segments: Array<string | undefined | null> ) => {
    const segmentsNormalized = segments.filter( isString ).map( normalizePath );
    const joined = normalizePath( _join( ...segmentsNormalized ) );
    const leadingDots = segmentsNormalized[0].match( /^((\.{1,2}[/\\])+)/ );
    return `${leadingDots ? leadingDots[0] : ''}${joined}`;
};

const trimExt = ( file: string ) => {
    if( !file.match( /\.[^/.]+$/ ) ){
        throw new Error( `Invalid non-extension filename "${file}"` );
    }
    return file.replace( /\.[^/.]+$/, '' );
};
export const getDir = ( node: IPageNode, kind: 'output' | 'source' ): string => {
    const childKey = `children${startCase( kind )}Dir` as `children${PascalCase<typeof kind>}Dir`;
    const childVal = node[childKey];
    if( isString( childVal ) ){
        return childVal;
    } else if( isString( node.childrenDir ) ){
        return node.childrenDir;
    } else {
        const val = node[kind];
        if( !isString( val ) ){
            if( kind === 'output' ){
                return node.childrenDir ?? ( node.source ? trimExt( node.source ) : '.' );
            }
            return '.';
        }
        return trimExt( val );
    }
};

export const getNodeUrl = ( node: IPageNode ): string => {
    if( node.output ){
        if( node.output.endsWith( '.html' ) ){
            return node.output;
        } else {
            // TODO: Maybe throw if config
            return `${node.output}.html`;
        }
    } else {
        assert( node.source );
        const filenameNoExt = trimExt( node.source );
        if( node.children && isNil( node.childrenDir ) && isNil( node.childrenOutputDir ) ){
            return `${filenameNoExt}/index.html`;
        }
        return `${filenameNoExt}.html`;
    }
};

type NodeOrRef = IPageNode | Reflection;
export const getNodePath = ( self?: NodeOrRef, parent?: NodeOrRef ): string => [ parent, self ]
    .filter( isObject )
    .flatMap( iterateNodeName )
    .map( p => JSON.stringify( p ) ).join( ' ⇥ ' );
const iterateNodeName = ( node?: NodeOrRef ): string[] => {
    if( node instanceof ANodeReflection ){
        return [ ...iterateNodeName( node.parent ), node.name ];
    } else if( node instanceof Reflection ){
        return [];
    } else if( node ){
        return [ node.name ];
    } else {
        return [];
    }
};