Skip to content

Commit 3b55dc9

Browse files
committed
Allow undefined as exported value
1 parent 2543ac6 commit 3b55dc9

File tree

1 file changed

+126
-16
lines changed

1 file changed

+126
-16
lines changed

crates/next-core/src/segment_config.rs

Lines changed: 126 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use anyhow::{Result, bail};
44
use serde::{Deserialize, Serialize};
55
use serde_json::Value;
66
use swc_core::{
7-
common::{GLOBALS, Span, Spanned, source_map::SmallPos},
7+
common::{DUMMY_SP, GLOBALS, Span, Spanned, source_map::SmallPos},
88
ecma::{
99
ast::{
1010
ClassExpr, Decl, ExportSpecifier, Expr, ExprStmt, FnExpr, Lit, ModuleDecl,
@@ -378,7 +378,11 @@ pub async fn parse_segment_config_from_source(
378378

379379
parse(
380380
&ident.id.sym,
381-
decl.init.as_deref().map(Cow::Borrowed),
381+
Some(
382+
decl.init.as_deref().map(Cow::Borrowed).unwrap_or_else(
383+
|| Cow::Owned(*Expr::undefined(DUMMY_SP)),
384+
),
385+
),
382386
decl.span(),
383387
)
384388
.await?;
@@ -486,13 +490,32 @@ async fn parse_config_value(
486490
span: Span,
487491
) -> Result<()> {
488492
let get_value = || {
489-
init.map(|init| eval_context.eval(&init))
490-
.unwrap_or(JsValue::Constant(ConstantValue::Undefined))
493+
init.map(|init| eval_context.eval(&init)).map(|v| {
494+
// Special case, as we don't call `link` here: assume that `undefined` is a free
495+
// variable.
496+
if let JsValue::FreeVar(name) = &v
497+
&& name == "undefined"
498+
{
499+
JsValue::Constant(ConstantValue::Undefined)
500+
} else {
501+
v
502+
}
503+
})
491504
};
492505

493506
match key {
494507
"config" => {
495-
let value = get_value();
508+
let Some(value) = get_value() else {
509+
return invalid_config(
510+
source,
511+
"config",
512+
span,
513+
rcstr!("It musn't be reexported."),
514+
None,
515+
IssueSeverity::Error,
516+
)
517+
.await;
518+
};
496519

497520
if is_app_router {
498521
return invalid_config(
@@ -546,6 +569,9 @@ async fn parse_config_value(
546569
.await;
547570
};
548571

572+
if matches!(val, JsValue::Constant(ConstantValue::Undefined)) {
573+
return Ok(());
574+
}
549575
match key {
550576
"runtime" => {
551577
let Some(val) = val.as_str() else {
@@ -635,7 +661,20 @@ async fn parse_config_value(
635661
}
636662
}
637663
"dynamic" => {
638-
let value = get_value();
664+
let Some(value) = get_value() else {
665+
return invalid_config(
666+
source,
667+
"dynamic",
668+
span,
669+
rcstr!("It musn't be reexported."),
670+
None,
671+
IssueSeverity::Error,
672+
)
673+
.await;
674+
};
675+
if matches!(value, JsValue::Constant(ConstantValue::Undefined)) {
676+
return Ok(());
677+
}
639678
let Some(val) = value.as_str() else {
640679
return invalid_config(
641680
source,
@@ -664,8 +703,20 @@ async fn parse_config_value(
664703
};
665704
}
666705
"dynamicParams" => {
667-
let value = get_value();
668-
706+
let Some(value) = get_value() else {
707+
return invalid_config(
708+
source,
709+
"dynamicParams",
710+
span,
711+
rcstr!("It musn't be reexported."),
712+
None,
713+
IssueSeverity::Error,
714+
)
715+
.await;
716+
};
717+
if matches!(value, JsValue::Constant(ConstantValue::Undefined)) {
718+
return Ok(());
719+
}
669720
let Some(val) = value.as_bool() else {
670721
return invalid_config(
671722
source,
@@ -681,7 +732,17 @@ async fn parse_config_value(
681732
config.dynamic_params = Some(val);
682733
}
683734
"revalidate" => {
684-
let value = get_value();
735+
let Some(value) = get_value() else {
736+
return invalid_config(
737+
source,
738+
"revalidate",
739+
span,
740+
rcstr!("It musn't be reexported."),
741+
None,
742+
IssueSeverity::Error,
743+
)
744+
.await;
745+
};
685746

686747
match value {
687748
JsValue::Constant(ConstantValue::Num(ConstantNumber(val))) if val >= 0.0 => {
@@ -702,8 +763,20 @@ async fn parse_config_value(
702763
}
703764
}
704765
"fetchCache" => {
705-
let value = get_value();
706-
766+
let Some(value) = get_value() else {
767+
return invalid_config(
768+
source,
769+
"fetchCache",
770+
span,
771+
rcstr!("It musn't be reexported."),
772+
None,
773+
IssueSeverity::Error,
774+
)
775+
.await;
776+
};
777+
if matches!(value, JsValue::Constant(ConstantValue::Undefined)) {
778+
return Ok(());
779+
}
707780
let Some(val) = value.as_str() else {
708781
return invalid_config(
709782
source,
@@ -732,8 +805,20 @@ async fn parse_config_value(
732805
};
733806
}
734807
"runtime" => {
735-
let value = get_value();
736-
808+
let Some(value) = get_value() else {
809+
return invalid_config(
810+
source,
811+
"runtime",
812+
span,
813+
rcstr!("It musn't be reexported."),
814+
None,
815+
IssueSeverity::Error,
816+
)
817+
.await;
818+
};
819+
if matches!(value, JsValue::Constant(ConstantValue::Undefined)) {
820+
return Ok(());
821+
}
737822
let Some(val) = value.as_str() else {
738823
return invalid_config(
739824
source,
@@ -762,8 +847,20 @@ async fn parse_config_value(
762847
};
763848
}
764849
"preferredRegion" => {
765-
let value = get_value();
766-
850+
let Some(value) = get_value() else {
851+
return invalid_config(
852+
source,
853+
"preferredRegion",
854+
span,
855+
rcstr!("It musn't be reexported."),
856+
None,
857+
IssueSeverity::Error,
858+
)
859+
.await;
860+
};
861+
if matches!(value, JsValue::Constant(ConstantValue::Undefined)) {
862+
return Ok(());
863+
}
767864
let preferred_region = match value {
768865
// Single value is turned into a single-element Vec.
769866
JsValue::Constant(ConstantValue::Str(str)) => vec![str.to_string().into()],
@@ -813,7 +910,20 @@ async fn parse_config_value(
813910
config.generate_static_params = Some(span);
814911
}
815912
"experimental_ppr" => {
816-
let value = get_value();
913+
let Some(value) = get_value() else {
914+
return invalid_config(
915+
source,
916+
"experimental_ppr",
917+
span,
918+
rcstr!("It musn't be reexported."),
919+
None,
920+
IssueSeverity::Error,
921+
)
922+
.await;
923+
};
924+
if matches!(value, JsValue::Constant(ConstantValue::Undefined)) {
925+
return Ok(());
926+
}
817927
let Some(val) = value.as_bool() else {
818928
return invalid_config(
819929
source,

0 commit comments

Comments
 (0)