Skip to content

Commit ea29bad

Browse files
committed
fix: correctly validate undefined snippet params with default value
1 parent 3d6da41 commit ea29bad

File tree

5 files changed

+30
-4
lines changed

5 files changed

+30
-4
lines changed

.changeset/angry-mayflies-matter.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: correctly validate `undefined` snippet params with default value

packages/svelte/src/compiler/phases/3-transform/client/visitors/SnippetBlock.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export function SnippetBlock(node, context) {
2424
const transform = { ...context.state.transform };
2525
const child_state = { ...context.state, transform };
2626

27+
let fallback_arr = [];
28+
2729
for (let i = 0; i < node.parameters.length; i++) {
2830
const argument = node.parameters[i];
2931

@@ -49,6 +51,9 @@ export function SnippetBlock(node, context) {
4951
for (const path of paths) {
5052
const name = /** @type {Identifier} */ (path.node).name;
5153
const needs_derived = path.has_default_value; // to ensure that default value is only called once
54+
if (needs_derived) {
55+
fallback_arr.push(i);
56+
}
5257
const fn = b.thunk(
5358
/** @type {Expression} */ (context.visit(path.expression?.(b.maybe_call(b.id(arg_alias)))))
5459
);
@@ -67,12 +72,16 @@ export function SnippetBlock(node, context) {
6772
}
6873
}
6974
if (dev) {
75+
const [anchor, ...validations_args] = args;
7076
declarations.unshift(
7177
b.stmt(
7278
b.call(
7379
'$.validate_snippet_args',
7480
.../** @type {Identifier[]} */ (
75-
args.map((arg) => (arg?.type === 'Identifier' ? arg : arg?.left))
81+
[anchor, b.array(fallback_arr.map((i) => b.literal(i))), ...validations_args].map(
82+
(arg) =>
83+
arg?.type === 'Identifier' || arg.type === 'ArrayExpression' ? arg : arg?.left
84+
)
7685
)
7786
)
7887
)

packages/svelte/src/internal/client/dev/validation.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import { invalid_snippet_arguments } from '../../shared/errors.js';
22
/**
33
* @param {Node} anchor
4+
* @param {number[]} with_fallback_idx
45
* @param {...(()=>any)[]} args
56
*/
6-
export function validate_snippet_args(anchor, ...args) {
7+
export function validate_snippet_args(anchor, with_fallback_idx, ...args) {
78
if (typeof anchor !== 'object' || !(anchor instanceof Node)) {
89
invalid_snippet_arguments();
910
}
10-
for (let arg of args) {
11-
if (typeof arg !== 'function') {
11+
for (let i = 0; i < args.length; i++) {
12+
const arg = args[i];
13+
if (typeof arg !== 'function' && !(with_fallback_idx.includes(i) && arg === undefined)) {
1214
invalid_snippet_arguments();
1315
}
1416
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
html: `<p>default</p>`
5+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{#snippet test(param = "default")}
2+
<p>{param}</p>
3+
{/snippet}
4+
5+
{@render test()}

0 commit comments

Comments
 (0)