Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Routing aliases #1148

Merged
merged 1 commit into from
Nov 23, 2021
Merged

Fix: Routing aliases #1148

merged 1 commit into from
Nov 23, 2021

Conversation

Bengejd
Copy link
Contributor

@Bengejd Bengejd commented Nov 19, 2021

Relevant Issues:

#1108, #403, #885

Reasoning for PR

Compodoc has had this long-standing issue for quite some time now, and it's baring the entry for a lot of companies to utilize this library. The majority of mid-sized+ companies will utilize aliases for imports. Previously, the current work-around was to simply use relative imports for the routes:

../core/components/somecomponent/somecomponent.route.ts

instead of a nice import path of:

app/core/components/somecomponent/somecomponent.route.ts

This doesn't look like that big of a deal, but when you're importing sibling & nested routes, it becomes quite the hassle at scale.

In my case, I was originally receiving a path with the value of:

C:/Users/Benge/Documents/GitHub/@myclient/src/app/app/core/components/patients-list/patients-list.routes.ts

With the issue being

.../app/app/...

because while .../app/core/... is a existing file path, .../app/app/core/... is not.

Cause of issue

let importPath = path.resolve(
                        path.dirname(file.getFilePath()) +
                            '/' +
                            searchedImport.getModuleSpecifierValue() +
                            '.ts'
                    );

With path.dirname(file.getFilePath() having a value of C:/Users/Benge/Documents/GitHub/@myclient/src/app and searchedImport.getModuleSpecifierValue() having a value of app/core/components/patients-list/patients-list.routes.ts

Solution

My solution is simply a bandaid until a more long-term fix of the route-parser can be implemented, but to break it down:

// Reusable function to check to see if the path is bad or not. Can be inlined since it's only used once now.
const routePathIsBad = (path) => {
    return typeof ast.getSourceFile(path) == 'undefined';
};

// Returns an array of indicies for a given string.
const getIndicesOf = (searchStr, str, caseSensitive) => {
    var searchStrLen = searchStr.length;
    if (searchStrLen == 0) {
        return [];
    }
    var startIndex = 0, index, indices = [];
    if (!caseSensitive) {
        str = str.toLowerCase();
        searchStr = searchStr.toLowerCase();
    }
    while ((index = str.indexOf(searchStr, startIndex)) > -1) {
        indices.push(index);
        startIndex = index + searchStrLen;
    }
    return indices;
}

// Should probably be a constant for easier debugging in the future.
const dirNamePath = path.dirname(file.getFilePath());

// Should probably be a constant for easier debugging in the future.
const searchedImportPath = searchedImport.getModuleSpecifierValue();

// Grabs the leading folder name from the import Path and returns it. `app/core/components` would return `app`
const leadingFilePath = searchedImportPath.split('/').shift();

// Set the importPath like usual
let importPath = path.resolve(dirNamePath + '/' + searchedImport.getModuleSpecifierValue() + '.ts');

// Check to see if the path is bad or not. 
if (routePathIsBad(importPath)) {

   // Grab the indexes of leadingFilePath that are in importPath
    let leadingIndices = getIndicesOf(leadingFilePath, importPath, true);
    if (leadingIndices.length > 1) { // Nested route fixes
        let startIndex = leadingIndices[0];
        let endIndex = leadingIndices[leadingIndices.length -1];
        
        // Recreate the string from the two pieces 
        importPath = importPath.slice(0, startIndex) + importPath.slice(endIndex);
    } else { // Top level route fixes
        // Grab the parent folder path and slap them together.
        importPath = path.dirname(dirNamePath) + '/' + searchedImportPath + '.ts';
    }
}

And bam! You have a working Compodoc with route aliases.

@vogloblinsky
Copy link
Contributor

Thanks for the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants