UNPKG

eslint-plugin-svelte

Version:
97 lines (96 loc) 3.53 kB
import { createRule } from '../utils/index.js'; import { getSvelteVersion } from '../utils/svelte-context.js'; const EXPECTED_PROP_NAMES = ['data', 'errors', 'form', 'params', 'snapshot']; const EXPECTED_PROP_NAMES_SVELTE5 = [...EXPECTED_PROP_NAMES, 'children']; function checkProp(node, context, expectedPropNames) { if (node.id.type !== 'ObjectPattern') return; for (const p of node.id.properties) { if (p.type === 'Property' && p.key.type === 'Identifier' && !expectedPropNames.includes(p.key.name)) { context.report({ node: p.key, loc: p.key.loc, messageId: 'unexpected' }); } } } function isModuleScript(node) { // <script context="module"> if (node.key.name === 'context' && node.value.some((v) => v.type === 'SvelteLiteral' && v.value === 'module')) { return true; } // <script module> if (node.key.name === 'module' && node.value.length === 0) { return true; } return false; } export default createRule('valid-prop-names-in-kit-pages', { meta: { docs: { description: 'disallow props other than data or errors in SvelteKit page components.', category: 'SvelteKit', recommended: true }, schema: [], messages: { unexpected: 'disallow props other than data or errors in SvelteKit page components.' }, type: 'problem', conditions: [ { svelteKitFileTypes: ['+page.svelte', '+error.svelte', '+layout.svelte'] } ] }, create(context) { let isScript = false; const isSvelte5 = getSvelteVersion() === '5'; const expectedPropNames = isSvelte5 ? EXPECTED_PROP_NAMES_SVELTE5 : EXPECTED_PROP_NAMES; return { // <script> 'Program > SvelteScriptElement > SvelteStartTag': (node) => { // except for <script context="module"> isScript = !node.attributes.some((a) => a.type === 'SvelteAttribute' && isModuleScript(a)); }, // </script> 'Program > SvelteScriptElement:exit': () => { isScript = false; }, // Svelte3,4 'ExportNamedDeclaration > VariableDeclaration > VariableDeclarator': (node) => { if (!isScript) return; // export let foo if (node.id.type === 'Identifier') { if (!expectedPropNames.includes(node.id.name)) { context.report({ node, loc: node.loc, messageId: 'unexpected' }); } return; } // export let { xxx, yyy } = zzz checkProp(node, context, expectedPropNames); }, // Svelte5 // let { foo, bar } = $props(); 'VariableDeclaration > VariableDeclarator': (node) => { if (!isScript) return; if (node.init?.type !== 'CallExpression' || node.init.callee?.type !== 'Identifier' || node.init.callee?.name !== '$props') { return; } checkProp(node, context, expectedPropNames); } }; } });