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

feat: textlint-rule-allowed-uris.js #19

Merged
merged 7 commits into from
Aug 15, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ name: test
on:
push:
branches: [main]
paths: ['src/**/*.js', 'tests/**/*.js']
paths: ['src/**', 'tests/**']

pull_request:
branches: [main]
paths: ['src/**/*.js', 'tests/**/*.js']
paths: ['src/**', 'tests/**']

jobs:
test:
Expand Down
316 changes: 148 additions & 168 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"prepublishOnly": "npm run build",
"build": "npx babel src -d build",
"test": "concurrently \"npm:test-*\"",
"test-tests": "npx mocha ./tests --inline-diffs true",
"test-utils": "npx mocha ./tests/utils --inline-diffs true",
"lint": "concurrently \"npm:lint-*\"",
"lint-eslint": "npx eslint . --ext .js",
Expand All @@ -40,7 +41,10 @@
"lint-markdownlint": "npx markdownlint **/*.md",
"fix": "concurrently \"npm:fix-*\"",
"fix-eslint": "npx eslint . --fix --ext .js",
"fix-prettier": "npx prettier . --write"
"fix-prettier": "npx prettier . --write",
"textlint-pretty": "npx textlint tests/textlint-rule-allowed-uris.data.md --rulesdir ./src -f pretty-error",
"textlint-stylish": "npx textlint tests/textlint-rule-allowed-uris.data.md --rulesdir ./src -f stylish",
"textlint-json": "npx textlint tests/textlint-rule-allowed-uris.data.md --rulesdir ./src -f json"
},
"peerDependencies": {
"textlint": "^14.0.4"
Expand All @@ -60,7 +64,8 @@
"lint-staged": "^15.2.8",
"markdownlint-cli": "^0.41.0",
"mocha": "^10.7.3",
"prettier": "^3.3.3"
"prettier": "^3.3.3",
"textlint-tester": "^14.0.5"
},
"dependencies": {
"ansi-colors": "^4.1.3",
Expand All @@ -75,7 +80,8 @@
],
"*.js": "npx eslint",
"*.md": "npx markdownlint",
"{src,tests}/**/*.js": [
"{src,tests}/**": [
"npm run test-tests",
"npm run test-utils"
]
}
Expand Down
1 change: 0 additions & 1 deletion src/index.js

This file was deleted.

72 changes: 72 additions & 0 deletions src/textlint-rule-allowed-uris.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const c = require('ansi-colors');
const getUriList = require('./utils/getUriList');

/**
* The main reporter function that processes the node and reports any issues based on the specified options.
*
* @async
* @param {Object} context The context object containing the `report`, `locator`, and `RuleError`.
* @param {function} context.report Function to report errors or issues.
* @param {function} context.locator Function to locate the position of the node in the source.
* @param {function} context.RuleError Constructor to create a new rule error.
* @param {Object} options Configuration options containing `allowed` and `disallowed` URI patterns.
* @param {Object} [options.allowed] Object specifying `allowed` URI patterns.
* @param {RegExp[]} [options.allowed.links] Array of regular expressions for allowed links URIs.
* @param {RegExp[]} [options.allowed.images] Array of regular expressions for allowed images URIs.
* @param {Object} [options.disallowed] Object specifying `disallowed` URI patterns.
* @param {RegExp[]} [options.disallowed.links] Array of regular expressions for disallowed links URIs.
* @param {RegExp[]} [options.disallowed.images] Array of regular expressions for disallowed images URIs.
* @param {Object} node The node to be processed, containing potential URIs.
* @returns {Promise<void>} A `Promise` that resolves when the reporting is completed.
*/
const reporter = async ({ report, locator, RuleError }, options, node) => {
/* Initialize options */
const regexes = {
allowed: {
links: options?.allowed?.links ?? [/.*/],
images: options?.allowed?.images ?? [/.*/],
},
disallowed: {
links: options?.disallowed?.links ?? [],
images: options?.disallowed?.images ?? [],
},
};

/* Report process */
(await getUriList(node)).uriList.forEach(({ uri, type }) => {
Object.keys(regexes).forEach(key => {
if (
key === 'allowed'
? !regexes[key][`${type}s`].some(regex => regex.test(uri))
: regexes[key][`${type}s`].some(regex => regex.test(uri))
)
report(
node,
new RuleError(
`${c.red.bold(`${key}.${type}s`)}\n${c.bold.red('-')} problem: '${c.strikethrough.bold.white(uri)}'\n${c.bold.red('-')} ${key} regular expressions: '${c.bold.white(regexes[key][`${type}s`].join(' or '))}'`,
{
padding: locator.at(0),
},
),
);
});
});
};

/**
* The module export function that returns an object mapping node types to the `reporter` function.
*
* @param {Object} context The context object provided to the `reporter`.
* @param {Object} options Configuration options for the `reporter`.
* @returns {Object} An object with node type keys mapping to the `reporter` function.
*/
module.exports = (context, options) => {
// TODO: Error When it is offline.

return Object.fromEntries(
['Link', 'Image', 'Definition', 'Html'].map(type => [
type,
async node => reporter(context, options, node),
]),
);
};
4 changes: 2 additions & 2 deletions src/utils/getDefinitionNodeUriType.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const axios = require('axios');
/**
* Retrieves the MIME type of a given URI.
*
* @private
* @async
* @param {string} uri The URI to check. It can be a remote or local URI.
* @returns {Promise<string>} A promise that resolves to the MIME type of the URI. Defaults to `application/octet-stream` if the MIME type can't be determined.
*/
Expand All @@ -22,7 +22,7 @@ const getMimeType = async uri => {
/**
* Retrieves the type of a given URI.
*
* @public
* @async
* @param {string} uri The URI to check. It can be a remote or local URI.
* @returns {Promise<string>} A promise that resolves to `'comment'` for empty(` `) or hash-only(`#`) URIs, `'image'` if the URI's MIME type is an image, and `'link'` for other types of URIs.
*/
Expand Down
2 changes: 2 additions & 0 deletions src/utils/getUriList.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const getUriListImage = node => new UriList().push(node.url, 'image');
/**
* Retrieves URI from a given `Definition` node and returns an instance of `UriList`.
*
* @async
* @param {Object} node `Definition` type node.
* @param {string} node.url The URI of the node.
* @returns {Promise<UriList>} A `Promise` that resolves to an instance of `UriList` containing the URI if it is of type `'link'` or `'image'`, otherwise resolves to an empty `UriList`.
Expand Down Expand Up @@ -59,6 +60,7 @@ const getUriListHtml = node => {
/**
* Retrieves the URI and creates an instance of `UriList` from a given `node`.
*
* @async
* @param {Object} node The node from which to retrieve the URI.
* @param {string} node.type The type of the node, which should be `Link`, `Image`, `Definition`, or `Html`.
* @returns {Promise<UriList>} A `Promise` that resolves to an instance of `UriList` retrieved from the `node`.
Expand Down
Loading