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 broken links #548

Merged
merged 18 commits into from
Mar 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ UD-Viz is a 3-package JavaScript framework for creating web applications for vis
[License](./LICENSE.md) —
[Getting Started](#getting-started)


**Online demos**:

* [Ud-Viz examples](https://ud-viz.vcityliris.data.alpha.grandlyon.com/)
Expand Down Expand Up @@ -67,7 +68,7 @@ npm install # resolve dependencies based on the package.json (and package-lock.j

### Run an example urban data web application

To quickly build and locally host the examples landing page which links to several [UD-Viz example applications](./packages/browser/examples/).
To quickly build and locally host the examples landing page which links to several [UD-Viz example applications](./examples/).

```bash
npm run start
Expand Down
123 changes: 122 additions & 1 deletion bin/remarkValidateLinks.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const exec = require('child-process-promise').exec;
const fs = require('fs');
const { Data } = require('@ud-viz/shared');

const FAILURE_THRESHOLD = 74; // TODO this threshold should lower help please
const FAILURE_THRESHOLD = 0; // no warning should be found

exec('npx remark -u validate-links .').then((result) => {
console.log(result.stderr);
Expand All @@ -15,4 +17,123 @@ exec('npx remark -u validate-links .').then((result) => {
throw new Error('Too much warnings report to log above to fix them');
}
}

// DETECT ABSOLUTE PATH in Link

/**
* directory to not parse
*/
const blackDirectoryList = ['node_modules'];

/**
*
* @param {string} path - path to check
* @returns {boolean} - true if path is an absolute path
*/
const isAbsolutePath = (path) => {
const noAbsolutePathPrefix = ['https', 'http', '.', '#'];
let result = true;
for (let index = 0; index < noAbsolutePathPrefix.length; index++) {
const prefix = noAbsolutePathPrefix[index];
if (path.startsWith(prefix)) {
result = false;
break;
}
}
return result;
};

/**
* Record log infos to display for absolute path check
*/
class LogInfosAbsolutePath {
constructor(filename) {
this.filename = filename;
this.absoluteLinks = [];
}

record(link) {
this.absoluteLinks.push(link);
}

log() {
console.log(this.filename);
console.log(this.absoluteLinks);
}
}

const logInfos = [];

const parseDirectory = (directoryPath) => {
const dirents = fs.readdirSync(directoryPath, { withFileTypes: true });
dirents.forEach((dirent) => {
if (dirent.isFile() && Data.computeFileFormat(dirent.name) == 'md') {
const filePath = directoryPath + '/' + dirent.name;
let logInfo = null;
const contentMd = fs.readFileSync(filePath, {
encoding: 'utf-8',
});

const linkRegexResult = contentMd.match(/\[(.*?)\]\(.*?\)/gm);

if (linkRegexResult) {
linkRegexResult.forEach((link) => {
// could be done with a regex but i didn't find one matching all cases
let lastCharacter = null;
let path = null;
for (let index = link.length - 1; index >= 0; index--) {
const character = link[index];
if (index == link.length - 1 && character != ')') {
console.log(link);
throw new Error('wrong link format');
}

// detect first ]( path is between there and the end of link
if (lastCharacter == '(' && character == ']') {
path = link.slice(index + 2, link.length - 1);
break;
}

lastCharacter = character;
}

if (!path) throw new Error('cant find path in link');

if (isAbsolutePath(path)) {
if (!logInfo) {
logInfo = new LogInfosAbsolutePath(filePath);
logInfos.push(logInfo);
}
logInfo.record(link);
}
});
}

if (!logInfo) console.log(filePath + ': no issues found');
} else if (
dirent.isDirectory() &&
!blackDirectoryList.includes(dirent.name)
) {
parseDirectory(directoryPath + '/' + dirent.name); // recursive
}
});
};

console.log('\nCheck Absolute path\n');
parseDirectory('.');

if (logInfos.length) {
console.log('\nFound Absolute path\n');

let countAbsolutePath = 0;
logInfos.forEach((logInfo) => {
logInfo.log();
countAbsolutePath += logInfo.absoluteLinks.length;
});
throw new Error(
'There is ' +
countAbsolutePath +
' absolute path use relative path or URL instead'
);
}
});
6 changes: 3 additions & 3 deletions docs/static/Devel/ArchitectureMVCTargetDesign.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ We propose a nomenclature to use when working with classes in a module, so that

## Documents module

[[Detailed documentation](../../../packages/browser/src/Component/Widget/Server/Documents/README.md)]
[[Detailed documentation](./UD_Viz_Browser/Documents/README.md)]

The documents module follows an MVVM architecture :

![](Pictures/DocumentsArchitecture.png)
![](./Pictures/DocumentsArchitecture.png)

The model holds the documents and make requests to the server, the view model filter those documents and the view displays the filtered documents.

Expand All @@ -104,7 +104,7 @@ The code is separated in two main parts : the view and the service. It ressemble
* The service makes the appropriate request to the server, and processes the received data
* It then notifies the listeners. The service follows a simple implementation of the [Observer pattern](https://en.wikipedia.org/wiki/Observer_pattern) where observers are just callbacks without arguments (called listeners). The view has subscribed to the service when it was created, so it received the notification of the service and can update itself.

![](Pictures/ViewServiceArchitecture.png)
![](./Pictures/ViewServiceArchitecture.png)

### Services

Expand Down