From a94b83b7d4adcc25b5ff0d350bdd7d827989ab14 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 17 Jun 2024 18:07:45 +0200 Subject: [PATCH 1/7] fix: support function invocation from imported `*.svelte` components (#12061) When the TypeScript plugin we provide isn't enabled, imports to `.svelte`-files fall back to an ambient module declaration. Said declaration was still only providing the deprecated class. This PR widens the type so that you can also invoke it like a function. After the transition period (Svelte 6 or 7) only the new type should be provided from the module declaration. --- .changeset/ninety-days-visit.md | 5 +++++ packages/svelte/src/ambient.d.ts | 13 ++++++++++++- packages/svelte/tests/types/component.ts | 10 ++++++++++ packages/svelte/types/index.d.ts | 13 ++++++++++++- 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 .changeset/ninety-days-visit.md diff --git a/.changeset/ninety-days-visit.md b/.changeset/ninety-days-visit.md new file mode 100644 index 000000000..51e6e5267 --- /dev/null +++ b/.changeset/ninety-days-visit.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: support function invocation from imported `*.svelte` components diff --git a/packages/svelte/src/ambient.d.ts b/packages/svelte/src/ambient.d.ts index d024c5d52..04ad31acf 100644 --- a/packages/svelte/src/ambient.d.ts +++ b/packages/svelte/src/ambient.d.ts @@ -1,5 +1,16 @@ declare module '*.svelte' { - export { SvelteComponent as default } from 'svelte'; + import { SvelteComponent, Component, type ComponentConstructorOptions } from 'svelte'; + + // Support using the component as both a class and function during the transition period + interface ComponentType { + ( + ...args: Parameters>> + ): ReturnType, Record>>; + new (o: ComponentConstructorOptions): SvelteComponent; + } + const Comp: ComponentType; + type Comp = SvelteComponent; + export default Comp; } /** diff --git a/packages/svelte/tests/types/component.ts b/packages/svelte/tests/types/component.ts index 101927a46..ca520656f 100644 --- a/packages/svelte/tests/types/component.ts +++ b/packages/svelte/tests/types/component.ts @@ -281,3 +281,13 @@ render(functionComponent, { x: '' } }); + +// --------------------------------------------------------------------------- *.svelte components + +// import from a nonexistent file to trigger the declare module '*.svelte' in ambient.d.ts +// this could show an error in the future in the editor (because language tools intercepts and knows this is an error) +// but should always pass in tsc (because it will never know about this fact) +import Foo from './doesntexist.svelte'; + +Foo(null, { a: true }); +const f: Foo = new Foo({ target: document.body, props: { a: true } }); diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 742e048c9..4afd0698b 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -2634,7 +2634,18 @@ declare module 'svelte/types/compiler/interfaces' { */ type Namespace = 'html' | 'svg' | 'mathml' | 'foreign'; }declare module '*.svelte' { - export { SvelteComponent as default } from 'svelte'; + import { SvelteComponent, Component, type ComponentConstructorOptions } from 'svelte'; + + // Support using the component as both a class and function during the transition period + interface ComponentType { + ( + ...args: Parameters>> + ): ReturnType, Record>>; + new (o: ComponentConstructorOptions): SvelteComponent; + } + const Comp: ComponentType; + type Comp = SvelteComponent; + export default Comp; } /** From ad75111bdaff63226655d9fff3d93f9b4382cdbd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 18:09:06 +0200 Subject: [PATCH 2/7] Version Packages (next) (#12054) Co-authored-by: github-actions[bot] --- .changeset/pre.json | 5 +++++ packages/svelte/CHANGELOG.md | 14 ++++++++++++++ packages/svelte/package.json | 2 +- packages/svelte/src/version.js | 2 +- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index aedd9df5b..20787484c 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -268,6 +268,7 @@ "kind-spoons-return", "large-clouds-carry", "large-turkeys-deny", + "large-waves-join", "late-bees-vanish", "late-crabs-lay", "late-grapes-judge", @@ -295,6 +296,7 @@ "loud-cheetahs-flow", "loud-mugs-smile", "loud-numbers-flow", + "loud-penguins-unite", "loud-ravens-drop", "loud-socks-look", "lovely-bugs-sneeze", @@ -324,6 +326,7 @@ "moody-houses-argue", "moody-owls-cry", "moody-sheep-type", + "nasty-glasses-begin", "nasty-lions-double", "nasty-yaks-peel", "neat-boats-shake", @@ -338,6 +341,7 @@ "new-rabbits-flow", "nice-avocados-move", "nine-cooks-join", + "ninety-days-visit", "ninety-dingos-walk", "ninety-dots-train", "ninety-rockets-battle", @@ -394,6 +398,7 @@ "quiet-cobras-smile", "quiet-crabs-nail", "quiet-timers-speak", + "rare-insects-tell", "rare-mirrors-act", "rare-pears-whisper", "rare-worms-hunt", diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index fdf345996..4418b5cbb 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,19 @@ # svelte +## 5.0.0-next.157 + +### Patch Changes + +- fix: handle `is` attribute on elements with spread ([#12056](https://github.com/sveltejs/svelte/pull/12056)) + +- fix: correctly process empty lines in messages ([#12057](https://github.com/sveltejs/svelte/pull/12057)) + +- fix: rewrite state_unsafe_mutation message ([#12059](https://github.com/sveltejs/svelte/pull/12059)) + +- fix: support function invocation from imported `*.svelte` components ([#12061](https://github.com/sveltejs/svelte/pull/12061)) + +- fix: better types for `on` ([#12053](https://github.com/sveltejs/svelte/pull/12053)) + ## 5.0.0-next.156 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 2b0d1c5d4..e1b99c02a 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -2,7 +2,7 @@ "name": "svelte", "description": "Cybernetically enhanced web apps", "license": "MIT", - "version": "5.0.0-next.156", + "version": "5.0.0-next.157", "type": "module", "types": "./types/index.d.ts", "engines": { diff --git a/packages/svelte/src/version.js b/packages/svelte/src/version.js index 6371f8d5f..2e41ff7e6 100644 --- a/packages/svelte/src/version.js +++ b/packages/svelte/src/version.js @@ -6,5 +6,5 @@ * https://svelte.dev/docs/svelte-compiler#svelte-version * @type {string} */ -export const VERSION = '5.0.0-next.156'; +export const VERSION = '5.0.0-next.157'; export const PUBLIC_VERSION = '5'; From 29ca451c9eebdfb761bed2fb9f79b045a94c463c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 17 Jun 2024 09:10:34 -0700 Subject: [PATCH 3/7] chore: tidier generated message code (#12062) * chore: tidier generated message code * lint --- .../svelte/scripts/process-messages/index.js | 48 +++++++++++++++++++ packages/svelte/src/internal/client/errors.js | 36 +++++++------- .../svelte/src/internal/client/warnings.js | 12 ++--- packages/svelte/src/internal/server/errors.js | 2 +- packages/svelte/src/internal/shared/errors.js | 10 ++-- .../svelte/src/internal/shared/warnings.js | 2 +- 6 files changed, 79 insertions(+), 31 deletions(-) diff --git a/packages/svelte/scripts/process-messages/index.js b/packages/svelte/scripts/process-messages/index.js index 71a979d51..ea0a40c49 100644 --- a/packages/svelte/scripts/process-messages/index.js +++ b/packages/svelte/scripts/process-messages/index.js @@ -293,6 +293,54 @@ function transform(name, dest) { } }); }, + TemplateLiteral(node, context) { + /** @type {import('estree').TemplateElement} */ + let quasi = { + type: 'TemplateElement', + value: { + ...node.quasis[0].value + }, + tail: node.quasis[0].tail + }; + + /** @type {import('estree').TemplateLiteral} */ + let out = { + type: 'TemplateLiteral', + quasis: [quasi], + expressions: [] + }; + + for (let i = 0; i < node.expressions.length; i += 1) { + const q = node.quasis[i + 1]; + const e = node.expressions[i]; + + if (e.type === 'Literal' && e.value === 'CODE') { + quasi.value.raw += code + q.value.raw; + continue; + } + + if (e.type === 'Identifier' && e.name === 'MESSAGE') { + if (message.type === 'Literal') { + const str = /** @type {string} */ (message.value).replace(/(`|\${)/g, '\\$1'); + quasi.value.raw += str + q.value.raw; + continue; + } + + if (message.type === 'TemplateLiteral') { + quasi.value.raw += message.quasis[0].value.raw + q.value.raw; + out.quasis.push(...message.quasis.slice(1)); + out.expressions.push(...message.expressions); + quasi = message.quasis[message.quasis.length - 1]; + continue; + } + } + + out.quasis.push((quasi = q)); + out.expressions.push(/** @type {import('estree').Expression} */ (context.visit(e))); + } + + return out; + }, Literal(node) { if (node.value === 'CODE') { return { diff --git a/packages/svelte/src/internal/client/errors.js b/packages/svelte/src/internal/client/errors.js index e344c552d..ba41a560c 100644 --- a/packages/svelte/src/internal/client/errors.js +++ b/packages/svelte/src/internal/client/errors.js @@ -8,7 +8,7 @@ import { DEV } from 'esm-env'; */ export function bind_invalid_checkbox_value() { if (DEV) { - const error = new Error(`${"bind_invalid_checkbox_value"}\n${"Using `bind:value` together with a checkbox input is not allowed. Use `bind:checked` instead"}`); + const error = new Error(`bind_invalid_checkbox_value\nUsing \`bind:value\` together with a checkbox input is not allowed. Use \`bind:checked\` instead`); error.name = 'Svelte error'; throw error; @@ -27,7 +27,7 @@ export function bind_invalid_checkbox_value() { */ export function bind_invalid_export(component, key, name) { if (DEV) { - const error = new Error(`${"bind_invalid_export"}\n${`Component ${component} has an export named \`${key}\` that a consumer component is trying to access using \`bind:${key}\`, which is disallowed. Instead, use \`bind:this\` (e.g. \`<${name} bind:this={component} />\`) and then access the property on the bound component instance (e.g. \`component.${key}\`)`}`); + const error = new Error(`bind_invalid_export\nComponent ${component} has an export named \`${key}\` that a consumer component is trying to access using \`bind:${key}\`, which is disallowed. Instead, use \`bind:this\` (e.g. \`<${name} bind:this={component} />\`) and then access the property on the bound component instance (e.g. \`component.${key}\`)`); error.name = 'Svelte error'; throw error; @@ -46,7 +46,7 @@ export function bind_invalid_export(component, key, name) { */ export function bind_not_bindable(key, component, name) { if (DEV) { - const error = new Error(`${"bind_not_bindable"}\n${`A component is attempting to bind to a non-bindable property \`${key}\` belonging to ${component} (i.e. \`<${name} bind:${key}={...}>\`). To mark a property as bindable: \`let { ${key} = $bindable() } = $props()\``}`); + const error = new Error(`bind_not_bindable\nA component is attempting to bind to a non-bindable property \`${key}\` belonging to ${component} (i.e. \`<${name} bind:${key}={...}>\`). To mark a property as bindable: \`let { ${key} = $bindable() } = $props()\``); error.name = 'Svelte error'; throw error; @@ -65,7 +65,7 @@ export function bind_not_bindable(key, component, name) { */ export function component_api_changed(parent, method, component) { if (DEV) { - const error = new Error(`${"component_api_changed"}\n${`${parent} called \`${method}\` on an instance of ${component}, which is no longer valid in Svelte 5. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more information`}`); + const error = new Error(`component_api_changed\n${parent} called \`${method}\` on an instance of ${component}, which is no longer valid in Svelte 5. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more information`); error.name = 'Svelte error'; throw error; @@ -83,7 +83,7 @@ export function component_api_changed(parent, method, component) { */ export function component_api_invalid_new(component, name) { if (DEV) { - const error = new Error(`${"component_api_invalid_new"}\n${`Attempted to instantiate ${component} with \`new ${name}\`, which is no longer valid in Svelte 5. If this component is not under your control, set the \`legacy.componentApi\` compiler option to keep it working. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more information`}`); + const error = new Error(`component_api_invalid_new\nAttempted to instantiate ${component} with \`new ${name}\`, which is no longer valid in Svelte 5. If this component is not under your control, set the \`legacy.componentApi\` compiler option to keep it working. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more information`); error.name = 'Svelte error'; throw error; @@ -102,7 +102,7 @@ export function component_api_invalid_new(component, name) { */ export function each_key_duplicate(a, b, value) { if (DEV) { - const error = new Error(`${"each_key_duplicate"}\n${value ? `Keyed each block has duplicate key \`${value}\` at indexes ${a} and ${b}` : `Keyed each block has duplicate key at indexes ${a} and ${b}`}`); + const error = new Error(`each_key_duplicate\n${value ? `Keyed each block has duplicate key \`${value}\` at indexes ${a} and ${b}` : `Keyed each block has duplicate key at indexes ${a} and ${b}`}`); error.name = 'Svelte error'; throw error; @@ -119,7 +119,7 @@ export function each_key_duplicate(a, b, value) { */ export function effect_in_teardown(rune) { if (DEV) { - const error = new Error(`${"effect_in_teardown"}\n${`\`${rune}\` cannot be used inside an effect cleanup function`}`); + const error = new Error(`effect_in_teardown\n\`${rune}\` cannot be used inside an effect cleanup function`); error.name = 'Svelte error'; throw error; @@ -135,7 +135,7 @@ export function effect_in_teardown(rune) { */ export function effect_in_unowned_derived() { if (DEV) { - const error = new Error(`${"effect_in_unowned_derived"}\n${"Effect cannot be created inside a `$derived` value that was not itself created inside an effect"}`); + const error = new Error(`effect_in_unowned_derived\nEffect cannot be created inside a \`$derived\` value that was not itself created inside an effect`); error.name = 'Svelte error'; throw error; @@ -152,7 +152,7 @@ export function effect_in_unowned_derived() { */ export function effect_orphan(rune) { if (DEV) { - const error = new Error(`${"effect_orphan"}\n${`\`${rune}\` can only be used inside an effect (e.g. during component initialisation)`}`); + const error = new Error(`effect_orphan\n\`${rune}\` can only be used inside an effect (e.g. during component initialisation)`); error.name = 'Svelte error'; throw error; @@ -168,7 +168,7 @@ export function effect_orphan(rune) { */ export function effect_update_depth_exceeded() { if (DEV) { - const error = new Error(`${"effect_update_depth_exceeded"}\n${"Maximum update depth exceeded. This can happen when a reactive block or effect repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops"}`); + const error = new Error(`effect_update_depth_exceeded\nMaximum update depth exceeded. This can happen when a reactive block or effect repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops`); error.name = 'Svelte error'; throw error; @@ -184,7 +184,7 @@ export function effect_update_depth_exceeded() { */ export function hydration_failed() { if (DEV) { - const error = new Error(`${"hydration_failed"}\n${"Failed to hydrate the application"}`); + const error = new Error(`hydration_failed\nFailed to hydrate the application`); error.name = 'Svelte error'; throw error; @@ -201,7 +201,7 @@ export function hydration_failed() { */ export function lifecycle_legacy_only(name) { if (DEV) { - const error = new Error(`${"lifecycle_legacy_only"}\n${`\`${name}(...)\` cannot be used in runes mode`}`); + const error = new Error(`lifecycle_legacy_only\n\`${name}(...)\` cannot be used in runes mode`); error.name = 'Svelte error'; throw error; @@ -218,7 +218,7 @@ export function lifecycle_legacy_only(name) { */ export function props_invalid_value(key) { if (DEV) { - const error = new Error(`${"props_invalid_value"}\n${`Cannot do \`bind:${key}={undefined}\` when \`${key}\` has a fallback value`}`); + const error = new Error(`props_invalid_value\nCannot do \`bind:${key}={undefined}\` when \`${key}\` has a fallback value`); error.name = 'Svelte error'; throw error; @@ -235,7 +235,7 @@ export function props_invalid_value(key) { */ export function props_rest_readonly(property) { if (DEV) { - const error = new Error(`${"props_rest_readonly"}\n${`Rest element properties of \`$props()\` such as \`${property}\` are readonly`}`); + const error = new Error(`props_rest_readonly\nRest element properties of \`$props()\` such as \`${property}\` are readonly`); error.name = 'Svelte error'; throw error; @@ -252,7 +252,7 @@ export function props_rest_readonly(property) { */ export function rune_outside_svelte(rune) { if (DEV) { - const error = new Error(`${"rune_outside_svelte"}\n${`The \`${rune}\` rune is only available inside \`.svelte\` and \`.svelte.js/ts\` files`}`); + const error = new Error(`rune_outside_svelte\nThe \`${rune}\` rune is only available inside \`.svelte\` and \`.svelte.js/ts\` files`); error.name = 'Svelte error'; throw error; @@ -268,7 +268,7 @@ export function rune_outside_svelte(rune) { */ export function state_prototype_fixed() { if (DEV) { - const error = new Error(`${"state_prototype_fixed"}\n${"Cannot set prototype of `$state` object"}`); + const error = new Error(`state_prototype_fixed\nCannot set prototype of \`$state\` object`); error.name = 'Svelte error'; throw error; @@ -284,7 +284,7 @@ export function state_prototype_fixed() { */ export function state_unsafe_mutation() { if (DEV) { - const error = new Error(`${"state_unsafe_mutation"}\n${"Updating state inside a derived is forbidden. If the value should not be reactive, declare it without `$state`"}`); + const error = new Error(`state_unsafe_mutation\nUpdating state inside a derived is forbidden. If the value should not be reactive, declare it without \`$state\``); error.name = 'Svelte error'; throw error; @@ -300,7 +300,7 @@ export function state_unsafe_mutation() { */ export function svelte_component_invalid_this_value() { if (DEV) { - const error = new Error(`${"svelte_component_invalid_this_value"}\n${"The `this={...}` property of a `` must be a Svelte component, if defined"}`); + const error = new Error(`svelte_component_invalid_this_value\nThe \`this={...}\` property of a \`\` must be a Svelte component, if defined`); error.name = 'Svelte error'; throw error; diff --git a/packages/svelte/src/internal/client/warnings.js b/packages/svelte/src/internal/client/warnings.js index e5befc847..576453e52 100644 --- a/packages/svelte/src/internal/client/warnings.js +++ b/packages/svelte/src/internal/client/warnings.js @@ -13,7 +13,7 @@ var normal = 'font-weight: normal'; */ export function hydration_attribute_changed(attribute, html, value) { if (DEV) { - console.warn(`%c[svelte] ${"hydration_attribute_changed"}\n%c${`The \`${attribute}\` attribute on \`${html}\` changed its value between server and client renders. The client value, \`${value}\`, will be ignored in favour of the server value`}`, bold, normal); + console.warn(`%c[svelte] hydration_attribute_changed\n%cThe \`${attribute}\` attribute on \`${html}\` changed its value between server and client renders. The client value, \`${value}\`, will be ignored in favour of the server value`, bold, normal); } else { // TODO print a link to the documentation console.warn("hydration_attribute_changed"); @@ -26,7 +26,7 @@ export function hydration_attribute_changed(attribute, html, value) { */ export function hydration_mismatch(location) { if (DEV) { - console.warn(`%c[svelte] ${"hydration_mismatch"}\n%c${location ? `Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near ${location}` : "Hydration failed because the initial UI does not match what was rendered on the server"}`, bold, normal); + console.warn(`%c[svelte] hydration_mismatch\n%c${location ? `Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near ${location}` : "Hydration failed because the initial UI does not match what was rendered on the server"}`, bold, normal); } else { // TODO print a link to the documentation console.warn("hydration_mismatch"); @@ -38,7 +38,7 @@ export function hydration_mismatch(location) { */ export function lifecycle_double_unmount() { if (DEV) { - console.warn(`%c[svelte] ${"lifecycle_double_unmount"}\n%c${"Tried to unmount a component that was not mounted"}`, bold, normal); + console.warn(`%c[svelte] lifecycle_double_unmount\n%cTried to unmount a component that was not mounted`, bold, normal); } else { // TODO print a link to the documentation console.warn("lifecycle_double_unmount"); @@ -53,7 +53,7 @@ export function lifecycle_double_unmount() { */ export function ownership_invalid_binding(parent, child, owner) { if (DEV) { - console.warn(`%c[svelte] ${"ownership_invalid_binding"}\n%c${`${parent} passed a value to ${child} with \`bind:\`, but the value is owned by ${owner}. Consider creating a binding between ${owner} and ${parent}`}`, bold, normal); + console.warn(`%c[svelte] ownership_invalid_binding\n%c${parent} passed a value to ${child} with \`bind:\`, but the value is owned by ${owner}. Consider creating a binding between ${owner} and ${parent}`, bold, normal); } else { // TODO print a link to the documentation console.warn("ownership_invalid_binding"); @@ -67,7 +67,7 @@ export function ownership_invalid_binding(parent, child, owner) { */ export function ownership_invalid_mutation(component, owner) { if (DEV) { - console.warn(`%c[svelte] ${"ownership_invalid_mutation"}\n%c${component ? `${component} mutated a value owned by ${owner}. This is strongly discouraged. Consider passing values to child components with \`bind:\`, or use a callback instead` : "Mutating a value outside the component that created it is strongly discouraged. Consider passing values to child components with `bind:`, or use a callback instead"}`, bold, normal); + console.warn(`%c[svelte] ownership_invalid_mutation\n%c${component ? `${component} mutated a value owned by ${owner}. This is strongly discouraged. Consider passing values to child components with \`bind:\`, or use a callback instead` : "Mutating a value outside the component that created it is strongly discouraged. Consider passing values to child components with `bind:`, or use a callback instead"}`, bold, normal); } else { // TODO print a link to the documentation console.warn("ownership_invalid_mutation"); @@ -80,7 +80,7 @@ export function ownership_invalid_mutation(component, owner) { */ export function state_proxy_equality_mismatch(operator) { if (DEV) { - console.warn(`%c[svelte] ${"state_proxy_equality_mismatch"}\n%c${`Reactive \`$state(...)\` proxies and the values they proxy have different identities. Because of this, comparisons with \`${operator}\` will produce unexpected results. Consider using \`$state.is(a, b)\` instead`}`, bold, normal); + console.warn(`%c[svelte] state_proxy_equality_mismatch\n%cReactive \`$state(...)\` proxies and the values they proxy have different identities. Because of this, comparisons with \`${operator}\` will produce unexpected results. Consider using \`$state.is(a, b)\` instead`, bold, normal); } else { // TODO print a link to the documentation console.warn("state_proxy_equality_mismatch"); diff --git a/packages/svelte/src/internal/server/errors.js b/packages/svelte/src/internal/server/errors.js index 848e2e6e5..67f4a2dfc 100644 --- a/packages/svelte/src/internal/server/errors.js +++ b/packages/svelte/src/internal/server/errors.js @@ -6,7 +6,7 @@ * @returns {never} */ export function lifecycle_function_unavailable(name) { - const error = new Error(`${"lifecycle_function_unavailable"}\n${`\`${name}(...)\` is not available on the server`}`); + const error = new Error(`lifecycle_function_unavailable\n\`${name}(...)\` is not available on the server`); error.name = 'Svelte error'; throw error; diff --git a/packages/svelte/src/internal/shared/errors.js b/packages/svelte/src/internal/shared/errors.js index 4bfc595fa..984b86a54 100644 --- a/packages/svelte/src/internal/shared/errors.js +++ b/packages/svelte/src/internal/shared/errors.js @@ -9,7 +9,7 @@ import { DEV } from 'esm-env'; */ export function lifecycle_outside_component(name) { if (DEV) { - const error = new Error(`${"lifecycle_outside_component"}\n${`\`${name}(...)\` can only be used during component initialisation`}`); + const error = new Error(`lifecycle_outside_component\n\`${name}(...)\` can only be used during component initialisation`); error.name = 'Svelte error'; throw error; @@ -25,7 +25,7 @@ export function lifecycle_outside_component(name) { */ export function render_tag_invalid_argument() { if (DEV) { - const error = new Error(`${"render_tag_invalid_argument"}\n${"The argument to `{@render ...}` must be a snippet function, not a component or some other kind of function. If you want to dynamically render one snippet or another, use `$derived` and pass its result to `{@render ...}`"}`); + const error = new Error(`render_tag_invalid_argument\nThe argument to \`{@render ...}\` must be a snippet function, not a component or some other kind of function. If you want to dynamically render one snippet or another, use \`$derived\` and pass its result to \`{@render ...}\``); error.name = 'Svelte error'; throw error; @@ -41,7 +41,7 @@ export function render_tag_invalid_argument() { */ export function snippet_used_as_component() { if (DEV) { - const error = new Error(`${"snippet_used_as_component"}\n${"A snippet must be rendered with `{@render ...}`"}`); + const error = new Error(`snippet_used_as_component\nA snippet must be rendered with \`{@render ...}\``); error.name = 'Svelte error'; throw error; @@ -58,7 +58,7 @@ export function snippet_used_as_component() { */ export function store_invalid_shape(name) { if (DEV) { - const error = new Error(`${"store_invalid_shape"}\n${`\`${name}\` is not a store with a \`subscribe\` method`}`); + const error = new Error(`store_invalid_shape\n\`${name}\` is not a store with a \`subscribe\` method`); error.name = 'Svelte error'; throw error; @@ -74,7 +74,7 @@ export function store_invalid_shape(name) { */ export function svelte_element_invalid_this_value() { if (DEV) { - const error = new Error(`${"svelte_element_invalid_this_value"}\n${"The `this` prop on `` must be a string, if defined"}`); + const error = new Error(`svelte_element_invalid_this_value\nThe \`this\` prop on \`\` must be a string, if defined`); error.name = 'Svelte error'; throw error; diff --git a/packages/svelte/src/internal/shared/warnings.js b/packages/svelte/src/internal/shared/warnings.js index effcd13c5..2fc1b6fdd 100644 --- a/packages/svelte/src/internal/shared/warnings.js +++ b/packages/svelte/src/internal/shared/warnings.js @@ -11,7 +11,7 @@ var normal = 'font-weight: normal'; */ export function dynamic_void_element_content(tag) { if (DEV) { - console.warn(`%c[svelte] ${"dynamic_void_element_content"}\n%c${`\`\` is a void element — it cannot have content`}`, bold, normal); + console.warn(`%c[svelte] dynamic_void_element_content\n%c\`\` is a void element — it cannot have content`, bold, normal); } else { // TODO print a link to the documentation console.warn("dynamic_void_element_content"); From 4ddff6f9d0e619b76154d39a12b292819eef34ac Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 17 Jun 2024 21:42:50 +0200 Subject: [PATCH 4/7] fix: adjust module declaration to work around language tools bug (#12071) See https://github.com/sveltejs/language-tools/commit/026111228b5814a9109cc4d779d37fb02955fb8b for more info We can probably remove this after a few weeks --- .changeset/slow-ligers-enjoy.md | 5 +++++ packages/svelte/src/ambient.d.ts | 9 ++++++--- packages/svelte/types/index.d.ts | 9 ++++++--- 3 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 .changeset/slow-ligers-enjoy.md diff --git a/.changeset/slow-ligers-enjoy.md b/.changeset/slow-ligers-enjoy.md new file mode 100644 index 000000000..99bc046de --- /dev/null +++ b/.changeset/slow-ligers-enjoy.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: adjust module declaration to work around language tools bug diff --git a/packages/svelte/src/ambient.d.ts b/packages/svelte/src/ambient.d.ts index 04ad31acf..35bc292be 100644 --- a/packages/svelte/src/ambient.d.ts +++ b/packages/svelte/src/ambient.d.ts @@ -1,12 +1,15 @@ declare module '*.svelte' { - import { SvelteComponent, Component, type ComponentConstructorOptions } from 'svelte'; + // use prettier-ignore for a while because of https://github.com/sveltejs/language-tools/commit/026111228b5814a9109cc4d779d37fb02955fb8b + // prettier-ignore + import { SvelteComponent, Component, type ComponentConstructorOptions } from 'svelte' // Support using the component as both a class and function during the transition period + // prettier-ignore interface ComponentType { ( ...args: Parameters>> - ): ReturnType, Record>>; - new (o: ComponentConstructorOptions): SvelteComponent; + ): ReturnType, Record>> + new (o: ComponentConstructorOptions): SvelteComponent } const Comp: ComponentType; type Comp = SvelteComponent; diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 4afd0698b..67fde62e3 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -2634,14 +2634,17 @@ declare module 'svelte/types/compiler/interfaces' { */ type Namespace = 'html' | 'svg' | 'mathml' | 'foreign'; }declare module '*.svelte' { - import { SvelteComponent, Component, type ComponentConstructorOptions } from 'svelte'; + // use prettier-ignore for a while because of https://github.com/sveltejs/language-tools/commit/026111228b5814a9109cc4d779d37fb02955fb8b + // prettier-ignore + import { SvelteComponent, Component, type ComponentConstructorOptions } from 'svelte' // Support using the component as both a class and function during the transition period + // prettier-ignore interface ComponentType { ( ...args: Parameters>> - ): ReturnType, Record>>; - new (o: ComponentConstructorOptions): SvelteComponent; + ): ReturnType, Record>> + new (o: ComponentConstructorOptions): SvelteComponent } const Comp: ComponentType; type Comp = SvelteComponent; From 8388c4d90e6da88c65199a1186abfccc425acf50 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 17 Jun 2024 21:43:09 +0200 Subject: [PATCH 5/7] chore: add `@description` tags (#12063) add them so that the TypeScript parser doesn't put the following content under the `@deprecated` tag, which messes with the JSON-type-generation script. --- packages/svelte/src/index.d.ts | 2 ++ packages/svelte/types/index.d.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/svelte/src/index.d.ts b/packages/svelte/src/index.d.ts index a5e8aaf17..393d89498 100644 --- a/packages/svelte/src/index.d.ts +++ b/packages/svelte/src/index.d.ts @@ -170,6 +170,7 @@ export class SvelteComponentTyped< /** * @deprecated The new `Component` type does not have a dedicated Events type. Use `ComponentProps` instead. * + * @description * Convenience type to get the events the given component expects. Example: * ```html *