diff --git a/.changeset/icy-mammals-cover.md b/.changeset/icy-mammals-cover.md new file mode 100644 index 000000000..025752957 --- /dev/null +++ b/.changeset/icy-mammals-cover.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-svelte': patch +--- + +feat(no-navigation-without-resolve): added support for ResolvedPathname types diff --git a/packages/eslint-plugin-svelte/src/rules/no-navigation-without-resolve.ts b/packages/eslint-plugin-svelte/src/rules/no-navigation-without-resolve.ts index e3d234089..64532bb0b 100644 --- a/packages/eslint-plugin-svelte/src/rules/no-navigation-without-resolve.ts +++ b/packages/eslint-plugin-svelte/src/rules/no-navigation-without-resolve.ts @@ -1,10 +1,12 @@ import type { TSESTree } from '@typescript-eslint/types'; + import { createRule } from '../utils/index.js'; import { ReferenceTracker } from '@eslint-community/eslint-utils'; import { FindVariableContext } from '../utils/ast-utils.js'; import { findVariable } from '../utils/ast-utils.js'; import type { RuleContext } from '../types.js'; import type { AST } from 'svelte-eslint-parser'; +import { type TSTools, getTypeScriptTools } from '../utils/ts-utils/index.js'; export default createRule('no-navigation-without-resolve', { meta: { @@ -48,6 +50,8 @@ export default createRule('no-navigation-without-resolve', { ] }, create(context) { + const tsTools = getTypeScriptTools(context); + let resolveReferences: Set = new Set(); const ignoreGoto = context.options[0]?.ignoreGoto ?? false; @@ -66,7 +70,7 @@ export default createRule('no-navigation-without-resolve', { } = extractFunctionCallReferences(referenceTracker); if (!ignoreGoto) { for (const gotoCall of gotoCalls) { - checkGotoCall(context, gotoCall, resolveReferences); + checkGotoCall(context, gotoCall, resolveReferences, tsTools); } } if (!ignorePushState) { @@ -75,6 +79,7 @@ export default createRule('no-navigation-without-resolve', { context, pushStateCall, resolveReferences, + tsTools, 'pushStateWithoutResolve' ); } @@ -85,6 +90,7 @@ export default createRule('no-navigation-without-resolve', { context, replaceStateCall, resolveReferences, + tsTools, 'replaceStateWithoutResolve' ); } @@ -92,7 +98,7 @@ export default createRule('no-navigation-without-resolve', { }, ...(!ignoreLinks && { SvelteShorthandAttribute(node) { - checkLinkAttribute(context, node, node.value, resolveReferences); + checkLinkAttribute(context, node, node.value, resolveReferences, tsTools); }, SvelteAttribute(node) { if (node.value.length > 0) { @@ -100,7 +106,8 @@ export default createRule('no-navigation-without-resolve', { context, node, node.value[0].type === 'SvelteMustacheTag' ? node.value[0].expression : node.value[0], - resolveReferences + resolveReferences, + tsTools ); } } @@ -187,11 +194,18 @@ function extractFunctionCallReferences(referenceTracker: ReferenceTracker): { function checkGotoCall( context: RuleContext, call: TSESTree.CallExpression, - resolveReferences: Set + resolveReferences: Set, + tsTools: TSTools | null ): void { if ( call.arguments.length > 0 && - !isValueAllowed(new FindVariableContext(context), call.arguments[0], resolveReferences, {}) + !isValueAllowed( + new FindVariableContext(context), + call.arguments[0], + resolveReferences, + tsTools, + {} + ) ) { context.report({ loc: call.arguments[0].loc, messageId: 'gotoWithoutResolve' }); } @@ -201,13 +215,20 @@ function checkShallowNavigationCall( context: RuleContext, call: TSESTree.CallExpression, resolveReferences: Set, + tsTools: TSTools | null, messageId: string ): void { if ( call.arguments.length > 0 && - !isValueAllowed(new FindVariableContext(context), call.arguments[0], resolveReferences, { - allowEmpty: true - }) + !isValueAllowed( + new FindVariableContext(context), + call.arguments[0], + resolveReferences, + tsTools, + { + allowEmpty: true + } + ) ) { context.report({ loc: call.arguments[0].loc, messageId }); } @@ -217,7 +238,8 @@ function checkLinkAttribute( context: RuleContext, attribute: AST.SvelteAttribute | AST.SvelteShorthandAttribute, value: TSESTree.Expression | AST.SvelteLiteral, - resolveReferences: Set + resolveReferences: Set, + tsTools: TSTools | null ): void { if ( attribute.parent.parent.type === 'SvelteElement' && @@ -226,7 +248,7 @@ function checkLinkAttribute( attribute.parent.parent.name.name === 'a' && attribute.key.name === 'href' && !hasRelExternal(new FindVariableContext(context), attribute.parent) && - !isValueAllowed(new FindVariableContext(context), value, resolveReferences, { + !isValueAllowed(new FindVariableContext(context), value, resolveReferences, tsTools, { allowAbsolute: true, allowFragment: true, allowNullish: true @@ -275,6 +297,7 @@ function isValueAllowed( ctx: FindVariableContext, value: TSESTree.CallExpressionArgument | AST.SvelteLiteral, resolveReferences: Set, + tsTools: TSTools | null, config: { allowAbsolute?: boolean; allowEmpty?: boolean; @@ -287,16 +310,26 @@ function isValueAllowed( if ( variable !== null && variable.identifiers.length > 0 && - variable.identifiers[0].parent.type === 'VariableDeclarator' && - variable.identifiers[0].parent.init !== null + variable.identifiers[0].parent.type === 'VariableDeclarator' ) { - return isValueAllowed(ctx, variable.identifiers[0].parent.init, resolveReferences, config); + if (expressionIsResolvedPathname(variable.identifiers[0], tsTools)) { + return true; + } + if (variable.identifiers[0].parent.init !== null) { + return isValueAllowed( + ctx, + variable.identifiers[0].parent.init, + resolveReferences, + tsTools, + config + ); + } } } if (value.type === 'ConditionalExpression') { return ( - isValueAllowed(ctx, value.consequent, resolveReferences, config) && - isValueAllowed(ctx, value.alternate, resolveReferences, config) + isValueAllowed(ctx, value.consequent, resolveReferences, tsTools, config) && + isValueAllowed(ctx, value.alternate, resolveReferences, tsTools, config) ); } if ( @@ -304,6 +337,7 @@ function isValueAllowed( (config.allowEmpty && expressionIsEmpty(value)) || (config.allowFragment && expressionStartsWith(ctx, value, '#')) || (config.allowNullish && expressionIsNullish(value)) || + expressionIsResolvedPathname(value, tsTools) || expressionIsResolveCall(ctx, value, resolveReferences) ) { return true; @@ -313,6 +347,41 @@ function isValueAllowed( // Helper functions +function expressionIsResolvedPathname( + value: TSESTree.CallExpressionArgument | TSESTree.Expression | AST.SvelteLiteral, + tsTools: TSTools | null +): boolean { + if (tsTools === null) { + return false; + } + const checker = tsTools.service.program.getTypeChecker(); + + const tsNode = tsTools.service.esTreeNodeToTSNodeMap.get(value); + if (tsNode === undefined) { + return false; + } + const nodeType = checker.getTypeAtLocation(tsNode); + + const appTypesModule = checker.getAmbientModules().find((m) => m.name === '"$app/types"'); + if (!appTypesModule) { + return false; + } + + const resolvedPathnameSymbol = checker + .getExportsOfModule(appTypesModule) + .find((e) => e.name === 'ResolvedPathname'); + if (!resolvedPathnameSymbol) { + return false; + } + const resolvedPathnameType = checker.getDeclaredTypeOfSymbol(resolvedPathnameSymbol); + + // getTypeAtLocation returns the resolved (structural) type without alias information, so we cannot compare aliasSymbols directly. Instead we check structural equivalence by testing assignability in both directions: this correctly rejects strict subtypes like Pathname (Pathname ⊂ ResolvedPathname, so only one direction holds). + return ( + checker.isTypeAssignableTo(nodeType, resolvedPathnameType) && + checker.isTypeAssignableTo(resolvedPathnameType, nodeType) + ); +} + function expressionIsResolveCall( ctx: FindVariableContext, node: TSESTree.CallExpressionArgument | AST.SvelteLiteral, diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-resolved-pathname-wrong-module01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-resolved-pathname-wrong-module01-errors.yaml new file mode 100644 index 000000000..2c72d2a64 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-resolved-pathname-wrong-module01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected goto() call without resolve(). + line: 12 + column: 7 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-resolved-pathname-wrong-module01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-resolved-pathname-wrong-module01-input.svelte new file mode 100644 index 000000000..277afa403 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-resolved-pathname-wrong-module01-input.svelte @@ -0,0 +1,13 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-string-prop01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-string-prop01-errors.yaml new file mode 100644 index 000000000..f0f40c118 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-string-prop01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected goto() call without resolve(). + line: 10 + column: 7 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-string-prop01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-string-prop01-input.svelte new file mode 100644 index 000000000..13c3c4940 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-string-prop01-input.svelte @@ -0,0 +1,11 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-unresolved-pathname01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-unresolved-pathname01-errors.yaml new file mode 100644 index 000000000..2c72d2a64 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-unresolved-pathname01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected goto() call without resolve(). + line: 12 + column: 7 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-unresolved-pathname01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-unresolved-pathname01-input.svelte new file mode 100644 index 000000000..f6eabd39b --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/goto-unresolved-pathname01-input.svelte @@ -0,0 +1,13 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-resolved-pathname-wrong-module01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-resolved-pathname-wrong-module01-errors.yaml new file mode 100644 index 000000000..c51a64523 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-resolved-pathname-wrong-module01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected href link without resolve(). + line: 11 + column: 4 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-resolved-pathname-wrong-module01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-resolved-pathname-wrong-module01-input.svelte new file mode 100644 index 000000000..d22bf39c3 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-resolved-pathname-wrong-module01-input.svelte @@ -0,0 +1,11 @@ + + +Click me! diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-string-prop01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-string-prop01-errors.yaml new file mode 100644 index 000000000..0f06d107a --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-string-prop01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected href link without resolve(). + line: 9 + column: 4 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-string-prop01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-string-prop01-input.svelte new file mode 100644 index 000000000..d9129ceea --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-string-prop01-input.svelte @@ -0,0 +1,9 @@ + + +Click me! diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-unresolved-pathname01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-unresolved-pathname01-errors.yaml new file mode 100644 index 000000000..c51a64523 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-unresolved-pathname01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected href link without resolve(). + line: 11 + column: 4 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-unresolved-pathname01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-unresolved-pathname01-input.svelte new file mode 100644 index 000000000..0090b7823 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/link-unresolved-pathname01-input.svelte @@ -0,0 +1,11 @@ + + +Click me! diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-resolved-pathname-wrong-module01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-resolved-pathname-wrong-module01-errors.yaml new file mode 100644 index 000000000..d40ddce17 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-resolved-pathname-wrong-module01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected pushState() call without resolve(). + line: 12 + column: 12 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-resolved-pathname-wrong-module01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-resolved-pathname-wrong-module01-input.svelte new file mode 100644 index 000000000..927fa53c1 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-resolved-pathname-wrong-module01-input.svelte @@ -0,0 +1,13 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-string-prop01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-string-prop01-errors.yaml new file mode 100644 index 000000000..74116d69f --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-string-prop01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected pushState() call without resolve(). + line: 10 + column: 12 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-string-prop01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-string-prop01-input.svelte new file mode 100644 index 000000000..fa5588aa0 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-string-prop01-input.svelte @@ -0,0 +1,11 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-unresolved-pathname01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-unresolved-pathname01-errors.yaml new file mode 100644 index 000000000..d40ddce17 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-unresolved-pathname01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected pushState() call without resolve(). + line: 12 + column: 12 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-unresolved-pathname01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-unresolved-pathname01-input.svelte new file mode 100644 index 000000000..f0de7419b --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/pushState-unresolved-pathname01-input.svelte @@ -0,0 +1,13 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-resolved-pathname-wrong-module01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-resolved-pathname-wrong-module01-errors.yaml new file mode 100644 index 000000000..e9b8ab91c --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-resolved-pathname-wrong-module01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected replaceState() call without resolve(). + line: 12 + column: 15 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-resolved-pathname-wrong-module01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-resolved-pathname-wrong-module01-input.svelte new file mode 100644 index 000000000..275b54c0c --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-resolved-pathname-wrong-module01-input.svelte @@ -0,0 +1,13 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-string-prop01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-string-prop01-errors.yaml new file mode 100644 index 000000000..e8495d713 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-string-prop01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected replaceState() call without resolve(). + line: 10 + column: 15 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-string-prop01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-string-prop01-input.svelte new file mode 100644 index 000000000..ded48830d --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-string-prop01-input.svelte @@ -0,0 +1,11 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-unresolved-pathname01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-unresolved-pathname01-errors.yaml new file mode 100644 index 000000000..e9b8ab91c --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-unresolved-pathname01-errors.yaml @@ -0,0 +1,4 @@ +- message: Unexpected replaceState() call without resolve(). + line: 12 + column: 15 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-unresolved-pathname01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-unresolved-pathname01-input.svelte new file mode 100644 index 000000000..4c48df2e9 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/invalid/replaceState-unresolved-pathname01-input.svelte @@ -0,0 +1,13 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/goto-resolved-pathname01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/goto-resolved-pathname01-input.svelte new file mode 100644 index 000000000..04e18f371 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/goto-resolved-pathname01-input.svelte @@ -0,0 +1,13 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/goto-resolved-pathname02-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/goto-resolved-pathname02-input.svelte new file mode 100644 index 000000000..9e7e1c2cb --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/goto-resolved-pathname02-input.svelte @@ -0,0 +1,9 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-resolved-pathname01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-resolved-pathname01-input.svelte new file mode 100644 index 000000000..d1bddb44e --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-resolved-pathname01-input.svelte @@ -0,0 +1,11 @@ + + +Click me! diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-resolved-pathname02-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-resolved-pathname02-input.svelte new file mode 100644 index 000000000..874241a20 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/link-resolved-pathname02-input.svelte @@ -0,0 +1,7 @@ + + +Click me! diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/pushState-resolved-pathname01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/pushState-resolved-pathname01-input.svelte new file mode 100644 index 000000000..78311db21 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/pushState-resolved-pathname01-input.svelte @@ -0,0 +1,13 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/pushState-resolved-pathname02-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/pushState-resolved-pathname02-input.svelte new file mode 100644 index 000000000..cbc770b32 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/pushState-resolved-pathname02-input.svelte @@ -0,0 +1,9 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/replaceState-resolved-pathname01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/replaceState-resolved-pathname01-input.svelte new file mode 100644 index 000000000..16625d970 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/replaceState-resolved-pathname01-input.svelte @@ -0,0 +1,13 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/replaceState-resolved-pathname02-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/replaceState-resolved-pathname02-input.svelte new file mode 100644 index 000000000..58925806d --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-navigation-without-resolve/valid/replaceState-resolved-pathname02-input.svelte @@ -0,0 +1,9 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/sveltekit-types.d.ts b/packages/eslint-plugin-svelte/tests/fixtures/rules/sveltekit-types.d.ts new file mode 100644 index 000000000..46c9a99c1 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/sveltekit-types.d.ts @@ -0,0 +1,6 @@ +// Type stubs for SvelteKit's $app modules + +declare module '$app/types' { + export type Pathname = "/" | "/test" | "/test/123" | "/test/123/456"; + export type ResolvedPathname = `${"" | `/${string}`}${Pathname}`; +}