mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
92 lines
2.4 KiB
JavaScript
92 lines
2.4 KiB
JavaScript
const _ = require('lodash')
|
|
const { ignoreWords } = require('./prefer-kebab-url-ignore')
|
|
|
|
const removeTextBetweenBrackets = text => {
|
|
while (text.includes('[') || text.includes('(')) {
|
|
text = text.replaceAll(/\[[^[\]]*]/g, '')
|
|
text = text.replaceAll(/\([^()]*\)/g, '')
|
|
}
|
|
return text
|
|
}
|
|
|
|
const shouldIgnoreWord = str =>
|
|
str.includes(':') ||
|
|
str.includes('(') ||
|
|
str === '*' ||
|
|
str.match(/^[a-z0-9.]+$/) ||
|
|
ignoreWords.snake.has(str) ||
|
|
ignoreWords.camel.has(str) ||
|
|
ignoreWords.other.has(str)
|
|
|
|
const getSuggestion = routePath => {
|
|
if (typeof routePath === 'string') {
|
|
const kebabed = routePath
|
|
.split('/')
|
|
.map(word => (shouldIgnoreWord(word) ? word : _.kebabCase(word)))
|
|
.join('/')
|
|
return kebabed === routePath ? null : `'${kebabed}'`
|
|
}
|
|
|
|
if (routePath instanceof RegExp) {
|
|
const words = removeTextBetweenBrackets(routePath.source).match(/[\w-]+/g)
|
|
if (!words) return routePath
|
|
|
|
let newSource = routePath.source
|
|
for (const word of words) {
|
|
if (!shouldIgnoreWord(word)) {
|
|
newSource = newSource.replaceAll(
|
|
new RegExp(`\\b${word}\\b`, 'g'),
|
|
_.kebabCase(word)
|
|
)
|
|
}
|
|
}
|
|
|
|
const kebabed = new RegExp(newSource, routePath.flags)
|
|
return kebabed.source.toString() === routePath.source.toString()
|
|
? null
|
|
: kebabed
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
meta: {
|
|
type: 'problem',
|
|
fixable: 'code',
|
|
hasSuggestions: true,
|
|
docs: {
|
|
description: 'Enforce using kebab-case for URL paths',
|
|
},
|
|
},
|
|
create: context => ({
|
|
CallExpression(node) {
|
|
if (
|
|
node.callee.type === 'MemberExpression' &&
|
|
node.arguments[0]?.type === 'Literal' &&
|
|
[/app/i, /router/i].some(callee =>
|
|
typeof callee === 'string'
|
|
? node.callee.object.name === callee
|
|
: callee.test(node.callee.object.name)
|
|
) &&
|
|
['get', 'post', 'put', 'delete'].includes(node.callee.property.name)
|
|
) {
|
|
const routePath = node.arguments[0].value
|
|
|
|
const suggestion = getSuggestion(routePath)
|
|
|
|
if (suggestion) {
|
|
context.report({
|
|
node: node.arguments[0],
|
|
message: 'Route path should be in kebab-case.',
|
|
suggest: [
|
|
{
|
|
desc: `Change to kebab-case: ${suggestion}`,
|
|
fix: fixer => fixer.replaceText(node.arguments[0], suggestion),
|
|
},
|
|
],
|
|
})
|
|
}
|
|
}
|
|
},
|
|
}),
|
|
}
|