Skip to content

Commit

Permalink
Merge pull request #19 from lumirlumir/feature-textlint-rule-allowed-…
Browse files Browse the repository at this point in the history
…uris

feat: textlint-rule-allowed-uris.js
  • Loading branch information
lumirlumir authored Aug 15, 2024
2 parents 0eaba5a + 8aab2cf commit 4cc3cf8
Show file tree
Hide file tree
Showing 11 changed files with 674 additions and 177 deletions.
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

0 comments on commit 4cc3cf8

Please sign in to comment.