eslint-plugin-svelte3
Advanced tools
Comparing version 3.2.1 to 3.3.0
111
index.js
@@ -51,3 +51,3 @@ 'use strict'; | ||
} | ||
return { dedented, offsets: { offsets, total_offsets } }; | ||
return { dedented, offsets: { offsets, total_offsets }, indentation }; | ||
}; | ||
@@ -66,6 +66,11 @@ | ||
// return a new block | ||
// create a new block to add code transformations to | ||
const new_block = () => ({ transformed_code: '', line_offsets: null, translations: new Map() }); | ||
// get translation info and include the processed scripts in this block's transformed_code | ||
// each translation consists of info about the original text range (range), | ||
// the difference after dedenting (dedent), line/length info about the text itself (offsets), | ||
// line/length info about the transformed code prior to adding the text (unoffsets) and the new | ||
// line count of the transformed code after adding the text (end). This information can be used | ||
// to map code back to its original position. | ||
const get_translation = (text, block, node, options = {}) => { | ||
@@ -75,6 +80,7 @@ block.transformed_code += '\n'; | ||
translation.range = [node.start, node.end]; | ||
const { dedented, offsets } = dedent_code(text.slice(node.start, node.end)); | ||
const { dedented, offsets, indentation } = dedent_code(text.slice(node.start, node.end)); | ||
block.transformed_code += dedented; | ||
translation.offsets = get_offsets(text.slice(0, node.start)); | ||
translation.dedent = offsets; | ||
translation.indentation = indentation; | ||
translation.end = get_offsets(block.transformed_code).lines; | ||
@@ -215,3 +221,3 @@ for (let i = translation.unoffsets.lines; i <= translation.end; i++) { | ||
offset_in_fragment(offset) { | ||
return offset - this.diff.generated_start | ||
return offset - this.diff.generated_start; | ||
} | ||
@@ -295,3 +301,3 @@ } | ||
original_fragment_mapper: new OriginalFragmentMapper(original_code, diff) | ||
} | ||
}; | ||
}); | ||
@@ -358,2 +364,7 @@ } | ||
/** | ||
* Get the line and character position of an offset | ||
* @param offset Idx of the offset | ||
* @param text The text for which the position should be retrieved | ||
*/ | ||
function position_at(offset, text) { | ||
@@ -430,7 +441,17 @@ offset = clamp(offset, 0, text.length); | ||
}; | ||
// let-declaration that (when using TypeScript) is able to infer the type value of a autosubscribed store | ||
const make_let = (name, is_typescript) => | ||
is_typescript && name[0] === '$' ? | ||
// Disable eslint on that line because it may result in a "used before defined" error | ||
`declare let ${name}:Parameters<Parameters<typeof ${name.slice(1)}.subscribe>[0]>[0]; // eslint-disable-line\n` : | ||
`let ${name};`; | ||
// ignore_styles when a `lang=` or `type=` attribute is present on the <style> tag | ||
const ignore_styles_fallback = ({ type, lang }) => !!type || !!lang; | ||
// extract scripts to lint from component definition | ||
const preprocess = text => { | ||
const compiler = processor_options.custom_compiler || default_compiler || (default_compiler = require('svelte/compiler')); | ||
if (processor_options.ignore_styles) { | ||
const ignore_styles = processor_options.ignore_styles ? processor_options.ignore_styles : ignore_styles_fallback; | ||
if (ignore_styles) { | ||
// wipe the appropriate <style> tags in the file | ||
@@ -447,3 +468,3 @@ text = text.replace(/<style(\s[^]*?)?>[^]*?<\/style>/gi, (match, attributes = '') => { | ||
}); | ||
return processor_options.ignore_styles(attrs) ? match.replace(/\S/g, ' ') : match; | ||
return ignore_styles(attrs) ? match.replace(/\S/g, ' ') : match; | ||
}); | ||
@@ -521,7 +542,5 @@ } | ||
block.transformed_code = vars.filter(v => v.injected || !processor_options.typescript && v.module).map(v => make_let(v.name, processor_options.typescript)).join(''); | ||
if (ast.module && processor_options.typescript) { | ||
block.transformed_code = vars.filter(v => v.injected).map(v => `let ${v.name};`).join(''); | ||
block.transformed_code += text.slice(ast.module.content.start, ast.module.content.end); | ||
} else { | ||
block.transformed_code = vars.filter(v => v.injected || v.module).map(v => `let ${v.name};`).join(''); | ||
} | ||
@@ -544,5 +563,7 @@ | ||
} | ||
if (ast.instance || vars.length) { | ||
block.transformed_code += '\n'; | ||
} | ||
block.transformed_code += vars.filter(v => v.injected).map(v => make_let(v.name, true)).join(''); | ||
if (ast.instance) { | ||
block.transformed_code += '\n'; | ||
block.transformed_code += vars.filter(v => v.injected).map(v => `let ${v.name};`).join(''); | ||
block.transformed_code += text.slice(ast.instance.content.start, ast.instance.content.end); | ||
@@ -571,3 +592,3 @@ } | ||
find_contextual_names(compiler, parent.error); | ||
} else if (node.type === 'Element' || node.type === 'InlineComponent') { | ||
} else if (node.type === 'Element' || node.type === 'InlineComponent' || node.type === 'SlotTemplate') { | ||
node.attributes.forEach(node => node.type === 'Let' && find_contextual_names(compiler, node.expression || node.name)); | ||
@@ -606,2 +627,3 @@ } | ||
// TypeScript transformer for preserving imports correctly when preprocessing TypeScript files | ||
// Only needed if TS < 4.5 | ||
const ts_import_transformer = (context) => { | ||
@@ -644,16 +666,25 @@ const ts = processor_options.typescript; | ||
} else { | ||
const ts_options = { | ||
reportDiagnostics: false, | ||
compilerOptions: { | ||
target: ts.ScriptTarget.ESNext, | ||
importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Preserve, | ||
sourceMap: true | ||
}, | ||
transformers: { | ||
before: [ts_import_transformer] | ||
} | ||
}; | ||
// See if we can use `preserveValueImports` instead of the transformer (TS >= 4.5) | ||
const ts_version = ts.version.split('.').map(str => parseInt(str, 10)); | ||
if (ts_version[0] > 4 || (ts_version[0] === 4 && ts_version[1] >= 5)) { | ||
ts_options.compilerOptions.preserveValueImports = true; | ||
ts_options.transformers = {}; | ||
} | ||
const diffs = []; | ||
let accumulated_diff = 0; | ||
const transpiled = text.replace(/<script(\s[^]*?)?>([^]*?)<\/script>/gi, (match, attributes = '', content) => { | ||
const output = ts.transpileModule(content, { | ||
reportDiagnostics: false, | ||
compilerOptions: { | ||
target: ts.ScriptTarget.ESNext, | ||
importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Preserve, | ||
sourceMap: true | ||
}, | ||
transformers: { | ||
before: [ts_import_transformer] | ||
} | ||
}); | ||
const output = ts.transpileModule(content, ts_options); | ||
const original_start = text.indexOf(content); | ||
@@ -696,3 +727,3 @@ const generated_start = accumulated_diff + original_start; | ||
const ast = compiler.parse(text, { ...processor_options.compiler_options }); | ||
const{ warnings, vars } = ts_result; | ||
const { warnings, vars } = ts_result; | ||
return { ast, warnings, vars, mapper }; | ||
@@ -703,5 +734,7 @@ } | ||
// transform a linting message according to the module/instance script info we've gathered | ||
const transform_message = ({ transformed_code }, { unoffsets, dedent, offsets, range }, message) => { | ||
// strip out the start and end of the fix if they are not actually changes | ||
const transform_message = ({ transformed_code }, { unoffsets, dedent, indentation, offsets, range }, message) => { | ||
let fix_pos_start; | ||
let fix_pos_end; | ||
if (message.fix) { | ||
// strip out the start and end of the fix if they are not actually changes | ||
while (message.fix.range[0] < message.fix.range[1] && transformed_code[message.fix.range[0]] === message.fix.text[0]) { | ||
@@ -715,4 +748,13 @@ message.fix.range[0]++; | ||
} | ||
// If the fix spans multiple lines, add the indentation to each one | ||
message.fix.text = message.fix.text.split('\n').join(`\n${indentation}`); | ||
// The fix can span multiple lines and doesn't need to be on the same line | ||
// as the lint message, so we can't just add total_offsets at message.line to it | ||
// (see dedent-step below) | ||
fix_pos_start = position_at(message.fix.range[0], transformed_code); | ||
fix_pos_end = position_at(message.fix.range[1], transformed_code); | ||
} | ||
// shift position reference backward according to unoffsets | ||
// (aka: throw out the generated code lines prior to the original code) | ||
{ | ||
@@ -735,3 +777,5 @@ const { length, lines, last } = unoffsets; | ||
} | ||
// adjust position reference according to the previous dedenting | ||
// (aka: re-add the stripped indentation) | ||
{ | ||
@@ -744,7 +788,13 @@ const { offsets, total_offsets } = dedent; | ||
if (message.fix) { | ||
message.fix.range[0] += total_offsets[message.line]; | ||
message.fix.range[1] += total_offsets[message.line]; | ||
// We need the offset at the line relative to dedent's total_offsets. The dedents | ||
// start at the point in the total transformed code where a subset of the code was transformed. | ||
// Therefore substract (unoffsets.lines + 1) which marks the start of that transformation. | ||
// Add +1 afterwards because total_offsets are 1-index-based. | ||
message.fix.range[0] += total_offsets[fix_pos_start.line - unoffsets.lines + 2]; | ||
message.fix.range[1] += total_offsets[fix_pos_end.line - unoffsets.lines + 2]; | ||
} | ||
} | ||
// shift position reference forward according to offsets | ||
// (aka: re-add the code that is originally prior to the code) | ||
{ | ||
@@ -767,2 +817,3 @@ const { length, lines, last } = offsets; | ||
} | ||
// make sure the fix doesn't include anything outside the range of the script | ||
@@ -806,2 +857,4 @@ if (message.fix) { | ||
case 'no-unused-labels': return get_referenced_string(block, message) !== '$'; | ||
case '@typescript-eslint/no-unused-vars': | ||
case 'no-unused-vars': return !['$$Props', '$$Slots', '$$Events'].includes(get_referenced_string(block, message)); | ||
case '@typescript-eslint/quotes': | ||
@@ -808,0 +861,0 @@ case 'quotes': return !translation.options.in_quoted_attribute; |
{ | ||
"name": "eslint-plugin-svelte3", | ||
"version": "3.2.1", | ||
"description": "An ESLint plugin for Svelte v3 components.", | ||
"keywords": [ | ||
"eslint", | ||
"eslintplugin", | ||
"svelte", | ||
"sveltejs" | ||
], | ||
"files": [ | ||
"index.js" | ||
], | ||
"main": "index.js", | ||
"engines": { | ||
"node": ">=10" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/sveltejs/eslint-plugin-svelte3.git" | ||
}, | ||
"author": "Conduitry", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/sveltejs/eslint-plugin-svelte3/issues" | ||
}, | ||
"peerDependencies": { | ||
"eslint": ">=6.0.0", | ||
"svelte": "^3.2.0" | ||
}, | ||
"scripts": { | ||
"build": "rollup -c", | ||
"dev": "rollup -cw", | ||
"test": "npm run build && node test" | ||
}, | ||
"devDependencies": { | ||
"@rollup/plugin-node-resolve": "^11.2.0", | ||
"@typescript-eslint/eslint-plugin": "^4.14.2", | ||
"@typescript-eslint/parser": "^4.14.2", | ||
"eslint": ">=6.0.0", | ||
"rollup": "^2", | ||
"sourcemap-codec": "1.4.8", | ||
"svelte": "^3.2.0", | ||
"typescript": "^4.0.0" | ||
} | ||
} | ||
"name": "eslint-plugin-svelte3", | ||
"version": "3.3.0", | ||
"description": "An ESLint plugin for Svelte v3 components.", | ||
"keywords": [ | ||
"eslint", | ||
"eslintplugin", | ||
"svelte", | ||
"sveltejs" | ||
], | ||
"files": [ | ||
"index.js" | ||
], | ||
"main": "index.js", | ||
"engines": { | ||
"node": ">=10" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/sveltejs/eslint-plugin-svelte3.git" | ||
}, | ||
"author": "Conduitry", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/sveltejs/eslint-plugin-svelte3/issues" | ||
}, | ||
"peerDependencies": { | ||
"eslint": ">=6.0.0", | ||
"svelte": "^3.2.0" | ||
}, | ||
"devDependencies": { | ||
"@rollup/plugin-node-resolve": "^11.2.0", | ||
"@typescript-eslint/eslint-plugin": "^5.8.1", | ||
"@typescript-eslint/parser": "^5.8.1", | ||
"eslint": ">=7.0.0 < 8", | ||
"rollup": "^2", | ||
"sourcemap-codec": "1.4.8", | ||
"svelte": "^3.2.0", | ||
"typescript": "^4.5.4" | ||
}, | ||
"scripts": { | ||
"build": "rollup -c", | ||
"dev": "rollup -cw", | ||
"test": "npm run build && node test" | ||
} | ||
} |
@@ -137,3 +137,3 @@ # eslint-plugin-svelte3 | ||
This setting can be given a function that indicates whether to ignore a warning in the linting. The function will be passed a warning object and should return a boolean. | ||
This setting can be given a function that indicates whether to ignore a warning in the linting. The function will be passed a warning object and should return a boolean. Only warnings from the Svelte compiler itself can be filtered out through this function. Regular ESLint rules are configured/disabled through the corresponding ESLint settings. | ||
@@ -156,3 +156,3 @@ The default is to not ignore any warnings. | ||
The default is to not ignore any styles. | ||
The default is to ignore styles when the `<style>` tag has a `lang=` or `type=` attribute. | ||
@@ -159,0 +159,0 @@ ### `svelte3/named-blocks` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
41193
785