diff --git a/.changeset/perfect-bags-occur.md b/.changeset/perfect-bags-occur.md new file mode 100644 index 000000000..4c3a94ada --- /dev/null +++ b/.changeset/perfect-bags-occur.md @@ -0,0 +1,26 @@ +--- +'houdini-svelte': patch +--- + +Remove generics from script tag before calling svelte preprocessor. + +Otherwise it will fail to parse the source if the generics attribute contains angle brackets. + +For example this code failed to parse: + +```html + +``` + +Now the `parseSvelte` function will remove the generics attribute before calling the svelte preprocessor +preserving the token positions in the source code. + +The output for the above example will be: + +```html + +``` diff --git a/packages/houdini-svelte/src/plugin/extract.test.ts b/packages/houdini-svelte/src/plugin/extract.test.ts index 261571c2d..c8b98ba1c 100644 --- a/packages/houdini-svelte/src/plugin/extract.test.ts +++ b/packages/houdini-svelte/src/plugin/extract.test.ts @@ -54,6 +54,57 @@ describe('parser tests', () => { `) }) + test('happy path - typescript with generics', async () => { + const doc = ` + + ` + // parse the string + const result = await parseSvelte(doc) + + expect(result?.script).toMatchInlineSnapshot('export let x: T;') + }) + + test('happy path - typescript with generics over several lines', async () => { + const doc = ` + + + + ` + // parse the string + const result = await parseSvelte(doc) + + expect(result?.script).toMatchInlineSnapshot(` + import * as FormPrimitive from "formsnap"; + import { cn } from "$lib/utils.js"; + type $$Props = FormPrimitive.FieldsetProps; + export let form: SuperForm; + export let name: U; + let className: $$Props["class"] = undefined; + export { className as class }; + `) + }) + test('nested script block', async () => { const doc = `
diff --git a/packages/houdini-svelte/src/plugin/extract.ts b/packages/houdini-svelte/src/plugin/extract.ts index a0c9b3371..397a16c39 100644 --- a/packages/houdini-svelte/src/plugin/extract.ts +++ b/packages/houdini-svelte/src/plugin/extract.ts @@ -40,6 +40,15 @@ export async function parseSvelte(str: string): Promise> { // parsing a file happens in two steps: // - first we use svelte's parser to find the bounds of the script tag // - then we run the contents through babel to parse it + + // remove generics from script tag — otherwise svelte preprocessor will fail to parse + // if the generics attribute contains angle brackets + // Input: