seo-lint-next 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/CONTRIBUTING.md +21 -0
- package/LICENSE +21 -0
- package/README.md +85 -0
- package/SECURITY.md +5 -0
- package/assets/seo-lint-next-icon-512.png +0 -0
- package/assets/seo-lint-next-icon.png +0 -0
- package/dist/cli.cjs +1023 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1000 -0
- package/dist/cli.js.map +1 -0
- package/dist/eslint.cjs +907 -0
- package/dist/eslint.cjs.map +1 -0
- package/dist/eslint.d.cts +75 -0
- package/dist/eslint.d.ts +75 -0
- package/dist/eslint.js +874 -0
- package/dist/eslint.js.map +1 -0
- package/dist/index.cjs +912 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +875 -0
- package/dist/index.js.map +1 -0
- package/docs/industry-comparison.md +25 -0
- package/docs/rules/README.md +16 -0
- package/docs/rules/no-accidental-noindex.md +31 -0
- package/docs/rules/no-broken-heading-hierarchy.md +29 -0
- package/docs/rules/no-img-missing-alt.md +24 -0
- package/docs/rules/no-invalid-json-ld.md +33 -0
- package/docs/rules/no-missing-canonical.md +33 -0
- package/docs/rules/no-missing-description.md +29 -0
- package/docs/rules/no-missing-metadata-base.md +27 -0
- package/docs/rules/no-missing-og-tags.md +33 -0
- package/docs/rules/no-missing-sitemap.md +27 -0
- package/docs/rules/no-missing-title.md +30 -0
- package/examples/eslint.config.mjs +3 -0
- package/package.json +103 -0
package/dist/cli.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/rules/no-accidental-noindex.ts","../src/utils/ast.ts","../src/utils/files.ts","../src/utils/rule.ts","../src/rules/no-broken-heading-hierarchy.ts","../src/rules/no-img-missing-alt.ts","../src/rules/no-invalid-json-ld.ts","../src/rules/no-missing-canonical.ts","../src/rules/no-missing-description.ts","../src/rules/no-missing-metadata-base.ts","../src/rules/no-missing-og-tags.ts","../src/rules/no-missing-sitemap.ts","../src/rules/no-missing-title.ts","../src/eslint.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport process from 'node:process'\nimport tsParser from '@typescript-eslint/parser'\nimport fg from 'fast-glob'\nimport { Linter } from 'eslint'\nimport plugin from './eslint'\n\ntype CliOptions = {\n dir: string\n format: 'stylish' | 'json'\n strict: boolean\n}\n\nconst defaultSeverities: Record<string, 0 | 1 | 2> = {\n 'no-missing-title': 2,\n 'no-missing-metadata-base': 2,\n 'no-missing-description': 1,\n 'no-missing-canonical': 2,\n 'no-missing-og-tags': 1,\n 'no-broken-heading-hierarchy': 1,\n 'no-img-missing-alt': 1,\n 'no-accidental-noindex': 2,\n 'no-missing-sitemap': 1,\n 'no-invalid-json-ld': 2,\n}\n\nasync function main(): Promise<void> {\n const options = parseArgs(process.argv.slice(2))\n const cwd = process.cwd()\n const appDir = path.resolve(cwd, options.dir)\n\n if (!fs.existsSync(appDir)) {\n console.error(`seo-lint-next: app directory not found: ${options.dir}`)\n process.exitCode = 2\n return\n }\n\n const files = await fg(['**/*.{ts,tsx,js,jsx,mts,mjs}'], {\n cwd: appDir,\n absolute: true,\n ignore: ['**/node_modules/**', '**/.next/**'],\n })\n\n const linter = createLinter()\n const rules = Object.fromEntries(\n Object.keys(defaultSeverities).map((ruleName) => [\n `seo-lint-next/${ruleName}`,\n options.strict && defaultSeverities[ruleName] === 1 ? 2 : defaultSeverities[ruleName],\n ]),\n )\n\n const results = files.map((filePath) => {\n const text = fs.readFileSync(filePath, 'utf8')\n const messages = linter.verify(\n text,\n {\n parser: '@typescript-eslint/parser',\n parserOptions: {\n ecmaVersion: 'latest',\n sourceType: 'module',\n ecmaFeatures: { jsx: true },\n },\n rules,\n } as never,\n { filename: filePath },\n )\n return { filePath, messages }\n })\n\n if (options.format === 'json') {\n console.log(JSON.stringify(results, null, 2))\n } else {\n printStylish(results)\n }\n\n const hasErrors = results.some((result) => result.messages.some((message) => message.severity === 2))\n process.exitCode = hasErrors ? 1 : 0\n}\n\nfunction createLinter(): Linter {\n let linter: Linter\n try {\n linter = new Linter({ configType: 'eslintrc' } as never)\n } catch {\n linter = new Linter()\n }\n linter.defineParser('@typescript-eslint/parser', tsParser as never)\n for (const [ruleName, rule] of Object.entries(plugin.rules)) {\n linter.defineRule(`seo-lint-next/${ruleName}`, rule as never)\n }\n return linter\n}\n\nfunction parseArgs(args: string[]): CliOptions {\n const options: CliOptions = { dir: 'app', format: 'stylish', strict: false }\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index]\n if (arg === '--dir') options.dir = args[++index] ?? options.dir\n else if (arg === '--format') {\n const format = args[++index]\n if (format === 'json' || format === 'stylish') options.format = format\n else throw new Error(`Unsupported format: ${format}`)\n } else if (arg === '--strict') options.strict = true\n else if (arg === '--help' || arg === '-h') {\n console.log(`seo-lint-next\n\nUsage:\n seo-lint-next [--dir app] [--format stylish|json] [--strict]\n\nOptions:\n --dir App Router directory to lint. Defaults to app.\n --format Output format. Defaults to stylish.\n --strict Treat warnings as errors.\n`)\n process.exit(0)\n }\n }\n return options\n}\n\nfunction printStylish(results: Array<{ filePath: string; messages: Linter.LintMessage[] }>): void {\n let count = 0\n for (const result of results) {\n if (result.messages.length === 0) continue\n console.log(result.filePath)\n for (const message of result.messages) {\n count += 1\n const level = message.severity === 2 ? 'error' : 'warning'\n const line = String(message.line ?? 1).padStart(4)\n const column = String(message.column ?? 1).padEnd(3)\n console.log(` ${line}:${column} ${level.padEnd(7)} ${message.message} ${message.ruleId ?? ''}`)\n }\n console.log('')\n }\n if (count > 0) console.log(`${count} SEO issue${count === 1 ? '' : 's'} found.`)\n}\n\nmain().catch((error) => {\n console.error(error instanceof Error ? error.message : error)\n process.exitCode = 2\n})\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { getObjectProperty, getPathProperty, getStaticString, metadataSources, walk } from '../utils/ast'\nimport { findAppDir, findProjectRoot, isPageFile, routeIsPrivate } from '../utils/files'\nimport { createRule, report } from '../utils/rule'\n\nlet checkedRobots = false\n\nexport const noAccidentalNoindex = createRule(\n 'no-accidental-noindex',\n 'prevent public pages and robots files from disabling indexing',\n (context) => ({\n 'Program:exit'(program) {\n const filename = context.getFilename()\n const options = (context.options[0] ?? {}) as { privateRoutes?: string[] }\n const privateRoutes = options.privateRoutes\n\n if (isPageFile(filename) && !routeIsPrivate(filename, privateRoutes)) {\n for (const source of metadataSources(program as never)) {\n const robots = getPathProperty(source, ['robots'])\n if (!robots) continue\n if (getStaticString(robots.value)?.toLowerCase().includes('noindex')) {\n report(\n context,\n robots.node as never,\n 'Public page sets robots: \"noindex\"; this can remove the page from search indexes.',\n )\n }\n const index = getObjectProperty(robots.value, 'index')\n if (index?.value.type === 'Literal' && index.value.value === false) {\n report(context, index.node as never, 'Public page sets robots.index to false.')\n }\n }\n }\n\n walk(program as never, (node) => {\n if (node.type !== 'ConditionalExpression' && node.type !== 'LogicalExpression') return\n const text = context.sourceCode.getText(node as never)\n if (/NODE_ENV/.test(text) && /noindex/.test(text) && /production/.test(text)) {\n report(\n context,\n node as never,\n 'Environment-gated noindex logic should be reviewed; production pages must not emit noindex.',\n )\n }\n })\n\n if (checkedRobots) return\n checkedRobots = true\n const root = findProjectRoot(process.cwd())\n const appDir = findAppDir(root)\n const robotsTs = appDir\n ? ['robots.ts', 'robots.js'].map((name) => path.join(appDir, name)).find(fs.existsSync)\n : undefined\n if (robotsTs) {\n const text = fs.readFileSync(robotsTs, 'utf8')\n if (/disallow\\s*:\\s*['\"`]\\/['\"`]/i.test(text) && !/allow\\s*:\\s*['\"`]\\/['\"`]/i.test(text)) {\n report(context, program, `${robotsTs} appears to disallow \"/\" without an allow rule.`)\n }\n }\n const publicRobots = path.join(root, 'public', 'robots.txt')\n if (fs.existsSync(publicRobots)) {\n const text = fs.readFileSync(publicRobots, 'utf8')\n if (/^\\s*Disallow:\\s*\\/\\s*$/im.test(text) && !/^\\s*Allow:\\s*\\/.+/im.test(text)) {\n report(context, program, 'public/robots.txt disallows all crawling with \"Disallow: /\".')\n }\n }\n const nextConfig = ['next.config.js', 'next.config.mjs', 'next.config.ts']\n .map((name) => path.join(root, name))\n .find(fs.existsSync)\n if (nextConfig) {\n const text = fs.readFileSync(nextConfig, 'utf8')\n if (/X-Robots-Tag/i.test(text) && /noindex/i.test(text)) {\n report(\n context,\n program,\n 'next.config sets X-Robots-Tag: noindex; verify this is not applied to public routes.',\n )\n }\n }\n },\n }),\n)\n","import path from 'node:path'\nimport type { Rule } from 'eslint'\n\nexport type AstNode = {\n type: string\n loc?: Rule.Node['loc']\n range?: [number, number]\n [key: string]: unknown\n}\n\nexport type ObjectProperty = {\n key: string\n value: AstNode\n node: AstNode\n}\n\nexport function getNodeName(node: unknown): string | undefined {\n const typed = node as AstNode | undefined\n if (!typed) return undefined\n if (typed.type === 'Identifier') return typed.name as string\n if (typed.type === 'Literal') return String(typed.value)\n if (typed.type === 'Property' || typed.type === 'PropertyDefinition') {\n return getNodeName(typed.key)\n }\n if (typed.type === 'JSXIdentifier') return typed.name as string\n return undefined\n}\n\nexport function objectProperties(node: unknown): ObjectProperty[] {\n const typed = node as AstNode | undefined\n if (!typed || typed.type !== 'ObjectExpression') return []\n return ((typed.properties as AstNode[] | undefined) ?? [])\n .filter((property) => property.type === 'Property')\n .map((property) => ({\n key: getNodeName(property.key) ?? '',\n value: property.value as AstNode,\n node: property,\n }))\n .filter((property) => property.key.length > 0)\n}\n\nexport function getObjectProperty(node: unknown, key: string): ObjectProperty | undefined {\n return objectProperties(node).find((property) => property.key === key)\n}\n\nexport function getPathProperty(node: unknown, keys: string[]): ObjectProperty | undefined {\n let current = node\n let found: ObjectProperty | undefined\n for (const key of keys) {\n found = getObjectProperty(current, key)\n if (!found) return undefined\n current = found.value\n }\n return found\n}\n\nexport function getStaticString(node: unknown): string | undefined {\n const typed = node as AstNode | undefined\n if (!typed) return undefined\n if (typed.type === 'Literal' && typeof typed.value === 'string') return typed.value\n if (typed.type === 'TemplateLiteral') {\n const expressions = (typed.expressions as AstNode[] | undefined) ?? []\n const quasis = (typed.quasis as AstNode[] | undefined) ?? []\n if (expressions.length === 0) {\n return quasis.map((quasi) => ((quasi.value as AstNode)?.cooked ?? '') as string).join('')\n }\n }\n return undefined\n}\n\nexport function isNonEmptyStringNode(node: unknown): boolean {\n const value = getStaticString(node)\n return typeof value === 'string' && value.trim().length > 0\n}\n\nexport function findMetadataObject(program: AstNode): AstNode | undefined {\n for (const statement of (program.body as AstNode[] | undefined) ?? []) {\n if (statement.type !== 'ExportNamedDeclaration') continue\n const declaration = statement.declaration as AstNode | undefined\n if (!declaration || declaration.type !== 'VariableDeclaration') continue\n for (const item of (declaration.declarations as AstNode[] | undefined) ?? []) {\n if (\n getNodeName(item.id) === 'metadata' &&\n (item.init as AstNode | undefined)?.type === 'ObjectExpression'\n ) {\n return item.init as AstNode\n }\n }\n }\n return undefined\n}\n\nexport function findGenerateMetadataReturns(program: AstNode): AstNode[] {\n const returns: AstNode[] = []\n walk(program, (node) => {\n if (node.type !== 'ExportNamedDeclaration') return\n const declaration = node.declaration as AstNode | undefined\n if (!declaration) return\n const isNamedFunction =\n declaration.type === 'FunctionDeclaration' && getNodeName(declaration.id) === 'generateMetadata'\n const isVariable =\n declaration.type === 'VariableDeclaration' &&\n ((declaration.declarations as AstNode[] | undefined) ?? []).some(\n (item) => getNodeName(item.id) === 'generateMetadata',\n )\n if (!isNamedFunction && !isVariable) return\n walk(declaration, (child) => {\n if (\n child.type === 'ReturnStatement' &&\n (child.argument as AstNode | undefined)?.type === 'ObjectExpression'\n ) {\n returns.push(child.argument as AstNode)\n }\n })\n })\n return returns\n}\n\nexport function metadataSources(program: AstNode): AstNode[] {\n const staticMetadata = findMetadataObject(program)\n return [staticMetadata, ...findGenerateMetadataReturns(program)].filter(Boolean) as AstNode[]\n}\n\nexport function hasNullishFallback(node: unknown): boolean {\n let found = false\n walk(node as AstNode, (child) => {\n if (child.type === 'LogicalExpression' && child.operator === '??' && isNonEmptyStringNode(child.right)) {\n found = true\n }\n })\n return found\n}\n\nexport function hasDynamicInterpolation(node: unknown): boolean {\n const typed = node as AstNode | undefined\n if (!typed) return false\n if (typed.type === 'TemplateLiteral') {\n return ((typed.expressions as AstNode[] | undefined) ?? []).length > 0\n }\n let found = false\n walk(typed, (child) => {\n if (child.type === 'Identifier' && child.name === 'params') found = true\n })\n return found\n}\n\nexport function walk(node: AstNode | undefined, visitor: (node: AstNode) => void): void {\n if (!node || typeof node.type !== 'string') return\n visitor(node)\n for (const [key, value] of Object.entries(node)) {\n if (key === 'parent' || key === 'loc' || key === 'range' || key === 'tokens' || key === 'comments')\n continue\n if (!value) continue\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === 'object' && typeof (item as AstNode).type === 'string') {\n walk(item as AstNode, visitor)\n }\n }\n } else if (typeof value === 'object' && typeof (value as AstNode).type === 'string') {\n walk(value as AstNode, visitor)\n }\n }\n}\n\nexport function jsxAttribute(node: AstNode, name: string): AstNode | undefined {\n const attributes = (node.attributes as AstNode[] | undefined) ?? []\n return attributes.find(\n (attribute) => attribute.type === 'JSXAttribute' && getNodeName(attribute.name) === name,\n )\n}\n\nexport function jsxAttributeString(node: AstNode, name: string): string | undefined {\n const attribute = jsxAttribute(node, name)\n if (!attribute) return undefined\n const value = attribute.value as AstNode | undefined\n if (!value) return ''\n if (value.type === 'Literal') return String(value.value)\n if (value.type === 'JSXExpressionContainer') return getStaticString(value.expression)\n return undefined\n}\n\nexport function routeFromFilename(filename: string): string {\n const normalized = filename.split(path.sep).join('/')\n const appIndex = normalized.lastIndexOf('/app/')\n const relative = appIndex >= 0 ? normalized.slice(appIndex + 5) : normalized\n return (\n (\n '/' +\n relative\n .replace(/\\/(page|layout)\\.[cm]?[jt]sx?$/, '')\n .replace(/\\/?$/, '')\n .replace(/\\/\\([^/]+\\)/g, '')\n .replace(/\\/route$/, '')\n ).replace(/\\/+/g, '/') || '/'\n )\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport function findProjectRoot(start = process.cwd()): string {\n let current = path.resolve(start)\n while (current !== path.dirname(current)) {\n if (fs.existsSync(path.join(current, 'package.json'))) return current\n current = path.dirname(current)\n }\n return path.resolve(start)\n}\n\nexport function findAppDir(root = findProjectRoot()): string | undefined {\n const candidates = [path.join(root, 'app'), path.join(root, 'src', 'app')]\n return candidates.find((candidate) => fs.existsSync(candidate) && fs.statSync(candidate).isDirectory())\n}\n\nexport function isPageFile(filename: string): boolean {\n return /(^|\\/)page\\.[cm]?[jt]sx?$/.test(filename.split(path.sep).join('/'))\n}\n\nexport function isLayoutFile(filename: string): boolean {\n return /(^|\\/)layout\\.[cm]?[jt]sx?$/.test(filename.split(path.sep).join('/'))\n}\n\nexport function isRootLayoutFile(filename: string): boolean {\n const normalized = filename.split(path.sep).join('/')\n return /(^|\\/)(src\\/)?app\\/layout\\.[cm]?[jt]sx?$/.test(normalized)\n}\n\nexport function isDynamicRoute(filename: string): boolean {\n return /\\[[^/]+\\]/.test(filename)\n}\n\nexport function routeIsPrivate(\n filename: string,\n privateRoutes = ['/admin', '/api', '/auth', '/private'],\n): boolean {\n const normalized = filename.split(path.sep).join('/')\n return privateRoutes.some(\n (route) => normalized.includes(`/app${route}/`) || normalized.includes(`/src/app${route}/`),\n )\n}\n\nexport function hasMetadataBase(root = findProjectRoot()): boolean {\n const appDir = findAppDir(root)\n if (!appDir) return false\n for (const ext of ['ts', 'tsx', 'js', 'jsx', 'mts', 'mjs']) {\n const file = path.join(appDir, `layout.${ext}`)\n if (fs.existsSync(file) && fs.readFileSync(file, 'utf8').includes('metadataBase')) return true\n }\n return false\n}\n\nexport function routeSegmentDir(filename: string): string {\n return path.dirname(filename)\n}\n\nexport function hasOpenGraphImageRoute(filename: string): boolean {\n const dir = routeSegmentDir(filename)\n return [\n 'opengraph-image.tsx',\n 'opengraph-image.ts',\n 'opengraph-image.png',\n 'opengraph-image.jpg',\n 'opengraph-image.jpeg',\n ].some((name) => fs.existsSync(path.join(dir, name)))\n}\n\nexport function routeFromFilename(filename: string): string {\n const normalized = filename.split(path.sep).join('/')\n const appIndex = normalized.lastIndexOf('/app/')\n const relative = appIndex >= 0 ? normalized.slice(appIndex + 5) : normalized\n const route = relative\n .replace(/\\/(page|layout)\\.[cm]?[jt]sx?$/, '')\n .replace(/\\/?$/, '')\n .replace(/\\/\\([^/]+\\)/g, '')\n .replace(/\\/route$/, '')\n return `/${route}`.replace(/\\/+/g, '/') || '/'\n}\n","import type { Rule } from 'eslint'\nimport type { RuleModule } from '../types'\n\nexport function createRule(\n name: string,\n description: string,\n create: Rule.RuleModule['create'],\n type: 'problem' | 'suggestion' = 'problem',\n): RuleModule {\n return {\n meta: {\n type,\n docs: {\n description,\n recommended: true,\n url: `https://seo-lint-next.dev/rules/${name}`,\n },\n schema: [\n {\n type: 'object',\n additionalProperties: true,\n },\n ],\n messages: {},\n },\n create,\n }\n}\n\nexport function report(context: Rule.RuleContext, node: unknown, message: string): void {\n context.report({ node: node as Rule.Node, message })\n}\n","import { getNodeName, jsxAttributeString } from '../utils/ast'\nimport { isPageFile } from '../utils/files'\nimport { createRule, report } from '../utils/rule'\n\nexport const noBrokenHeadingHierarchy = createRule(\n 'no-broken-heading-hierarchy',\n 'require one h1 and sequential heading levels',\n (context) => {\n const headings: Array<{ level: number; node: never; empty: boolean }> = []\n return {\n JSXOpeningElement(node: any) {\n if (!isPageFile(context.getFilename())) return\n const name = getNodeName(node.name)\n if (!name || !/^h[1-6]$/.test(name)) return\n const ariaHidden = jsxAttributeString(node as never, 'aria-hidden')\n headings.push({ level: Number(name.slice(1)), node: node as never, empty: ariaHidden === 'true' })\n },\n 'Program:exit'(program) {\n if (!isPageFile(context.getFilename())) return\n const h1s = headings.filter((heading) => heading.level === 1)\n if (h1s.length === 0)\n report(context, program, 'Page has no <h1>; each indexable page should expose one primary heading.')\n if (h1s.length > 1) {\n for (const h1 of h1s.slice(1))\n report(context, h1.node, 'Page has more than one <h1>; keep one primary topic heading.')\n }\n for (let index = 1; index < headings.length; index += 1) {\n if (headings[index].level > headings[index - 1].level + 1) {\n report(\n context,\n headings[index].node,\n `Heading level jumps from h${headings[index - 1].level} to h${headings[index].level}.`,\n )\n }\n }\n },\n }\n },\n 'suggestion',\n)\n","import { getNodeName, jsxAttribute, jsxAttributeString } from '../utils/ast'\nimport { createRule, report } from '../utils/rule'\n\nconst meaningless = new Set(['image', 'img', 'photo', 'picture', 'screenshot'])\n\nexport const noImgMissingAlt = createRule(\n 'no-img-missing-alt',\n 'require useful alt text and stable Next/Image sizing',\n (context) => {\n let imageIndex = 0\n return {\n JSXOpeningElement(node: any) {\n const typed = node as never\n const name = getNodeName(node.name)\n if (name !== 'img' && name !== 'Image') return\n\n imageIndex += 1\n if (name === 'img')\n report(context, typed, 'Use next/image instead of raw <img> for optimized image delivery.')\n\n const altAttribute = jsxAttribute(typed, 'alt')\n if (!altAttribute) {\n report(context, typed, `${name} is missing an alt attribute.`)\n } else {\n const alt = jsxAttributeString(typed, 'alt')\n if (alt === undefined) return\n if (alt.length > 125)\n report(context, altAttribute as never, 'Alt text should stay under 125 characters.')\n const normalized = alt.trim().toLowerCase()\n if (\n normalized &&\n (meaningless.has(normalized) || /\\.(png|jpe?g|webp|gif|svg)$/i.test(normalized))\n ) {\n report(\n context,\n altAttribute as never,\n 'Alt text is too generic; describe the image content or use alt=\"\" for decorative images.',\n )\n }\n }\n\n if (name === 'Image') {\n if (!jsxAttribute(typed, 'width') || !jsxAttribute(typed, 'height')) {\n report(context, typed, '<Image> should include width and height props to prevent layout shift.')\n }\n if (imageIndex === 1 && !jsxAttribute(typed, 'priority')) {\n report(\n context,\n typed,\n 'The first <Image> in a page is likely above the fold; add priority when it is the LCP image.',\n )\n }\n }\n },\n }\n },\n 'suggestion',\n)\n","import { getNodeName, getStaticString, jsxAttributeString, walk } from '../utils/ast'\nimport { isPageFile, routeFromFilename } from '../utils/files'\nimport { createRule, report } from '../utils/rule'\n\nconst requiredFields: Record<string, string[]> = {\n Article: ['headline', 'author', 'datePublished'],\n BlogPosting: ['headline', 'author', 'datePublished'],\n Product: ['name', 'offers'],\n FAQPage: ['mainEntity'],\n BreadcrumbList: ['itemListElement'],\n Organization: ['name', 'url'],\n WebSite: ['name', 'url'],\n Person: ['name'],\n Event: ['name', 'startDate', 'location'],\n}\n\nconst recognized = new Set(Object.keys(requiredFields))\n\nexport const noInvalidJsonLd = createRule(\n 'no-invalid-json-ld',\n 'validate JSON-LD syntax and required schema fields',\n (context) => {\n let scriptCount = 0\n return {\n JSXElement(node: any) {\n const opening = node.openingElement\n if (getNodeName(opening?.name) !== 'script') return\n if (jsxAttributeString(opening, 'type') !== 'application/ld+json') return\n scriptCount += 1\n\n const html = (opening.attributes ?? []).find(\n (attribute: any) => getNodeName(attribute.name) === 'dangerouslySetInnerHTML',\n )\n if (html) {\n const text = context.sourceCode.getText(html)\n if (!/JSON\\.stringify/.test(text) && !/__html\\s*:\\s*['\"`{]/.test(text)) {\n report(\n context,\n html,\n 'JSON-LD dangerouslySetInnerHTML should pass JSON.stringify(data) or a static JSON string.',\n )\n }\n return\n }\n\n const text = extractScriptText((node.children ?? []) as any[])\n if (!text) return\n try {\n validateJsonLd(JSON.parse(text), (message) => report(context, node as never, message))\n } catch {\n report(context, node as never, 'JSON-LD script contains invalid JSON.')\n }\n },\n 'Program:exit'(program) {\n if (!isPageFile(context.getFilename())) return\n const route = routeFromFilename(context.getFilename())\n if (/\\/(blog|posts|product|products|articles)(\\/|$)/.test(route) && scriptCount === 0) {\n report(context, program, 'Content page is missing an application/ld+json structured data block.')\n }\n let websiteSchema = false\n walk(program as never, (child) => {\n if (child.type === 'Literal' && child.value === 'WebSite') websiteSchema = true\n })\n if (/\\/layout\\.[cm]?[jt]sx?$/.test(context.getFilename()) && !websiteSchema) {\n report(\n context,\n program,\n 'Root layout should include WebSite JSON-LD with SearchAction for sitelinks search eligibility.',\n )\n }\n },\n }\n },\n)\n\nfunction extractScriptText(children: any[]): string {\n return children\n .map((child) => {\n if (typeof child.value === 'string') return child.value\n if (child.type === 'JSXExpressionContainer') return getStaticString(child.expression) ?? ''\n return ''\n })\n .join('')\n .trim()\n}\n\nfunction validateJsonLd(value: unknown, onError: (message: string) => void): void {\n const items = Array.isArray(value) ? value : [value]\n const byType = new Map<string, string>()\n for (const item of items) {\n if (!item || typeof item !== 'object') continue\n const record = item as Record<string, unknown>\n if (record['@context'] !== 'https://schema.org')\n onError('JSON-LD @context must be exactly \"https://schema.org\".')\n const type = String(record['@type'] ?? '')\n if (!recognized.has(type))\n onError(`JSON-LD @type \"${type || '(missing)'}\" is not in the built-in recognized type list.`)\n const missing = (requiredFields[type] ?? []).filter((field) => record[field] == null)\n if (missing.length > 0) onError(`JSON-LD ${type} is missing required field(s): ${missing.join(', ')}.`)\n const serialized = JSON.stringify(record)\n const previous = byType.get(type)\n if (previous && previous !== serialized)\n onError(`Multiple JSON-LD ${type} blocks contain conflicting data.`)\n byType.set(type, serialized)\n }\n}\n","import { getPathProperty, getStaticString, hasDynamicInterpolation, metadataSources } from '../utils/ast'\nimport { hasMetadataBase, isDynamicRoute, isPageFile } from '../utils/files'\nimport { createRule, report } from '../utils/rule'\n\nexport const noMissingCanonical = createRule(\n 'no-missing-canonical',\n 'require canonical URLs for App Router pages',\n (context) => ({\n 'Program:exit'(program) {\n const filename = context.getFilename()\n if (!isPageFile(filename)) return\n\n const sources = metadataSources(program as never)\n const canonical = sources\n .map((source) => getPathProperty(source, ['alternates', 'canonical']))\n .find(Boolean)\n if (!canonical) {\n report(\n context,\n program,\n 'Page is missing alternates.canonical; duplicate URL variants can split ranking signals.',\n )\n return\n }\n\n const value = getStaticString(canonical.value)\n if (value && !/^https?:\\/\\//.test(value) && !value.startsWith('/') && !hasMetadataBase()) {\n report(\n context,\n canonical.node as never,\n 'Relative alternates.canonical requires metadataBase in the root app layout.',\n )\n }\n\n if (isDynamicRoute(filename) && value && !hasDynamicInterpolation(canonical.value)) {\n report(\n context,\n canonical.node as never,\n 'Dynamic routes need a param-specific canonical, not a hardcoded URL string.',\n )\n }\n },\n }),\n)\n","import { getPathProperty, getStaticString, metadataSources } from '../utils/ast'\nimport { isLayoutFile, isPageFile, routeFromFilename } from '../utils/files'\nimport { createRule, report } from '../utils/rule'\n\nconst seenDescriptions = new Map<string, string>()\n\nexport const noMissingDescription = createRule(\n 'no-missing-description',\n 'require useful Next.js metadata descriptions',\n (context) => ({\n 'Program:exit'(program) {\n const filename = context.getFilename()\n if (!isPageFile(filename) && !isLayoutFile(filename)) return\n\n const option = (context.options[0] ?? {}) as { descriptionLength?: { min?: number; max?: number } }\n const min = option.descriptionLength?.min ?? 120\n const max = option.descriptionLength?.max ?? 160\n const sources = metadataSources(program as never)\n const description = sources.map((source) => getPathProperty(source, ['description'])).find(Boolean)\n if (!description) {\n report(\n context,\n program,\n 'Page is missing metadata.description or a generateMetadata() description return value.',\n )\n return\n }\n\n const value = getStaticString(description.value)\n if (typeof value !== 'string' || value.trim().length === 0) {\n report(context, description.node as never, 'metadata.description must not be empty or whitespace.')\n return\n }\n\n if (value.length < min || value.length > max) {\n report(\n context,\n description.node as never,\n `metadata.description should be ${min}-${max} characters; found ${value.length}.`,\n )\n }\n\n const title = sources.map((source) => getPathProperty(source, ['title'])).find(Boolean)\n const titleValue = title ? getStaticString(title.value) : undefined\n if (titleValue && value.startsWith(titleValue)) {\n report(\n context,\n description.node as never,\n 'metadata.description should not start with the exact page title.',\n )\n }\n\n const route = routeFromFilename(filename)\n const previous = seenDescriptions.get(value)\n if (previous && previous !== route) {\n report(\n context,\n description.node as never,\n `Duplicate metadata.description also appears in ${previous}.`,\n )\n } else {\n seenDescriptions.set(value, route)\n }\n },\n }),\n 'suggestion',\n)\n","import { getPathProperty, getStaticString, metadataSources } from '../utils/ast'\nimport { isRootLayoutFile } from '../utils/files'\nimport { createRule, report } from '../utils/rule'\n\nexport const noMissingMetadataBase = createRule(\n 'no-missing-metadata-base',\n 'require production metadataBase in the root app layout',\n (context) => ({\n 'Program:exit'(program) {\n const filename = context.getFilename()\n if (!isRootLayoutFile(filename)) return\n\n const metadata = metadataSources(program as never)[0]\n const metadataBase = metadata ? getPathProperty(metadata, ['metadataBase']) : undefined\n if (!metadataBase) {\n report(\n context,\n program,\n 'Root app layout is missing metadata.metadataBase; relative canonicals and OG images will not resolve safely.',\n )\n return\n }\n\n const value = metadataBase.value\n if (\n value.type !== 'NewExpression' ||\n (value.callee as any)?.type !== 'Identifier' ||\n (value.callee as any).name !== 'URL'\n ) {\n report(\n context,\n metadataBase.node as never,\n 'metadataBase should be created with new URL(\"https://example.com\").',\n )\n return\n }\n\n const firstArg = Array.isArray(value.arguments) ? value.arguments[0] : undefined\n const literal = getStaticString(firstArg)\n if (literal) {\n if (!literal.startsWith('https://')) {\n report(\n context,\n metadataBase.node as never,\n 'metadataBase must use an absolute https:// production URL.',\n )\n }\n if (/localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0/.test(literal)) {\n report(\n context,\n metadataBase.node as never,\n 'metadataBase must not point at localhost in committed source.',\n )\n }\n }\n },\n }),\n)\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { imageSize } from 'image-size'\nimport { getObjectProperty, getPathProperty, getStaticString, metadataSources } from '../utils/ast'\nimport { hasMetadataBase, hasOpenGraphImageRoute, isPageFile } from '../utils/files'\nimport { createRule, report } from '../utils/rule'\n\nexport const noMissingOgTags = createRule(\n 'no-missing-og-tags',\n 'require Open Graph and Twitter metadata',\n (context) => ({\n 'Program:exit'(program) {\n const filename = context.getFilename()\n if (!isPageFile(filename)) return\n\n const source = metadataSources(program as never)[0]\n if (!source) return\n const openGraph = getPathProperty(source, ['openGraph'])\n if (!openGraph) {\n if (!hasOpenGraphImageRoute(filename)) report(context, program, 'Page is missing openGraph metadata.')\n return\n }\n\n for (const key of ['title', 'description', 'type']) {\n if (!getObjectProperty(openGraph.value, key)) {\n report(context, openGraph.node as never, `openGraph.${key} is missing.`)\n }\n }\n\n const images = getObjectProperty(openGraph.value, 'images')\n if (!images && !hasOpenGraphImageRoute(filename)) {\n report(\n context,\n openGraph.node as never,\n 'openGraph.images is missing and no opengraph-image file exists in this route segment.',\n )\n } else if (\n images?.value.type === 'ArrayExpression' &&\n ((images.value.elements as unknown[]) ?? []).length === 0\n ) {\n report(context, images.node as never, 'openGraph.images must include at least one image.')\n }\n\n if (images?.value.type === 'ArrayExpression') {\n for (const image of (images.value.elements as never[]) ?? []) {\n if (!image) continue\n const urlNode = getObjectProperty(image, 'url')?.value ?? image\n const url = getStaticString(urlNode)\n if (url?.startsWith('/') && !hasMetadataBase()) {\n report(\n context,\n images.node as never,\n 'Relative openGraph image URLs require metadataBase in the root app layout.',\n )\n }\n const width = Number(getObjectProperty(image, 'width')?.value?.value ?? 0)\n const height = Number(getObjectProperty(image, 'height')?.value?.value ?? 0)\n if ((width && width < 800) || (height && height < 418)) {\n report(\n context,\n images.node as never,\n 'Open Graph image dimensions should be at least 800x418, ideally 1200x630.',\n )\n }\n if (url?.startsWith('/')) {\n const publicFile = path.join(process.cwd(), 'public', url)\n if (fs.existsSync(publicFile)) {\n const size = imageSize(fs.readFileSync(publicFile))\n if ((size.width ?? 0) < 800 || (size.height ?? 0) < 418) {\n report(context, images.node as never, `Open Graph image file ${url} is smaller than 800x418.`)\n }\n }\n }\n }\n }\n\n const twitter = getObjectProperty(source, 'twitter')\n if (!twitter) {\n report(\n context,\n source as never,\n 'twitter metadata is missing; set twitter.card and twitter.images for share previews.',\n )\n return\n }\n const card = getObjectProperty(twitter.value, 'card')\n if (!card)\n report(\n context,\n twitter.node as never,\n 'twitter.card is missing; use \"summary_large_image\" for OG-style previews.',\n )\n if (\n getStaticString(card?.value) === 'summary_large_image' &&\n !getObjectProperty(twitter.value, 'images')\n ) {\n report(\n context,\n twitter.node as never,\n 'twitter.images is required when twitter.card is \"summary_large_image\".',\n )\n }\n },\n }),\n 'suggestion',\n)\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { findAppDir, findProjectRoot } from '../utils/files'\nimport { createRule, report } from '../utils/rule'\n\nlet checked = false\n\nexport const noMissingSitemap = createRule(\n 'no-missing-sitemap',\n 'require a Next.js sitemap and robots sitemap reference',\n (context) => ({\n 'Program:exit'(program) {\n if (checked) return\n checked = true\n const root = findProjectRoot(process.cwd())\n const appDir = findAppDir(root)\n const sitemap = appDir\n ? ['sitemap.ts', 'sitemap.js', 'sitemap.mjs']\n .map((name) => path.join(appDir, name))\n .find(fs.existsSync)\n : undefined\n const nextSitemap = path.join(root, 'next-sitemap.config.js')\n\n if (!sitemap && !fs.existsSync(nextSitemap)) {\n report(\n context,\n program,\n 'Missing app/sitemap.ts or next-sitemap.config.js; search engines may discover pages slowly.',\n )\n return\n }\n\n if (sitemap) {\n const text = fs.readFileSync(sitemap, 'utf8')\n if (!/export\\s+default\\s+(async\\s+)?function|export\\s+default\\s+\\w+/.test(text)) {\n report(context, program, `${sitemap} should export a default sitemap function.`)\n }\n if (/url\\s*:\\s*['\"`]\\//.test(text)) {\n report(context, program, 'Sitemap entries must use absolute URLs, not relative paths.')\n }\n if (/\\[[^/]+\\]/.test(text) && !/lastModified/.test(text)) {\n report(context, program, 'Dynamic sitemap entries should include lastModified.')\n }\n }\n\n const robots = appDir\n ? ['robots.ts', 'robots.js'].map((name) => path.join(appDir, name)).find(fs.existsSync)\n : undefined\n if (robots && !/sitemap\\s*:/.test(fs.readFileSync(robots, 'utf8'))) {\n report(context, program, 'app/robots.ts should include a sitemap field pointing to the sitemap URL.')\n }\n },\n }),\n 'suggestion',\n)\n","import { getPathProperty, getStaticString, hasNullishFallback, metadataSources } from '../utils/ast'\nimport { isLayoutFile, isPageFile, routeFromFilename } from '../utils/files'\nimport { createRule, report } from '../utils/rule'\n\nconst seenTitles = new Map<string, string>()\n\nexport const noMissingTitle = createRule(\n 'no-missing-title',\n 'require useful Next.js metadata titles',\n (context) => ({\n 'Program:exit'(program) {\n const filename = context.getFilename()\n if (!isPageFile(filename) && !isLayoutFile(filename)) return\n\n const sources = metadataSources(program as never)\n const title = sources.map((source) => getPathProperty(source, ['title'])).find(Boolean)\n\n if (!title) {\n report(context, program, 'Page is missing metadata.title or a generateMetadata() title return value.')\n return\n }\n\n if (title.value.type === 'Literal' && String(title.value.value ?? '').trim().length === 0) {\n report(context, title.node as never, 'metadata.title must not be empty or whitespace.')\n }\n\n const titleString = getStaticString(title.value)\n if (titleString?.trim()) {\n const route = routeFromFilename(filename)\n const previous = seenTitles.get(titleString)\n if (previous && previous !== filename) {\n report(\n context,\n title.node as never,\n `Duplicate metadata.title \"${titleString}\" also appears in ${previous}.`,\n )\n } else {\n seenTitles.set(titleString, route)\n }\n }\n\n if (isLayoutFile(filename) && !getPathProperty(title.value, ['template'])) {\n report(\n context,\n title.node as never,\n 'Root/layout metadata.title should define a title.template such as \"%s | Brand\".',\n )\n }\n\n if (\n title.value.type !== 'ObjectExpression' &&\n !getStaticString(title.value) &&\n !hasNullishFallback(title.value)\n ) {\n report(\n context,\n title.node as never,\n 'Dynamic metadata.title should include a non-empty fallback with ?? \"Fallback title\".',\n )\n }\n },\n }),\n)\n","import { noAccidentalNoindex } from './rules/no-accidental-noindex'\nimport { noBrokenHeadingHierarchy } from './rules/no-broken-heading-hierarchy'\nimport { noImgMissingAlt } from './rules/no-img-missing-alt'\nimport { noInvalidJsonLd } from './rules/no-invalid-json-ld'\nimport { noMissingCanonical } from './rules/no-missing-canonical'\nimport { noMissingDescription } from './rules/no-missing-description'\nimport { noMissingMetadataBase } from './rules/no-missing-metadata-base'\nimport { noMissingOgTags } from './rules/no-missing-og-tags'\nimport { noMissingSitemap } from './rules/no-missing-sitemap'\nimport { noMissingTitle } from './rules/no-missing-title'\n\nconst rules = {\n 'no-missing-title': noMissingTitle,\n 'no-missing-metadata-base': noMissingMetadataBase,\n 'no-missing-description': noMissingDescription,\n 'no-missing-canonical': noMissingCanonical,\n 'no-missing-og-tags': noMissingOgTags,\n 'no-broken-heading-hierarchy': noBrokenHeadingHierarchy,\n 'no-img-missing-alt': noImgMissingAlt,\n 'no-accidental-noindex': noAccidentalNoindex,\n 'no-missing-sitemap': noMissingSitemap,\n 'no-invalid-json-ld': noInvalidJsonLd,\n}\n\nconst recommendedRules = {\n 'seo-lint-next/no-missing-title': 'error',\n 'seo-lint-next/no-missing-metadata-base': 'error',\n 'seo-lint-next/no-missing-description': 'warn',\n 'seo-lint-next/no-missing-canonical': 'error',\n 'seo-lint-next/no-missing-og-tags': 'warn',\n 'seo-lint-next/no-broken-heading-hierarchy': 'warn',\n 'seo-lint-next/no-img-missing-alt': 'warn',\n 'seo-lint-next/no-accidental-noindex': 'error',\n 'seo-lint-next/no-missing-sitemap': 'warn',\n 'seo-lint-next/no-invalid-json-ld': 'error',\n} as const\n\nconst plugin = {\n meta: {\n name: 'seo-lint-next',\n version: '0.1.0',\n },\n rules,\n configs: {\n recommended: [\n {\n plugins: {\n 'seo-lint-next': null as unknown,\n },\n rules: recommendedRules,\n },\n ],\n legacyRecommended: {\n plugins: ['seo-lint-next'],\n rules: recommendedRules,\n },\n },\n}\n\nplugin.configs.recommended[0].plugins['seo-lint-next'] = plugin\n\nexport default plugin\n"],"mappings":"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","names":["import_node_fs","import_node_path","import_node_fs","import_node_path","import_node_path","path","fs","path","fs","text","import_node_fs","import_node_path","path","fs","import_node_fs","import_node_path","path","fs","process","path","fs","fg","rules","tsParser"]}
|
package/dist/cli.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|